2

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());  
            } 
        }); 
    } 
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
vpointer
  • 71
  • 7
  • 6
    Don't use a MouseListener on buttons, use an ActionListener instead. The Event Object is created by the system as the event is interrupted and processed – MadProgrammer Oct 08 '15 at 20:15
  • 2
    If you're really interested, you will want to do (a lot) of research into the Event Dispatching Thread/Process – MadProgrammer Oct 08 '15 at 20:17
  • 1
    For [example](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html) and [example](http://stackoverflow.com/questions/7217013/java-event-dispatching-thread-explanation) – MadProgrammer Oct 08 '15 at 20:21
  • @MadProgrammer I hate you for writing this as a comment, not as an answer. :P – mezzodrinker Oct 08 '15 at 20:28
  • @flashdrive2049 The answer would be to broad and to long for this forum, it's quite a technical related issues, crossing multiple platforms and implementations – MadProgrammer Oct 08 '15 at 20:31
  • Use ActionListener only if you care about the clicked action, otherwise if you need Pressed/Released you must use the MouseListener. – Marcos Vasconcelos Oct 08 '15 at 20:31
  • @MarcosVasconcelos Why would you care about the difference? A button is either triggered or it's not, including been triggered by the mouse, keyboard and programmatically, which the `MouseListener` won't be notified of the last two use-cases. If you want to know when the button becomes "armed" (or some other state), you should use monitor the state of the button's `ButtonModel`, which would provide far more useful information then a `MouseListener` – MadProgrammer Oct 08 '15 at 20:35
  • @MadProgrammer, cause MouseListener is declarative avoiding a lot of ifs. And good to note that Keyboard focus+enter will not fire the event. And often, you want pressed/released states. – Marcos Vasconcelos Oct 08 '15 at 20:38
  • @MarcosVasconcelos Then monitor the `ButtonModel`, that's what it's therefore, the `MouseListener` is just the wrong the point of entry. Maybe it's just my experience, but in 15+ years, I'v never cared for anything other then knowing that the button was pressed – MadProgrammer Oct 08 '15 at 20:39
  • In 8+ years usually I do it for games without JComponents, so I'm user of the declarative interfaces. – Marcos Vasconcelos Oct 08 '15 at 20:45
  • @MarcosVasconcelos So you're not using a JButton then? So it's irrelevant to the question and context? – MadProgrammer Oct 08 '15 at 20:49
  • I found one source of "new MouseEvents", check sun.awt.XWindow. – Marcos Vasconcelos Oct 08 '15 at 20:55
  • @MadProgrammer, bro, no, its not irrelevant, I just said that MouseListeners are declaratives while ButtonModel is not, ours discussion is irrelevant to the question. – Marcos Vasconcelos Oct 08 '15 at 20:56
  • 1
    @MarcosVasconcelos I won't discount the last point, but a MouseListener is 99.9% the wrong choice for a JButton and either using the buttons model (as part of the MVC nature of the API) or ActionListener are more appropriate ways to get information from the button. But of courses, if your not using a JButton, that's a different issue. – MadProgrammer Oct 08 '15 at 21:00

1 Answers1

3

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.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • Just to note, you can go this path and find the source, and as the owner of the answer dont want edits to his post, so I will say that one source of "new MouseEvent" is at sun.awt.XWindow. – Marcos Vasconcelos Oct 08 '15 at 21:03
  • @MarcosVasconcelos I disagreed with the style of your edit. Listing "one more source" doesn't really add much to my answer. Thanks for the revenge downvote though. – Kevin Workman Oct 08 '15 at 21:04
  • welcome to StackOverflow then. And the line add the only thing that the user asks in this questions and your answer doesnt provides: "where the event is created" – Marcos Vasconcelos Oct 08 '15 at 21:06