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 * @key headful 27 * @bug 6263446 28 * @summary Tests that double-clicking to edit a cell doesn't select the content. 29 * @author Shannon Hickey 30 * @run main bug6263446 31 */ 32 import java.awt.*; 33 import java.awt.event.InputEvent; 34 import java.lang.reflect.Field; 35 import javax.swing.*; 36 import javax.swing.tree.*; 37 import sun.awt.SunToolkit; 38 39 public class bug6263446 { 40 41 private static final String FIRST = "AAAAAAAAAAA"; 42 private static final String SECOND = "BB"; 43 private static final String ALL = FIRST + " " + SECOND; 44 private static JTree tree; 45 private static Robot robot; 46 private static SunToolkit toolkit; 47 48 public static void main(String[] args) throws Exception { 49 toolkit = (SunToolkit) Toolkit.getDefaultToolkit(); 50 robot = new Robot(); 51 robot.setAutoDelay(50); 52 53 SwingUtilities.invokeAndWait(new Runnable() { 54 55 public void run() { 56 createAndShowGUI(); 57 } 58 }); 59 60 toolkit.realSync(); 61 62 Point point = getClickPoint(); 63 robot.mouseMove(point.x, point.y); 64 65 // click count 3 66 click(1); 67 assertNotEditing(); 68 69 click(2); 70 assertNotEditing(); 71 72 click(3); 73 assertEditing(); 74 cancelCellEditing(); 75 assertNotEditing(); 76 77 click(4); 78 checkSelectedText(FIRST); 79 80 click(5); 81 checkSelectedText(ALL); 82 83 // click count 4 84 setClickCountToStart(4); 85 86 click(1); 87 assertNotEditing(); 88 89 click(2); 90 assertNotEditing(); 91 92 click(3); 93 assertNotEditing(); 94 95 click(4); 96 assertEditing(); 97 cancelCellEditing(); 98 assertNotEditing(); 99 100 click(5); 101 checkSelectedText(FIRST); 102 103 click(6); 104 checkSelectedText(ALL); 105 106 // start path editing 107 startPathEditing(); 108 assertEditing(); 109 110 click(1); 111 checkSelection(null); 112 113 click(2); 114 checkSelection(FIRST); 115 116 click(3); 117 checkSelection(ALL); 118 } 119 120 private static void click(int times) { 121 robot.delay(500); 122 for (int i = 0; i < times; i++) { 123 robot.mousePress(InputEvent.BUTTON1_MASK); 124 robot.mouseRelease(InputEvent.BUTTON1_MASK); 125 } 126 } 127 128 private static Point getClickPoint() throws Exception { 129 final Point[] result = new Point[1]; 130 131 SwingUtilities.invokeAndWait(new Runnable() { 132 133 @Override 134 public void run() { 135 Rectangle rect = tree.getRowBounds(0); 136 // UPDATE !!! 137 Point p = new Point(rect.x + rect.width / 2, rect.y + 2); 138 SwingUtilities.convertPointToScreen(p, tree); 139 result[0] = p; 140 141 } 142 }); 143 144 return result[0]; 145 } 146 147 private static TreeModel createTreeModel() { 148 return new DefaultTreeModel(new DefaultMutableTreeNode(ALL)); 149 } 150 151 private static void createAndShowGUI() { 152 153 JFrame frame = new JFrame(); 154 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 155 156 tree = new JTree(createTreeModel()); 157 tree.setRootVisible(true); 158 tree.setEditable(true); 159 160 161 frame.getContentPane().add(tree); 162 frame.pack(); 163 frame.setVisible(true); 164 } 165 166 private static void setClickCountToStart(final int clicks) throws Exception { 167 SwingUtilities.invokeAndWait(new Runnable() { 168 169 @Override 170 public void run() { 171 try { 172 DefaultTreeCellEditor editor = 173 (DefaultTreeCellEditor) tree.getCellEditor(); 174 Field field = DefaultTreeCellEditor.class.getDeclaredField("realEditor"); 175 field.setAccessible(true); 176 DefaultCellEditor ce = (DefaultCellEditor) field.get(editor); 177 ce.setClickCountToStart(clicks); 178 } catch (IllegalAccessException e) { 179 throw new RuntimeException(e); 180 } catch (NoSuchFieldException e) { 181 throw new RuntimeException(e); 182 } 183 } 184 }); 185 186 toolkit.realSync(); 187 188 } 189 190 private static void startPathEditing() throws Exception { 191 SwingUtilities.invokeAndWait(new Runnable() { 192 193 @Override 194 public void run() { 195 tree.startEditingAtPath(tree.getPathForRow(0)); 196 } 197 }); 198 } 199 200 private static void cancelCellEditing() throws Exception { 201 SwingUtilities.invokeAndWait(new Runnable() { 202 203 @Override 204 public void run() { 205 tree.getCellEditor().cancelCellEditing(); 206 } 207 }); 208 } 209 210 private static void checkSelection(final String sel) throws Exception { 211 SwingUtilities.invokeAndWait(new Runnable() { 212 213 @Override 214 public void run() { 215 try { 216 DefaultTreeCellEditor editor = 217 (DefaultTreeCellEditor) tree.getCellEditor(); 218 Field field = DefaultTreeCellEditor.class.getDeclaredField("realEditor"); 219 field.setAccessible(true); 220 DefaultCellEditor ce = (DefaultCellEditor) field.get(editor); 221 JTextField tf = (JTextField) ce.getComponent(); 222 String text = tf.getSelectedText(); 223 224 if (sel == null) { 225 if (text != null && text.length() != 0) { 226 throw new RuntimeException("Nothing should be selected, but \"" + text + "\" is selected."); 227 } 228 } else if (!sel.equals(text)) { 229 throw new RuntimeException("\"" + sel + "\" should be selected, but \"" + text + "\" is selected."); 230 } 231 } catch (IllegalAccessException e) { 232 throw new RuntimeException(e); 233 } catch (NoSuchFieldException e) { 234 throw new RuntimeException(e); 235 } 236 } 237 }); 238 } 239 240 private static void checkSelectedText(String sel) throws Exception { 241 assertEditing(); 242 checkSelection(sel); 243 cancelCellEditing(); 244 assertNotEditing(); 245 } 246 247 private static void assertEditing() throws Exception { 248 assertEditingNoTreeLock(true); 249 } 250 251 private static void assertNotEditing() throws Exception { 252 assertEditingNoTreeLock(false); 253 } 254 255 private static void assertEditingNoTreeLock(final boolean editing) throws Exception { 256 toolkit.realSync(); 257 258 SwingUtilities.invokeAndWait(new Runnable() { 259 260 @Override 261 public void run() { 262 if (editing && !tree.isEditing()) { 263 throw new RuntimeException("Tree should be editing"); 264 } 265 if (!editing && tree.isEditing()) { 266 throw new RuntimeException("Tree should not be editing"); 267 } 268 } 269 }); 270 271 } 272 273 }