在事件调度线程外更新默认列表模型
Updating Default List Model outside Event Dispatch Thread
我正在尝试编写一个带有 GUI 的 java 应用程序,允许用户连接到服务器并挑战玩家列表中的玩家。因此,必须有EDT和其他线程正在等待邀请。
现在我在尝试刷新用户 table 时遇到问题。这是刷新按钮。单击时,它只是将 "REFR" 发送到服务器。
class RefreshButton extends JButton implements ActionListener {
private static final long serialVersionUID = 1L;
PrintWriter outC;
public RefreshButton(PrintWriter outC) {
this.addActionListener(this);
this.setText("Refresh");
this.outC = outC;
}
public void actionPerformed(ActionEvent e) {
outC.println("REFR");
}
}
现在,还有另一个线程,它侦听来自服务器的响应。为避免竞争,EDT 仅发送数据(在 EDT 中不从服务器读取数据),而另一个处理来自服务器的所有响应。
public void run() {
while (true) {
try {
String c = inC.readLine();
System.out.println(c);
String[] cmd = c.split(" ");
switch (cmd[0]) {
case "INV":
int reply = JOptionPane.showConfirmDialog(null,
"Do you accept challenge from " + cmd[1] + "?", "Challenge",
JOptionPane.YES_NO_OPTION);
if (reply == JOptionPane.YES_OPTION) {
...
} else {
outC.println("NO");
}
break;
case "REFR":
retrievePlayersList(inC);
break;
case "DECL":
JOptionPane.showMessageDialog(null,
"Challenge declined");
break;
...
应该更新与 EDT 中的 JList 关联的默认列表模型的方法。
private static void retrievePlayersList(BufferedReader inC)
throws IOException {
String p = inC.readLine();
model.clear(); ///delete old data
while (!p.equals("ENDlist")) {
...
model.addElement(new Player(...));
//DefaultListModel is assigned in constructor of the class (thread)
p = inC.readLine();
}
}
有时有效,有时无效。我知道问题是在 EDT 之外调用了 addElement()。有人可以告诉我如何解决这个问题吗?
使用 SwingUtilities.invokeAndWait() 向模型添加元素。 "invokeLatter" 可能不适合您。这取决于您的应用程序。
我正在尝试编写一个带有 GUI 的 java 应用程序,允许用户连接到服务器并挑战玩家列表中的玩家。因此,必须有EDT和其他线程正在等待邀请。
现在我在尝试刷新用户 table 时遇到问题。这是刷新按钮。单击时,它只是将 "REFR" 发送到服务器。
class RefreshButton extends JButton implements ActionListener {
private static final long serialVersionUID = 1L;
PrintWriter outC;
public RefreshButton(PrintWriter outC) {
this.addActionListener(this);
this.setText("Refresh");
this.outC = outC;
}
public void actionPerformed(ActionEvent e) {
outC.println("REFR");
}
}
现在,还有另一个线程,它侦听来自服务器的响应。为避免竞争,EDT 仅发送数据(在 EDT 中不从服务器读取数据),而另一个处理来自服务器的所有响应。
public void run() {
while (true) {
try {
String c = inC.readLine();
System.out.println(c);
String[] cmd = c.split(" ");
switch (cmd[0]) {
case "INV":
int reply = JOptionPane.showConfirmDialog(null,
"Do you accept challenge from " + cmd[1] + "?", "Challenge",
JOptionPane.YES_NO_OPTION);
if (reply == JOptionPane.YES_OPTION) {
...
} else {
outC.println("NO");
}
break;
case "REFR":
retrievePlayersList(inC);
break;
case "DECL":
JOptionPane.showMessageDialog(null,
"Challenge declined");
break;
...
应该更新与 EDT 中的 JList 关联的默认列表模型的方法。
private static void retrievePlayersList(BufferedReader inC)
throws IOException {
String p = inC.readLine();
model.clear(); ///delete old data
while (!p.equals("ENDlist")) {
...
model.addElement(new Player(...));
//DefaultListModel is assigned in constructor of the class (thread)
p = inC.readLine();
}
}
有时有效,有时无效。我知道问题是在 EDT 之外调用了 addElement()。有人可以告诉我如何解决这个问题吗?
使用 SwingUtilities.invokeAndWait() 向模型添加元素。 "invokeLatter" 可能不适合您。这取决于您的应用程序。