Pregunta

Mis GUI se bloquea porque necesito actualizarlo a través de la EDT, sin embargo, tienen que pasar también una variable que está siendo actualizaciones con la interfaz gráfica de usuario:

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

Esto no funciona. Necesito fijar el texto de la EDT, pero no puedo pasar numOfPlayers a ella sin que se declara como final (que no quiero hacer, porque cambió como nuevos jugadores se unen al servidor)

¿Fue útil?

Solución

La solución más fácil sería utilizar una variable temporal final:

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

Otros consejos

Hay que hacer que sea definitiva o la referencia Runnable un campo (varable clase). Si hace referencia a un campo de asegurarse de que es seguro para subprocesos (a través sincronizada o volátil).

¿Qué tal esto:

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: Asumo que el PO tiene una buena razón para no marcar numOfPlayers como final, tal vez que se cambia más adelante en el mismo bucle while en código que no es relevante para la cuestión, por lo que no se muestra. Y por lo tanto que se declara numOfPlayers antes del bucle while.

Sin este supuesto, yo no haría el newText variable adicional.

Definir esta clase fuera de su 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 los fines de este ejemplo, estoy asumiendo que hay una buena razón por la cual el uso de un local con ámbito variable TEMP final no va a funcionar. Sinceramente, no puedo pensar en ninguna razón para que la restricción, sin embargo.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top