Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8216971

[macosx swing] For JCheckBoxMenuItem actionPerformed() is called twice, when apple.laf.useScreenMenuBar=true and modifier is InputEvent.META_DOWN_MASK

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 13
    • 9, 10, 11, 12
    • client-libs
    • b15
    • os_x

      When using the Mac menubar via System.setProperty("apple.laf.useScreenMenuBar", "true") and using an accelerator key that contains the COMMAND button (i.e. InputEvent.META_DOWN_MASK) the actionPerformed() method of an action contained in a JCheckBoxMenuItem is called twice.

      The problem does not seem to occur with other modifiers (like SHIFT).

      This probably should have been fixed by JDK-8152492, but apparently wasn't, as the fix explicitly does not work for checkboxes (see http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/ee787ce3d454).

      The problem does not occur in Java 8.

      Code to reproduce:

      import javax.swing.*;
      import java.awt.event.ActionEvent;
      import java.awt.event.InputEvent;
      import java.awt.event.KeyEvent;

      public class DoubleActionTest {

          public static void main(String[] args) {
              System.setProperty("apple.laf.useScreenMenuBar", "true");
              
              final JFrame frame = new JFrame();
              final JMenuBar menubar = new JMenuBar();
              final JMenu fileMenu = new JMenu("OPEN ME");
              final MyAction myAction = new MyAction();
              final JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(myAction);
              fileMenu.add(menuItem);
              menubar.add(fileMenu);
              frame.setJMenuBar(menubar);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              SwingUtilities.invokeLater(() -> {
                  frame.setBounds(200, 200, 200, 200);
                  frame.setVisible(true);
              });
          }

          private static class MyAction extends AbstractAction {

              MyAction() {
                  putValue(Action.NAME, "HIT MY ACCELERATOR KEY");
                  putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_DOWN_MASK));
              }

              @Override
              public void actionPerformed(final ActionEvent e) {
                  System.out.println("Action! called with modifiers: " + e.getModifiers() + "\n" + e);
              }
          }
      }

      Run the code and hit the accelerator key (COMMAND+E). On system out you should see a single line of output, but you see two. The first one for the correct call and a second one that is the result of an internal ItemEvent (state changed). The second one should not happen.

            psadhukhan Prasanta Sadhukhan
            hschreiber Hendrik Schreiber
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: