1 /*
   2  * Copyright (c) 2015, 2019, 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         "AA", "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 
  64     public static void main(String[] args) throws Exception {
  65         iterateLookAndFeels(new bug8033069NoScrollBar(NO_SCROLL_ITEMS));
  66     }
  67 
  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 
  81     public bug8033069NoScrollBar(String[] items) throws AWTException {
  82         this.items = items;
  83 
  84         robot = new Robot();
  85         robot.setAutoDelay(200);
  86     }
  87 
  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 
 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             System.out.println(d.width + "," + d.height);
 116             robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2);
 117             // Click it to open popup
 118             robot.mousePress(InputEvent.BUTTON1_MASK);
 119             robot.mouseRelease(InputEvent.BUTTON1_MASK);
 120 
 121             robot.waitForIdle();
 122             assertTrue("cb1 popup is not visible",
 123                        Util.invokeOnEDT(cb1::isPopupVisible));
 124 
 125             robot.mouseWheel(1);
 126             robot.waitForIdle();
 127             assertTrue("cb1 popup is not visible after mouse wheel up on combo box",
 128                        Util.invokeOnEDT(cb1::isPopupVisible));
 129 
 130             robot.mouseWheel(-1);
 131             robot.waitForIdle();
 132             assertTrue("cb1 popup is not visible after mouse wheel down on combo box",
 133                        Util.invokeOnEDT(cb1::isPopupVisible));
 134 
 135             // Move mouse down on the popup
 136             robot.mouseMove(p.x + d.width / 2, p.y + d.height * 3);
 137 
 138             robot.mouseWheel(1);
 139             robot.waitForIdle();
 140             assertTrue("cb1 popup is not visible after mouse wheel up on popup",
 141                        Util.invokeOnEDT(cb1::isPopupVisible));
 142 
 143             robot.mouseWheel(-1);
 144             robot.waitForIdle();
 145             assertTrue("cb1 popup is not visible after mouse wheel down on popup",
 146                        Util.invokeOnEDT(cb1::isPopupVisible));
 147 
 148 
 149             // Move mouse pointer to the center of the second combo box
 150             p = cb2.getLocationOnScreen();
 151             d = cb2.getSize();
 152             robot.mouseMove(p.x + d.width / 2, p.y + d.height / 2);
 153 
 154             robot.mouseWheel(1);
 155             robot.waitForIdle();
 156             assertFalse("cb1 popup is visible after mouse wheel up on cb2",
 157                         Util.invokeOnEDT(cb1::isPopupVisible));
 158         } finally {
 159             if (frame != null) {
 160                 frame.dispose();
 161             }
 162         }
 163 
 164         System.out.println("Test passed");
 165     }
 166 
 167     @Override
 168     public void run() {
 169         setupUI();
 170     }
 171 
 172     private static void assertTrue(String message, boolean value) {
 173         assertEquals(message, true, value);
 174     }
 175 
 176     private static void assertFalse(String message, boolean value) {
 177         assertEquals(message, false, value);
 178     }
 179 
 180     private static void assertEquals(String message, boolean expected, boolean actual) {
 181         if (expected != actual) {
 182             throw new RuntimeException(message);
 183         }
 184     }
 185 }