2

Re: Requirement to create Swing Object on Event-Dispatch Thread.

I am working on an application, the purpose of which is to monitor and display the condition of various remote embedded servers. I'm pretty new to Java, and my understanding of the requirement with respect to the Swing Objects and the EDT is incomplete.

The main GUI is started on the EDT in the usual fashion as follows,

    javax.swing.SwingUtilities.invokeLater(new Runnable() {

        public void run() {
            createAndShowGUI();
        }
    });

The user may then select one or more menu options corresponding to the one or other of the remote machines. The effect of this is to create a new thread each time as follows

                new Thread(new VoterStatus(itemNumber)).start();

which invokes VoterStatus's class "run" method which in turn creates a new window with a JFrame. The new thread, an instance of VoterStatus class, then interrogates (TCP etc) the particular remote specified (itemNumber), collecting various bits of information and displaying them in the JFrame.

There may be any number of such threads corresponding to an instance of VoterStatus, all updating their own windows. There is no sharing of data between these various windows/JFrame/tasks.

This seems to work just fine, but is is safe?

Have I violated the rule about creating Swing components on the EDT?

Would use of the SwingWorker class be beneficial?

I would appreciate any comments from Java programmers more experienced in such matters.

Thanks Steve

Steve Kuo
  • 61,876
  • 75
  • 195
  • 257
Steve
  • 21
  • 1
  • Do you use EDT only to start the main GUI? If yes, then everything is fine. But if subsequent windows are also created in EDT, and their creation is long enough (i.e. > 200 ms) your GUI will freeze for the time of new window creation. – Rogach Feb 01 '11 at 04:30
  • Hi Rogach - That comments appears slightly at odds with a couple of the other answers, although I would prefer it if was indeed the case. I am creating the main GUI on the EDT, but the other windows are started on threads started in the EDT. Any more thoughts. Thanks Steve – Steve Feb 02 '11 at 04:59

4 Answers4

5

From the section in the Swing tutorial titled The Event Dispatch Thread

Some Swing component methods are labelled "thread safe" in the API specification; these can be safely invoked from any thread. All other Swing component methods must be invoked from the event dispatch thread. Programs that ignore this rule may function correctly most of the time, but are subject to unpredictable errors that are difficult to reproduce.

I always invoke my methods on the EDT so I don't waste time chasing gremlins.

Edit:

I just read another posting which states that the comment "thread safe" has been removed from many methods in the JDK7 API. http://forums.oracle.com/forums/thread.jspa?threadID=2167051. This looks like another reason to make sure all methods that affect the GUI are executed on the EDT.

camickr
  • 321,443
  • 19
  • 166
  • 288
2

@camickr has the right of it. Incorrectly synchronized programs may appear to work most of the time, but the result is not reliable. Several related approaches are discussed here. SwingWorker is an especially convenient implementation of the Future interface, as process() runs on the event dispatch thread.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
0

You might be safe, but you can be sure by creating your other UI components in the EDT, just like you did for the main application.

However, I would suggest a different approach. Rather than firing off a new Thread which creates the windows and stuff for each new VoterStatus, create the UI components in the EDT in response to ActionEvents from menus or whatever, and do processing of the network stuff only in a different thread. Then get the results and use the EDT to display them. As you've suggested, a SwingWorker is ideal for this - this is exactly the sort of use it was designed for. This represents a cleaner separation for me, separating the UI stuff from the network stuff as much as possible.

Stewart Murrie
  • 1,319
  • 7
  • 12
0

I'm not really answering my own question, but I do want to thank those that responded and ask a follow up question or two.

Rogash commented that if I was only creating the GUI on the EDT, I would be ok, but this doesn't seem quite in accordance with a strict interpretation of the rule?

The additional threads are created in the EDT, but they are still separate threads.

Whilst slightly better separation of the GUI and comms may be desirable, I expect this will add considerable complexity to the main GUI code, since it will have to determine which window originated various events and then update the correct window, not to mention the communication between the various threads and the main GUI thread. Perhaps I am overstating this difficulty (I haven't designed or thought about how to code it yet) but it would seem more complicated. Each of the threads/JFrame already has a couple of JToggleButton arrays (30 elements) causing potential events and 10 or so JTextField arrays with the same number of elements requiring updating.

Of course, if my method is unsafe, I'll have to change it, and that's that!

Actually, I wonder if I might be better off leaving things the way they are, and using a mutex or semaphore to make sure only one thread is accessing Swing methods at a time. There is really no long user actions or any other activity takes a long time, just lots of TCP or UDP packets being received that require the screen display to be updated.

Thanks again Steve

PS I tried to register on this forum, but I think this discussion will stay with my unregistered persona.

Steve
  • 21
  • 1