有人告诉我,我需要为一个长时间运行的目录树步行者创建一个SwingWorker
,其"胆量"显示在下面的部分。(为了简短起见,我删除了很多结束 } 和 ) 以及其他多余的(对我的问题)的东西,例如忽略的捕获子句。
当匹配给定的文件名模式时,文件名(和其他内容)通过report()
写入文本区域:
public class TASK extends SimpleFileVisitor<Path> implements Runnable{
public static FileVisitResult disposition = FileVisitResult.CONTINUE;
private static void report(String s){
try{
Output.jTextArea1.append(s + "n");
catch (Exception e){ aborted = true ; disposition = FileVisitResult.TERMINATE;}
public void run() {
disposition = FileVisitResult.CONTINUE;
Files.walkFileTree(p , this); // walkTreeFile calls visitFile() for each file.
public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException {
report(f1.getFileName().toString());
return disposition;
main()
只是为 GUI 和输出创建线程:
public static void main(String args[]) { // main
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
gui = new GUI();
gui.setVisible(true);
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
info = new Output();
单击"搜索"按钮时jbSearch...()
使输出窗口可见并实例化TASK
树漫步开始:
private void jbSearchActionPerformed(ActionEvent evt) { // this is in GUI
try {
TASK v = new TASK();
Thread t = new Thread(v);
t.start();
一切正常,但输出窗口闪烁并看起来被黑客入侵,所以我需要 SwingWorker。但我不能说以下内容,因为TASK
(或其他东西)必须扩展SimpleFileVisitor
:
class TASK extends SwingWorker<List<String>, String>
所以我正在寻找一些要实现的东西。我的笔记告诉我"因为 SwingWorker 实现了 Runnable,所以 SwingWorker 可以提交给Executor
执行",所以我想我接下来要去那里,除非有人阻止我!(我以前从未使用过执行器。
在我弄清楚如何涉及 Swingworker 之后,我认为我应该执行以下操作,可能jbSearch...()
代替所示的 3 行(就在上面):
TASK.execute();
我想我必须调用doInBackground()
visitFile(),这是应用于步行中所有文件的内容。填充doInBackground()
返回的数组是我的责任吗?SwingWorker 的 Java 教程突然返回numbers
,该未在任何地方定义为数组或其他任何数组。
所以我想我必须调用(我的)process()
report()
,这会将新信息附加到输出窗口(文本区域)。我假设一旦doInBackground()
填满了块数组,就很容易处理它们。
但是我把get()
放在哪里?SwingWorker 的 Java 教程表明get()
不是必需的,因为该示例写入文本区域,get()
仅用于 System.out 以在控制台上显示相同的信息。
(编辑)哦,是的...我该怎么publish()
?我想我在report()
里面发表.
但我还是要发帖,因为我认为这个问题和/或答案对于提出下一个关于 Swingworker 的问题的人来说可能是一个有价值的发现。
(编辑)我认为我面临的一个大问题是,walkFileTree
或多或少"是"一个循环,在幕后反复调用visitFile()
,在树结束时结束或当visitFile()
中的返回值设置为TERMINATE
时结束。那么我是否只是visitFile()
doInBackground()
,因为它或多或少已经处于循环中?然后把publish()
放在它之后?
但是我如何返回数组呢?
呃。
所以我正在寻找一些要实现的东西。我的笔记告诉我"因为 SwingWorker 实现了 Runnable,一个 SwingWorker 可以提交给 执行执行人"所以我想我接下来要去那里,除非 有人拦住我!(我以前从未使用过执行器。
在我弄清楚如何让 Swingworker 参与之后,我想我应该这样做 以下内容,可能在 jbSearch...() 代替所示的 3 行 (就在上面):
TASK.execute();
是的,SwingWorker#execute
是启动 SwingWorker 的典型方式
我想我必须使doInBackground()调用visitFile(),这是 应用于漫游中所有文件的内容。这是我的责任吗 填充 doInBackground() 返回的数组?Java 教程 SwingWorker 突然返回未在任何地方定义的数字 是数组或其他任何薄型。
要在后台完成的任何操作都应从此方法调用。
是的,您需要自己生成结果。实际值可以在任何地方定义,但我个人在doInBackground
方法的上下文中定义了一个局部变量
所以我想我必须使进程()调用(我的)报告(),它附加 输出窗口(文本区域)的新信息。我假设曾经 doInBackground() 填充块数组,它将很容易处理 他们。
为了处理值,您需要首先publish
它们。何时将这些值传递给process
将取决于后台进程的密集程度。
覆盖done
和调用 get 还将允许您访问从 EDT 上下文中的doInBackground
返回的内容
但是我把get()放在哪里?SwingWorker 的 Java 教程有点 建议 get() 不是必需的,因为该示例写入 文本区域和get()仅与System.out一起使用以显示相同的 控制台上的信息。如果我不需要调用get(),也许我更接近 到我开始这个时想到的解决方案。
这将取决于。你关心结果吗?如果您这样做,我倾向于在 done
方法中调用它,因为通常,我想使用 EDT 中的值。
关于get
,重要的是要知道它是阻塞的,也就是说,它会等到doInBackground
返回
例如