MouseEvent getModifiersEx() call does not work as expected (or as documented)

Viewed 560

I have some classes needing to migrate from the old deprecated call: MouseEvent getModifiers()

That need to be converted to the new style: MouseEvent getModifiersEx()

Clicking on the frame in the example calls the mouse listener. Note that the (deprecated) getModifiers() gives the expected results for rt-click vs lt-click:

 right click: 4, left click: 16

This shows that rt-click is distinguishable from lt-click and the bit values are as expected.

However, using getModifiersEx() does not show the expected values.

The expected bit values for getModifiersEx are:

 right click: 4096, left click: 1024

But the actual values seen are:

 right click: 0, left click: 0

This makes rt-click vs lt-click indistinguishable.

Note that pressing the modifier keys (e.g. Shift, Cntrl, Alt) does set the expected bits (but the button down mask bits are still zero so rt-click vs lt-click are still indistinguishable)

Calling MouseEvent getButton() does return the correct button, so that is a work-around. But why does getModifiersEx() not work?

This is on MacOS BTW

/**Example showing issue with MouseEvent.getModifiersEx()*/
public class TrialGetModEx extends JFrame {

  public TrialGetModEx() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(300, 200);
    setLocation(100,100);
    setVisible(true);

    addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        System.out.print("Mod="+e.getModifiers());
        System.out.print(" ModEx="+e.getModifiersEx());
        System.out.println();
      }

    });

    System.out.println("Expected Bit values:");
    System.out.println("  BUTTON_1_MASK: "+MouseEvent.BUTTON1_MASK);
    System.out.println("  BUTTON_3_MASK: "+MouseEvent.BUTTON3_MASK);
    System.out.println("  BUTTON_1_DOWN_MASK: "+MouseEvent.BUTTON1_DOWN_MASK);
    System.out.println("  BUTTON_3_DOWN_MASK: "+MouseEvent.BUTTON3_DOWN_MASK);
  }

  public static void main(String[] args) {
    new TrialGetModEx();
  }
}

1 Answers

Ok well after a bit of investigation, answering my own question here.

Although the documentation recommends replacing the deprecated MouseEvent getModifiers() with getModifiersEx(), there is a fundamental difference between those two.

Namely, getModifiersEx() represents the real-time state of the mouse buttons, which means that by the time the click event occurs, the button has already been released (by definition). This is why it always shows no buttons pressed.

Therefore getModifiersEx() is more useful for button presses during the mousePressed() event and not so much for mouseClicked() or mouseReleased() events.

One exception would be for specialized situations like say, where multiple separate button releases are being tracked.

The actual thing that replaces the older style click detectors:

if((event.getModifiers() & MouseEvent.BUTTON3_MASK) != 0)

is not getModifiersEx, instead it is:

if(event.getButton()==MouseEvent.BUTTON3)

Related