最接近标准的或现成的方法是提供的progress
属性和/或发布/处理方法对SwingWorker
。您可以在方法结束时将其设置为“我已完成”值,以指示后台工作已完成。等待 swing worker 的线程可以发出“Canceling...”消息并定期检查进度以查看是否已完成。如果等待线程是 swing EDT,那么您将需要使用 Timer 定期检查进度属性并在完成后清除取消消息。
这是一些运行顽固后台线程的示例代码,该线程被取消,然后等待直到进度达到 100。
@Test
public void testSwingWorker()
{
SwingWorker worker = new SwingWorker() {
@Override
protected void process(List chunks)
{
for (Object chunk : chunks)
{
System.out.println("process: "+chunk.toString());
}
}
@Override
protected void done()
{
System.out.println("done");
}
@Override
protected Object doInBackground() throws Exception
{
// simulate long running method
for (int i=0; i<1000000000; i++)
{
double d = Math.sqrt(i);
}
System.err.println("finished");
publish("finished");
setProgress(100);
return null;
}
};
Thread t = new Thread(worker);
t.start();
try
{
worker.get(1, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
}
catch (ExecutionException e) {
}
catch (TimeoutException e) {
}
worker.cancel(true);
// now wait for finish.
int progress = 0;
do
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
progress = worker.getProgress();
System.out.println(String.format("progress %d", progress));
}
while (progress<100);
}
另一种方法是使用publish\process
方法对将指示后台线程已完成的特殊值推送到 EDT。然后,您process
在 SwingWorker 中的覆盖方法会选择此特殊值并隐藏“Canceling...”消息。这样做的好处是不需要轮询或计时器。示例代码显示,虽然done
在任务取消后立即调用,但即使任务取消,发布/处理方法对仍然有效。