Pasar variables a la rosca de distribución de eventos
-
09-09-2019 - |
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)
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.)