1

I am new to swing and still learning the ins and outs of it. I wrote a basic code and started experimenting with EDT. Here is the code:

public class SwingDemo2 extends Thread implements ActionListener {

JLabel jl;

SwingDemo2() {
    JFrame jfr = new JFrame("Swing Event Handling");
    jfr.setSize(250, 100);
    jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    jl = new JLabel("Press a button!", SwingConstants.CENTER);

    System.out.println("After Label: " + SwingUtilities.isEventDispatchThread());

    JButton jb1 = new JButton("OK");
    jb1.setActionCommand("OK");

    jb1.addActionListener(this);

    JButton jb2 = new JButton("Reset");
    jb2.setActionCommand("Reset");

    jb2.addActionListener(this);

    jfr.add(jl, BorderLayout.NORTH);
    jfr.add(jb1, BorderLayout.WEST);
    jfr.add(jb2, BorderLayout.EAST);

    System.out.println("After adding: " + SwingUtilities.isEventDispatchThread());

    jfr.setVisible(true);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.println("In main: " + SwingUtilities.isEventDispatchThread());
            new SwingDemo2();
        }
    });
}

public void actionPerformed(ActionEvent ae) {
    if (ae.getActionCommand() == "OK") {
        System.out.println("In OK: " + SwingUtilities.isEventDispatchThread());
        jl.setText("You pressed Ok");
    }
    else if (ae.getActionCommand() == "Reset") {
        System.out.println("In Reset: " + SwingUtilities.isEventDispatchThread());
        jl.setText("You pressed Reset");
    }

}

}

I added a few isEventDispatchThread() methods to verify the thread I am in. Apart from the GUI the messages in console were:

In main: true
After Label: true
After adding: true
In OK: true
In Reset: true

It seems all the time I was in the EDT. My question is, after the jfr.setVisible(true) statement shouldn't the SwingDemo2() constructor return to main() and shouldn't that be the end of EDT?

I waited for many seconds before I first pressed any button in the GUI so why is still my event handling being done in EDT? Shouldn't that have given the EDT enough time to terminate?

Thanx in advance!

Surender Thakran
  • 3,560
  • 9
  • 39
  • 76
  • 2
    Just try to write one `isEventDispatchThread()` outside `invokeLater()`, in your main method, you will get an idea, how separate they are. When a Swing Application runs, three threads are started. **1. Main Thread :** from which your application runs. **2. Toolkit Thread :** This thread is in charge of capturing the system events, like Keyboard key presses or mouse movements. Though, this thread never runs application code. Captured events are passed over to the third thread, the EDT. **3. EDT - Event Dispatch Thread :** is in charge of dispatching the events captured by the toolkit thread. – nIcE cOw Jan 08 '13 at 13:31
  • EDT is the thread on which you interact with your Swing. – nIcE cOw Jan 08 '13 at 13:34
  • @GagandeepBali **Another silly question:** How many EDTs does a swing app has? When i tried to call `invokeLater` **again** after the already present one, the program compiled and ran perfectly. Did it ran in the same EDT or a new one was created? – Surender Thakran Jan 08 '13 at 14:46
  • No `invokeLater()` is actually used to put your new task on the same `EDT`. There is one more method known as `invokeAndWait()`, though it will put the task on the EDT, and wait till this task is not finished. Hence it will block the `EDT` for this duration, until the task is not finished. This one is a bit trickier to use, since it might can lead to `deadlocks/run conditions`, if used in an improper way. – nIcE cOw Jan 08 '13 at 14:56
  • Whenever a new task is created, you simply use `invokeLater()` to put that task on the `EDT queue`, which performs the task on the `FIFO` principle AFAIK. – nIcE cOw Jan 08 '13 at 15:01
  • Here is one [example](http://stackoverflow.com/a/13004927/1057230), that might interest you. Inside the `BubbleSort` class if you change all `invokeAndWait()` to `invokeLater()`, you might be able to get a wonderful idea, regarding the difference between the two. – nIcE cOw Jan 08 '13 at 15:10

3 Answers3

5

In Event Dispatching Thread, you see the word "Event". This means that all (UI) "Events" are always dispatched on that particular Thread: ActionEvent, PaintEvent, KeyEvent, MouseEvent, etc... You can wait as long as you want, a button click (ActionEvent) will always be dispatched on the EDT.

When the JVM starts, it invokes the main() method on the "Main"-Thread. Inside that, you use SwingUtilities.invokeLater() which will start the EDT and the Runnable you provide will be executed (in the scope of the EDT). Meanwhile your Main Thread stops running since it reached its last statement. On the other hand, the EDT never stops running and constantly waits for new events to occur.

Guillaume Polet
  • 45,783
  • 4
  • 79
  • 115
2

Scope of EDT will last till event handling, which includes:

  • All events directly triggered by the end user (mouse events, key events) and all higher-level events triggered by these (actionListeners, focusListeners etc...); actually you could say that all AWT and Swing EventListeners are always called in the EDT
  • All painting code (as triggered by changes in components or changes in widows size or positions, whenver an area needs to be painted)
  • Or any code called through SwingUtilities.invokeAndWait() or SwingUtilities.invokeLater().
exexzian
  • 7,345
  • 6
  • 41
  • 50
1
  1. by default for (I'm talking about your code) creating Swing code are important two points

    • use and apply LayoutManager on EDT (for example pack(), setSize etc...)

    • setVisible() for container on EDT

    • rest of built the Swing code isn't EDT sensitive at all

  2. EDT is separate a special thread that is present (not alive) in current JVM all time if initalized from Swing Code, expired with currnet JVM too

    • by default from invokeLater or invokeAndWait (never see real reason to use == my view)

    • EDT isn't active in the case that all events are done, then have to wake_up, alive this thread from invokeLater / invokeAndWait (notice caused exception if is EDT alive) or by using SwingWorker

  3. WorkersThread by default never to invoke / alive the EDT, Swing GUI doesn't know something about output from WorkersThreads to the GUI, event part of methods in Swing APIs are declared as thread_safe, this works only in the case that EDT is alive, otherwise nothing happends,

  4. I waited for many seconds before I first pressed any button in the GUI so why is still my event handling being done in EDT? Shouldn't that have given the EDT enough time to terminate?,

not true in the case that EDT is empty then returns is false, see for example

Community
  • 1
  • 1
mKorbel
  • 108,320
  • 17
  • 126
  • 296