vpointer
vpointer

Reputation: 71

The mouse listener in Java

The MouseListener on a JButton is registered during the application startup then after startup any mouse clicks on the button the corresponding mouseClicked(MouseEvent e) method will be called.

The question is what/who is responsible to create the MouseEvent object with all the metadata and invoke the mouseClicked method.

Posting a SSCCE:

public class TestMouseListener {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            createAndShowGui();  
        }); 
    }

    private void createAndShowGui(){
        JFrame frame = new JFrame(); 
        JButton button = new JButton(); 
        frame.add(button); 
        button.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) { 
                System.out.println("The button was clicked");   
                System.out.println("The clicked time is":e.getWhen());  
            } 
        }); 
    } 
}

Upvotes: 2

Views: 1235

Answers (1)

Kevin Workman
Kevin Workman

Reputation: 42174

Take a look at the source for the Component class. You can do this from eclipse by right-clicking your JButton class and going to "show declaration", or you can view the src.zip that comes with your JDK. You might also be able to find it on grepcode.

The Component class has this processMouseEvent() function:

protected void processMouseEvent(MouseEvent e) {
    MouseListener listener = mouseListener;
    if (listener != null) {
        int id = e.getID();
        switch(id) {
          case MouseEvent.MOUSE_PRESSED:
              listener.mousePressed(e);
              break;
          case MouseEvent.MOUSE_RELEASED:
              listener.mouseReleased(e);
              break;
          case MouseEvent.MOUSE_CLICKED:
              listener.mouseClicked(e);
              break;
          case MouseEvent.MOUSE_EXITED:
              listener.mouseExited(e);
              break;
          case MouseEvent.MOUSE_ENTERED:
              listener.mouseEntered(e);
              break;
        }
    }
}

This is the short answer to your question. This function is what calls the mousePressed() function. But we can go deeper...

The processMouseEvent() function is called from the processEvent() function:

protected void processEvent(AWTEvent e) {
        if (e instanceof FocusEvent) {
            processFocusEvent((FocusEvent)e);

        } else if (e instanceof MouseEvent) {
            switch(e.getID()) {
              case MouseEvent.MOUSE_PRESSED:
              case MouseEvent.MOUSE_RELEASED:
              case MouseEvent.MOUSE_CLICKED:
              case MouseEvent.MOUSE_ENTERED:
              case MouseEvent.MOUSE_EXITED:
                  processMouseEvent((MouseEvent)e);
                  break;
              case MouseEvent.MOUSE_MOVED:
              case MouseEvent.MOUSE_DRAGGED:
                  processMouseMotionEvent((MouseEvent)e);
                  break;
              case MouseEvent.MOUSE_WHEEL:
                  processMouseWheelEvent((MouseWheelEvent)e);
                  break;
            }

        } else if (e instanceof KeyEvent) {
            processKeyEvent((KeyEvent)e);

        } else if (e instanceof ComponentEvent) {
            processComponentEvent((ComponentEvent)e);
        } else if (e instanceof InputMethodEvent) {
            processInputMethodEvent((InputMethodEvent)e);
        } else if (e instanceof HierarchyEvent) {
            switch (e.getID()) {
              case HierarchyEvent.HIERARCHY_CHANGED:
                  processHierarchyEvent((HierarchyEvent)e);
                  break;
              case HierarchyEvent.ANCESTOR_MOVED:
              case HierarchyEvent.ANCESTOR_RESIZED:
                  processHierarchyBoundsEvent((HierarchyEvent)e);
                  break;
            }
        }
    }

Which is called from the dispatchEventImpl() function, which is called from the dispatchEvent() function, which is called from a bunch of functions:

