Question

I've read a few books about Java. In all of them there was at least one chapter teaching GUI programming. In all of them, creating a simple form application was following this logic:

MyFrame.java

public class MyFrame extends JFrame
{
    JButton button1;

    public MyFrame()
    {
        button1 = new JButton("Click here.");
    }
}

FrameTest.java:

public class FrameTest
{
    public static void main(String[] args)
    {
        MyFrame myFrame = new MyFrame();

        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setSize(600, 600);
        myFrame.setVisible(true);
    }
}

Basically, just subclass JFrame to create a form and declare as instance variables the other components and initialize those components in the constructor. And then create another test class, instantiate the frame subclass in that class and call some of its methods to make it visible.

But in concurrency lessons I've learned that we have a main thread which runs main() in every application we create. As far as I know, when we use Swing in order to create GUI applications we have another thread (Event Dispatcher Thread). So if i am not mistaken, in every Swing based GUI application there are at least two threads. This makes every GUI application multithreaded. And in some articles and tutorials that I've read, it says that Swing doesn't support multithreading therefore all GUI components should be created and modified only in Event Dispatcher Thread otherwise Thread Interference and Memory Inconsistency Errors may arise.

Even in the simplest example in Wikipedia (http://en.wikipedia.org/wiki/Swing_%28Java%29), it's made like this via invokeLater method.

So which one is the true approach? Where am I wrong?

Was it helpful?

Solution

ALL interactions with any UI/Swing component MUST be done for within the context of the EDT

When starting an application, you should ensure that you are executing within the EDT BEFORE you try and create/interact with any Swing component.

Simply put, you should use something like...

EventQueue.invokeLater(new Runnable() {
    public void run() {
        // Now in the event dispatching thread
    }
});

If you need to run long running task or perform any blocking task, you should execute it in a separate thread. SwingWorker is a good choice in most cases as it provides some simple mechanisms for re-syncing code to the event dispatching thread.

Take a read through

So, the short answer is, yes, all Swing based code should be accessed/modified/interacted with from the context of the EDT

OTHER TIPS

So if i am not mistaken, in every Swing based GUI application there are at least two threads

Yes. One is main thread and other is EDT(Event Dispatch Thread).

This makes every GUI application multithreaded.

Yes. But in that case , the other thread is not interacting with the GUI component.

Swing doesn't support multithreading therefore all GUI components should be created and modified only in Event Dispatcher Thread otherwise Thread Interference and Memory Inconsistency Errors may arise.

Yes , Absolutely true. This means that at a time only one Thread should interact with the given GUI component.
A Swing programmer deals with the following kinds of threads:

  • Initial threads, the threads that execute initial application code.
  • The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also execute on this thread.
  • Worker threads, also known as background threads, where time-consuming background tasks are executed.

The programmer does not need to provide code that explicitly creates these threads: they are provided by the runtime or the Swing framework. The programmer's job is to utilize these threads to create a responsive, maintainable Swing program.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top