5

我的 GUI 被锁定,因为我需要通过 EDT 更新它,但是,我还需要传递一个正在使用 GUI 更新的变量:

while ((message = this.in.readLine()).startsWith("NUMPLAYERS"))
{
    numOfPlayers = Integer.parseInt(message.split(":")[1]);
    numPlayers.setText("There are currently " + numOfPlayers + " players in this game");
}

这不起作用。我需要在 EDT 中设置文本,但我不能将 numOfPlayers 传递给它而不将其声明为最终的(我不想这样做,因为它随着新玩家加入服务器而改变)

4

4 回答 4

10

最简单的解决方案是使用final临时变量:

final int currentNumOfPlayers = numOfPlayers;
EventQueue.invokeLater(new Runnable() {
    public void run() {
       numPlayers.setText("There are currently " + 
               currentNumOfPlayers + " players in this game");
    }
});
于 2009-04-15T21:59:17.250 回答
2

您必须将其设为最终版本或将Runnable引用作为字段(类变量)。如果引用一个字段,请确保它是线程安全的(通过同步或易失性)。

于 2009-04-15T22:24:03.090 回答
1

这个怎么样:

while ((message = this.in.readLine()).startsWith("NUMPLAYERS")) {
    numOfPlayers = Integer.parseInt(message.split(":")[1]);
    final newText = "There are currently " + numOfPlayers + " players in this game";
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            numPlayers.setText(newText);
        }
    });
}

注意:我认为 OP 有充分的理由不将其标记numOfPlayers为最终版本,也许是稍后在与while问题无关的代码中的同一循环中对其进行了更改,因此未显示。因此,这numOfPlayers是在while循环之前声明的。

没有这个假设,我不会做额外的变量newText

于 2009-04-15T22:35:35.963 回答
0

在您的方法之外定义此类:

public abstract class MyRunnable implements Runnable {
    protected int var;
    public MyRunnable (int var) {
        this.var = var;
    }
}

Now your code can look like this:
SwingUtilities.invokeAndWait(new MyRunnable(5) {
    @Override
    public void run() {
        //numPlayers.setText("There are currently " + var + " players in this game");
    }
});

(出于本示例的目的,我假设有充分的理由说明为什么使用局部范围的最终临时变量不起作用。不过,老实说,我想不出有任何限制的原因。)

于 2009-04-16T04:07:22.843 回答