1 /* 2 * Copyright (c) 2016, 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.Point; 25 import java.awt.Rectangle; 26 import java.awt.Robot; 27 import java.awt.event.InputEvent; 28 import javax.swing.JCheckBoxMenuItem; 29 import javax.swing.JComponent; 30 import javax.swing.JFrame; 31 import javax.swing.JMenu; 32 import javax.swing.JMenuBar; 33 import javax.swing.JMenuItem; 34 import javax.swing.JRadioButtonMenuItem; 35 import javax.swing.SwingUtilities; 36 import javax.swing.UIManager; 37 38 /* 39 * @test 40 * @bug 8158566 8160879 8160977 8158566 41 * @summary Provide a Swing property which modifies MenuItemUI behaviour 42 */ 43 public class CloseOnMouseClickPropertyTest { 44 45 private static final String CHECK_BOX_PROP = "CheckBoxMenuItem." 46 + "doNotCloseOnMouseClick"; 47 private static final String RADIO_BUTTON_PROP = "RadioButtonMenuItem" 48 + ".doNotCloseOnMouseClick"; 49 50 private static JFrame frame; 51 private static JMenu menu; 52 53 private static TestItem[] TEST_ITEMS = { 54 new TestItem(TestType.CHECK_BOX_MENU_ITEM, true, true), 55 new TestItem(TestType.CHECK_BOX_MENU_ITEM, true, false), 56 new TestItem(TestType.CHECK_BOX_MENU_ITEM, false, true), 57 new TestItem(TestType.CHECK_BOX_MENU_ITEM, false, false), 58 59 new TestItem(TestType.CHECK_BOX_MENU_ITEM, null, true), 60 new TestItem(TestType.CHECK_BOX_MENU_ITEM, null, false), 61 new TestItem(TestType.CHECK_BOX_MENU_ITEM, true, null), 62 new TestItem(TestType.CHECK_BOX_MENU_ITEM, false, null), 63 64 65 new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, true, true), 66 new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, true, false), 67 new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, false, true), 68 new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, false, false), 69 70 new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, true, null), 71 new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, false, null), 72 new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, null, true), 73 new TestItem(TestType.RADIO_BUTTON_MENU_ITEM, null, false), 74 75 new TestItem(TestType.MENU_ITEM, true, true), 76 new TestItem(TestType.MENU_ITEM, true, false), 77 new TestItem(TestType.MENU_ITEM, false, true), 78 new TestItem(TestType.MENU_ITEM, false, false), 79 80 new TestItem(TestType.MENU_ITEM, true, null), 81 new TestItem(TestType.MENU_ITEM, false, null), 82 new TestItem(TestType.MENU_ITEM, null, true), 83 new TestItem(TestType.MENU_ITEM, null, false), 84 }; 85 86 public static void main(String[] args) throws Exception { 87 88 for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 89 UIManager.setLookAndFeel(info.getClassName()); 90 for (TestItem testItem : TEST_ITEMS) { 91 test(testItem); 92 } 93 } 94 } 95 96 private static void test(TestItem item) throws Exception { 97 98 Robot robot = new Robot(); 99 robot.setAutoDelay(50); 100 SwingUtilities.invokeAndWait(() -> createAndShowGUI(item)); 101 robot.waitForIdle(); 102 103 Point point = getClickPoint(true); 104 robot.mouseMove(point.x, point.y); 105 robot.mousePress(InputEvent.BUTTON1_MASK); 106 robot.mouseRelease(InputEvent.BUTTON1_MASK); 107 robot.waitForIdle(); 108 109 point = getClickPoint(false); 110 robot.mouseMove(point.x, point.y); 111 robot.mousePress(InputEvent.BUTTON1_MASK); 112 robot.mouseRelease(InputEvent.BUTTON1_MASK); 113 robot.waitForIdle(); 114 115 SwingUtilities.invokeAndWait(() -> { 116 JMenuItem menuItem = menu.getItem(0); 117 boolean isShowing = menuItem.isShowing(); 118 frame.dispose(); 119 if (isShowing ^ item.doNotCloseOnMouseClick()) { 120 throw new RuntimeException("Property is not taken into account!"); 121 } 122 }); 123 } 124 125 private static void createAndShowGUI(TestItem testItem) { 126 127 frame = new JFrame(); 128 frame.setSize(300, 300); 129 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 130 131 JMenuBar menuBar = new JMenuBar(); 132 menu = new JMenu("Menu"); 133 JMenuItem menuItem = testItem.getMenuItem(); 134 testItem.setProperties(menuItem); 135 menu.add(menuItem); 136 menuBar.add(menu); 137 138 frame.setJMenuBar(menuBar); 139 frame.setVisible(true); 140 } 141 142 private static Point getClickPoint(boolean parent) throws Exception { 143 Point points[] = new Point[1]; 144 145 SwingUtilities.invokeAndWait(() -> { 146 147 JComponent comp = parent ? menu : menu.getItem(0); 148 149 Point point = comp.getLocationOnScreen(); 150 Rectangle bounds = comp.getBounds(); 151 point.x += bounds.getWidth() / 2; 152 point.y += bounds.getHeight() / 2; 153 154 points[0] = point; 155 }); 156 157 return points[0]; 158 } 159 160 enum TestType { 161 162 MENU_ITEM, 163 CHECK_BOX_MENU_ITEM, 164 RADIO_BUTTON_MENU_ITEM 165 } 166 167 static class TestItem { 168 169 TestType type; 170 Boolean compDoNotCloseOnMouseClick; 171 Boolean lafDoNotCloseOnMouseClick; 172 173 public TestItem(TestType type, 174 Boolean compDoNotCloseOnMouseClick, 175 Boolean lafDoNotCloseOnMouseClick) 176 { 177 this.type = type; 178 this.compDoNotCloseOnMouseClick = compDoNotCloseOnMouseClick; 179 this.lafDoNotCloseOnMouseClick = lafDoNotCloseOnMouseClick; 180 } 181 182 boolean doNotCloseOnMouseClick() { 183 switch (type) { 184 case MENU_ITEM: 185 return false; 186 default: 187 return compDoNotCloseOnMouseClick != null 188 ? compDoNotCloseOnMouseClick 189 : lafDoNotCloseOnMouseClick; 190 } 191 } 192 193 void setProperties(JMenuItem menuItem) { 194 switch (type) { 195 case CHECK_BOX_MENU_ITEM: 196 menuItem.putClientProperty(CHECK_BOX_PROP, compDoNotCloseOnMouseClick); 197 UIManager.put(CHECK_BOX_PROP, lafDoNotCloseOnMouseClick); 198 break; 199 case RADIO_BUTTON_MENU_ITEM: 200 menuItem.putClientProperty(RADIO_BUTTON_PROP, compDoNotCloseOnMouseClick); 201 UIManager.put(RADIO_BUTTON_PROP, lafDoNotCloseOnMouseClick); 202 break; 203 default: 204 menuItem.putClientProperty(CHECK_BOX_PROP, compDoNotCloseOnMouseClick); 205 menuItem.putClientProperty(RADIO_BUTTON_PROP, compDoNotCloseOnMouseClick); 206 UIManager.put(CHECK_BOX_PROP, lafDoNotCloseOnMouseClick); 207 UIManager.put(RADIO_BUTTON_PROP, lafDoNotCloseOnMouseClick); 208 } 209 } 210 211 JMenuItem getMenuItem() { 212 switch (type) { 213 case CHECK_BOX_MENU_ITEM: 214 return new JCheckBoxMenuItem("Check Box"); 215 case RADIO_BUTTON_MENU_ITEM: 216 return new JRadioButtonMenuItem("Radio Button"); 217 default: 218 return new JMenuItem("Menu Item"); 219 } 220 } 221 } 222 }