1 /*
2  * Copyright (c) 2010, 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 6495920
27  * @summary Tests that if the JPopupMenu.setVisible method throws an exception,
28             interaction with GNOME is not crippled
29  * @author Sergey Malenkov
30  * @library ../..
31  */
32 
33 import sun.awt.AppContext;
34 
35 import java.awt.Point;
36 import java.awt.Robot;
37 import java.awt.event.InputEvent;
38 import java.lang.reflect.Field;
39 import javax.swing.JFrame;
40 import javax.swing.JMenuItem;
41 import javax.swing.JPanel;
42 import javax.swing.JPopupMenu;
43 import javax.swing.SwingUtilities;
44 import javax.swing.plaf.basic.BasicPopupMenuUI;
45 
46 public class bug6495920 implements Thread.UncaughtExceptionHandler {
47 
main(String[] args)48     public static void main(String[] args) throws Throwable {
49         SwingTest.start(bug6495920.class);
50     }
51 
52     private static Robot robot;
53     private final JPanel panel;
54 
bug6495920(JFrame frame)55     public bug6495920(JFrame frame) {
56         JPopupMenu menu = new JPopupMenu() {
57             public void setVisible(boolean visible) {
58                 super.setVisible(visible);
59                 throw new AssertionError(visible ? "show popup" : "hide popup");
60             }
61         };
62         for (int i = 0; i < 10; i++) {
63             menu.add(new JMenuItem(String.valueOf(i)));
64         }
65         this.panel = new JPanel();
66         this.panel.setComponentPopupMenu(menu);
67         frame.add(this.panel);
68     }
69 
firstShowPopup()70     public void firstShowPopup() throws Exception {
71         Point point = this.panel.getLocation();
72         SwingUtilities.convertPointToScreen(point, this.panel);
73 
74         robot = new Robot(); // initialize shared static field first time
75         robot.mouseMove(point.x + 1, point.y + 1);
76         robot.mousePress(InputEvent.BUTTON3_MASK);
77         Thread.currentThread().setUncaughtExceptionHandler(this);
78         robot.mouseRelease(InputEvent.BUTTON3_MASK); // causes first AssertionError on EDT
79     }
80 
secondHidePopup()81     public void secondHidePopup() {
82         Point point = this.panel.getLocation();
83         SwingUtilities.convertPointToScreen(point, this.panel);
84 
85         robot.mouseMove(point.x - 1, point.y - 1);
86         Thread.currentThread().setUncaughtExceptionHandler(this);
87         robot.mousePress(InputEvent.BUTTON1_MASK); // causes second AssertionError on EDT
88         robot.mouseRelease(InputEvent.BUTTON1_MASK);
89     }
90 
thirdValidate()91     public void thirdValidate() throws Exception {
92         Field key = BasicPopupMenuUI.class.getDeclaredField("MOUSE_GRABBER_KEY");
93         key.setAccessible(true);
94 
95         Object grabber = AppContext.getAppContext().get(key.get(null));
96         if (grabber == null) {
97             throw new Exception("cannot find a mouse grabber in app's context");
98         }
99 
100         Field field = grabber.getClass().getDeclaredField("grabbedWindow");
101         field.setAccessible(true);
102 
103         Object window = field.get(grabber);
104         if (window != null) {
105             throw new Exception("interaction with GNOME is crippled");
106         }
107     }
108 
uncaughtException(Thread thread, Throwable throwable)109     public void uncaughtException(Thread thread, Throwable throwable) {
110         System.out.println(throwable);
111     }
112 }
113