我有一个JavaFX应用程序,每当重命名文件时,它都必须触发。我是WatchService的新手,我已经做了演示,它很有效。
不过,这个演示是一个类的简单应用程序。现在我想在自己的应用程序中实现它,制作一个单独的类来处理WatchService。
主要类别:
public class KochFractalDraw extends Application {
@Override
public void start(Stage primaryStage) throws IOException, InterruptedException {
//..define GUI etc..
watchdirectory = new WatchDirectory();
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
watchdirectory.Register();
} catch (InterruptedException ex) {
Logger.getLogger(JSF31KochFractalFX.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
使用WatchDirectory:
public class WatchDirectory {
WatchService watchService;
Path path;
WatchKey key;
public WatchDirectory() throws IOException {
this.watchService = FileSystems.getDefault().newWatchService();
path = Paths.get("D:\Test");
path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
}
public void Register() throws InterruptedException {
for (;;) {
this.key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind kind = event.kind();
switch (kind.name()) {
case "ENTRY_CREATE":
System.out.println("Create triggered!");
break;
default:
System.out.println("Wrong event called.");
break;
}
boolean valid = key.reset();
if (!valid) {
break;
}
}
}
}
}
我遇到的问题是它可以工作,但我的GUI会立即冻结。因此,我放置了观察目录。Register();在RunLater中,希望它不会影响主JavaFX应用程序线程。
(我知道它是有效的,因为每当我在"D:\Test"中创建/重命名文件时,输出都会一直响应"create triggered!")
感谢您的提示James_D
我已经使WatchDirectory成为可运行的。在我的主要课程中,我用运行它
new Thread(watchdirectory).start();
我以前接近这个解决方案,但后来我使用了.run(),这再次冻结了GUI。没有意识到.start();和.run();
再也不会!
Platform.runLater()旨在在某个时候让FX应用程序进程执行,以运行其他运行的小程序,并且存在,执行将返回FX应用程序。
如果你在这个过程中有无限循环,就像Watch Service的使用方式一样,执行永远不会从中返回,FX应用程序自然会冻结。
你绝对不能做:
while(true) {
key = watchService.take();
...
}
使用Platform.runLater().时的轮询循环
相反,您必须将while(true)
替换为某些FX组件,如每秒触发事件的TimeLine。忘记Runnable和Platform.runLater()
吧,我认为要想让它发挥作用,你需要在FX内部进行轮询循环。
到目前为止,我还不知道该怎么做。