Answer the question
In order to leave comments, you need to log in
What causes the Not on FX application thread error?
I am writing an mp3 player. I want to make it so that when the song ends, the next one on the list starts playing automatically. There is a "beginTimer()" method that counts the time while the song is playing and moves the slider according to it:
private void beginTimer() {
timer = new Timer();
mediaPlayer.setOnReady(() -> songDuration.setMax(media.getDuration().toSeconds()));
timerTask = new TimerTask() {
@Override
public void run() {
double current = mediaPlayer.getCurrentTime().toSeconds();
double end = media.getDuration().toSeconds();
running = true;
songDuration.setValue((int) current);
if (current / end == 1) {
cancelTimer();
nextMedia();
}
}
};
timer.scheduleAtFixedRate(timerTask, 0, 1000);
}
Exception in thread "Timer-2" java.lang.IllegalStateException: Not on FX application thread; currentThread = Timer-2
at javafx.graphics/com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:292)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:446)
at javafx.graphics/javafx.scene.Parent$3.onProposedChange(Parent.java:474)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:113)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.setAll(VetoableListDecorator.java:108)
at javafx.controls/javafx.scene.control.skin.LabeledSkinBase.updateChildren(LabeledSkinBase.java:283)
at javafx.controls/javafx.scene.control.skin.LabeledSkinBase.lambda$new$11(LabeledSkinBase.java:220)
at javafx.controls/com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler.lambda$new$1(LambdaMultiplePropertyChangeListenerHandler.java:49)
at javafx.base/javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:86)
at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:181)
at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.base/javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)
at javafx.base/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)
at javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
at javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
at javafx.base/javafx.beans.property.StringProperty.setValue(StringProperty.java:71)
at javafx.controls/javafx.scene.control.Labeled.setText(Labeled.java:147)
at main.Controller.setSongLabel(Controller.java:182)
at main.Controller.nextMedia(Controller.java:105)
at main.Controller$1.run(Controller.java:138)
at java.base/java.util.TimerThread.mainLoop(Timer.java:556)
at java.base/java.util.TimerThread.run(Timer.java:506)
public void nextMedia() {
if (songCounter < playList.size() - 1) songCounter++;
else songCounter = 0;
mediaPlayer.stop();
if (running) cancelTimer();
setMediaPlayer();
setSongLabel();
playMedia();
}
private void setSongLabel() {
String fileName = playList.get(songCounter).getName();
songLabel.setText(fileName.substring(0, fileName.length() - 4));
}
Answer the question
In order to leave comments, you need to log in
Almost any UI system has its own thread, on which you need to access UI elements. Obviously, here you need to transfer the execution back to the FX application thread.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question