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