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