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" };
  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     };
  45 
  46     static volatile int listenerCallCounter = 0;
  47     public static void main(String[] args) throws Exception {
  48         if (sun.awt.OSInfo.getOSType() != sun.awt.OSInfo.OSType.MACOSX) {
  49             System.out.println("This test is for MacOS only. Automatically passed on other platforms.");
  50             return;
  51         }
  52 
  53         System.setProperty("apple.laf.useScreenMenuBar", "true");
  54         SwingUtilities.invokeAndWait(new Runnable() {
  55             public void run() {
  56                 createAndShowGUI();
  57             }
  58         });
  59 
  60         SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
  61         Robot robot = new Robot();
  62         robot.setAutoDelay(100);
  63 
  64         for (int i = 0; i < menuItems.length; ++i) {
  65             KeyStroke ks = keyStrokes[i];
  66             int modKeyCode = getModKeyCode(ks.getModifiers());
  67 
  68             if (modKeyCode != 0) {
  69                 robot.keyPress(modKeyCode);
  70             }
  71 
  72             robot.keyPress(ks.getKeyCode());
  73             robot.keyRelease(ks.getKeyCode());
  74 
  75             if (modKeyCode != 0) {
  76                 robot.keyRelease(modKeyCode);
  77             }
  78 
  79             toolkit.realSync();
  80 
  81             if (listenerCallCounter != 1) {
  82                 throw new Exception("Test failed: ActionListener for " + menuItems[i] +
  83                     " called " + listenerCallCounter + " times instead of 1!");
  84             }
  85 
  86             listenerCallCounter = 0;
  87         }
  88     }
  89 
  90     private static void createAndShowGUI() {
  91         JMenu menu = new JMenu("Menu");
  92 
  93         for (int i = 0; i < menuItems.length; ++i) {
  94             JMenuItem newItem = new JMenuItem(menuItems[i]);
  95             newItem.setAccelerator(keyStrokes[i]);
  96             newItem.addActionListener(
  97                 new ActionListener(){
  98                     public void actionPerformed(ActionEvent e) {
  99                         listenerCallCounter++;
 100                     }
 101                 }
 102             );
 103             menu.add(newItem);
 104         }
 105 
 106         JMenuBar bar = new JMenuBar();
 107         bar.add(menu);
 108         JFrame frame = new JFrame("Test");
 109         frame.setJMenuBar(bar);
 110         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 111         frame.pack();
 112         frame.setVisible(true);
 113     }
 114 
 115     private static int getModKeyCode(int mod) {
 116         if ((mod & (InputEvent.SHIFT_DOWN_MASK | InputEvent.SHIFT_MASK)) != 0) {
 117             return KeyEvent.VK_SHIFT;
 118         }
 119 
 120         if ((mod & (InputEvent.CTRL_DOWN_MASK | InputEvent.CTRL_MASK)) != 0) {
 121             return KeyEvent.VK_CONTROL;
 122         }
 123 
 124         if ((mod & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK)) != 0) {
 125             return KeyEvent.VK_ALT;
 126         }
 127 
 128         if ((mod & (InputEvent.META_DOWN_MASK | InputEvent.META_MASK)) != 0) {
 129             return KeyEvent.VK_META;
 130         }
 131 
 132         return 0;
 133     }
 134 }