看了网上的资料,对于 SwingUtilities.invokeLater() 的用法还是不解。
我在 actionPerformed() 方法中新起一个线程去做事情并更新组件的状态,与使用 SwingUtilities.invokeLater() 有什么不同?我自己写了个例子,一个button 和一个progressbar,点button,progressbar开始更新,发现两种方法实现的效果是一样的,网上看到说,在新起一个线程中更新组件状态是不安全的,不安全在哪里呢?
我在 actionPerformed() 方法中新起一个线程去做事情并更新组件的状态,与使用 SwingUtilities.invokeLater() 有什么不同?我自己写了个例子,一个button 和一个progressbar,点button,progressbar开始更新,发现两种方法实现的效果是一样的,网上看到说,在新起一个线程中更新组件状态是不安全的,不安全在哪里呢?
如果你在当前线程里做,则按钮就一直是沉下状态,直到你的事情办完。按钮弹起之前,界面会失去响应。
如果你用SwingUtilities.invokeLater()的方式,则点完之后按钮直接就弹起来了。这项费时的操作将在后台进行。这是ui设计中非常常用的方法。
然后换成SwingUtilities.invokeLater()的方式,看有什么区别。
我有说过在 actionPerformed()中进行费时的操作吗??
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;public class Calendar extends JFrame implements ActionListener { private JButton button_ok = new JButton("Click me."); public Calendar() {
super();
this.setTitle("TEST");
this.setLocation(500, 300);
this.setResizable(true);
button_ok.addActionListener(this);
getContentPane().add(button_ok);
pack();
} public void actionPerformed(ActionEvent e) { new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getId());
}
}).start(); // try {
// Thread.sleep(3000);
// } catch (InterruptedException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
} public static void main(String[] args) {
System.out.println(Thread.currentThread().getId());
Calendar CT = new Calendar();
CT.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CT.setVisible(true);
}
}
actionPerformed方法稍加改动你就能看见效果。
在事件分派线程中,SwingUtilities.invokeLater()还是会阻塞当前线程。
线程中执行任务,执行完毕后,将按钮enabled。
”I was calling JLabel.setText from a thread that wasn't EDT“
Agreed it doesn't seem like a big deal because the setText() method simply saves the text in a class variable and invokes repaint(). According to the article repaint() is thread safe.However, the setText() method also creates a PropertyChangeEvent. So if you have a listener that does something with the property change event it won't be executing on the EDT, so I guess you could have a problem.后半段是重点,自己 new 一个 Thread 并简单的在里面更新组件状态是不安全的。