ALUE)就睡觉了,无暇管塞入EventQueue的其他事件了,比如关 闭窗体。
所以绝对不能将持有锁的逻辑塞到EventQueue,而应该放到外边main线程或 者其他线程里面。
提到invokeAndWait,还必须说说invokelater 这两个区别在哪里呢?
invokeAndWait与invokelater区别: 看JDK代码:
public static void invokeLater(Runnable runnable) {
Toolkit.getEventQueue().postEvent(
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable));
}
public static void invokeAndWait(Runnable runnable)
throws InterruptedException, InvocationTargetException {
if (EventQueue.isDispatchThread()) {
throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
}
class AWTInvocationLock {}
Object lock = new AWTInvocationLock();
InvocationEvent event =
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock,
true);
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
lock.wait();
}
Throwable eventThrowable = event.getThrowable();
if (eventThrowable != null) {
throw new InvocationTargetException (eventThrowable);
}
}
invokelater:当在main方法中调用SwingUtils.invokelater,后,把事件塞入 EventQueue就返回了,main线程不会阻塞。
invokeAndWait: 当在Main方法中调用SwingUtils.invokeAndWait 后,看代 码片段:
synchronized (lock) {
Toolkit.getEventQueue().postEvent(event);
lock.wait();
}
深入浅出Java多线程(2)-Swing中的EDT(事件分发线程)(6)
时间:2010-12-09 advincenting
main线程获得lock 后就wait()了,直到事件分发线程调用 lock对象的notify唤醒main线程,否则main 就干等着吧。
这下明白了吧!
总之,对于我们问题最简单的方法就是是main线程里,或者在其他线程里处 理。
最后的解决方案是:
package desktopapplication1;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class SwingApplication {
private static String labelPrefix = "Number of button clicks: ";
private int numClicks = 0;
public Component createComponents() {
final JLabel label = new JLabel(labelPrefix + "0 ");
JButton button = new JButton("I''m a Swing button!");
button.setMnemonic(KeyEvent.VK_I);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
numClicks++;
label.setText(labelPrefix + numClicks);
}
});
label.setLabelFor(button);
/*
|