您的位置:首页 > 产品设计 > UI/UE

跨线程操作UI

2011-10-18 19:07 316 查看
由于众所周知的原因,一般只有一个线程操作UI。对于多线程程序,怎么让工作线程去操作UI呢?在C++里,可以很方便地利用Windows消息,sendMessage和postMessage。在C#中,MSDN中也给出了用委托的方法。那Java中呢?

Java中观察者模式非常常见。跨线程操作UI也可以用观察者模式来实现。UI线程作为观察者,当工作线程有“动静”时,主动通知UI线程。

import java.util.Observable;
import java.util.Observer;

public class MyAction extends Observable{

public void test(){
this.setChanged();
this.notifyObservers();

}

}

被观察的对象“MyAction”通过test方法来通知观察者。MyAction应该在工作线程中。

public class MainFrame extends JFrame implements Observer {

@Override
protected void frameInit() {
// TODO Auto-generated method stub
super.frameInit();
this.setLayout(null);
JButton jb = new JButton("test");
jb.setSize(100, 100);
jb.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
Thread t = new Thread(){

@Override
public void run() {
// TODO Auto-generated method stub
MyAction action = new MyAction();
//注册观察者
action.addObserver(MainFrame.this);
try {
this.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
action.test();
}

};
t.start();
}
});
this.add(jb);
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MainFrame f = new MainFrame();
f.setVisible(true);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
f.setSize(200, 200);

}

@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
JOptionPane.showMessageDialog(null, "message");

}

}

观察者收到通知时,update方法就会被调用,在这个方法里更新UI即可。

纠错:

这种方法不能实现跨线程操作UI。测试方法,在update方法中获取Thread.currentThread().getId(),发现是非UI线程的ID。看了Observable的代码,确实没有跨线程的内容。

不过下述JComponent方法是安全的,可以从任何线程调用:repaint()、revalidate()、和invalidate()。(repaint()和revalidate()方法为事件派发线程对请求排队,并分别调用paint()和validate()方法。invalidate()方法只在需要确认时标记一个组件和它的所有直接祖先。)所以,可以重写这些方法,来更新UI。

另外,一般也不能使用Timer来主动获取工作线程的数据,因为Timer运行在其它线程上,不过可以参考http://jianshusoft.blog.51cto.com/2380869/764382。
本文出自 “木又寸的技术博客” 博客,请务必保留此出处http://jianshusoft.blog.51cto.com/2380869/691372
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: