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