JDK-8216971 : [macosx swing] For JCheckBoxMenuItem actionPerformed() is called twice, when apple.laf.useScreenMenuBar=true and modifier is InputEvent.META_DOWN_MASK
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 9,10,11,12
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: os_x
  • Submitted: 2019-01-14
  • Updated: 2021-09-09
  • Resolved: 2019-03-27
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 13
13 b15Fixed
Related Reports
Relates :  
Relates :  
Description
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.
Comments
URL: http://hg.openjdk.java.net/jdk/jdk/rev/6526e0a7dd99 User: psadhukhan Date: 2019-04-03 08:46:47 +0000
03-04-2019

Since this is a showstopper bug for Swing applications (with no known workaround), please consider backporting this to make adoption of pre-Java13 JDKs possible. Thanks.
27-03-2019

URL: http://hg.openjdk.java.net/jdk/client/rev/6526e0a7dd99 User: psadhukhan Date: 2019-03-27 06:56:06 +0000
27-03-2019

Reported behaviour is also observed with CTRL+E key press.
11-02-2019

Issue reproduced on Mac OS 10.13 with JDK version 12b25, 11b28
17-01-2019