処理された情報を迅速に公開せずに使用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
編集さSwingWorker
れprocess
ます。
ほとんどの場合はうまく機能しますが、一致するファイルが大量にある場合、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
編集
私はここで助けを見つけたかもしれません。
しかし、ねえ、閉じますか??
私は私の質問を強調しました。