Waarom krijg ik java.lang.IllegalStateException “Not on FX application thread” op JavaFX?

Ik heb een toepassing met een TableViewmet een aangesloten listener, zodat deze wordt vernieuwd zodra er een wijziging wordt gedetecteerd, maar het punt is dat ik java.lang.IllegalStateException: Not on FX application thread; currentThread = Smack Listener Processor (0).
Hier is mijn code:

/**
 * 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");
                    }
                }
            }
         });
}

Hoewel het de resetPage-methode invoert, krijg ik die uitzondering.
Waarom gebeurt dit?
Hoe kan ik het repareren?
Bij voorbaat dank.


Antwoord 1, autoriteit 100%

De gebruikersinterface kan niet rechtstreeks worden bijgewerkt vanuit een thread die niet van toepassing is. Gebruik in plaats daarvan Platform.runLater(), met de logica in het Runnable-object. Bijvoorbeeld:

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

Als lambda-uitdrukking:

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

Antwoord 2, autoriteit 3%

JavaFX-code maakt het mogelijk om de gebruikersinterface te updaten vanuit een JavaFX-toepassingsthread. Maar uit het bovenstaande uitzonderingsbericht staat dat het geen FX Application-thread gebruikt.

Een manier om dit op te lossen is door een FX Application-thread te starten vanaf de resetPage-methode en daar de wijzigingen aan te brengen.


Antwoord 3

Ik had een soortgelijk probleem dat ik zonderheb opgelost met behulp van het Platform.runLater():

“java.lang.IllegalStateException: niet op FX-toepassingsthread; currentThread = Thread-6”

Button play = new Button("Play");
EventHandler<ActionEvent> playHandler = e1 -> {
    Runnable runnable = () -> {
        play.setText("Pause");
        EventHandler<ActionEvent> timelineHandler e2 -> play();
        timeline = new Timeline(new KeyFrame(Duration.millis(2000), timelineHandler));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    };
    Thread t = new Thread(runnable);
    t.start();
};
play.setOnAction(playHandler);

OPGELOST! Verplaats alles wat niet gerelateerd is buiten de runnablelambda:

Button play = new Button("Play");
EventHandler<ActionEvent> playHandler = e1 -> {
    play.setText("Pause");
    Runnable runnable = () -> {
        EventHandler<ActionEvent> timelineHandler e2 -> play();
        timeline = new Timeline(new KeyFrame(Duration.millis(2000), timelineHandler));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
    };
    Thread t = new Thread(runnable);
    t.start();
};
play.setOnAction(playHandler);

Other episodes