我写了一个简单的Javafx应用程序,启动了一个新线程,在Netbeans中运行正常。但是在编译过程中出现以下警告:
explicit use of threads is not supported
这是否意味着它现在可能无法在所有可能的设备上工作,例如手机或浏览器?
我写了一个简单的Javafx应用程序,启动了一个新线程,在Netbeans中运行正常。但是在编译过程中出现以下警告:
explicit use of threads is not supported
JavaFX本身必须在主JavaFX线程上运行,因此直接从JavaFX启动线程目前不受支持。但是,您可以创建一个生成线程的Java类。因此,您的JavaFX类调用Java类,然后启动线程。
从Java线程回调到JavaFX时,您需要在主JavaFX线程上。如何执行此操作的示例:
import com.sun.javafx.runtime.Entry;
Entry.deferAction( new Runnable() {
@Override
public void run() {
fxListener.onMessage(copy);
}
} );
你不应该直接从Java中操作JavaFX对象。如果你需要在Java中进行操作,你需要使用javafx.reflect类。
我要推荐JFXtras(http://jfxtras.org/)的XWorker类。它本质上是解决你提到的问题的一种方法,因为它允许你在后台线程中使用JavaFX代码。它适用于大多数任务,但也有一定的危险性,因为你很容易创建不安全的线程代码。
基本用法:
var currentImage:Image;
var worker = XWorker {
inBackground: function() {
return Image {url: currentFile.toURL().toString(), height: imageHeight};
}
onDone: function(result) {
currentImage = result as Image;
}
}
在inBackground中完成的所有操作都是在后台Swing线程中完成的。该线程可以返回结果,该结果将传递给onDone。onDone在JavaFX事件分派线程(所有其他JavaFX代码运行的主线程)中执行,因此您可以返回到正常使用。将其视为前景。在大多数情况下,您不希望访问可以在“前景”中同时访问的任何inBackground内容。您可以对此规则进行例外处理,只要在线程之间共享的对象是线程安全的即可。在大多数情况下,JavaFX代码无法保证线程安全,但是您可以使用Java线程安全对象(例如JPA EntityManager工厂)或容器,例如BlockingQueue。后者可用于执行生产者/消费者模型。
此外,如果您有一个长时间运行的任务,并且想要定期向“前景”发送更新,则可以使用publish/process。以下是一个示例:
var worker = XWorker {
inBackground: function() {
while (true) {
// Do something
publish(someStuff);
}
}
process: function(someStuff: SomeStuff[]):Void {
// Do something with some stuff. You are now in
// "the foreground", so you can freely access
// JavaFX objects.
}
onDone: function(result) {
currentImage = result as Image;
}
}
这对于从后台线程发送诸如日志消息以在某种 UI 中显示非常有用。