Question

My GUI locks up because I need to update it through the EDT, however, I need to also pass a variable that is being updates with the GUI:

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

This does not work. I need to set the text in the EDT but I cannot pass numOfPlayers to it without declaring it as final (which I don't want to do, because it changed as new players join the server)

Was it helpful?

Solution

The easiest solution would be to use a final temporary variable:

final int currentNumOfPlayers = numOfPlayers;
EventQueue.invokeLater(new Runnable() {
    public void run() {
       numPlayers.setText("There are currently " + 
               currentNumOfPlayers + " players in this game");
    }
});

OTHER TIPS

You have to make it final or have the Runnable reference a field (class varable). If referencing a field make sure that it's thread safe (via synchronized or volatile).

How about this:

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

NOTE: I assume that the OP has a good reason for not marking numOfPlayers as final, perhaps that it is changed later in the same while loop in code that's not relevant to the question, so not shown. And thus that numOfPlayers is declared before the while loop.

Without this assumption, I wouldn't make the additional variable newText.

Define this class outside of your method:

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

(For the purposes of this example, I am assuming that there is a good reason why using a locally scoped final temp variable will not work. I honestly can't think of any reason for that restriction, though.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top