2

I have the following piece of code

import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;
import javax.swing.*;
class QueueTest {
    public static void main(String[] args) throws InterruptedException, 

InvocationTargetException {
        EventQueue eventQueue = 

Toolkit.getDefaultToolkit().getSystemEventQueue();
        eventQueue.push(new MyEventQueue());


    Frame f=new Frame();
    f.setSize(400,400);
    //f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setLocation(150,150);
    f.setVisible(true);

    Button b=new Button("button");
    f.add(b);

    b.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent ae)
        {
        System.out.println("button is clicked");
        }
    });
    }

    private static class MyEventQueue extends EventQueue {
        public void postEvent(AWTEvent theEvent) {
//            System.out.println("Event Posted");
  System.out.println("The source of event is "+theEvent.getSource());
            super.postEvent(theEvent);
        }
    }
}

I have written a custom EventQueue. This is working in swing when I've replaced Frame with JFrame and Button with JButton. But why isn't this working for AWT components?

When i have resized the frame, clicked on the button the control is not entered into the postEvent() method. But in swing, it is entered. Why is it so?

Aren't events placed in the EventQueue in AWT? Also who posts the events to this EventQueue? Windows kernel?

Kindly, reply me.

JavaTechnical
  • 8,846
  • 8
  • 61
  • 97

1 Answers1

1

The AWT events are placed on the queue, but not using the method postEvent. That method exists to allow code outside the AWT to post events. You should have noticed that there are a very little number of events posted that way.

If you override the method protected void dispatchEvent(AWTEvent event) you will see a lot more events, including the Button events.

However, it’s not recommended to mess around with the event queue. It will fail once another piece of code pushes a new queue. And it has some other oddities.

If you want to detect ActionEvents globally, use

Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
  public void eventDispatched(AWTEvent event)
  {
    System.out.println("eventDispatched: "+event);
  }
}, AWTEvent.ACTION_EVENT_MASK);
Holger
  • 285,553
  • 42
  • 434
  • 765
  • Interesting. But could I know why is it so? Thanks. – JavaTechnical Jan 31 '14 at 12:50
  • @JavaTechnical: what is your question, exactly? – Holger Jan 31 '14 at 13:23
  • I mean, why are very little no. of events posted to postEvent() method? – JavaTechnical Feb 01 '14 at 10:16
  • As said, this method is not meant to be the universal entry point for all events. It just exists to allow posting events from different packages. So by overriding that method you see events posted from code outside the `java.awt` package only. – Holger Feb 03 '14 at 09:53
  • `dispatchEvent()` is responsible for the other side of the queue; it will dispatch the events which are just removed from the queue. This affects almost all events of the queue. Note that `Swing` will deliver certain high-level events (e.g. tree and table events) directly after its creation without queuing them. – Holger Feb 03 '14 at 10:08
  • Why does swing deliver those high-level events directly without queuing? – JavaTechnical Feb 06 '14 at 19:19
  • The AWT does only dispatch events it knows how to dispatch. The others have to be `ActiveEvent`s which know how to dispatch themselves. In other words, Swing had to encode every high-level event delivery into another object to post it on the queue (similar to what `invokeLater` does). Further, queuing them would change the order of the high level events compared to low-level events being already on the queue. Another advantage of direct delivery is that a listener hearing about a high level event can query the EventQueue for the current low-level event to get more context information. – Holger Feb 07 '14 at 09:42
  • Could you say me what are the events that AWT know how to dispatch? – JavaTechnical Feb 07 '14 at 18:44
  • Events having a `Component`, `MenuComponent`, or `TrayIcon` source. So all instances of [`ComponentEvent` and its subclasses](http://stackoverflow.com/questions/21523883/what-is-sun-awt-windows-wtoolkit#comment32674656_21524246) are unconditionally included, but this excludes events having a Swing data model or selection model source. – Holger Feb 10 '14 at 09:44
  • So that means always a low-level event is delivered before the high-level event in swing. Is it same in the case of AWT too? – JavaTechnical Feb 11 '14 at 08:50
  • But when I add both `ActionListener` and `MouseListener` to a `JButton` `actionPerformed()` is executed before `mouseClicked`. How is this possible? Is it just because not only a mouse click can generate `ActionEvent`? – JavaTechnical Feb 11 '14 at 09:19
  • Swing depends on receiving low-level events in order to react on them and generate the high-level events. Exception are timer-generated events but these have a corresponding `ActiveEvent`/`InvocationEvent` on the queue. In contrast, AWT interacts with native components which in theory could produce high-level events without corresponding low-level events seen by the Java code. Note that both, AWT and Swing, support the Accessibility framework which allows external tools to produce high-level events without low-level cause. – Holger Feb 11 '14 at 09:21
  • That means the native code itself creates a high level event object in AWT? – JavaTechnical Feb 11 '14 at 09:23
  • It’s system-specific which kind of events trigger an `ActionEvent`. Typically, releasing the mouse button over the same component where it has been pressed before triggers an `ActionEvent`. That’s the same condition which will be treated as *click* but the click is not the cause of the `ActionEvent`. It’s implementation specific who produces the high-level event but you cannot assume that it is generated by a `MouseListener`. Therefore, in case of AWT, you are able to see the low-level events *too* but not to see them *before*. – Holger Feb 11 '14 at 09:25
  • Yes, I just now have observed that when you press the mouse on a button at a particular point and then release at other point in the same button, you will see an ActionEvent generated but not a mouse click. – JavaTechnical Feb 11 '14 at 09:27
  • So is that 'native event' which triggers ActionEvent placed in the event queue? – JavaTechnical Feb 11 '14 at 09:28