Почему я получаю java.lang.IllegalStateException "Не в потоке приложения FX" на JavaFX?

У меня есть приложение с TableView, у которого есть подключенный слушатель, поэтому он обновляется, как только он обнаруживает изменение, но дело в том, что я получаю java.lang.IllegalStateException: Not on FX application thread; currentThread = Smack Listener Processor (0). Вот мой код:

/**
 * This function resets the pagination pagecount
 */
public void resetPage() {
    try {
        System.out.println("RESET"); 
        int tamRoster = this.loginManager.getRosterService().getRosterList().size();
        paginationContactos.setPageCount((int)(Math.ceil(tamRoster*1.0/limit.get())));
        int tamEnviados = this.loginManager.getRosterService().getEnviadasList().size();
        paginationEnviadas.setPageCount((int)(Math.ceil(tamEnviados*1.0/limit.get())));
        int tamRecibidas = this.loginManager.getRosterService().getRecibidasList().size();
        paginationRecibidas.setPageCount((int)(Math.ceil(tamRecibidas*1.0/limit.get())));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void doSomething () {
        this.loginManager.getRosterService().getRosterList().addListener(new ListChangeListener<RosterDTO>() {
            @Override
            public void onChanged(
                    javafx.collections.ListChangeListener.Change<? extends RosterDTO> c) {
                // TODO Auto-generated method stub
                resetPage();
                while (c.next()) {
                    if (c.wasPermutated()) {
                        System.out.println("PERM");
                    } else if (c.wasUpdated()) {
                        System.out.println("UPD");
                    } else {
                        System.out.println("ELSE");
                    }
                }
            }
         });
}

Пока он входит в метод resetPage, я получаю это исключение. Почему это происходит? Как я могу это исправить? Спасибо заранее.

Ответ 1

Пользовательский интерфейс не может быть напрямую обновлен из потока, отличного от приложения. Вместо этого используйте Platform.runLater(), с логикой внутри объекта Runnable. Например:

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

Как выражение лямбда:

// Avoid throwing IllegalStateException by running from a non-JavaFX thread.
Platform.runLater(
  () -> {
    // Update UI here.
  }
);

Ответ 2

Код JavaFX позволяет обновлять пользовательский интерфейс из потока приложений JavaFX. Но из приведенного выше сообщения об исключении говорится, что он не использует поток приложений FX.

Один из способов, который вы можете исправить, - запустить поток приложения FX из метода resetPage и внести изменения в него.