actionPerformed(ActionEvent e)是否在与事件调度线程(EDT)不同的线程中运行? 说我写了下面的代码:
public void main(String args[]){
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Frame f = new Frame();
f.setVisible(true);
javax.swing.SwingUtilities.isEventDispatchThread()
}
catch(Exception e){ e.printStackTree;}
}
public Frame()
{ //...some code....
JButton btn = new JButton();
//int a;
javax.swing.SwingUtilities.isEventDispatchThread()
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//..some code....
javax.swing.SwingUtilities.isEventDispatchThread()
//a++;
}
}
}
虽然在所有三种情况下运行javax.swing.SwingUtilities.isEventDispatchThread()返回true,但是在actionPreformed中执行++是不可能的。
我调试了这个项目,如果我错了就纠正我:尽管整个框架都在EDT中运行,但是EDT为Frame()构造函数和actionPreformed()函数启动了新的不同线程。然后,正因为如此,为了逃避actionPreformed()的可能性将使用在另一个线程中创建的变量a,该变量可以在actionPreformed()的线程之前结束,它不可能具有作为常规的'' int'',只允许''final int''。
1 此示例中的actionPrefromed()函数是否在与Frame()构造函数的线程不同的线程中运行?
1.1 如果没有,那么为什么不能在actionPreformed()函数中修改a?
1.2 如果是,那么我如何存储可以保存在Frame()构造函数中的值?或至少可以通过其他不同的按钮访问?
2 为什么要创建框架f,或者将其设置为可见应该首先在ETD内完成?
答案 0 :(得分:4)
问题不在于线程,而是匿名的ActionListener类就是那个 - 一个不同的类。 ActionListener的生命周期比局部变量'a'的生命周期长,因此您无法修改它。因此,它必须是最终的。
实际上,你试图“在构造函数中保留一个变量”,然后允许一个寿命更长的类来修改它是完全没有意义的。
我认为最接近你想要的是使'a'成为Frame类的成员变量。然后,如果必须,可以在ActionListener中使用“Frame.this.a”访问它,但是Frame中的公共方法会更好。
最后,创建框架并将其设置为“可见”是在EDT上完成的,因为这是修改Swing组件安全的唯一线程。