JDK-8041928 : MouseEvent.getModifiersEx gives wrong result
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7u21,7u51,8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • Submitted: 2013-05-16
  • Updated: 2021-12-24
  • Resolved: 2015-12-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9 Other
8u311Fixed 9 b105Fixed openjdk8u322Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
Picked up _JAVA_OPTIONS: -Djava.net.preferIPv4Stack=true
java version  " 1.7.0_21 " 
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

EXTRA RELEVANT SYSTEM CONFIGURATION :
Mouse/keyboard are Microsoft Wireless Multimedia. Standard Microsoft drivers.

A DESCRIPTION OF THE PROBLEM :
Using getModifiersEx() produces the wrong result in various situations when it is called from a mouse event.

When clicking right button it gives Button3 and the Meta key (which I am not pressing at the time) on the click and released events, but not on the pressed event.

When clicking any button with the Alt-Gr key it gives the button with Ctrl-Alt.

When the mouse is moved quickly the key pick-up seems a bit random.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the program (sorry it's a bit big, but it was generated by Netbeans). Try a few clicks in combination with the modifier buttons. Sample output (edited by hand with comments so you can see what actions generated the output) is:

Some annotated output follows. I can post the code (it uses Netbeans to generate it, so some tweaking may be needed) if it would help.


//left click
Button 1 pressed count=1
Button 1 released count=1
Button 1 clicked count=1

//Right-click
Button 3 pressed count=1
Button 3 released count=1 Meta
Button 3 clicked count=1 Meta

//alt-gr left click
Button 1 pressed count=1 Alt Ctrl
Button 1 released count=1 Alt Ctrl
Button 1 clicked count=1 Alt Ctrl

//Ctrl right click
Button 3 pressed count=1 Ctrl
Button 3 released count=1 Ctrl
Button 3 clicked count=1 Ctrl

//Right click again
Button 3 pressed count=1
Button 3 released count=1 Meta
Button 3 clicked count=1 Meta

//Shift right click
Button 3 pressed count=1
Button 3 released count=1 Shift
Button 3 clicked count=1 Shift

//alt right click
Button 3 pressed count=1 Alt
Button 3 released count=1 Alt
Button 3 clicked count=1 Alt

//quick movements
Button 1 pressed count=1
Button 1 released count=1 Ctrl
//note no click event at all

Button 1 pressed count=1
Button 1 released count=1 Ctrl
Button 1 clicked count=1 Ctrl

Button 1 pressed count=1
Button 1 released count=1 Alt
Button 1 clicked count=1 Alt

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Consistent and correct detection of which key(s) are pressed.
ACTUAL -
See  " Steps to reproduce "  above

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package testmouseclick;

import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;

/**
 *
 * @author Peter_2
 */
public class MouseCLick extends javax.swing.JFrame {

  /**
   * Creates new form MouseCLick
   */
  public MouseCLick() {
    initComponents();
    jTA1.setText( " No of buttons:  " +java.awt.MouseInfo.getNumberOfButtons()+ " 
 " );
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings( " unchecked " )
  // <editor-fold defaultstate= " collapsed "  desc= " Generated Code " >
  private void initComponents() {

    jScrollPane2 = new javax.swing.JScrollPane();
    jTA1 = new javax.swing.JTextArea();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle( " Test Mouse Click " );

    jTA1.setColumns(20);
    jTA1.setRows(5);
    jTA1.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseReleased(java.awt.event.MouseEvent evt) {
        jTA1MouseReleased(evt);
      }
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        jTA1MouseClicked(evt);
      }
      public void mousePressed(java.awt.event.MouseEvent evt) {
        jTA1MousePressed(evt);
      }
    });
    jScrollPane2.setViewportView(jTA1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 390, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
    );

    pack();
  }// </editor-fold>

  private void jTA1MouseClicked(java.awt.event.MouseEvent evt) {
    mouseAction(evt);
  }

  private void jTA1MousePressed(java.awt.event.MouseEvent evt) {
    mouseAction(evt);
  }

  private void jTA1MouseReleased(java.awt.event.MouseEvent evt) {
    mouseAction(evt);
  }

  private void mouseAction(java.awt.event.MouseEvent evt) {
    String s;
    int button, count, id, mask;
    button = evt.getButton();
    count = evt.getClickCount();
    mask=evt.getModifiersEx();
    id = evt.getID();

    switch (button) {
      case MouseEvent.BUTTON1:
        s =  " Button 1  " ;
        break;

      case MouseEvent.BUTTON2:
        s =  " Button 2  " ;
        break;

      case MouseEvent.BUTTON3:
        s =  " Button 3  " ;
        break;

      default:
        throw new AssertionError();
    }

    switch (id) {
      case MouseEvent.MOUSE_CLICKED:
        s +=  " clicked  " ;
        break;

      case MouseEvent.MOUSE_PRESSED:
        s +=  " pressed  " ;
        break;

      case MouseEvent.MOUSE_RELEASED:
        s +=  " released  " ;
        break;

      default:
        throw new AssertionError();
    }

    s +=  " count= "  + count;

    if ((mask & InputEvent.ALT_GRAPH_DOWN_MASK) !=0) {
      s+= "  Alt-Gr " ;
    }
    if ((mask & InputEvent.ALT_DOWN_MASK) !=0) {
      s+= "  Alt " ;
    }
    if ((mask & InputEvent.CTRL_DOWN_MASK) !=0) {
      s+= "  Ctrl " ;
    }
    if ((mask & InputEvent.META_DOWN_MASK) !=0) {
      s+= "  Meta " ;
    }
    if ((mask & InputEvent.SHIFT_DOWN_MASK) !=0) {
      s+= "  Shift " ;
    }
//    if ((mask & InputEvent.BUTTON1_DOWN_MASK) !=0) {
//      s+= "  Button1 " ;
//    }
//    if ((mask & InputEvent.BUTTON2_DOWN_MASK) !=0) {
//      s+= "  Button2 " ;
//    }
//    if ((mask & InputEvent.BUTTON3_DOWN_MASK) !=0) {
//      s+= "  Button3 " ;
//    }
    s+= " 
 " ;
    jTA1.append(s);

  }

  /**
   * @param args the command line arguments
   */
  public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate= " collapsed "  desc= "  Look and feel setting code (optional)  " >
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
     */
    try {
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
        if ( " Nimbus " .equals(info.getName())) {
          javax.swing.UIManager.setLookAndFeel(info.getClassName());
          break;
        }
      }
    } catch (ClassNotFoundException ex) {
      java.util.logging.Logger.getLogger(MouseCLick.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
      java.util.logging.Logger.getLogger(MouseCLick.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
      java.util.logging.Logger.getLogger(MouseCLick.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
      java.util.logging.Logger.getLogger(MouseCLick.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
        new MouseCLick().setVisible(true);
      }
    });
  }
  // Variables declaration - do not modify
  private javax.swing.JScrollPane jScrollPane2;
  private javax.swing.JTextArea jTA1;
  // End of variables declaration
}

---------- END SOURCE ----------
Comments
Fix Request (8u) A clean backport for parity with Oracle 8u321, and the backport helps JDK-8274846 and JDK-8274847 backports.
13-10-2021

URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/687dbe642746 User: lana Date: 2016-02-10 21:55:24 +0000
10-02-2016

URL: http://hg.openjdk.java.net/jdk9/client/jdk/rev/687dbe642746 User: ssadetsky Date: 2015-12-24 11:05:21 +0000
24-12-2015

The fix is different for windows, linux and mac.Windows fix is ready and will be fixed as part of this bug for mac and ubuntu different bug will be raised..
23-11-2015

Reproduced this bug with 7u51, 8, and 9-ea. Right-click results in the following output: Button 3 pressed count= 1 Button 3 released count= 1 Meta Button 3 clicked count= 1 Meta Middle-click results: Button 2 pressed count= 1 Button 2 released count= 1 Alt Button 2 clicked count= 1 Alt I do not press any keys on the keyboard while clicking, and MOUSE_PRESSED event contains the right flags. At the same time, MOUSE_RELEASED and MOUSE_CLICKED events contain the keys in getModifiersEx() mask.
25-04-2014