dispatchEvent(AWTEvent) : void - java.awt.Component
    addDelicately(Component, Container, int) : void - java.awt.Container
    addImpl(Component, Object, int) : void - java.awt.Container
    addNotify() : void - java.awt.Component
    close() : void - javax.swing.plaf.metal.MetalTitlePane
    createHierarchyEvents(int, Component, Container, long, boolean) : int - java.awt.Component (2 matches)
    dispatchAndCatchException(Throwable, Component, FocusEvent) : Throwable - java.awt.KeyboardFocusManager
    dispatchEventImpl(AWTEvent, Object) : void - java.awt.EventQueue
    forwardEventToParent(MouseEvent) : void - com.sun.java.swing.plaf.motif.MotifDesktopIconUI.IconButton
    forwardEventToParent(MouseEvent) : void - com.sun.java.swing.plaf.motif.MotifDesktopIconUI.IconLabel
    forwardEventToParent(MouseEvent) : void - com.sun.java.swing.plaf.motif.MotifInternalFrameTitlePane.Title
    mouseClicked(MouseEvent) : void - javax.swing.plaf.basic.BasicTreeUI.MouseInputHandler
    mouseDragged(MouseEvent) : void - javax.swing.plaf.basic.BasicTreeUI.MouseInputHandler
    MouseInputHandler(BasicTreeUI, Component, Component, MouseEvent, Component) - javax.swing.plaf.basic.BasicTreeUI.MouseInputHandler
    mouseReleased(MouseEvent) : void - javax.swing.plaf.basic.BasicTreeUI.MouseInputHandler
    postClosingEvent(JInternalFrame) : void - javax.swing.plaf.basic.BasicInternalFrameTitlePane
    redispatchEvent(Component, AWTEvent) : void - java.awt.KeyboardFocusManager
    remove(int) : void - java.awt.Container
    removeAll() : void - java.awt.Container
    removeDelicately(Component, Container, int) : boolean - java.awt.Container
    removeNotify() : void - java.awt.Component
    repostEvent(MouseEvent) : boolean - javax.swing.plaf.basic.BasicTableUI.Handler
    retargetMouseEvent(Component, int, MouseEvent) : void - java.awt.LightweightDispatcher (2 matches)

As for what creates the MouseEvent, here are some of the places that call new MouseEvent():

MouseEvent(Component, int, long, int, int, int, int, int, int, boolean, int) - java.awt.event.MouseEvent
    actionPerformed(ActionEvent) : void - javax.swing.Autoscroller
    convertMouseEvent(Component, MouseEvent, Component) : MouseEvent - javax.swing.SwingUtilities
    convertMouseEvent(MouseEvent) : MouseEvent - javax.swing.plaf.basic.BasicComboPopup
    eventDispatched(AWTEvent) : void - java.awt.LightweightDispatcher
    forwardEventToParent(MouseEvent) : void - com.sun.java.swing.plaf.motif.MotifDesktopIconUI.IconButton
    forwardEventToParent(MouseEvent) : void - com.sun.java.swing.plaf.motif.MotifDesktopIconUI.IconLabel
    forwardEventToParent(MouseEvent) : void - com.sun.java.swing.plaf.motif.MotifInternalFrameTitlePane.Title
    getToolTipText(MouseEvent) : String - javax.swing.JList
    getToolTipText(MouseEvent) : String - javax.swing.JTable
    getToolTipText(MouseEvent) : String - javax.swing.JTree
    getToolTipText(MouseEvent) : String - javax.swing.table.JTableHeader
    MenuDragMouseEvent(Component, int, long, int, int, int, int, int, int, boolean, MenuElement[], MenuSelectionManager) - javax.swing.event.MenuDragMouseEvent
    MouseEvent(Component, int, long, int, int, int, int, boolean, int) - java.awt.event.MouseEvent
    MouseWheelEvent(Component, int, long, int, int, int, int, int, int, boolean, int, int, int, double) - java.awt.event.MouseWheelEvent
    processMouseEvent(MouseEvent) : void - javax.swing.MenuSelectionManager (3 matches)
    processMouseEvent(MouseEvent) : void - javax.swing.plaf.basic.new JList() {...}
    retargetMouseEvent(Component, int, MouseEvent) : void - java.awt.LightweightDispatcher
    start(JComponent, MouseEvent) : void - javax.swing.Autoscroller

You can keep digging deeper, but at some point you reach native code where the OS sends the underlying events to Java.

But mostly you don't ever have to care about any of this stuff.

Upvotes: 3

Related Questions