3

I have read about that when programming Java Swing, we should put these components into Java Event Queue, because Java Swing thread is not-thread safe.

But, when I use Event Queue, I don't know how to update component properties (for example : set text for label or change something..). Here is my code :

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();
    }

}

I know, if I write SwingExample example = new SwingExample(); the error won't appear again, but if i use that, I cannot process example.setLabel later.

Please tell me about this error and how to fix this.

Thanks :)

hqt
  • 29,632
  • 51
  • 171
  • 250
  • @AndrewThompson `example.setLablel` just my example to update GUI. I must to save `SwingExample` object for another class to update this. – hqt Aug 24 '12 at 07:26
  • I misread the source, please ignore my first comment. For better help sooner, post an [SSCCE](http://sscce.org/) (of your best attempt) with two classes. – Andrew Thompson Aug 24 '12 at 07:29
  • @AndrewThompson As I add comment to line `example.setLabel`: In fact, I want to set label text sometime in the "future" for some situation in other class or another method outside. – hqt Aug 24 '12 at 07:31
  • While this isn't a general solution, you could make `SwingExample` a field in your class. This will make it accessible to your anonymous inner class. Also, make sure any future usages of your `SwingExample` instance are on the event dispatch thread. – Duncan Jones Aug 24 '12 at 07:31
  • @DuncanJones can you tell me more clearer. thanks :) – hqt Aug 24 '12 at 07:35

1 Answers1

3

By having your SwingExample instance as a field, you can reference it inside the inner classes without it being 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();
            }
        });
    }
}
Duncan Jones
  • 67,400
  • 29
  • 193
  • 254