在AWT线程中运行代码

时间:2014-11-26 16:00:47

标签: java multithreading awt jtextpane

我有一个JTextPane,我用来放置聊天应用程序的聊天记录。现在有两个来源:

  1. 客户端线程侦听服务器消息。
  2. GUI:一个JField和添加到消息的按钮(临时,因为一切都是来自服务器)
  3. 以下是两种方法使用的代码:

    private void appendText(String text, AttributeSet attr) {
            try {
                int len = history.getDocument().getLength();
                history.getDocument().insertString(len, text + "\n", attr);
                        // Convert the new end location
                // to view co-ordinates
                Rectangle r = history.modelToView(len);
    
                // Finally, scroll so that the new text is visible
                if (r != null) {
                    scrollRectToVisible(r);
                }
            } catch (BadLocationException e) {
                System.out.println("Failed to append text: " + e);
            }
        }
    

    调试我注意到代码在两种情况下都会执行,但只有在通过GUI在AWT线程中运行时才能实际显示在组件中。

    因此,除非其他人有更好的主意,否则我有以下选择:

    1. 以某种方式在AWT上运行客户端线程。
    2. 以某种方式在AWT上运行append方法。
    3. 使用你们其中一个人的聪明答案。
    4. 有任何想法/建议吗?

2 个答案:

答案 0 :(得分:2)

试试这个:

private void appendText(String text, AttributeSet attr) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            // your method code here
        }
    });
}

看起来您正在尝试更新AWT线程之外的swing组件,因为您直接从客户端的线程调用appendText。你不能这样做。现在,如果您使用EventQueue.invokeLater,它将确保更新swing组件的代码在AWT线程中执行,无论您从哪个线程调用该方法。

答案 1 :(得分:0)

我相信你应该创建一个包含消息信息的类(如消息文本,发送者,接收者,时间戳)。像这样:

public class ChatHistoryElement {
    private String text;
    private Date moment;
    private User sender;
    private User receiver;
    public volatile volatile AbstractList<ChatHistoryElement> chatHistory = null;

    public String getMessage() {
        return text;
    }

    public Date getMoment() {
        return moment;
    }

    public User getSender() {
        return sender;
    }

    public User getReceiver() {
        return receiver;
    }

    public ChatHistoryElement(String text, Date moment, User sender, User receiver) {
        this.text = text;
        this.moment = moment;
        this.sender = sender;
        this.receiver = receiver;
        if (chatHistory == null) {
            chatHistory = new ArrayList<ChatHistoryElement>();
        }
        chatHistory.add(this);
    }
}

通过使您的历史记录不稳定,您始终可以使用ChatHistoryElement.chatHistory

来覆盖它