Multithreading 如何在JavaFX中使用并发(线程)(使用FXML!!!(JavaFX场景生成器))?

Multithreading 如何在JavaFX中使用并发(线程)(使用FXML!!!(JavaFX场景生成器))?,multithreading,concurrency,controller,fxml,scenebuilder,Multithreading,Concurrency,Controller,Fxml,Scenebuilder,如何将JavaFX中的线程与FXML以及任务或服务类一起使用 我的程序需要并发性,因为我使用很长的循环。 如果我“手动”(不使用FXML)编写代码,那么它可以工作。但对于FXML,它不起作用(JavaFX场景生成器)。我不想在控制台中打印“stringbuffer”变量,而是想将其写入textarea(这是一个可更新的组件)。但是在本例中,当然会出现一条错误消息,因为它不再属于JavaFX应用程序线程。如何使该组件(textareatextareaausgabe)更新/可更新,以便在线程中使用它

如何将JavaFX中的线程与FXML以及任务或服务类一起使用

我的程序需要并发性,因为我使用很长的循环。 如果我“手动”(不使用FXML)编写代码,那么它可以工作。但对于FXML,它不起作用(JavaFX场景生成器)。我不想在控制台中打印“stringbuffer”变量,而是想将其写入textarea(这是一个可更新的组件)。但是在本例中,当然会出现一条错误消息,因为它不再属于JavaFX应用程序线程。如何使该组件(textareatextareaausgabe)更新/可更新,以便在线程中使用它? 对不起,我的英语不好? 希望您知道我的问题是什么(它是FXML:-D)。 如果在NetBeans中有另一个类似于swing的gui构建器,我会使用它。 据我所知,场景生成器是JavaFX的唯一gui生成器:-(

我想在代码段中使用task3。 这是我的代码片段,它不起作用(如果我使用标签、文本字段等组件):

出现以下错误:

Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
这是NetBeans输出中的完整错误消息:

ant -f D:\\Users\\Benutzer\\Documents\\NetBeansProjects\\Threading jfxsa-run
init:
Deleting: D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\built-jar.properties
deps-jar:
Updating property file: D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\built-jar.properties
Compiling 1 source file to D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\classes
warning: [options] bootstrap class path not set in conjunction with -source 1.5
warning: [options] source value 1.5 is obsolete and will be removed in a future release
warning: [options] target value 1.5 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
4 warnings
compile:
Detected JavaFX Ant API version 1.3
Launching <fx:jar> task from F:\Java\Java Development Kit\Java Development Kit (1.8.0_20) (x64)\jre\..\lib\ant-javafx.jar
Warning: From JDK7u25 the Codebase manifest attribute should be used to restrict JAR repurposing.
         Please set manifest.custom.codebase property to override the current default non-secure value '*'.
Launching <fx:deploy> task from F:\Java\Java Development Kit\Java Development Kit (1.8.0_20) (x64)\jre\..\lib\ant-javafx.jar
jfx-deployment-script:
jfx-deployment:
jar:
Copying 12 files to D:\Users\Benutzer\Documents\NetBeansProjects\Threading\dist\run1389427067
jfx-project-run:
Executing D:\Users\Benutzer\Documents\NetBeansProjects\Threading\dist\run1389427067\Threading.jar using platform F:\Java\Java Development Kit\Java Development Kit (1.8.0_20) (x64)\jre/bin/java
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:364)
    at javafx.scene.Scene.addToDirtyList(Scene.java:485)
    at javafx.scene.Node.addToSceneDirtyList(Node.java:424)
    at javafx.scene.Node.impl_markDirty(Node.java:415)
    at javafx.scene.shape.Shape.impl_markDirty(Shape.java:942)
    at javafx.scene.Node.impl_geomChanged(Node.java:3784)
    at javafx.scene.text.Text.impl_geomChanged(Text.java:763)
    at javafx.scene.text.Text.needsTextLayout(Text.java:194)
    at javafx.scene.text.Text.needsFullTextLayout(Text.java:189)
    at javafx.scene.text.Text.access$200(Text.java:96)
    at javafx.scene.text.Text$2.invalidated(Text.java:386)
    at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:109)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:143)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
    at javafx.scene.text.Text.setText(Text.java:367)
    at com.sun.javafx.scene.control.skin.TextAreaSkin.lambda$new$231(TextAreaSkin.java:571)
    at com.sun.javafx.scene.control.skin.TextAreaSkin$$Lambda$256/235779996.invalidated(Unknown Source)
    at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:349)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1123)
    at javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1127)
    at javafx.scene.control.TextInputControl$TextProperty.invalidate(TextInputControl.java:1066)
    at javafx.scene.control.TextInputControl$TextProperty.access$1300(TextInputControl.java:1038) 
