Welcome to the CSC Q&A, on our server named in honor of Ada Lovelace. Write great code! Get help and give help!
It is our choices... that show what we truly are, far more than our abilities.

Categories

+36 votes

I get this error: Exception in thread "pool-2-thread-1" java.lang.IllegalStateException: Not on FX application thread; currentThread = pool-2-thread-1 when an action calls this method

    public void startVideo() {
	if (chosenVideo.isOpened()) {
		Runnable frameGrabber = new Runnable() {
			public void run() {
				if (chosenVideo.getCurrentFrameNum() <= chosenVideo.getEndFrameNum()) {
					sliderBar.setValue(chosenVideo.getCurrentFrameNum());
					//currentTimeLabel.setText(getTime(chosenVideo.getCurrentFrameNum()));
					displayFrame();
				}
			}
		};
		
		this.timer = Executors.newSingleThreadScheduledExecutor();
		this.timer.scheduleAtFixedRate(frameGrabber, 0,(int) chosenVideo.getFrameRate(), TimeUnit.MILLISECONDS);
	}
}

The commented out line is the origin of the error. I am trying to have a label displaying the current time update as the "video" plays. Any suggestions?

asked in CSC285_Fall2018 by (1 point)

1 Answer

+16 votes
 
Best answer

The timer is running its code on a separate thread from the JavaFX UI thread, and the UI thread is the only one that is allowed to make changes to elements of the user interface. This is why we had to wrap: Platform.runLater(() -> { /* code here */ } ); around the imageview.setImage(...) method, to ask the JavaFX UI thread to schedule some code to be run soon (but not immediately). You're probably already doing this inside of your displayFrame() method.

So, the simplest fix is to change your code to use:

Platform.runLater(() -> { 
   currentTimeLabel.setText(getTime(chosenVideo.getCurrentFrameNum()));
});

One unrelated tip for improving the elegance of your code:

instead of having a getTime(...) converter method inside of your Controller class, why not have your Video class provide a getCurrentTime() method? (Converting between frames and seconds should be the Video class's responsibility, not the UI Controller's responsibility!)

answered by (508 points)
selected by
+7

Ahhh. Thank you.

...