2

使用不快速发布处理过的信息SwingWorkerGUI 挂起。我宁愿它没有,也想帮助解决这个问题FileVisitor

以下是我如何使用接口在 Windows 目录节点中搜索与用户指定条件匹配的文件的简要SwingWorker概述FileVisitor。:

  public class Main 
  {
    public static void main(String args[]) 
    {
      EventQueue.invokeLater( new Runnable() {
          @Override public void run() {
            gui = new GUI();
          }});
    }
  }
  //==============================================================
  public class GUI extends JFrame
  {
    public     GUI()
    {
      init();
      createAndShowGUI();
    }

     private void init()
     {
       dftTableModel = new DefaultTableModel(0 , 4);
         tblOutput     = new JTable(dftTableModel);
         tblOutput.setAutoResizeMode(AUTO_RESIZE_OFF);
         scrTblOutput     = new JScrollPane(tblOutput);
       dftTableModel.setColumnIdentifiers(new Object[]{"Date", "Size", "Filename", "Path"});

编辑如果我只包含这两行,问题可能已经立即解决

       tca = new tablecolumnadjuster.TableColumnAdjuster(tblOutput);
       tca.setDynamicAdjustment(true);

     }

      private static void btnSearchActionPerformed(ActionEvent evt) 
      {
        TASK task = new TASK();
        task.execute();      
      }
    }
  }
  //==============================================================

  public class TASK extends SwingWorker<Void,String>
  {

    private class rowRec{
      String date;
      int size;
      String filename;
      String pathname;

      private rowRec(String d, int s, String f, String p) 
      {
        date = d; 
        size = s; 
        filename = f; 
        pathname = p;
      }
    }

    FV fv;

    TASK() {        fv = new FV();        }

    //-------------- inner class   

      class FV implements FileVisitor<Path>
      {
        // When walk begins, internal FileVisitor code makes this routine
        // loop until no more files are found OR disposition = TERMINATE.

        public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException 
        {
          if(f.getFileName().toString().toLowerCase().matches(fPatt.toLowerCase().trim()))
          {

             publish(s); 

             if(++k > parseInt(GUI.txtMaxMatches.getText()))

                disposition = TERMINATE;
                publish("Stopped at max. records specified");
          }
          return disposition;
        }
      }
    //----------------

    private  void report(String s)
    {
      rowData = new rowRec(date, isize, filename, path);
      dftTableModel.addRow(new Object[]{rowData.date, rowData.size, rowData.filename, rowData.pathname});
    }

    @Override
    protected void process(List<String> chunks)
    {
      chunks.stream().
        forEach
        (
           (chunk) -> 
           {
             report(chunk);
           }
      );
      kc += chunks.size();
      System.out.println(kc); // *********************************
    }

    @Override
    public Void doInBackground() throws Exception 
    {
        disposition = FileVisitResult.CONTINUE;
        Files.walkFileTree(GUI.p ,fv);
    }
  }

GUI启动 的新实例SwingWorker,其工作是显示(在 中)由它启动JTable的实例找到的文件信息。实例化, 并开始。在方法中找到的每个匹配文件都被编辑为to 。TASKTASKFileVisitorwalkFileTreevisitFilepublishSwingWorkerprocess

它在大多数情况下都很好用,但是如果有大量匹配的文件,GUI 会在几秒钟内变得无响应;同时,发生了大量的读取和显示,并且每读取几千个文件就更新一次 UI。

尽管SwingWorker用于填充JTable背景,但显然(我猜)太多匹配的文件信息来得太快而无法跟上。

这就是我这么说的原因:

即使visitFile有一个发出信号的计数器,TERMINATEprocess添加记录方面显然远远落后JTable。它的println内部表明,随着时间的推移,通过的数量会发生chunks很大变化,具体取决于FileVisitor找到匹配项的速度:

41
81
138
250
604
1146
...
1417
1497
1590
1670
1672
1676
1680
1682
1692
1730
1788
1794
1797
1801
1807
1820
1826
1829
1847
1933
2168
10001

visitFile终止后,process必须发送(10001-2168)或 7833 条记录到JTable,并且花费了很长时间,并且 GUI 大部分时间都没有响应。事实上,如果最大。匹配是(荒谬的)10,000,程序挂起很多分钟,但 10,000 条记录在JTable.

我不知道如何处理反应迟钝。我希望能够按下停止按钮并停止程序。或者能够X(关闭)窗口。没门。

我没有SwingWorker正确使用吗?SwingWorker由于没有可用的循环(它是内部的),因此我无法基于树行走。

PS 虽然显然挂起,但javaw它占用了稳定的 25% 的 CPU 时间,并将其内存分配增加了大约 16K/秒,process直到它最终发布最后一个块。

在此处输入图像描述

编辑

我可能在这里找到了帮助。

但是,天哪,接近??

我已经强调了我的问题。

4

2 回答 2

2

我不知道您的问题的解决方案,但我知道这不应该在 SwingWorker 或其内部类中完成:

GUI.txtMaxMatches.getText())

您应该在 EDT 上获取此信息,并通过其构造函数将其传递给您的 SwingWorker。

于 2015-08-20T16:33:31.307 回答
0

响应性问题在一行代码中得到解决。

// tca.setDynamicAdjustment(true);

请参阅原始问题中的编辑。

于 2015-08-20T19:32:51.187 回答