1

I'm having some trouble with my JavaFX application. I'm currently creating a Music Player and I have a slider at the bottom (similar to Spotify) that should move based on the duration of the song.

The problem is that my code lags out when using this Thread code. It gets the current duration of song and then it sets the value of the durationSlider before going to sleep for 1000 ms.

Does anyone know a way to fix this lag problem? The code still runs every second but my GUI lags out and I am completely unable to do anything.

public void startCounting(){
    mediaPlayer.setOnPlaying(new Thread() {
        @Override
        public void run() {
            Duration a;
            while (mediaPlayer.getStatus().equals(MediaPlayer.Status.PLAYING)) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("Shit aint workin bro");
                }
                a = mediaPlayer.getCurrentTime();
                int currentTime = (int) a.toSeconds();
                System.out.println(currentTime);
                durationSlider.setValue(50.0);  //Testing the setValue() method

            }
        }
    });
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Kristianasp
  • 61
  • 11
  • well i cant test your code right now , but as a suggestion , you should not update the UI from a `Runnable` , it also awkward how your code didnt throw an exception. The way you have attached the event listener is correct but you should change the method `durationSlider.setValue(50.0);` to be called from a `Platform.RunLater()` thread in order to update the UI. Check a similar solution here http://stackoverflow.com/questions/13784333/platform-runlater-and-task-in-javafx – AntJavaDev Feb 17 '16 at 10:30

1 Answers1

2

You are basically halting your UI thread, because onPlaying is called using the run method, not the start method of Thread. Instead, you should pass a Runnable that creates a new Thread and calls start on it. Do note that as @AntJavaDev said, in this case all changes to the UI should be made using Platform.runLater :

mediaPlayer.setOnPlaying(()-> {
    Thread th = new Thread() {
        @Override
        public void run() {
            Duration a;
            while (mediaPlayer.getStatus().equals(MediaPlayer.Status.PLAYING)) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("Shit aint workin bro");
                }
                a = mediaPlayer.getCurrentTime();
                int currentTime = (int) a.toSeconds();
                System.out.println(currentTime);
                Platform.runLater(() -> durationSlider.setValue(50.0));  //Testing the setValue() method

        }
    };
    th.start();
});

You might want to save this Thread instance so you can interact with it in your onStopped etc, or maybe set it to be a daemon thread, so it doesn't inhibit program closing.

Itai
  • 6,641
  • 6
  • 27
  • 51