Вопрос

Мой графический интерфейс блокируется, потому что мне нужно обновить его через 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");
    }
});

(Для целей этого примера я предполагаю, что существует веская причина, по которой использование конечной временной переменной с локальной областью действия не будет работать.Хотя, честно говоря, я не могу придумать никакой причины для такого ограничения.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top