最接近標準或現成的方法是progress
財產和/或由SwingWorker
提供的發佈/處理方法對。您可以在方法末尾將此值設置爲「我已完成」值,以指示後臺工作已完成。等待揮杆員的線程可以發出「正在取消...」消息,並定期檢查進度,看看是否已完成。如果等待線程是擺動式EDT,那麼您需要使用定時器定期檢查進度屬性,並在完成時清除取消消息。
下面是一個運行頑固後臺線程,這是取消了一些示例代碼,然後等待,直到進度達到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。 SwingWorker中的你的process
重寫方法然後拾取這個特殊值並隱藏「正在取消...」消息。這樣做的好處是不需要輪詢或定時器。示例代碼顯示,雖然done
在任務取消後立即被調用,但即使任務被取消,發佈/進程方法對仍然可以工作。
這兩項想法是事情我還沒有考慮。我不喜歡以你引用的相同理由來使用進度 - 它需要投票。我大多喜歡發佈/過程的想法,但它將我將要完成的任務完成的邏輯與「SwingWorker」類本身結合在一起。出於同樣的原因,我很少使用'done()'方法,而是通常將監聽器添加到worker對象中。 – 2010-08-19 17:20:32
我同意你的看法,發佈/過程是兩者中較好的一個。至於耦合,你可以通過創建一個重寫流程方法的SwingWorker子類來解耦它,監聽「我完成了」的值,並通知註冊的監聽者後臺任務真的完成了。這將邏輯與擺動工作人員分開。 – mdma 2010-08-19 19:20:52
的確如此,但是在此期間監聽對象將如何阻塞直到它收到通知? – 2010-08-20 12:59:08