0

My problem is that I have a JavaFX TextArea and want to update its contents in a separate thread to show new text instantly instead of a bunch after the method has finished. Say, for example, I wanted to build a timer. In the current case, the TextArea would show 10 at the beginning, then I would press the "Start" button, wait ten seconds and a zero shows up. If this works multithreaded, it would count down from ten to zero with all the numbers in between.

Here's a sample code:

TextArea textArea = new TextArea();
Button button = new Button("Start");
GridPane root = new GridPane();
root.add(textArea);
root.add(button);

button.setOnMouseClicked((event) -> {
   new Thread(() -> {
      for (int i = 10; i >= 0; i--) {
         textArea.setText(Integer.parseInt(i));
         try { Thread.sleep(1000); }
         catch (InterruptedException ie) { ie.printStackTrace(); }
      }
   }).start();
});

This code ends in an IndexOutOfBoundsException in the FX Application Thread for me, which only shows up when the setOnMouseClicked event is executed in another thread. It works for both the "FX Application Thread" and the "Main" thread.

nick16384
  • 41
  • 5
  • 3
    See if something from the `Animation` API like `Timeline` or `AnimationTimer` can help – SedJ601 Jul 29 '23 at 22:20
  • 4
    So, that code should fail to compile, as `parseInt` returns an `int`, and `setText` expects a `String`. But I'll assume that's a mistake only in your question and in your real code you actually use something like `Integer.toString(i)`. Now, a quick fix for your code would be to use `String text = Integer.toString(i); Platform.runLater(() -> textArea.setText(text));`. However, using background threads for something like this is overkill and makes everything harder. You should do as SedJ601 suggests and use an animation. – Slaw Jul 29 '23 at 22:24
  • 4
    See https://stackoverflow.com/a/60685975/6395627 for some more information. – Slaw Jul 29 '23 at 22:27
  • [JavaFX countdown using timeline and displaying as a label](https://stackoverflow.com/questions/67578178/javafx-countdown-using-timeline-and-displaying-as-a-label) – Abra Jul 30 '23 at 06:03
  • https://stackoverflow.com/questions/50626831/how-to-set-up-two-timelines-to-one-app/50627639#50627639 – SedJ601 Jul 30 '23 at 06:48
  • 3
    Understand that JavaFX is, by design, single threaded, **you must not**: *Modify JavaFX TextArea with a Thread other than "JavaFX Application Thread"*. Techniques suggested in comments, don't actually modify the node from another thread at all. All animation events and timeline events occur only on the JavaFX thread. `runLater` calls schedule the thing to run later on the JavaFX application thread. [Why?](https://web.archive.org/web/20120122082554/http://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html) – jewelsea Jul 30 '23 at 11:58

0 Answers0