Search code examples
javamultithreadinggluon

JavaFX freezes when I start the thread - I'm using Runlater command


I have a simple thread like this.

public class CameraThread extends Thread {

    private AtomicBoolean runCamera;

    public CameraThread(AtomicBoolean runCamera) {
        this.runCamera = runCamera;
    }

    @Override
    public void run() {
        while (Main.RUNTHREAD) {
            while (runCamera.get()) {
                Platform.runLater(() -> {
                    System.out.println("Hello");
                    threadSleep();
                });
            }
        }
    }

    private void threadSleep() {
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

And when I set runCamera to runCamera.set(true) utside from the thread, the whole GUI freezes and I cannot do anything.

This is a minimal example and I can't get it to work properly. I have used RunLater command before, but this time, I'm sitting at a Dell precision M6400 machine from 2007. Could it happen that this machine cannot handle threads with Java?

Or how can I solve this issue?

To reproduce this issue, just type the following:

wget https://github.com/DanielMartensson/Darknet-Data-Creator/archive/main.zip
unzip Darknet-Data-Creator-main.zip
cd Darknet-Data-Creator-main
mvn javafx:run

Then click on Scan button, select a web camera (USB, laptop camera) and then press Save to folder button. Just select some arbitary folder. Then press Open camera button


Solution

  • The issue is that you are using Thread.Sleep() inside Platform.runLater(...), which means that you are sleeping the GUI, not your camera thread.

    Try this instead, note how runLater is outside of the Platform.runLater code:

    @Override
    public void run() {
        while (Main.RUNTHREAD) {
            while (runCamera.get()) {
                Platform.runLater(() -> {
                    System.out.println("Hello");
                });
                //Now thread sleep is outside of runLater:
                threadSleep();
            }
        }
    }
    

    The only thing that should go inside the runlater is things that directly change the GUI. Any calculation, sleeping, processing, file reading etc should be kept separate.