WrongSelectionOnMouseOver.java revision 17113:d17577d4839b
1/* 2 * Copyright (c) 2015, 2017, 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 * @key headful 27 * @bug 8072900 28 * @summary Mouse events are captured by the wrong menu in OS X 29 * @author Anton Nashatyrev 30 * @run main WrongSelectionOnMouseOver 31 */ 32 33import javax.swing.*; 34import javax.swing.event.MenuEvent; 35import javax.swing.event.MenuListener; 36import java.awt.*; 37import java.awt.event.MouseAdapter; 38import java.awt.event.MouseEvent; 39import java.util.concurrent.CountDownLatch; 40import java.util.concurrent.TimeUnit; 41 42import static javax.swing.UIManager.getInstalledLookAndFeels; 43 44public class WrongSelectionOnMouseOver implements Runnable { 45 46 CountDownLatch firstMenuSelected = new CountDownLatch(1); 47 CountDownLatch secondMenuMouseEntered = new CountDownLatch(1); 48 CountDownLatch secondMenuSelected = new CountDownLatch(1); 49 50 JMenu m1, m2; 51 52 private UIManager.LookAndFeelInfo laf; 53 JFrame frame1; 54 JFrame frame2; 55 private Point menu1location; 56 private Point menu2location; 57 58 public WrongSelectionOnMouseOver(UIManager.LookAndFeelInfo laf) throws Exception { 59 this.laf = laf; 60 } 61 62 private void createUI() throws Exception { 63 System.out.println("Testing UI: " + laf); 64 UIManager.setLookAndFeel(laf.getClassName()); 65 66 { 67 frame1 = new JFrame("Frame1"); 68 JMenuBar mb = new JMenuBar(); 69 m1 = new JMenu("File"); 70 JMenuItem i1 = new JMenuItem("Save"); 71 JMenuItem i2 = new JMenuItem("Load"); 72 73 m1.addMenuListener(new MenuListener() { 74 @Override 75 public void menuSelected(MenuEvent e) { 76 firstMenuSelected.countDown(); 77 System.out.println("Menu1: menuSelected"); 78 } 79 80 @Override 81 public void menuDeselected(MenuEvent e) { 82 System.out.println("Menu1: menuDeselected"); 83 } 84 85 @Override 86 public void menuCanceled(MenuEvent e) { 87 System.out.println("Menu1: menuCanceled"); 88 } 89 }); 90 91 frame1.setJMenuBar(mb); 92 mb.add(m1); 93 m1.add(i1); 94 m1.add(i2); 95 96 frame1.setLayout(new FlowLayout()); 97 frame1.setBounds(200, 200, 200, 200); 98 99 frame1.setVisible(true); 100 } 101 102 { 103 frame2 = new JFrame("Frame2"); 104 JMenuBar mb = new JMenuBar(); 105 m2 = new JMenu("File"); 106 JMenuItem i1 = new JMenuItem("Save"); 107 JMenuItem i2 = new JMenuItem("Load"); 108 109 m2.addMouseListener(new MouseAdapter() { 110 @Override 111 public void mouseEntered(MouseEvent e) { 112 secondMenuMouseEntered.countDown(); 113 System.out.println("WrongSelectionOnMouseOver.mouseEntered"); 114 } 115 }); 116 117 m2.addMenuListener(new MenuListener() { 118 @Override 119 public void menuSelected(MenuEvent e) { 120 secondMenuSelected.countDown(); 121 System.out.println("Menu2: menuSelected"); 122 } 123 124 @Override 125 public void menuDeselected(MenuEvent e) { 126 System.out.println("Menu2: menuDeselected"); 127 } 128 129 @Override 130 public void menuCanceled(MenuEvent e) { 131 System.out.println("Menu2: menuCanceled"); 132 } 133 }); 134 135 frame2.setJMenuBar(mb); 136 mb.add(m2); 137 m2.add(i1); 138 m2.add(i2); 139 140 frame2.setLayout(new FlowLayout()); 141 frame2.setBounds(450, 200, 200, 200); 142 143 frame2.setVisible(true); 144 } 145 } 146 147 public void disposeUI() { 148 frame1.dispose(); 149 frame2.dispose(); 150 } 151 152 @Override 153 public void run() { 154 try { 155 if (frame1 == null) { 156 createUI(); 157 } else { 158 disposeUI(); 159 } 160 } catch (Exception e) { 161 throw new RuntimeException(e); 162 } 163 } 164 165 public void test() throws Exception { 166 Robot robot = new Robot(); 167 robot.setAutoDelay(100); 168 169 robot.waitForIdle(); 170 171 SwingUtilities.invokeAndWait(() -> { 172 menu1location = m1.getLocationOnScreen(); 173 menu2location = m2.getLocationOnScreen(); 174 }); 175 176 robot.mouseMove((int) menu1location.getX() + 5, 177 (int) menu1location.getY() + 5); 178 robot.mousePress(MouseEvent.BUTTON1_MASK); 179 robot.mouseRelease(MouseEvent.BUTTON1_MASK); 180 181 if (!firstMenuSelected.await(5, TimeUnit.SECONDS)) { 182 throw new RuntimeException("Menu has not been selected."); 183 }; 184 185 robot.mouseMove((int) menu2location.getX() + 5, 186 (int) menu2location.getY() + 5); 187 188 if (!secondMenuMouseEntered.await(5, TimeUnit.SECONDS)) { 189 throw new RuntimeException("MouseEntered event missed for the second menu"); 190 }; 191 192 if (secondMenuSelected.await(1, TimeUnit.SECONDS)) { 193 throw new RuntimeException("The second menu has been selected"); 194 }; 195 } 196 197 public static void main(final String[] args) throws Exception { 198 for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) { 199 WrongSelectionOnMouseOver test = new WrongSelectionOnMouseOver(laf); 200 SwingUtilities.invokeAndWait(test); 201 test.test(); 202 SwingUtilities.invokeAndWait(test); 203 } 204 System.out.println("Test passed"); 205 } 206} 207