user1597002
user1597002

Reputation:

Calling event dispatch thread

I have a main class which extends JFrame.

I add panels to this instance of frame which consist of JTable and other Swing components.

In this main class in the "public static void main", I set swing event dispatch thread.

I add panels to this instance frame, and initiate:

this.setTitle("Test");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);

etc...

All fine up to here.

Now, for JTable it has a listener and when a row is clicked it opens up a new instance of a class InfoDialog.

In this InfoDialog I add Swing components as usual.

I have another dispatch thread in JDialog like this:

class InfoDialog  {
    JDialog jd;
    public void initGUI() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
                 jd = new JDialog();
            jd.setModalityType(ModalityType.APPLICATION_MODAL);
            jd.setTitle("Buy");
            jd.setDefaultCloseOperation(jd.DISPOSE_ON_CLOSE);
            jd.pack();
            jd.setLocationRelativeTo(null);
    jd.setVisible(true);
    }});
   } 
}

Putting the event dispatch thread solves the errors I'm getting (probably because its blocking the current thread previosuly), and my question is, is this the right way to do it?

Thanks for any advice.

Upvotes: 2

Views: 2071

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347332

Basically, you should only be creating and interacting with the dialog (and all other UI components) from within the context of the Event Dispatching Thread.

You can (at some extent), ensure this by calling EventQueue.invokeLater from your main method to start with. This ensures that most of the UI is already been called from within the context of the EDT.

public static void main(String args[]) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            //...Your UI code here...
        }
    });
}

It should be safe to assume that you are within the EDT at all other times. It should be the responsibility of the caller to ensure this, not your components. I often create "safe" factory methods to make it easier to construct some UI components (things like progress indicators for example) which are designed and documented to be thread safe.

Check out Concurrency in Swing and Initial Threads for more details.

Upvotes: 2

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147164

There is only one AWT EDT. (Well there can be multiple in Applets and WebStart, but effectively just one.)

What's happening with your invokeLater is that an event is placed on the EventQueue, then execution goes back through the caller of initGUI, previously queued events are dispatched and then then your run method is executed.

Possibly you shoul move the call to initGUI() further down your code.

Upvotes: 0

Related Questions