How does a button know it's pressed?

Hi!

If I connect a listener of any kind. For example an ActionListener to a JButton.

How does the button know when it's pressed?

Is there like a loop that asks: "Is the button pressed", "Is the button pressed", etc... until it is pressed and then the event occur?

Someone care to explain?

[320 byte] By [rejeepa] at [2007-11-27 5:20:27]
# 1

the attached listener to the button will do the monitoring or obviously the "listening" if any action (or event was done) to the button (or more generally

the component). All you need to do as the client programmer is provide code - corresponding action - if such an action to the button was done.

did it help? :)

lem@phila at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 2

button.addActionListener(new ActionListener() { // adding a listener to this button

// if an action was done to the button, this 'actionPerformed' method will

// automatically be invoked

public void actionPerformed(ActionEvent evt) {

// place corresponding method, or body of code here to be called

// or implemented if such an action was done

}

});

lem@phila at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 3

the attached listener to the button will do the monitoring or obviously the "listening" if any action (or event was done) to the button (or more generally

the component).

Well... I know this! The thing I was wondering about is how it works on a lower level.

You say that the listener does the "monitoring". But how does it monitor? Does it check every thousands of second if the button is pressed or what?

rejeepa at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 4

There is a special thread with GUI applications - the event thread. Native user events like keyboard events and mouse events wake that thread and applications can listen to these events. Now there also other Swing events like the ActionEvent, which is build upon the mouse events. The button listens for mouse events - mouse pressed, mouse released, mouse clicked etc. (something like these). Then it fires the high level ActionEvent at the appropriate time. That way clients don't have to listen for mouse events on the button, but can just listen for ActionEvents.

So the whole story is about the event thread listening for user events (which propably uses wait and notify and not busy waiting).

Is it more clear now?

-Puce

Pucea at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 5
> Is it more clear now?Yes, I think so!So instead of that the button listens to if it's clicked and then calls some listener class/method, the listener method/class listens after events that occur when a button is pressed.Is this correct?
rejeepa at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 6

I don't know exactly the lowest level, but I think it must be something like this:

-user clicks the mouse

-event thread gets notified (wakes up)

- a Java event object is created and delegated to all registered mouse listeners (simple loop over all registered listeners, simple method call to each registered listener)

- Puce

Pucea at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 7
Try with ROBOin java.
harishspia at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 8
> Try with ROBOin java.?
Pucea at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 9
he could mean java.awt.robot ?! for automatic events
Oleka at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 10

> So instead of that the button listens to if it's

> clicked and then calls some listener class/method,

> the listener method/class listens after events that

> occur when a button is pressed.

>

> Is this correct?

Almost. I once bothered to browse through tons of Swing code (esp. event handling) and found out that it roughly works like this, starting from the very lowest level:

* When you move or click the mouse, a hardware interrupt is triggered (which one is usually configured by the OS at boot time) on the PS/2 or USB port

* An interrupt handler within the OS - usually the mouse driver - captures the interrupt and passes it over to the "interested parties" in a OS specific way

* The native windowing system (like X11 on *NIX or the Windows Shell on Windows) is usually one of those interested parties and it gets informed of the mouse event

* That native windowing system figures out what to do with the event and usually sends it to the window that is below the mouse pointer (this is handled by the so called "window manager" on X11)

* If that window is a Java Window, then there is a heavyweight Java component that corresponds to the native window on the screen, usually an AWT Frame, Window or Dialog (look for heavyweight and lightweight components in Java for more info on that topic)

* Here's where Java gets involved: the JVM has some deeply buried highly platform dependent code that gets notified of such events within its window. This code wakes up the event thread (aka EDT = event dispatching thread)

* The EDT runs an infinite loop waiting to be awakened, reading the event that occurred and passing it to the heavyweight AWT component within which the event occurred (it calls Component.dispatchEvent() on that component).

* So far, we are dealing only with "external" events, i.e. ones that come from the native world outside the JVM. Those are mostly mouse and keyboard events.

* The Component's dispatchEvent() method runs a long and complicated series of checks to determine what to do with the event. Swing components often override the inherited AWT implementation to dispatch the event correctly to the lightweight (sub)components.

* Usually a lot of interested parties need to be notified of the event, such as the KeyboardFocusManager, AWTListeners, child components, etc.

* This is where the low-level input events are transformed into higher level semantic events. A single input event usually results in a cascade of semantic events. The KeyboardFocusManager for example generates FocusEvents depending on the mouse or keyboard events, and dispatches those immediately by (recursively) calling the dispatchEvent() method on the affected components (i.e. the old and the new focus owner). Resizing or moving a component with the mouse on the other hand results in a series of ComponentEvents.

* This is why the dispatchEvent() method sometimes occurs more than once on a call stack trace - each new event generated as a result of another event is immediately dispatched via a recursive call.

* The default implementation of dispatchEvent, among other things, informs all registered listeners for the particular event and passes it along to subcomponents if needed.

* Sooner or later the event reaches "end user" components such as JButton and the like. What JButton does is it registers a MouseListener with itself and thus gets notified on every mouse event occurring over its surface, in particular click events. This way it knows when it gets clicked. The mouse event handler then generates ActionEvents and in turn calls all action listeners' actionPerformed() method.

* (More precisely, not the JButton registers a mouse listeners with itself, but the JButton UI delegate registers a mouse listener with its corresponding JButton, and upon click, it notifies the ButtonModel of the JButton, the ButtonModel notifies the JButton of this change, and the JButton finally notifies its action listeners.)

As you see, the whole thing gets quite complicated as you dig into the details, but that's the way in generally works. What's for sure, no busy waiting occurs on the EDT (that would be a complete performance kill!), and all state changes of the components take place as part of the event dispatching process.

Is it more clear now? :)

Btw, any comments, corrections etc. on the above description are welcome!

Greets,

Mike

MikePa at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...
# 11

Nice detailed explanation...

Would just suggest a slight change in that the JButton's (or UI delegate's) MouseListener is probably not listening for mouse-clicked events, but for a combination of mouse-entered/mouse-exited and mouse-pressed/mouse-released. So it only generates an action event when the press and release happen over the button, such that you can click, then drag out and let go without getting a click triggering action event.

But other then that, the rest sounds about right.

bsampieria at 2007-7-12 11:44:36 > top of Java-index,Desktop,Core GUI APIs...