1 /*
2  * Copyright (c) 2011, 2012, 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 4966112
28  * @summary Some Composite components does not show the Context Popup.
29  * @library ../../regtesthelpers
30  * @build Util
31  * @author Alexander Zuev
32  * @run main bug4966112
33  */
34 import javax.swing.*;
35 import javax.swing.event.PopupMenuListener;
36 import javax.swing.event.PopupMenuEvent;
37 import java.awt.*;
38 import java.awt.event.*;
39 
40 public class bug4966112 {
41 
42     private static final int NO_MOUSE_BUTTON = -1;
43     private static volatile boolean shown = false;
44     private static volatile int popupButton = NO_MOUSE_BUTTON;
45     private static volatile JButton testButton;
46     private static volatile JSplitPane jsp;
47     private static volatile JSpinner spin;
48     private static volatile JFileChooser filec;
49     private static int buttonMask;
50     private static Robot robot;
51 
main(String[] args)52     public static void main(String[] args) throws Exception {
53         robot = new Robot();
54         robot.setAutoDelay(100);
55 
56         createAndShowButton();
57         robot.waitForIdle();
58 
59         setClickPoint(testButton);
60         clickMouse(InputEvent.BUTTON1_MASK);
61         clickMouse(InputEvent.BUTTON2_MASK);
62         clickMouse(InputEvent.BUTTON3_MASK);
63 
64         robot.waitForIdle();
65         closeFrame();
66 
67         if (popupButton == NO_MOUSE_BUTTON) {
68             System.out.println("Test can't identify the popup trigger button. Test skipped");
69             return;
70         }
71 
72         setButtonMask();
73 
74         // Test Split Pane
75         createAndShowSplitPane();
76         robot.waitForIdle();
77 
78         clickMouse(jsp);
79         robot.waitForIdle();
80         closeFrame();
81 
82         if (!shown) {
83             throw new RuntimeException("Popup was not shown on splitpane");
84         }
85 
86         // Test Spinner
87         createAndShowSpinner();
88         robot.waitForIdle();
89 
90         clickMouse(spin);
91         robot.waitForIdle();
92         closeFrame();
93 
94         if (!shown) {
95             throw new RuntimeException("Popup was not shown on spinner");
96         }
97 
98         // Test File Chooser
99         createAndShowFileChooser();
100         robot.waitForIdle();
101 
102         clickMouse(filec);
103         robot.waitForIdle();
104 
105         Util.hitKeys(robot, KeyEvent.VK_ESCAPE);
106         robot.waitForIdle();
107 
108         Util.hitKeys(robot, KeyEvent.VK_ESCAPE);
109         robot.waitForIdle();
110         closeFrame();
111 
112         if (!shown) {
113             throw new RuntimeException("Popup was not shown on filechooser");
114         }
115     }
116 
clickMouse(JComponent c)117     private static void clickMouse(JComponent c) throws Exception {
118         setClickPoint(c);
119         clickMouse(buttonMask);
120     }
121 
clickMouse(int buttons)122     private static void clickMouse(int buttons) {
123         robot.mousePress(buttons);
124         robot.mouseRelease(buttons);
125     }
126 
setButtonMask()127     private static void setButtonMask() {
128         switch (popupButton) {
129             case MouseEvent.BUTTON1:
130                 buttonMask = InputEvent.BUTTON1_MASK;
131                 break;
132             case MouseEvent.BUTTON2:
133                 buttonMask = InputEvent.BUTTON2_MASK;
134                 break;
135             case MouseEvent.BUTTON3:
136                 buttonMask = InputEvent.BUTTON3_MASK;
137                 break;
138         }
139     }
140 
setClickPoint(final JComponent c)141     private static void setClickPoint(final JComponent c) throws Exception {
142         final Point[] result = new Point[1];
143         SwingUtilities.invokeAndWait(new Runnable() {
144 
145             @Override
146             public void run() {
147                 Point p = c.getLocationOnScreen();
148                 Dimension size = c.getSize();
149                 result[0] = new Point(p.x + size.width / 2, p.y + size.height / 2);
150             }
151         });
152 
153         robot.mouseMove(result[0].x, result[0].y);
154     }
155 
createJPopupMenu()156     private static JPopupMenu createJPopupMenu() {
157         JPopupMenu jpm = new JPopupMenu();
158         jpm.add("One");
159         jpm.add("Two");
160         jpm.add("Three");
161         jpm.addPopupMenuListener(new PopupMenuListener() {
162 
163             public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
164                 shown = true;
165             }
166 
167             public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
168             }
169 
170             public void popupMenuCanceled(PopupMenuEvent e) {
171             }
172         });
173 
174         AutoClosable.INSTANCE.setPopup(jpm);
175         return jpm;
176     }
177 
createAndShowButton()178     private static void createAndShowButton() throws Exception {
179         SwingUtilities.invokeAndWait(new Runnable() {
180 
181             @Override
182             public void run() {
183                 JFrame frame = new JFrame("Button Frame");
184                 frame.setLayout(new BorderLayout());
185                 testButton = new JButton("Popup Tester");
186 
187                 testButton.addMouseListener(new MouseAdapter() {
188 
189                     void setPopupTrigger(MouseEvent e) {
190                         if (e.isPopupTrigger()) {
191                             popupButton = e.getButton();
192                         }
193                     }
194 
195                     public void mouseClicked(MouseEvent e) {
196                         setPopupTrigger(e);
197                     }
198 
199                     public void mousePressed(MouseEvent e) {
200                         setPopupTrigger(e);
201                     }
202 
203                     public void mouseReleased(MouseEvent e) {
204                         setPopupTrigger(e);
205                     }
206                 });
207 
208                 frame.add(testButton, BorderLayout.CENTER);
209                 frame.pack();
210                 frame.setVisible(true);
211                 AutoClosable.INSTANCE.setFrame(frame);
212             }
213         });
214     }
215 
createAndShowSplitPane()216     private static void createAndShowSplitPane() throws Exception {
217         SwingUtilities.invokeAndWait(new Runnable() {
218 
219             @Override
220             public void run() {
221                 JFrame frame = new JFrame("Test SplitPane");
222                 frame.setSize(250, 200);
223                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
224                 frame.setLayout(new BorderLayout());
225 
226                 shown = false;
227                 jsp = new JSplitPane();
228                 jsp.setRightComponent(new JPanel());
229                 jsp.setLeftComponent(new JPanel());
230                 jsp.setComponentPopupMenu(createJPopupMenu());
231 
232                 frame.add(jsp, BorderLayout.CENTER);
233 
234                 jsp.setDividerLocation(150);
235 
236                 frame.setLocation(400, 300);
237                 frame.setVisible(true);
238                 AutoClosable.INSTANCE.setFrame(frame);
239             }
240         });
241     }
242 
createAndShowSpinner()243     private static void createAndShowSpinner() throws Exception {
244         SwingUtilities.invokeAndWait(new Runnable() {
245 
246             @Override
247             public void run() {
248                 JFrame frame = new JFrame("JSpinner Test");
249                 frame.setLayout(new BorderLayout());
250                 frame.setSize(200, 100);
251                 shown = false;
252                 spin = new JSpinner();
253                 spin.setComponentPopupMenu(createJPopupMenu());
254                 frame.add(spin, BorderLayout.CENTER);
255                 frame.setVisible(true);
256                 AutoClosable.INSTANCE.setFrame(frame);
257             }
258         });
259     }
260 
createAndShowFileChooser()261     private static void createAndShowFileChooser() throws Exception {
262         SwingUtilities.invokeLater(new Runnable() {
263 
264             @Override
265             public void run() {
266                 JFrame frame = new JFrame("FileChooser test dialog");
267                 frame.setSize(100, 100);
268 
269                 shown = false;
270                 filec = new JFileChooser();
271                 filec.setComponentPopupMenu(createJPopupMenu());
272                 filec.showOpenDialog(frame);
273 
274                 frame.setVisible(true);
275                 AutoClosable.INSTANCE.setFrame(frame);
276             }
277         });
278     }
279 
closeFrame()280     private static void closeFrame() {
281         SwingUtilities.invokeLater(new Runnable() {
282 
283             @Override
284             public void run() {
285                 AutoClosable.INSTANCE.close();
286             }
287         });
288     }
289 
290     private static class AutoClosable {
291 
292         static final AutoClosable INSTANCE = new AutoClosable();
293         private JFrame frame;
294         private JPopupMenu popup;
295 
setFrame(JFrame frame)296         public void setFrame(JFrame frame) {
297             this.frame = frame;
298         }
299 
setPopup(JPopupMenu popup)300         public void setPopup(JPopupMenu popup) {
301             this.popup = popup;
302         }
303 
close()304         public void close() {
305             frame.dispose();
306             if (popup != null) {
307                 popup.setVisible(false);
308             }
309         }
310     }
311 }
312