5

EDT を使用して GUI を更新する必要があるため、GUI がロックしますが、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 を final として宣言せずに渡すことはできません (新しいプレイヤーがサーバーに参加すると変更されるため、これはしたくありません)。

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");
    }
});

(この例では、ローカル スコープの final temp 変数を使用しても機能しない十分な理由があると想定しています。ただし、正直なところ、その制限の理由は思いつきません。)

于 2009-04-16T04:07:22.843 に答える