1 /*
   2  * Copyright (c) 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   @test
  25   @key headful
  26   @bug 4476629
  27   @library ../../../../javax/swing/regtesthelpers
  28   @build Util
  29   @summary KeyEvents dispatched to old focus owner that is no longer showing
  30   @author son@sparc.spb.su: area=awt.focus
  31   @run main KeyEventForBadFocusOwnerTest
  32 */
  33 
  34 /**
  35  * KeyEventForBadFocusOwnerTest.java
  36  *
  37  * summary: KeyEvents dispatched to old focus owner that is no longer showing
  38  */
  39 
  40 
  41 import java.awt.Robot;
  42 import java.awt.Toolkit;
  43 
  44 import java.awt.event.*;
  45 
  46 import javax.swing.*;
  47 import javax.swing.event.*;
  48 import sun.awt.SunToolkit;
  49 
  50 public class KeyEventForBadFocusOwnerTest {
  51     final static String ITEM_ONE_TEXT = "one";
  52     final static String ITEM_TWO_TEXT = "two";
  53 
  54     volatile static boolean itemOneSelected = false;
  55     volatile static boolean itemTwoSelected = false;
  56     volatile static boolean unexpectedItemSelected = false;
  57 
  58     static Robot robot;
  59     static SunToolkit toolkit;
  60 
  61     public static void main(String[] args) throws Exception {
  62         SwingUtilities.invokeAndWait(new Runnable() {
  63             public void run() {
  64                 JFrame frame = new JFrame("TEST");
  65                 JMenuBar mb = new JMenuBar();
  66                 JMenu one = new JMenu(ITEM_ONE_TEXT);
  67                 JMenu two = new JMenu(ITEM_TWO_TEXT);
  68 
  69                 mb.add(one);
  70                 mb.add(two);
  71 
  72                 ActionListener al = new ActionListener() {
  73                     public void actionPerformed(ActionEvent ae) {
  74                         String itemText = ((JMenuItem)ae.getSource()).getText();
  75                         System.out.println("--> " + itemText);
  76                         unexpectedItemSelected = true;
  77                     }
  78                 };
  79                 one.setMnemonic(KeyEvent.VK_O);
  80                 JMenuItem item = new JMenuItem("one 1");
  81                 item.setMnemonic(KeyEvent.VK_O);
  82                 item.addActionListener(al);
  83                 one.add(item);
  84                 one.add("two");
  85                 one.add("three");
  86 
  87                 two.setMnemonic(KeyEvent.VK_T);
  88                 item = new JMenuItem("two 2");
  89                 item.setMnemonic(KeyEvent.VK_T);
  90                 item.addActionListener(al);
  91                 two.add(item);
  92                 two.add("three");
  93                 two.add("four");
  94 
  95                 PopupMenuListener popupMenuListener = new PopupMenuListener() {
  96                     public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
  97                         System.out.print(e);
  98                         System.out.print(e.getSource());
  99                         String itemText = ((JPopupMenu)e.getSource()).getName();
 100                         System.out.println("Menu " + itemText + "is opened.");
 101                         switch(itemText) {
 102                             case ITEM_ONE_TEXT:
 103                                 itemOneSelected = true;
 104                                 break;
 105                             case ITEM_TWO_TEXT:
 106                                 itemTwoSelected = true;
 107                                 break;
 108                         }
 109                     }
 110 
 111                     public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
 112                     public void popupMenuCanceled(PopupMenuEvent e) {}
 113                 };
 114                 one.getPopupMenu().setName(ITEM_ONE_TEXT);
 115                 two.getPopupMenu().setName(ITEM_TWO_TEXT);
 116                 one.getPopupMenu().addPopupMenuListener(popupMenuListener);
 117                 two.getPopupMenu().addPopupMenuListener(popupMenuListener);
 118                 frame.setJMenuBar(mb);
 119                 frame.setSize(100,100);
 120                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 121                 frame.pack();
 122                 frame.setVisible(true);
 123             }
 124         });
 125 
 126         toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
 127         toolkit.realSync();
 128 
 129         robot = new Robot();
 130         robot.setAutoDelay(100);
 131 
 132         Util.hitMnemonics(robot, KeyEvent.VK_O);
 133         Util.hitMnemonics(robot, KeyEvent.VK_T);
 134 
 135         toolkit.realSync();
 136         Thread.sleep(1000); // workaround for MacOS
 137 
 138         if (unexpectedItemSelected) {
 139             throw new Exception("Test failed. KeyEvent dispatched to old focus owner. ");
 140         }
 141         if (!itemOneSelected || !itemTwoSelected) {
 142             throw new Exception("Not all expected events were received");
 143         }
 144     }
 145 }