1/*
2 * Copyright (c) 2015, 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 7124218
28 * @summary verifies different behaviour of SPACE and ENTER in JTable
29 * @library ../../regtesthelpers
30 * @build Util
31 * @run main SelectEditTableCell
32 */
33import java.awt.Point;
34import java.awt.Robot;
35import java.awt.event.InputEvent;
36import java.awt.event.KeyEvent;
37import javax.swing.DefaultListSelectionModel;
38import javax.swing.JFrame;
39import javax.swing.JTable;
40import javax.swing.LookAndFeel;
41import javax.swing.SwingUtilities;
42import javax.swing.UIManager;
43import javax.swing.UnsupportedLookAndFeelException;
44
45public class SelectEditTableCell {
46
47    private static JFrame frame;
48    private static JTable table;
49    private static Robot robot;
50
51    public static void main(String[] args) throws Exception {
52        robot = new Robot();
53        robot.delay(2000);
54        UIManager.LookAndFeelInfo[] lookAndFeelArray
55                = UIManager.getInstalledLookAndFeels();
56        for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
57            executeCase(lookAndFeelItem.getClassName());
58        }
59
60    }
61
62    private static void executeCase(String lookAndFeelString) throws Exception {
63        if (tryLookAndFeel(lookAndFeelString)) {
64            createUI(lookAndFeelString);
65            robot.delay(2000);
66            runTestCase();
67            robot.delay(2000);
68            cleanUp();
69            robot.delay(2000);
70        }
71
72    }
73
74    private static void createUI(final String lookAndFeelString)
75            throws Exception {
76        SwingUtilities.invokeAndWait(new Runnable() {
77            @Override
78            public void run() {
79                String[][] data = {{"Foo"}};
80                String[] cols = {"One"};
81                table = new JTable(data, cols);
82                table.setSelectionMode(
83                        DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
84                frame = new JFrame(lookAndFeelString);
85                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
86                frame.getContentPane().add(table);
87                frame.pack();
88                frame.setSize(500, frame.getSize().height);
89                frame.setLocationRelativeTo(null);
90                frame.setVisible(true);
91                frame.toFront();
92            }
93        });
94    }
95
96    private static void runTestCase() throws Exception {
97        Point centerPoint;
98        centerPoint = Util.getCenterPoint(table);
99        LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
100        robot.mouseMove(centerPoint.x, centerPoint.y);
101        robot.mousePress(InputEvent.BUTTON1_MASK);
102        robot.mouseRelease(InputEvent.BUTTON1_MASK);
103        SwingUtilities.invokeAndWait(new Runnable() {
104            @Override
105            public void run() {
106                table.clearSelection();
107                if (table.isEditing() || table.isCellSelected(0, 0)) {
108                    // assumption is bad, bail
109                    frame.dispose();
110                    throw new AssertionError("Failed assumption: assumed no"
111                            + "editing and no selection.");
112                }
113            }
114        });
115        robot.waitForIdle();
116        int fetchKeyCode;
117        keyTap(fetchKeyCode = isMac(lookAndFeel)
118                ? KeyEvent.VK_ENTER : KeyEvent.VK_SPACE);
119        final int keyCode = fetchKeyCode;
120        robot.waitForIdle();
121        SwingUtilities.invokeAndWait(new Runnable() {
122            @Override
123            public void run() {
124                if (!table.isCellSelected(0, 0)) {
125                    frame.dispose();
126                    throw new RuntimeException(((keyCode == KeyEvent.VK_ENTER)
127                            ? "Enter" : "Space")
128                            + " should select cell");
129                }
130            }
131        });
132        robot.waitForIdle();
133        keyTap(KeyEvent.VK_SPACE);
134        robot.waitForIdle();
135        SwingUtilities.invokeAndWait(new Runnable() {
136            @Override
137            public void run() {
138                if (!table.isEditing()) {
139                    frame.dispose();
140                    throw new RuntimeException("Space should start editing");
141                }
142                table.getCellEditor().cancelCellEditing();
143                table.clearSelection();
144                if (table.isEditing() || table.isCellSelected(0, 0)) {
145                    // assumption is bad, bail
146                    frame.dispose();
147                    throw new AssertionError("Failed assumption: assumed no "
148                            + "editing and no selection.");
149                }
150            }
151        });
152        robot.waitForIdle();
153        // hitting a letter key will start editing
154        keyTap(KeyEvent.VK_A);
155        keyTap(KeyEvent.VK_SPACE);
156        keyTap(KeyEvent.VK_A);
157        robot.waitForIdle();
158        SwingUtilities.invokeAndWait(new Runnable() {
159            @Override
160            public void run() {
161                if (table.isCellSelected(0, 0)) {
162                    frame.dispose();
163                    throw new RuntimeException("Space should not select when "
164                            + "already editing.");
165                }
166            }
167        });
168    }
169
170    private static void cleanUp() throws Exception {
171        SwingUtilities.invokeAndWait(new Runnable() {
172            @Override
173            public void run() {
174                frame.dispose();
175            }
176        });
177    }
178
179    private static boolean isMac(LookAndFeel lookAndFeel) {
180
181        return lookAndFeel.toString().toLowerCase().contains("mac");
182    }
183
184    private static void keyTap(int keyCode) {
185        robot.keyPress(keyCode);
186        robot.keyRelease(keyCode);
187    }
188
189    private static boolean tryLookAndFeel(String lookAndFeelString)
190            throws Exception {
191        try {
192            UIManager.setLookAndFeel(
193                    lookAndFeelString);
194
195        } catch (UnsupportedLookAndFeelException
196                | ClassNotFoundException
197                | InstantiationException
198                | IllegalAccessException e) {
199            return false;
200        }
201        return true;
202    }
203}
204