ant-fd:\\Users\\Benutzer\\Documents\\NetBeansProjects\\Threading jfxsa run
初始化:
删除:D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\build-jar.properties
deps jar:
正在更新属性文件:D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\build-jar.properties
正在将1个源文件编译为D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\classes
警告:[选项]引导类路径未与-source 1.5一起设置
警告:[选项]源值1.5已过时,将在将来的版本中删除
警告:[选项]目标值1.5已过时,将在将来的版本中删除
警告:[选项]若要抑制有关过时选项的警告,请使用-Xlint:-options。
4警告
汇编:
检测到JavaFX Ant API版本1.3
从F:\Java\Java开发工具包\Java开发工具包(1.8.0_20)(x64)\jre\..\lib\ant-javafx.jar启动任务
警告:在JDK7u25中,应使用Codebase manifest属性来限制JAR重新调整用途。
请设置manifest.custom.codebase属性以覆盖当前默认的非安全值“*”。
从F:\Java\Java开发工具包\Java开发工具包(1.8.0_20)(x64)\jre\..\lib\ant-javafx.jar启动任务
jfx部署脚本:
jfx部署:
罐子:
正在将12个文件复制到D:\Users\Benutzer\Documents\NetBeansProjects\Threading\dist\run1389427067
jfx项目运行:
使用平台F:\Java\Java开发工具包\Java开发工具包(1.8.0\u 20)(x64)\jre/bin/Java执行D:\Users\Benutzer\Documents\NetBeansProjects\Threading\dist\run1389427067\Threading.jar
线程“thread-4”java.lang.IllegalStateException中的异常:不在FX应用程序线程上;currentThread=thread-4
位于com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
位于com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:364)
位于javafx.scene.scene.addToDirtyList(scene.java:485)
位于javafx.scene.Node.addToSceneDirtyList(Node.java:424)
位于javafx.scene.Node.impl_markDirty(Node.java:415)
位于javafx.scene.shape.shape.impl_markDirty(shape.java:942)
位于javafx.scene.Node.impl_(Node.java:3784)
在javafx.scene.text.text.impl_中(text.java:763)
在javafx.scene.text.text.needsTextLayout(text.java:194)中
在javafx.scene.text.text.needsFullTextLayout(text.java:189)中
javafx.scene.text.text.access$200(text.java:96)
在javafx.scene.text.text$2.invalidated(text.java:386)
位于javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:109)
位于javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:143)
位于javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
位于javafx.scene.text.text.setText(text.java:367)
在com.sun.javafx.scene.control.skin.TextAreaSkin.lambda$new$231(TextAreaSkin.java:571)
位于com.sun.javafx.scene.control.skin.TextAreaSkin$$Lambda$256/235779996。无效(未知来源)
位于com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:349)
位于com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
位于javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1123)
位于javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1127)
位于javafx.scene.control.TextInputControl$TextProperty.invalidate(TextInputControl.java:1066)
位于javafx.scene.control.TextInputControl$TextProperty.access$1300(TextInputControl.java:1038)

您的问题与FXML无关

