Передача переменных в поток отправки событий
-
09-09-2019 - |
Вопрос
Мой графический интерфейс блокируется, потому что мне нужно обновить его через EDT, однако мне также нужно передать переменную, которая обновляется с помощью графического интерфейса:
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
временная переменная:
final int currentNumOfPlayers = numOfPlayers;
EventQueue.invokeLater(new Runnable() {
public void run() {
numPlayers.setText("There are currently " +
currentNumOfPlayers + " players in this game");
}
});
Другие советы
Вы должны сделать это окончательным или иметь Runnable
ссылаться на поле (переменную класса).При ссылке на поле убедитесь, что оно потокобезопасно (через синхронизированное или нестабильное).
Как насчет этого:
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);
}
});
}
ПРИМЕЧАНИЕ:Я предполагаю, что у ОП есть веская причина не отмечать numOfPlayers
как окончательное, возможно, что оно будет изменено позже в том же самом while
цикл в коде, который не имеет отношения к вопросу, поэтому не показан.И таким образом, что numOfPlayers
объявляется до того, как while
петля.
Без этого предположения я бы не стал создавать дополнительную переменную newText
.
Определите этот класс вне вашего метода:
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");
}
});
(Для целей этого примера я предполагаю, что существует веская причина, по которой использование конечной временной переменной с локальной областью действия не будет работать.Хотя, честно говоря, я не могу придумать никакой причины для такого ограничения.)