Java事件队列:如何在JFrame中更新组件

3

我了解到,在编写Java Swing程序时,我们应该将这些组件放入Java事件队列中,因为Java Swing线程不是线程安全的。

但是,当我使用事件队列时,我不知道如何更新组件属性(例如:为标签设置文本或更改某些内容..)。以下是我的代码:

public class SwingExample {

    private JLabel lblLabel;    
    SwingExample(){
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        lblLabel = new JLabel("Hello, world!", JLabel.CENTER);
        frame.getContentPane().add(lblLabel); // adds to CENTER
        frame.setSize(200, 150);
        frame.setVisible(true);

    }

    public void setLabel(){
        lblLabel.setText("Bye Bye !!!");
    }



    public static void main(String[] args) throws Exception
    {
        SwingExample example = null;
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                example = new SwingExample(); // ERROR : Cannot refer to non-final variable inside an inner class defined in different method
            }
        });

        // sometime in the futures, i want to update label, so i will call this method...
        example.setLabel();
    }

}

我知道,如果我写 SwingExample example = new SwingExample(); 错误就不会再出现了,但如果我使用这个,我以后就不能处理 example.setLabel 了。
请告诉我关于这个错误的信息以及如何修复它。
谢谢 :)

@AndrewThompson example.setLablel 只是我的一个用来更新 GUI 的例子。我必须保存 SwingExample 对象,以便另一个类能够更新它。 - hqt
我误读了源代码,请忽略我的第一条评论。为了更快地获得更好的帮助,请发布一个包含两个类的SSCCE(您的最佳尝试)。 - Andrew Thompson
@AndrewThompson 当我在example.setLabel这一行添加注释时:实际上,我想要在其他类或方法之外的某些情况下,在“未来”设置标签文本。 - hqt
虽然这不是一个通用的解决方案,但你可以将 SwingExample 设为类中的一个字段。这样它就可以被匿名内部类访问到了。同时,请确保你的 SwingExample 实例在事件分发线程上使用。 - Duncan Jones
@DuncanJones你能不能更清楚地告诉我?谢谢 :) - hqt
1个回答

3

如果将您的 SwingExample 实例作为字段,那么您可以在内部类中引用它而无需将其设置为 final

public class SwingExample {

    private JLabel lblLabel;    
    private static SwingExample instance;    

    SwingExample() {
        // code omitted
    }

    public void setLabel() {
        lblLabel.setText("Bye Bye !!!");
    }

    public static void main(String[] args) throws Exception {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                instance = new SwingExample();
            }
        });

        // ...

        EventQueue.invokeLater(new Runnable() {
            public void run() {
              instance.setLabel();
            }
        });
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接