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