3

As we know MouseEvent gets lost in JScrollPane, i.e. not delivered to a parent, it is an old bug not fixed yet: https://forums.oracle.com/forums/thread.jspa?threadID=1362237

So I was using work-around by catching event in JScrollPane with a temporary listener and then dispatching event to it is parent to be processed with a real listener.

    private class DispatchListener extends MouseAdapter {
    @Override
    public void mousePressed (MouseEvent me) {
        System.out.println("dispatch.mousePressed: " + me.getButton());
        preDispatchEvent(me);
    }

    @Override
    public void mouseReleased (MouseEvent me) {
        preDispatchEvent(me);
    }

    @Override
    public void mouseDragged (MouseEvent me) {
        System.out.println("dispatch.mouseDragged");
        preDispatchEvent(me);
    }

    private void preDispatchEvent (MouseEvent me) {
        JScrollPane pane = (JScrollPane)me.getSource();
        MouseEvent newMe = SwingUtilities.convertMouseEvent(pane.getViewport(), me, tablePanel);
        dispatchEvent(newMe);
    }
}

It worked okay, but people with Java 7 started to complain that mouse click has no reaction in the application. After downgrading to Java 6 the issue was resolved, but now I was testing Applet and Chrome forced me to upgrade plugin to version 7.

After debugging I have figure out that convertMouseEvent sets button to MouseEvent.NOBUTTON independant of button passed

MouseEvent newMe = SwingUtilities.convertMouseEvent(pane.getViewport(), me, tablePanel);

From source code in Eclipse

else {
        newEvent = new MouseEvent(newSource,
                                  sourceEvent.getID(),
                                  sourceEvent.getWhen(),
                                  sourceEvent.getModifiers(),
                                  p.x,p.y,
                                  sourceEvent.getXOnScreen(),
                                  sourceEvent.getYOnScreen(),
                                  sourceEvent.getClickCount(),
                                  sourceEvent.isPopupTrigger(),
                                  MouseEvent.NOBUTTON ); //!!!
    }
    return newEvent;

I don't know why is it implemented that way? Is it another bug or feature?

Seems like I need to create my own object without calling SwingUtilities.convertMouseEvent and set button from sourceEvent.

Nikolay Kuznetsov
  • 9,467
  • 12
  • 55
  • 101
  • this púossible only for mouse with more than three buttons, isn't it, this issue was solved here, hmmmm you have to search for downvoted post by @camickr :-) – mKorbel Jan 22 '13 at 07:52
  • @mKorbel, `Point p = SwingUtilities.convertPoint(pane.getViewport(), me.getPoint(), tablePanel); MouseEvent newMe = new MouseEvent(tablePanel, me.getID(), me.getWhen(), me.getModifiers(), p.x,p.y, me.getXOnScreen(), me.getYOnScreen(), me.getClickCount(), me.isPopupTrigger(), me.getButton());` solves the problem but question remains – Nikolay Kuznetsov Jan 22 '13 at 07:58
  • 1
    _why?_ Shit happens ... ;-) You might consider filing an issue in the snoracle's bug parade – kleopatra Jan 22 '13 at 10:07

2 Answers2

4

This is an interesting issue. The use of MouseEvent.NOBUTTON in SwingUtilities.convertMouseEvent sure looks very strange. However, I'm unable to reproduce the problem with Java 7; for me the button field of the converted mouse event is correct for Java 7 and 6 (using 1.7.0-b147 64-bit and 1.6.0_21-b07 64-bit on a Windows 7 laptop).

Debugging through the MouseEvent constructor I saw that while the button field is initially set to zero, the call to setNewModifiers at the end of the constructor changes button based on the modifiers field (which receives its value from sourceEvent.getModifiers when the converted mouse event is constructed in SwingUtilities.convertMouseEvent).

The converted mouse events from a single click look like this (for Java 7):

java.awt.event.MouseEvent[MOUSE_PRESSED,(185,175),absolute(593,305),button=1,modifiers=Button1,extModifiers=Button1,clickCount=1] on javax.swing.JPanel[,0,0,381x259,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]
java.awt.event.MouseEvent[MOUSE_RELEASED,(185,175),absolute(593,305),button=1,modifiers=Button1,clickCount=1] on javax.swing.JPanel[,0,0,381x259,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]

In response to your questions: I think MouseEvent.NOBUTTON is passed to the MouseEvent constructor because the value of the button field will be determined by the value of the modifiers field anyway. On my laptop, things work as I expected for both Java 7 and 6, so it doesn't look like a bug to me. Is your application running in a browser and does that make a difference in how the mouse events are converted? Did you create a work around to solve the issue already or else could you share some of the applet code?


Other event types
The first two cases that are handled by SwingUtilities.convertMouseEvent create a MouseWheelEvent or a MenuDragMouseEvent object. Both constructors (eventually) call a MouseEvent constructor with a MouseEvent.NOBUTTON parameter. (Looking at these events (without conversion) on my laptop, the button field of a MouseWheelEvent is always zero (my mouse has only one wheel). For MenuDragMouseEvent objects button is equal to one for the menuDragMouseReleased event and is zero otherwise, while the modifiers field is always equal to BUTTON1_MASK.) So it looks like MouseEvent.NOBUTTON is quite popular as a parameter to the MouseEvent constructors.

Freek de Bruijn
  • 3,552
  • 2
  • 22
  • 28
0

See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7181403 - it looks like convertMouseEvent() did not change recently, so other code changes must be responsible for the change you see in Java 7 (I can reproduce the issue here as well with 1.7.0_21).

In any case, it looks like the problem has been solved in Java 8.

Axel Dörfler
  • 379
  • 3
  • 6