actionPerformed(ActionEvent e)是否在与事件调度线程(EDT)不同的线程中运行?

时间:2014-09-22 21:08:34

标签: java swing event-dispatch-thread

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内完成?

1 个答案:

答案 0 :(得分:4)

问题不在于线程,而是匿名的ActionListener类就是那个 - 一个不同的类。 ActionListener的生命周期比局部变量'a'的生命周期长,因此您无法修改它。因此,它必须是最终的。

实际上,你试图“在构造函数中保留一个变量”,然后允许一个寿命更长的类来修改它是完全没有意义的。

我认为最接近你想要的是使'a'成为Frame类的成员变量。然后,如果必须,可以在ActionListener中使用“Frame.this.a”访问它,但是Frame中的公共方法会更好。

最后,创建框架并将其设置为“可见”是在EDT上完成的,因为这是修改Swing组件安全的唯一线程。