在处理 Java (Swing) 中的其他线程时,哪种设计模式最适合更新 GUI?
例如,假设一个对象(如自定义 JPanel)有一个 JList,而 DefaultListModel 支持它。一个在 Socket 上监听的线程可以接收数据,然后想要根据来自套接字的信息更新 JList。
我了解 SwingUtilities.invokeLater,但这似乎是笨拙的代码,因为实际上我有许多不同的函数可以调用(从非 EDT 线程)来操作不同的 GUI 组件。
我想到的想法是创建某种带有 ArrayBlockingQueue 的消息传递系统。基本上我实现了 Runnable 并在 SwingUtilities.invokeLater 方法调用中传入this
. 然后该方法被执行,但它并不真正知道该做什么,但这就是我从线程安全的 ArrayBlockingQueue 中弹出“消息”的地方。
还有比这更好的设计模式吗?我的基本 JPanel 类
public class JPanelGUIThread extends JPanel implements Runnable
{
protected ArrayBlockingQueue<Object> guiUpdateMessages;
public JPanelGUIThread()
{
guiUpdateMessages = new ArrayBlockingQueue<Object>(10);
}
@Override
public void run()
{
while(guiUpdateMessages.size() > 0)
{
try
{
Object data = guiUpdateMessages.take();
if(data instanceof Object[])
{
handleGUIUpdateArray((Object[])data);
}
else
{
handleGUIUpdateObject(data);
}
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void handleGUIUpdateArray(Object[] objectArray)
{
}
public void handleGUIUpdateObject(Object object)
{
}
}
我的主要JPanel
public JLabel getChatLabel()
{
return chatLabel;
}
public JTextArea getChatArea()
{
return chatArea;
}
public JScrollPane getChatScrollPane()
{
return chatScrollPane;
}
public JTextField getMychat()
{
return mychat;
}
public JButton getSendButton()
{
return sendButton;
}
//This method is called from the EDT, so no need to perform adding messages
@Override
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == sendButton)
{
client.sendChatInformation(mychat.getText());
mychat.setText("");
}
}
public void clearOldChat()
{
Object[] data = new Object[3];
data[0] = chatArea;
data[1] = MessageType.SET;
data[2] = "";
guiUpdateMessages.add(data);
SwingUtilities.invokeLater(this);
}
@Override
public void handleGUIUpdateArray(Object[] objectArray)
{
if(objectArray[0] == chatArea)
{
if(objectArray[1] == MessageType.APPEND)
{
chatArea.append((String) objectArray[2]);
}
else if(objectArray[1] == MessageType.SET)
{
chatArea.setText((String) objectArray[2]);
}
}
}
}