如何修改工作 Java 程序以涉及 SwingWorker (因为输出窗口闪烁并且看起来被黑客入侵)



有人告诉我,我需要为一个长时间运行的目录树步行者创建一个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返回

例如

最新更新