2

処理された情報を迅速に公開せずに使用SwingWorkerする。GUI がハングします。私はそれがなかったことを望み、その問題の助けを求めています.FileVisitor

SwingWorkerインターフェイスを使用してFileVisitor、ユーザー指定の条件に一致するファイルを Windows ディレクトリ ノードで検索する方法の概要を次に示します。:

  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"});

編集この 2 行だけを含めていれば、問題はすぐに解決された可能性があります

       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した のインスタンスによって見つかったファイル情報を ( に)表示TASKすることです。TASKをインスタンス化FileVisitorし、walkFileTree開始します。visitFileメソッドで見つかったすべての一致するファイルは、 to に対してpublish編集さSwingWorkerprocessます。

ほとんどの場合はうまく機能しますが、一致するファイルが大量にある場合、GUI は数秒間応答しなくなります。その間、大量の読み取りと表示が行われ、UI は数千のファイル読み取りごとに更新されます。

SwingWorkerバックグラウンドで を使用しているにも関わらずJTable、どうやら (推測では) 一致するファイル情報が多すぎると、追いつくには速すぎます。

これが私がそう言う理由です:

visitFileに信号を送るカウンターがありますが、TERMINATEレコードprocessを に追加するのは明らかに遅れてい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.

無反応でどうしたらいいのかわからない。STOP ボタンを押してプログラムを停止できるようにしたいです。Xまたは、ウィンドウを (閉じる)ことができます。とんでもない。

私はSwingWorker正しく使用していませんか?SwingWorker私が利用できるループがないため、ツリーウォークをベースにすることはできません(内部的なものです)。

PS明らかにハングしている間、最終的に最後のチャンクを発行するまでjavaw、CPU時間の25%を確実に使用し、メモリ割り当てを毎秒約16Kずつ増やしています。process

ここに画像の説明を入力

編集

私はここで助けを見つけたかもしれません。

しかし、ねえ、閉じますか??

私は私の質問を強調しました。

4

2 に答える 2

2

問題の解決策はわかりませんが、これを SwingWorker またはその内部クラス内で行うべきではないことはわかっています。

GUI.txtMaxMatches.getText())

EDT でこの情報を取得し、コンストラクターを介して SwingWorker に渡す必要があります。

于 2015-08-20T16:33:31.307 に答える
0

応答性の問題は、1 行のコードで解決されます。

// tca.setDynamicAdjustment(true);

元の質問の編集を参照してください。

于 2015-08-20T19:32:51.187 に答える