//一个更新JLabel的线程
class CountLabel implements Runnable{
private JLabel label;
CountLabel(JLabel label){
this.label=label;
}
@Override
public void run() {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
String result_start = "共抓取";
String result_end = "条结果";
while (!c.getState()) {
label.setText(result_start+c.getList().size()+result_end);
}
}
}
//省略了无关代码
//这是ActionListener的一个方法
//crawler时一个自定义爬虫类的对象,其中有一个耗时较长的getInfo方法
//我希望在JLabel上实时更新爬取的数据条数
//可能会写出下面的代码
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if (arg0.getActionCommand().equals("crawler")){
//关键代码
new Thread(new CountLabel(countLabel)).start();
//直接在UI主线程调用
crawler.getInfo();
flButton.setEnabled(true);
}else if (arg0.getActionCommand().equals("filter")){
if (c.getState())
new Thread(progress).start();
else
JOptionPane.showMessageDialog(null, "爬取未完成");
}else if(arg0.getActionCommand().equals("save")){
}
}
好,ok,多线程刷新JLabel,想法是对的,但是由于主线程UI在Listener的actionPerformed阻塞了,就无法更新组件,修改后的代码如下
//让Crawler实现在另开的线程工作
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
if (arg0.getActionCommand().equals("crawler")){
//关键代码
//开启新线程执行任务
new Thread(new CountLabel(countLabel)).start();
new Thread(crawler).start();
flButton.setEnabled(true);
}else if (arg0.getActionCommand().equals("filter")){
if (c.getState())
new Thread(progress).start();
else
JOptionPane.showMessageDialog(null, "爬取未完成");
}else if(arg0.getActionCommand().equals("save")){
}
}
上面我们把爬取的任务开了另一个线程执行,就不会让UI线程阻塞在监听器了
如有什么错误,请指正