1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 7160951
  27  * @summary [macosx] ActionListener called twice for JMenuItem using ScreenMenuBar
  28  * @author vera.akulova@oracle.com
  29  * @run main ActionListenerCalledTwiceTest
  30  */
  31 
  32 import sun.awt.*;
  33 import java.awt.*;
  34 import java.awt.event.*;
  35 import javax.swing.*;
  36 
  37 public class ActionListenerCalledTwiceTest {
  38     static String menuItems[] = { "Item1", "Item2", "Item3", "Item4", "Item5", "Item6" };
  39     static KeyStroke keyStrokes[] = {
  40         KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_MASK),
  41         KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
  42         KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_MASK),
  43         KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.META_MASK),
  44         KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK),
  45         KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.META_MASK)
  46     };
  47 
  48     static volatile int listenerCallCounter = 0;
  49     public static void main(String[] args) throws Exception {
  50         if (sun.awt.OSInfo.getOSType() != sun.awt.OSInfo.OSType.MACOSX) {
  51             System.out.println("This test is for MacOS only. Automatically passed on other platforms.");
  52             return;
  53         }
  54 
  55         System.setProperty("apple.laf.useScreenMenuBar", "true");
  56         SwingUtilities.invokeAndWait(new Runnable() {
  57             public void run() {
  58                 createAndShowGUI();
  59             }
  60         });
  61 
  62         SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
  63         Robot robot = new Robot();
  64         robot.setAutoDelay(100);
  65 
  66         for (int i = 0; i < menuItems.length; ++i) {
  67             KeyStroke ks = keyStrokes[i];
  68             int modKeyCode = getModKeyCode(ks.getModifiers());
  69 
  70             if (modKeyCode != 0) {
  71                 robot.keyPress(modKeyCode);
  72             }
  73 
  74             robot.keyPress(ks.getKeyCode());
  75             robot.keyRelease(ks.getKeyCode());
  76 
  77             if (modKeyCode != 0) {
  78                 robot.keyRelease(modKeyCode);
  79             }
  80 
  81             toolkit.realSync();
  82 
  83             if (listenerCallCounter != 1) {
  84                 throw new Exception("Test failed: ActionListener for " + menuItems[i] +
  85                     " called " + listenerCallCounter + " times instead of 1!");
  86             }
  87 
  88             listenerCallCounter = 0;
  89         }
  90     }
  91 
  92     private static void createAndShowGUI() {
  93         JMenu menu = new JMenu("Menu");
  94 
  95         for (int i = 0; i < menuItems.length; ++i) {
  96             JMenuItem newItem = new JMenuItem(menuItems[i]);
  97             newItem.setAccelerator(keyStrokes[i]);
  98             newItem.addActionListener(
  99                 new ActionListener(){
 100                     public void actionPerformed(ActionEvent e) {
 101                         listenerCallCounter++;
 102                     }
 103                 }
 104             );
 105             menu.add(newItem);
 106         }
 107 
 108         JMenuBar bar = new JMenuBar();
 109         bar.add(menu);
 110         JFrame frame = new JFrame("Test");
 111         frame.setJMenuBar(bar);
 112         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 113         frame.pack();
 114         frame.setVisible(true);
 115     }
 116 
 117     private static int getModKeyCode(int mod) {
 118         if ((mod & (InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK)) != 0) {
 119             return KeyEvent.VK_SHIFT;
 120         }
 121 
 122         if ((mod & (InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK)) != 0) {
 123             return KeyEvent.VK_CONTROL;
 124         }
 125 
 126         if ((mod & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK)) != 0) {
 127             return KeyEvent.VK_ALT;
 128         }
 129 
 130         if ((mod & (InputEvent.META_DOWN_MASK | InputEvent.META_MASK)) != 0) {
 131             return KeyEvent.VK_META;
 132         }
 133 
 134         return 0;
 135     }
 136 }