您的问题是您的任务代码违反了JavaFX线程规则(即,您不能在JavaFX应用程序线程之外修改活动场景中的节点)

更换不起作用的代码:

textAreaAusgabe.appendText (buffer); // Does not work 
与:

这将在JavaFX应用程序线程上执行文本区域节点的操作,并解决线程运行时的问题

请参阅文档部分“修改场景图的任务”

然而,对于您的示例应用程序,您现在将遇到另一个问题,因为您将快速更新JavaFX场景一亿次,这将使JavaFX系统过载并使您的应用程序无响应。您需要做的是批量处理文本更改,只需发出runlater调用来更新UIn每秒60次。要求UI每秒更新60次以上是没有用的,因为没有人能看到中间更新

另外,要回答您的辅助问题=>否,目前除了SceneBuilder之外,没有其他用于JavaFX的GUI编辑器

ant -f D:\\Users\\Benutzer\\Documents\\NetBeansProjects\\Threading jfxsa-run
init:
Deleting: D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\built-jar.properties
deps-jar:
Updating property file: D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\built-jar.properties
Compiling 1 source file to D:\Users\Benutzer\Documents\NetBeansProjects\Threading\build\classes
warning: [options] bootstrap class path not set in conjunction with -source 1.5
warning: [options] source value 1.5 is obsolete and will be removed in a future release
warning: [options] target value 1.5 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
4 warnings
compile:
Detected JavaFX Ant API version 1.3
Launching <fx:jar> task from F:\Java\Java Development Kit\Java Development Kit (1.8.0_20) (x64)\jre\..\lib\ant-javafx.jar
Warning: From JDK7u25 the Codebase manifest attribute should be used to restrict JAR repurposing.
         Please set manifest.custom.codebase property to override the current default non-secure value '*'.
Launching <fx:deploy> task from F:\Java\Java Development Kit\Java Development Kit (1.8.0_20) (x64)\jre\..\lib\ant-javafx.jar
jfx-deployment-script:
jfx-deployment:
jar:
Copying 12 files to D:\Users\Benutzer\Documents\NetBeansProjects\Threading\dist\run1389427067
jfx-project-run:
Executing D:\Users\Benutzer\Documents\NetBeansProjects\Threading\dist\run1389427067\Threading.jar using platform F:\Java\Java Development Kit\Java Development Kit (1.8.0_20) (x64)\jre/bin/java
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
    at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
    at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:364)
    at javafx.scene.Scene.addToDirtyList(Scene.java:485)
    at javafx.scene.Node.addToSceneDirtyList(Node.java:424)
    at javafx.scene.Node.impl_markDirty(Node.java:415)
    at javafx.scene.shape.Shape.impl_markDirty(Shape.java:942)
    at javafx.scene.Node.impl_geomChanged(Node.java:3784)
    at javafx.scene.text.Text.impl_geomChanged(Text.java:763)
    at javafx.scene.text.Text.needsTextLayout(Text.java:194)
    at javafx.scene.text.Text.needsFullTextLayout(Text.java:189)
    at javafx.scene.text.Text.access$200(Text.java:96)
    at javafx.scene.text.Text$2.invalidated(Text.java:386)
    at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:109)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:143)
    at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:49)
    at javafx.scene.text.Text.setText(Text.java:367)
    at com.sun.javafx.scene.control.skin.TextAreaSkin.lambda$new$231(TextAreaSkin.java:571)
    at com.sun.javafx.scene.control.skin.TextAreaSkin$$Lambda$256/235779996.invalidated(Unknown Source)
    at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:349)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1123)
    at javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1127)
    at javafx.scene.control.TextInputControl$TextProperty.invalidate(TextInputControl.java:1066)
    at javafx.scene.control.TextInputControl$TextProperty.access$1300(TextInputControl.java:1038) 
textAreaAusgabe.appendText (buffer); // Does not work 
Platform.runLater(() -> textAreaAusgabe.appendText (buffer));