-3

I am currently creating a program that utilizes multithreading. In each thread, it appends to a TextArea. I've come upon an error that I believe is due to multiple threads attempting to append to the TextArea at once. I am unable to switch to just using .setText() because of the bug where the textProperty listener does not notice a change when using the .setText() method. I'm relatively new to multithreading and apolgize if anything I said doesn't make sense, feel free to leave a comment for clarification.

Here is the code:

else console.appendText("\nfailure - " + arrays[finalJ][i] + ":" + word);

And the exception:

Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IndexOutOfBoundsException: Index 94 out of bounds for length 94 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266) at java.base/java.util.Objects.checkIndex(Objects.java:359) at java.base/java.util.ArrayList.get(ArrayList.java:427) at javafx.controls/javafx.scene.control.TextArea$TextAreaContent.get(TextArea.java:130) at javafx.controls/javafx.scene.control.TextArea$TextAreaContent.get(TextArea.java:311) at javafx.controls/javafx.scene.control.TextArea$TextAreaContent.get(TextArea.java:88) at javafx.controls/javafx.scene.control.TextInputControl$TextProperty.get(TextInputControl.java:1386) at javafx.controls/javafx.scene.control.TextInputControl$TextProperty.get(TextInputControl.java:1370) at javafx.base/javafx.beans.binding.StringExpression.getValueSafe(StringExpression.java:68) at javafx.controls/javafx.scene.control.skin.TextAreaSkin.lambda$new$16(TextAreaSkin.java:348) at javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:348) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80) at javafx.controls/javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1459) at javafx.controls/javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1463) at javafx.controls/javafx.scene.control.TextInputControl$TextProperty.controlContentHasChanged(TextInputControl.java:1402) at javafx.controls/javafx.scene.control.TextInputControl.lambda$new$0(TextInputControl.java:146) at javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:136) at javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80) at javafx.controls/javafx.scene.control.TextArea$TextAreaContent.insert(TextArea.java:218) at javafx.controls/javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:1264) at javafx.controls/javafx.scene.control.TextInputControl.updateContent(TextInputControl.java:572) at javafx.controls/javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:564) at javafx.controls/javafx.scene.control.TextInputControl.insertText(TextInputControl.java:486) at javafx.controls/javafx.scene.control.TextInputControl.appendText(TextInputControl.java:476) at com.example.encryptionraw/com.example.encryptionraw.HelloController.lambda$runSoloBrute$4(HelloController.java:247)

RBT
  • 24,161
  • 21
  • 159
  • 240
Ahxius
  • 19
  • 5
  • 7
    JavaFX, like most ui frameworks, is not thread safe, you need sync your updates back to the main event thread. You could use either a “push” or “pull” model. Pushing would have each thread sync their own updates to the UI, this can be messy and can occur a performance hit which could overload the main event thread. A pull model would have the threads “publish” their updates to some kind of queue, which would then be “polled” on a regular interval which then be used to update the ui (from within the main thread context) – MadProgrammer May 13 '22 at 23:54
  • [mcve] please .. btw: not aware of any bug in missing notification of setText vs. appendText. And even if there were any, don't understand how using the latter could work around any in the former because their effect is different. – kleopatra May 14 '22 at 07:16
  • The [JavaFX log solution](https://stackoverflow.com/questions/24116858/most-efficient-way-to-log-messages-to-javafx-textarea-via-threads-with-simple-cu) in the duplicate uses the "pull" model described by MadProgrammer as opposed to the "push" model for the naive runLater solution. – jewelsea May 15 '22 at 07:27

1 Answers1

1

Found answer on my own, using Platform.runLater() for any lines that I was updating the TextArea fixed the solution.

Ahxius
  • 19
  • 5
  • 7
    The more threads you add, the higher the risk that you’ll flood the main thread with updates, causing it to “stall” under the load – MadProgrammer May 13 '22 at 23:55