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