1 /*
2  * Copyright (c) 2015, 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 import java.awt.AWTException;
25 import java.awt.Dimension;
26 import java.awt.GridLayout;
27 import java.awt.Point;
28 import java.awt.Robot;
29 import java.awt.event.InputEvent;
30 import javax.swing.JComboBox;
31 import javax.swing.JFrame;
32 import javax.swing.JPanel;
33 import javax.swing.SwingUtilities;
34 import javax.swing.UIManager;
35 import javax.swing.UIManager.LookAndFeelInfo;
36 import javax.swing.UnsupportedLookAndFeelException;
37 
38 /*
39  * @test
40  * @key headful
41  * @bug 8033069
42  * @summary Checks that JComboBox popup does not close when mouse wheel is
43  *          rotated over combo box and over its popup. The case where popup
44  *          has no scroll bar.
45  * @library ../../regtesthelpers
46  * @build Util
47  * @run main bug8033069NoScrollBar
48  * @author Alexey Ivanov
49  */
50 public class bug8033069NoScrollBar implements Runnable {
51 
52     private static final String[] NO_SCROLL_ITEMS = new String[] {
53         "A", "B", "C", "D", "E", "F"
54     };
55 
56     private final Robot robot;
57 
58     private final String[] items;
59 
60     private JFrame frame;
61     private JComboBox cb1;
62     private JComboBox cb2;
63 
main(String[] args)64     public static void main(String[] args) throws Exception {
65         iterateLookAndFeels(new bug8033069NoScrollBar(NO_SCROLL_ITEMS));
66     }
67 
iterateLookAndFeels(final bug8033069NoScrollBar test)68     protected static void iterateLookAndFeels(final bug8033069NoScrollBar test) throws Exception {
69         LookAndFeelInfo[] lafInfo = UIManager.getInstalledLookAndFeels();
70         for (LookAndFeelInfo info : lafInfo) {
71             try {
72                 UIManager.setLookAndFeel(info.getClassName());
73                 System.out.println("Look and Feel: " + info.getClassName());
74                 test.runTest();
75             } catch (UnsupportedLookAndFeelException e) {
76                 System.out.println("Skipping unsupported LaF: " + info);
77             }
78         }
79     }
80 
bug8033069NoScrollBar(String[] items)81     public bug8033069NoScrollBar(String[] items) throws AWTException {
82         this.items = items;
83 
84         robot = new Robot();
85         robot.setAutoDelay(200);
86     }
87 
setupUI()88     private void setupUI() {
89         frame = new JFrame();
90         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
91 
92         cb1 = new JComboBox<>(items);
93         cb2 = new JComboBox<>(items);
94         JPanel panel = new JPanel(new GridLayout(1, 2));
95         panel.add(cb1);
96         panel.add(cb2);
97 
98         frame.add(panel);
99 
100         frame.pack();
101         frame.setVisible(true);
102     }
103 
runTest()104     public void runTest() throws Exception {
105         try {
106             SwingUtilities.invokeAndWait(this);
107 
108             robot.waitForIdle();
109             assertFalse("cb1 popup is visible",
110                         Util.invokeOnEDT(cb1::isPopupVisible));
111 
112             // Move mouse pointer to the center of the fist combo box
113             Point p = cb1.getLocationOnScreen();
114             Dimension d = cb1.getSize();
115             robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2);
116             // Click it to open popup
117             robot.mousePress(InputEvent.BUTTON1_MASK);
118             robot.mouseRelease(InputEvent.BUTTON1_MASK);
119 
120             robot.waitForIdle();
121             assertTrue("cb1 popup is not visible",
122                        Util.invokeOnEDT(cb1::isPopupVisible));
123 
124             robot.mouseWheel(1);
125             robot.waitForIdle();
126             assertTrue("cb1 popup is not visible after mouse wheel up on combo box",
127                        Util.invokeOnEDT(cb1::isPopupVisible));
128 
129             robot.mouseWheel(-1);
130             robot.waitForIdle();
131             assertTrue("cb1 popup is not visible after mouse wheel down on combo box",
132                        Util.invokeOnEDT(cb1::isPopupVisible));
133 
134             // Move mouse down on the popup
135             robot.mouseMove(p.x + d.width / 2, p.y + d.height * 3);
136 
137             robot.mouseWheel(1);
138             robot.waitForIdle();
139             assertTrue("cb1 popup is not visible after mouse wheel up on popup",
140                        Util.invokeOnEDT(cb1::isPopupVisible));
141 
142             robot.mouseWheel(-1);
143             robot.waitForIdle();
144             assertTrue("cb1 popup is not visible after mouse wheel down on popup",
145                        Util.invokeOnEDT(cb1::isPopupVisible));
146 
147 
148             // Move mouse pointer to the center of the second combo box
149             p = cb2.getLocationOnScreen();
150             d = cb2.getSize();
151             robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2);
152 
153             robot.mouseWheel(1);
154             robot.waitForIdle();
155             assertFalse("cb1 popup is visible after mouse wheel up on cb2",
156                         Util.invokeOnEDT(cb1::isPopupVisible));
157         } finally {
158             if (frame != null) {
159                 frame.dispose();
160             }
161         }
162 
163         System.out.println("Test passed");
164     }
165 
166     @Override
run()167     public void run() {
168         setupUI();
169     }
170 
assertTrue(String message, boolean value)171     private static void assertTrue(String message, boolean value) {
172         assertEquals(message, true, value);
173     }
174 
assertFalse(String message, boolean value)175     private static void assertFalse(String message, boolean value) {
176         assertEquals(message, false, value);
177     }
178 
assertEquals(String message, boolean expected, boolean actual)179     private static void assertEquals(String message, boolean expected, boolean actual) {
180         if (expected != actual) {
181             throw new RuntimeException(message);
182         }
183     }
184 }
185