Pergunta

Meu GUI trava porque eu preciso atualizá-lo através do EDT, no entanto, eu preciso também passar uma variável que está sendo atualizações com a GUI:

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

Esta não funciona. Eu preciso definir o texto na EDT, mas não posso passar numOfPlayers a ele sem declará-lo como final (o que eu não quero fazer, porque mudou à medida que novos jogadores se juntar ao servidor)

Foi útil?

Solução

A solução mais fácil seria usar um final variável temporária:

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

Outras dicas

Você tem que torná-la definitiva ou têm a referência Runnable um campo (varable classe). Se referência a um campo se certificar de que o segmento seguro (via sincronizados ou volátil).

Como sobre isto:

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

NOTA: Presumo que o OP tem uma boa razão para não marcar numOfPlayers como final, talvez que ele seja alterado mais tarde no mesmo loop while no código que não é relevante para a questão, por isso não mostrado. E assim que numOfPlayers é declarada antes do laço while.

Sem esta hipótese, eu não iria fazer a newText variável adicional.

Definir esta fora classe de seu método:

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

(Para os fins deste exemplo, estou assumindo que há uma boa razão para usar uma variável temporária última escopo localmente não vai funcionar. Eu honestamente não consigo pensar em qualquer razão para essa restrição, no entanto.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top