Search code examples
javajavafxmedia-player

JavaFX - MediaPlayer - How do I change the cursor while the media player is loading the image?


I am using OpenJDK 15.0.1 and JavaFX 15.0.1 on Windows 10.

I have provided a UI to allow a user to select a video from their machine using a FileChooser. Once selected the video will start to play in a MediaPlayer. Loading the video takes a little time depending on the size of the video. During this time, I am trying to change the cursor to a WAIT cursor so the user knows the system is processing their request.

Nothing I have tried works. I have deleted or commented out all lines that change the cursor back to DEFAULT in the entire code base. I am setting the cursor to WAIT on every JavaFX Node I can find that has the method. I have cut and paste the following lines in between every line of code in the button's action method that opens the FileChooser and loads the video into the MediaPlayer:

mediaView.setCursor(Cursor.WAIT);
videosTabGrid.setCursor(Cursor.WAIT);
primaryStage.getScene().setCursor(Cursor.WAIT);
primaryStage.getScene().getRoot().setCursor(Cursor.WAIT);

The whole time the video is loading, the cursor is the ARROW. As soon the video loads, the cursor changes to WAIT. I just can't find a way to change the cursor while the video loads. Please help.

Thanks.


Solution

  • This all had to do with the UI thread. This was not the typical UI blocking thread issue since the MediaPlayer is itself a JavaFX UI component. The solution was two fold:

    1. Start a new thread inside of the UI thread to off load the work being done.
    2. Inside the new thread, run the UI changes inside of a Platform.runLater() method.

    Here is the example code:

    primaryStage.getScene().getRoot().setCursor(Cursor.WAIT);
    new Thread(){
        public void run() {
            try {
                ...
                [MEDIA PLAYER VIDEO LOAD HERE]
                ...
            } finally {
                Platform.runLater(() -> primaryStage.getScene().getRoot().setCursor(Cursor.DEFAULT));
            } // try finally
        } // run
    }.start();