1 /*
   2  * Copyright (c) 2011, 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.*;
  34 import javax.swing.*;
  35 import javax.swing.table.*;
  36 import sun.awt.SunToolkit;
  37 
  38 public class bug6263446 {
  39 
  40     private static JTable table;
  41     private static final String FIRST = "AAAAA";
  42     private static final String SECOND = "BB";
  43     private static final String ALL = FIRST + " " + SECOND;
  44     private static Robot robot;
  45 
  46     public static void main(String[] args) throws Exception {
  47         SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
  48         robot = new Robot();
  49         robot.setAutoDelay(50);
  50 
  51         SwingUtilities.invokeAndWait(new Runnable() {
  52 
  53             public void run() {
  54                 createAndShowGUI();
  55             }
  56         });
  57 
  58 
  59         toolkit.realSync();
  60 
  61         Point point = getClickPoint();
  62         robot.mouseMove(point.x, point.y);
  63         toolkit.realSync();
  64 
  65         click(1);
  66         toolkit.realSync();
  67         assertEditing(false);
  68 
  69         click(2);
  70         toolkit.realSync();
  71         checkSelectedText(null);
  72 
  73         click(3);
  74         toolkit.realSync();
  75         checkSelectedText(FIRST);
  76 
  77 
  78         click(4);
  79         toolkit.realSync();
  80         checkSelectedText(ALL);
  81 
  82         setClickCountToStart(1);
  83 
  84         click(1);
  85         toolkit.realSync();
  86         checkSelectedText(null);
  87 
  88         click(2);
  89         toolkit.realSync();
  90         checkSelectedText(FIRST);
  91 
  92         click(3);
  93         toolkit.realSync();
  94         checkSelectedText(ALL);
  95 
  96         setClickCountToStart(3);
  97 
  98         click(1);
  99         toolkit.realSync();
 100         assertEditing(false);
 101 
 102         click(2);
 103         toolkit.realSync();
 104         assertEditing(false);
 105 
 106         click(3);
 107         toolkit.realSync();
 108         checkSelectedText(null);
 109 
 110         click(4);
 111         toolkit.realSync();
 112         checkSelectedText(FIRST);
 113 
 114         click(5);
 115         toolkit.realSync();
 116         checkSelectedText(ALL);
 117 
 118 
 119         SwingUtilities.invokeAndWait(new Runnable() {
 120 
 121             @Override
 122             public void run() {
 123                 table.editCellAt(0, 0);
 124             }
 125         });
 126 
 127         toolkit.realSync();
 128         assertEditing(true);
 129 
 130         click(2);
 131         toolkit.realSync();
 132         checkSelectedText(FIRST);
 133 
 134     }
 135 
 136     private static void checkSelectedText(String sel) throws Exception {
 137         assertEditing(true);
 138         checkSelection(sel);
 139         cancelCellEditing();
 140         assertEditing(false);
 141     }
 142 
 143     private static void setClickCountToStart(final int clicks) throws Exception {
 144         SwingUtilities.invokeAndWait(new Runnable() {
 145 
 146             @Override
 147             public void run() {
 148                 DefaultCellEditor editor =
 149                         (DefaultCellEditor) table.getDefaultEditor(String.class);
 150                 editor.setClickCountToStart(clicks);
 151             }
 152         });
 153 
 154     }
 155 
 156     private static void cancelCellEditing() throws Exception {
 157         SwingUtilities.invokeAndWait(new Runnable() {
 158 
 159             @Override
 160             public void run() {
 161                 table.getCellEditor().cancelCellEditing();
 162             }
 163         });
 164     }
 165 
 166     private static void checkSelection(final String sel) throws Exception {
 167         SwingUtilities.invokeAndWait(new Runnable() {
 168 
 169             @Override
 170             public void run() {
 171                 DefaultCellEditor editor =
 172                         (DefaultCellEditor) table.getDefaultEditor(String.class);
 173                 JTextField field = (JTextField) editor.getComponent();
 174                 String text = field.getSelectedText();
 175                 if (sel == null) {
 176                     if (text != null && text.length() != 0) {
 177                         throw new RuntimeException("Nothing should be selected,"
 178                                 + " but \"" + text + "\" is selected.");
 179                     }
 180                 } else if (!sel.equals(text)) {
 181                     throw new RuntimeException("\"" + sel + "\" should be "
 182                             + "selected, but \"" + text + "\" is selected.");
 183                 }
 184             }
 185         });
 186     }
 187 
 188     private static void assertEditing(final boolean editing) throws Exception {
 189         SwingUtilities.invokeAndWait(new Runnable() {
 190 
 191             @Override
 192             public void run() {
 193                 if (editing && !table.isEditing()) {
 194                     throw new RuntimeException("Table should be editing");
 195                 }
 196                 if (!editing && table.isEditing()) {
 197                     throw new RuntimeException("Table should not be editing");
 198                 }
 199             }
 200         });
 201     }
 202 
 203     private static Point getClickPoint() throws Exception {
 204         final Point[] result = new Point[1];
 205         SwingUtilities.invokeAndWait(new Runnable() {
 206 
 207             @Override
 208             public void run() {
 209                 Rectangle rect = table.getCellRect(0, 0, false);
 210                 Point point = new Point(rect.x + rect.width / 5,
 211                         rect.y + rect.height / 2);
 212                 SwingUtilities.convertPointToScreen(point, table);
 213                 result[0] = point;
 214             }
 215         });
 216 
 217         return result[0];
 218     }
 219 
 220     private static void click(int times) {
 221         robot.delay(500);
 222         for (int i = 0; i < times; i++) {
 223             robot.mousePress(InputEvent.BUTTON1_MASK);
 224             robot.mouseRelease(InputEvent.BUTTON1_MASK);
 225         }
 226     }
 227 
 228     private static TableModel createTableModel() {
 229         String[] columnNames = {"Column 0"};
 230         String[][] data = {{ALL}};
 231 
 232         return new DefaultTableModel(data, columnNames);
 233     }
 234 
 235     private static void createAndShowGUI() {
 236         JFrame frame = new JFrame("bug6263446");
 237         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 238         table = new JTable(createTableModel());
 239         frame.add(table);
 240         frame.pack();
 241         frame.setVisible(true);
 242     }
 243 }