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