您好,我正在尝试使用RMI实现聊天。该算法如下:共享RMI对象和客户端都有一个String变量用于最后输入的消息。每当客户端键入消息时,来自共享RMI对象的消息都会更新(messageRMI = messageClient)。如果客户端的最后一条消息没有与RMI对象中的消息相同,则最后一条消息将自动输入到jTextPane中。
这是摇摆工作者:
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground()
throws Exception {
byte[] the_image;
while (true) {
Thread.sleep(1000);
if (connected) {
try {
remote = (I) Naming.lookup("rmi://" + jTextFieldAddress.getText() + "/Niemand23");
switch (remote.refresh_chat(last_message)) {
case 0:
last_message = remote.last_message();
jTextPane1.getStyledDocument().insertString(jTextPane1.getDocument().getLength(), "\n ", null);
if (remote.hasImage()) {
the_image = remote.client_image();
formatC = new ImageIcon(the_image);
jTextPane1.insertIcon(formatC);
} else {
jTextPane1.insertIcon(noImageIcon);
}
jTextPane1.getStyledDocument()
.insertString(jTextPane1.getDocument().getLength(), "\n " + remote.last_message(), style);
jTextPane1.getStyledDocument().insertString(jTextPane1.getDocument().getLength(), "\n", null);
}
} catch (NotBoundException | MalformedURLException | RemoteException | BadLocationException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
};
工人应该每秒检查一下情况。最大的问题是,无论何时客户端键入消息,第二个GUI都会冻结。我已经尝试了一切但没有结果。有什么想法吗?
答案 0 :(得分:3)
如果您阅读了SwingWorker javadocs,则表示您不应该在doInBackground()
方法中直接更改Swing组件。
相反,您应该实施process()
方法并使用publish()
中的doInBackground()
方法。有关具体信息,请查看publish method。
在您的情况下,这需要在收到时将SwingWorker<Void, Void>
切换为SwingWorker<Void,String>
和publish()
每条消息。然后,您的process(String...s)
方法会使用传入的消息填充jTextPane1
。
尝试一下,看看它是如何工作的。
ETA :此外,您是否需要在循环的每个粗体中执行命名查找?地址不变,是吗?