我有一个类,可以从串行端口接收和发送信息:

public class Terminal implements Runnable
{
    static LinkedList<String> receiver = new LinkedList<String>();
    public Terminal()
    {
        //...
    }
    public String getReceivedMessage()
    {
        String data = receivedMessfges.removeFirst();
        return data;
    }
    // Other function that perform connection to COM port
    // ...
}

我还有基于 Swing 的 gui 类:

public class Gui extends JFrame
{
// Functions that display information, received from COM port
}

Terminal使用Gui第三类传递信息的正确方法是什么:

public class Monitor
{
    static Gui gui;
    static terminal terminal;
    public static void main(String args[])
    {
        monitor = new Monitor();
    }
    public Monitor()
    {
        gui = new Gui();
        terminal = new Terminal();
    }
    // Functions, that get information COM port
    // using getReceivedMessage() function
    // and display it on Gui
}

谢谢)


我将使用该类在Monitor之间进行通信GuiTerminal

如果receivedMessfges.removeFirst();直到收到应在 GUI 中显示的完整消息后才返回,您可以这样做:

Thread messageChecker = new Thread(new Runnable() {
    public void run() {
        while (!Thread.isInterrupted()) {
            String message = terminal.getReceivedMessage();
            // Prepare message for gui display
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    gui.methodToDisplayTheReceivedMessage(message);
                }
            }
        }
    }
}).start();

班级内的某个地方Monitor

该代码执行以下操作:

  • 创建一个新的 Runnable (匿名类)
    • 通过一种run()方法,我们
      • 检查线程是否被中断
      • 如果有,停止
      • 如果没有,请等到我们收到来自 的新消息并将其发送到 GUI。
  • 创建一个新的线程集来执行run()我们新的 Runnable 的方法
  • 启动这个线程。
  • 将对线程的引用分配给变量messageChecker

要停止线程,只需调用messageChecker.interrupt();.

另一方面,如果terminal.getReceivedMessage();仅返回部分消息,即在我们调用它之前收到的消息,我认为最好的方法是使用观察者模式。

Then, you need to write code to notify the observers of a complete message as soon as the terminal class has one. I would suggest to have a Thread internal to the Terminal class checking periodically for new data. As soon as it has a complete message, it should call notifyObservers(message) (with message obviously being a variable of type String containing the complete message).

In the Monitor class, you have to have an update(Observable o, Object arg) method to satisfy the Observer interface:

// In the Monitor class
void update(Observable terminal, Object message) {
    SwingUtilities.invokeLater(new Runnable() {
        gui.methodToDisplayTheReceivedMessage((String)message); // This cast is safe, since we only ever call notifyObservers() with a string argument.
    }
}

Last but not least, you need to call terminal.addObserver(this); from the Monitor class (from the constructor, probably), otherwise notifyObservers() will notify all your 0 observers and nothing happens.

Googling for the "java observer pattern" yields lots of useful resources and examples, in case you want to know more about it.


您可以使用外部接口,例如将数据写入文件并从那里读取......


我使用Monitor类的 Runnable 接口得到解决方案。但我需要睡觉,这可能是丢失数据的原因。是否有任何巧妙的方法可以将数据从 发送到 ,Terminal而Gui无需相互“介绍”它们(类Terminal和之间没有依赖关系Gui)

是receivedMessfges.removeFirst();阻塞功能吗?

我想是的。它是在 Java 标准集合中实现的函数。

现在不是转向 Java 8 的时候了吗?;)

@user1803551 好点!我的电脑太旧了,甚至不支持 Java 7,所以我没有关注最近的 Java 更新。😁

然后小心你的答案。JDK6 现在已经很老了,很多事情都发生了变化。您应该使用最新的 API 和约定。

我想念 invokeLater 作为 EDT 的通知程序