/* * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @key headful * @bug 8072900 * @summary Mouse events are captured by the wrong menu in OS X * @author Anton Nashatyrev * @run main WrongSelectionOnMouseOver */ import javax.swing.*; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static javax.swing.UIManager.getInstalledLookAndFeels; public class WrongSelectionOnMouseOver implements Runnable { CountDownLatch firstMenuSelected = new CountDownLatch(1); CountDownLatch secondMenuMouseEntered = new CountDownLatch(1); CountDownLatch secondMenuSelected = new CountDownLatch(1); JMenu m1, m2; private UIManager.LookAndFeelInfo laf; JFrame frame1; JFrame frame2; public WrongSelectionOnMouseOver(UIManager.LookAndFeelInfo laf) throws Exception { this.laf = laf; } private void createUI() throws Exception { System.out.println("Testing UI: " + laf); UIManager.setLookAndFeel(laf.getClassName()); { frame1 = new JFrame("Frame1"); JMenuBar mb = new JMenuBar(); m1 = new JMenu("File"); JMenuItem i1 = new JMenuItem("Save"); JMenuItem i2 = new JMenuItem("Load"); m1.addMenuListener(new MenuListener() { @Override public void menuSelected(MenuEvent e) { firstMenuSelected.countDown(); System.out.println("Menu1: menuSelected"); } @Override public void menuDeselected(MenuEvent e) { System.out.println("Menu1: menuDeselected"); } @Override public void menuCanceled(MenuEvent e) { System.out.println("Menu1: menuCanceled"); } }); frame1.setJMenuBar(mb); mb.add(m1); m1.add(i1); m1.add(i2); frame1.setLayout(new FlowLayout()); frame1.setBounds(200, 200, 200, 200); frame1.setVisible(true); } { frame2 = new JFrame("Frame2"); JMenuBar mb = new JMenuBar(); m2 = new JMenu("File"); JMenuItem i1 = new JMenuItem("Save"); JMenuItem i2 = new JMenuItem("Load"); m2.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { secondMenuMouseEntered.countDown(); System.out.println("WrongSelectionOnMouseOver.mouseEntered"); } }); m2.addMenuListener(new MenuListener() { @Override public void menuSelected(MenuEvent e) { secondMenuSelected.countDown(); System.out.println("Menu2: menuSelected"); } @Override public void menuDeselected(MenuEvent e) { System.out.println("Menu2: menuDeselected"); } @Override public void menuCanceled(MenuEvent e) { System.out.println("Menu2: menuCanceled"); } }); frame2.setJMenuBar(mb); mb.add(m2); m2.add(i1); m2.add(i2); frame2.setLayout(new FlowLayout()); frame2.setBounds(400, 200, 200, 200); frame2.setVisible(true); } } public void disposeUI() { frame1.dispose(); frame2.dispose(); } @Override public void run() { try { if (frame1 == null) { createUI(); } else { disposeUI(); } } catch (Exception e) { throw new RuntimeException(e); } } public void test() throws Exception { Robot robot = new Robot(); robot.setAutoDelay(100); robot.waitForIdle(); robot.mouseMove((int) m1.getLocationOnScreen().getX() + 5, (int) m1.getLocationOnScreen().getY() + 5); robot.mousePress(MouseEvent.BUTTON1_MASK); robot.mouseRelease(MouseEvent.BUTTON1_MASK); if (!firstMenuSelected.await(5, TimeUnit.SECONDS)) { throw new RuntimeException("Menu has not been selected."); }; robot.mouseMove((int) m2.getLocationOnScreen().getX() + 5, (int) m2.getLocationOnScreen().getY() + 5); if (!secondMenuMouseEntered.await(5, TimeUnit.SECONDS)) { throw new RuntimeException("MouseEntered event missed for the second menu"); }; if (secondMenuSelected.await(1, TimeUnit.SECONDS)) { throw new RuntimeException("The second menu has been selected"); }; } public static void main(final String[] args) throws Exception { for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) { WrongSelectionOnMouseOver test = new WrongSelectionOnMouseOver(laf); SwingUtilities.invokeAndWait(test); test.test(); SwingUtilities.invokeAndWait(test); } System.out.println("Test passed"); } }