class ProgressBarSwingWorker extends SwingWorker<Void, Void>
{
private int byteWritten = 0;
private String downloadDir = "";
private String fileAddress = "";
private String fileName = "";
private int fileSize;
public void fileUrlReadAndDownload(String fileAddress, String downloadDir)
{
OutputStream outStream = null;
URLConnection uCon = null;
InputStream is = null;
try
{
message.setText(fileName + "in Update");
URL Url;
byte[] buf;
int byteRead;
Url = new URL(fileAddress);
outStream = new BufferedOutputStream(new FileOutputStream(downloadDir));
uCon = Url.openConnection();
is = uCon.getInputStream();
buf = new byte[size];
while ((byteRead = is.read(buf)) != -1)
{
outStream.write(buf, 0, byteRead);
byteWritten += byteRead;
pbar.setValue(byteWritten);
frame.repaint();
}
message.setText("update finish");
} catch (Exception e)
{
message.setText("server is not runing.");
e.printStackTrace();
} finally
{
try
{
is.close();
outStream.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
public ProgressBarSwingWorker(String fileAddress, String downloadDir, String fileName, int fileSize)
{
this.fileAddress = fileAddress;
this.downloadDir = downloadDir;
this.fileName = fileName;
this.fileSize = fileSize;
}
@Override
protected Void doInBackground() throws Exception
{
pbar.setMaximum(fileSize);
fileUrlReadAndDownload(fileAddress, downloadDir);
return null;
}
@Override
protected void done()
{
try
{
get();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我从这样做swingworker从http下载文件并显示进度条GUI
我制作了10个progreebarswingworker实例并放入列表并像这样运行
for(ProgressBarSwingWorker p : progressList)
{
p.execute();
}
并且所有progressList都是同时开始的
我想逐步执行等待其他进度完成
所以我把像这样的done()或get()方法
for(ProgressBarSwingWorker p : progressList)
{
p.execute();
p.done(); // or p.get();
}
此代码执行进度其他进度已完成
但! GUI冻结,因此我无法显示任何JLabel更改或JProgressBar
如何在没有gui冻结的情况下等待其他进度完成?
答案 0 :(得分:2)
你正在尝试一些概念错误的东西。您尝试等待完成以执行另一个操作,从而产生您想要避免的单线程行为。重写代码并不重要,只要你总是试图等待你的GUI 冻结。
你必须改变你的观念。而不是等待你必须告诉Swing在任务完成时该做什么,即开始下一个任务。您无需调用get
,因为它与定义下一个操作无关。你可以:
告诉您的ProgressBarSwingWorker
对下一个的引用,并在execute
方法中调用其done
方法
class ProgressBarSwingWorker extends SwingWorker<Object, Object>
{
ProgressBarSwingWorker next;
// …
public ProgressBarSwingWorker(ProgressBarSwingWorker nextWorker)
{
next=nextWorker;
}
// …
@Override
protected void done()
{
if(next!=null) next.execute();
}
}
或
添加一个侦听器,该侦听器将调用下一个execute
ProgressBarSwingWorker
方法
ProgressBarSwingWorker previous=null;
for(final ProgressBarSwingWorker p: progressList)
{
if(previous==null) p.execute();
else previous.addPropertyChangeListener(new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent evt)
{
if("state".equals(evt.getPropertyName())
&& evt.getNewValue() == SwingWorker.StateValue.DONE)
p.execute();
}
});
previous=p;
}