我写了一个简单的Javafx应用程序,它启动了一个新的线程,它可以从Netbeans中运行。 但是我在编译期间收到了警告:
explicit use of threads is not supported
这是否意味着它现在可能适用于所有可能的设备,如手机或浏览器?
答案 0 :(得分:1)
JavaFX本身必须在主JavaFX线程上运行,因此目前不支持直接从JavaFX启动Thread。但是,您可以创建一个生成Thread的Java类。因此,您的JavaFX类调用Java类,然后启动一个Thread。
从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类。
答案 1 :(得分:0)
我必须推荐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)。后者可用于制作生产者/消费者模型。
此外,如果您有一个长时间运行的任务,并且您想要定期向“前台”发送更新,则可以使用发布/进程。这是一个例子:
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中显示非常有用。