JavaFX: задача не будет обновлять интерфейс

1

Я работаю над клиентом онлайн-покера Омахи, написанным в javaFX + java.

Мне нужно показать anchorPane, содержащую 3 кнопки после того, как control.call() завершит выполнение. Я знаю, что control.call() завершает выполнение, но по какой-то причине task.setOnSucceeded(new EventHandler() { метод task.setOnSucceeded(new EventHandler() { handle не обновляет пользовательский интерфейс.

Что я делаю не так?

public void newRound() {

    sog = StateOfGame.PREFLOP;       

     ControlGameOnNewThread control = new ControlGameOnNewThread();

    Task task = new Task() {

        @Override
        protected Object call() throws Exception {
            control.call();
            return null;
        }
    };

    task.setOnSucceeded(new EventHandler() {

        @Override
        public void handle(Event event) {
            if (client.getAction() == FirstToAct.me) {
                System.out.println("Task finsished");
                    showOptions(client.getToCall());
                    opponentBetField.setText(new Integer(opp.chipsInvested).toString());
                    myBetField.setText(new Integer(client.chipsInvested).toString());
                    System.out.println("Task finsished");

            }
    }
    });


    new Thread(task).start();


}
  • 0
    Вы уверены, что ваш метод call(...) выполняется успешно, а не вызывает исключение? Попробуйте зарегистрировать setOnFailed(...) с помощью task.getException().printStackTrace() чтобы увидеть, если что-то выбрасывается.
Теги:
multithreading
javafx
task
concurrency

3 ответа

1

Когда вы переопределяете метод call(), вы можете переопределить метод succeeded(): (См. Последний пример в javadoc задачи.)

@Override protected void succeeded() {
     super.succeeded();
     updateMessage("Done!");
}

succeeded() уже вызван в приложении JavaFX Application Thread, поэтому вам не нужно делать это самостоятельно.

Вы уверены, что код в методе дескриптора не вызывается? Может быть, выбрано исключение NullPointerException, которое вы, возможно, не видите? Является ли сравнение работой, как ожидалось?

Попробуйте переместить код, if (client.getAction()... в переопределенном succeeded() метод и поставить Println перед Условным оператором для того, чтобы увидеть это называется или нет.

(EDIT: опечатки)

  • 0
    Строка 347 ish github.com/zeroRooter/Omaha-Poker/blob/master/src/huclient/… Да, код определенно не выполняется, я сделал то, что вы сказали с помощью println, и я загрузил его в git снова. Переопределение выполнено успешно должно делать то же самое, что я делаю, правда?
  • 0
    @zeroRooter yes - поместить оператор if с его блоком в переопределенный метод successful (). Это должно сделать то же самое. Пока вы это делаете, также переопределите fail () и cancelled () и поместите туда операторы println. Вы также должны поместить оператор print прямо перед оператором return в методе call (). Таким образом, вы можете видеть, делает ли метод вызова это или получает исключение между ними. Исключение будет храниться в exceptionProperty которое вы можете посмотреть в методе failed() .
1

Проблема в том, что вы обновляете пользовательский интерфейс в другом потоке. Если вы находитесь в другом потоке и хотите обновить интерфейс пользователя

Вам нужно позвонить


Platform.runLater(new Runnable() {
  @Override public void run() {
    //Update UI here     
  }
});

вызывающий это вызовет основной поток и обновит все необходимое обновление до пользовательского интерфейса

РЕДАКТИРОВАТЬ

public void newRound() {

    sog = StateOfGame.PREFLOP;       

     ControlGameOnNewThread control = new ControlGameOnNewThread();

    Task task = new Task() {

        @Override
        protected Object call() throws Exception {
            control.call();
            return null;
        }
    };

    task.setOnSucceeded(new EventHandler() {

        @Override
        public void handle(Event event) {

            if (client.getAction() == FirstToAct.me) {

                Platform.runLater(new Runnable() {
                  @Override public void run() {
                    System.out.println("Task finsished");
                    showOptions(client.getToCall());
                    opponentBetField.setText(new Integer(opp.chipsInvested).toString());
                    myBetField.setText(new Integer(client.chipsInvested).toString());
                    System.out.println("Task finsished");     
                  }
                });
            }
    }
    });


    new Thread(task).start();


}
  • 0
    Я пытался реализовать то, что вы сказали, но я столкнулся с той же проблемой. Вот новый код: pastebin.com/zcvybKik
  • 0
    @zeroRooter обновил мой ответ. Я имел в виду, что обновление пользовательского интерфейса должно быть только в экземплярах классов.
Показать ещё 5 комментариев
-1

Ваша информация была полезной, но я думаю, что все предложенные методы сработали бы (включая мою начальную). Проблема в том, что задача никогда не заканчивалась тем, что onTaskSucceded никогда не выполнялся. Чтобы завершить задачу после завершения, я должен был установить демона в true:

Thread thread = new Thread(task);
        thread.setDaemon(true);
        thread.start();
  • 0
    Даже если это работает, я думаю, что это может скрывать некоторые основные проблемы с тем, как вы используете задачи. То, действительно ли вызывается задача onTaskSucceeded, не должно быть связано с состоянием демона потока.
  • 0
    Ваш " setDaemon(true) " код был выполнен после вставки вызова setDaemon(true) ?
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню