45fan.com - 路饭网

搜索: 您的位置主页 > 电脑频道 > 电脑教程 > 阅读资讯:同步Java Swing中GUI代码的线程的步骤

同步Java Swing中GUI代码的线程的步骤

2016-08-29 10:20:09 来源:www.45fan.com 【

同步Java Swing中GUI代码的线程的步骤

 

GUI代码的线程同步

Swing组件的事件处理和绘画代码,都是被一个线程依次调用的,
这样保证事件处理的同步执行。
这个线程就是 Event-Dispatching Thread。

为了避免可能的死锁,确保Swing组件和model的创建、修改和查找
只在Event-dispatching Thread中调用。

SwingUtilities的invokeLater(Runnable),invokeAndWait(Runnable)
都是将GUI代码加入Event-dispatching Thread的方法。

invokeLater()立即返回,而invokeAndWait()阻塞,直到Event-dispatching Thread
执行完指定的GUI代码。
invokeAndWait()方法也有导致deadlock的可能,尽量使用invokeLater()。

About Realized
Realized means that the component has been painted on screen, or is ready to be painted.
setVisible(true) and pack() cause a window to be realized, which in turn causes the components it contains to be realized.

同步会导致等待,当一个事件处理时间太长,后面的事件处理就得不到响应,给人响应不灵敏的感觉。
SwingWorker或者Timer类可以解决缓解这个问题,
其中SwingWorker是java-tutorials定义的类,不是Swing API。

SwingWorker 让你在利用其它线程执行完耗时任务后,向Event-dispatching Thread中添加GUI代码。
耗时任务写在construct()中,耗时任务后的GUI代码写道finish()中。
public void actionPerformed(ActionEvent e) {
...
if (icon == null) { //haven't viewed this photo before
loadImage(imagedir + pic.filename, current);
} else {
updatePhotograph(current, pic);
}
}
...
//Load an image in a separate thread.
private void loadImage(final String imagePath, final int index) {
final SwingWorker worker = new SwingWorker() {
ImageIcon icon = null;

public Object construct() {
icon = new ImageIcon(getURL(imagePath));
return icon; //return value not used by this program
}

//Runs on the event-dispatching thread.
public void finished() {
Photo pic = (Photo)pictures.elementAt(index);
pic.setIcon(icon);
if (index == current)
updatePhotograph(index, pic);
}
};
worker.start();
}

可以使用如下的技术,使得Swing程序顺利工作:
● 如果你需要更新组件,但是代码不在Event Listener中,使用invokeLater()或invokeAndWait()向Event-dispacthing Thread添加代码。
●如果你不能确定你的代码是不是在Event Listener中,你必须弄清楚,程序中方法会被线程调用的情况。很难确定方法被线程的调用情况,可是调用SwingUtilies.isEventDispatchThread()来确定调用方法的线程是不是Event-dispatching Thread。安全起见,你可以把Event Listener外的GUI代码都通过invokeLater()传入EdThread,即使是在EdThread中调用invokeLater()。但是在EdThread中调用invokeAndWait()是会抛出异常的。
●如果你需要在一段时间的等待后,才更新组件,创建一个Timer,让它来完成这个任务。
●如果你需要每个一段时间(regular interval)更新组件,使用Timer吧。
* see Also: How to Use Swing Timers:
http://java.sun.com/docs/books/tutorial/uiswing/misc/timer.html


参考资料:

* How to Use Threads
java tutorials > Creating a GUI with JFC/Swing > Using Other Swing Features
http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html

 

本文地址:http://www.45fan.com/dnjc/69282.html
Tags: Java GUI swing
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部