java在后台更新JavaFX窗口
我目前正在使用一个文件资源管理器。我想实现一个搜索功能,它显示当前目录和所有子目录中的所有匹配文件。我用shell命令“find”尝试了一下,但没有成功。之后,我尝试使用Java8API的文件。步行(…)作用这起了部分作用。我现在可以得到所有文件并打印出来。唯一的问题是,我不能在GUI中为找到的每个文件添加一个窗格
我尝试了一个任务,但是GUI没有更新。在下面的最终版本中,有两个线程。一个获取文件并将其填充到队列中,另一个轮询队列中的对象并将其显示在GUI上。通过调试,我知道队列的大小始终在0和2之间。这意味着,我的系统正在工作。但是GUI仍然没有更新
谁能帮我一下吗
public static final ConcurrentLinkedQueue<FilePane> files = new ConcurrentLinkedQueue<>();
public void search(String key) {
Task<Boolean> listLoader = new Task<Boolean>() {
{
setOnSucceeded(workerStateEvent -> {
System.out.println("Done");
});
setOnFailed(workerStateEvent -> getException().printStackTrace());
}
@Override
protected Boolean call() throws Exception {
try {
Files.walkFileTree(Paths.get(currentDirectoryController().getDir().getAbsolutePath()), new HashSet<FileVisitOption>(Arrays.asList(FileVisitOption.FOLLOW_LINKS)),
Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file , BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file , IOException e) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir , BasicFileAttributes attrs) throws IOException {
files.add(new FilePane(new KFile(dir.toFile()), cont));
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
};
Thread loader = new Thread(listLoader);
loader.setDaemon(true);
loader.start();
new Thread(() -> {
Platform.runLater(() -> {
while(true) {
if(!files.isEmpty()) {
fileContainer.getChildren().add(files.poll());
}
}
});
}).start();
}
# 1 楼答案
这句话实际上有以下几点:
因此,action2执行得非常快,在单独的线程上运行它是没有意义的。然而,action2有一个无限循环并永远运行,它在GUI线程上运行,实际上阻塞了这个线程并阻止它重新绘制屏幕
您可能听说过,您可能不会占用GUI线程很长时间。也就是说,您应该在GUI线程之外执行循环,如下所示:
现在我们看到这个线程所做的很少——从队列中获取文件窗格,用一个简单的方法包装它们,并将它们放入GUI线程的输入队列。因此可以消除它,所有的工作都可以在加载器线程中完成:而不是
files.add(new FilePane(...))
do# 2 楼答案
这只是启动一个不同的线程,然后发布一个长时间运行的任务(实际上是一个无限循环)在应用程序线程上运行
为了不阻塞应用程序线程,您只需要发布可以在应用程序线程上快速完成的任务
其他优化:
ListView
或TableView
来显示文件。这避免了在内存中创建大量的节点,也加快了布局,因为它只需要考虑可见节点。<李>实际上,您可以通过简单地使用原始任务中的
Platform.runLater
来避免使用者/生产者实现的复杂性: