bug4927934.java revision 15235:fe58d505fffd
1/*
2 * Copyright (c) 2013, 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   @test
25  @key headful
26   @bug 4927934
27   @summary JTree traversal is unlike Native windows tree traversal
28   @author Andrey Pikalev
29   @run main bug4927934
30*/
31
32import javax.swing.*;
33import javax.swing.event.*;
34import javax.swing.tree.*;
35import java.awt.*;
36import java.awt.event.*;
37import java.lang.reflect.InvocationTargetException;
38
39public class bug4927934 implements TreeSelectionListener, TreeExpansionListener, FocusListener {
40
41    final static Object listener = new bug4927934();
42
43    static boolean focusGained = false;
44    public static boolean selectionChanged = false;
45    public static boolean treeExpanded = false;
46    public static boolean treeCollapsed = false;
47
48    static JFrame frame;
49    static JTree tree;
50    static Robot robot;
51
52    public static void main(String args[]) throws Exception {
53        UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel());
54
55        robot = new Robot();
56        robot.setAutoDelay(50);
57
58        SwingUtilities.invokeAndWait(new Runnable() {
59            public void run() {
60                frame = new JFrame();
61
62                DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
63                createNodes(root);
64                tree = new JTree(root);
65                JScrollPane scrollPane = new JScrollPane(tree);
66                frame.getContentPane().add(scrollPane);
67
68                tree.addFocusListener((FocusListener)listener);
69                tree.addTreeSelectionListener((TreeSelectionListener)listener);
70                tree.addTreeExpansionListener((TreeExpansionListener)listener);
71
72                frame.setSize(300, 300);
73                frame.setVisible(true);
74            }
75        });
76
77        robot.waitForIdle();
78        Thread.sleep(1000);
79
80        SwingUtilities.invokeLater(new Runnable() {
81            public void run() {
82                tree.requestFocus();
83            }
84        });
85
86        synchronized(listener) {
87            if (!focusGained) {
88                System.out.println("waiting focusGained...");
89                try {
90                    listener.wait(10000);
91                } catch (InterruptedException e) {
92                    e.printStackTrace();
93                }
94            }
95        }
96
97        // GO TO RIGHT
98        selectionChanged = false;
99        hitKey(KeyEvent.VK_RIGHT);
100        robot.waitForIdle();
101        if (!checkSelectionChanged(tree, 0)) {
102            throw new RuntimeException("Root should be selected");
103        }
104
105        selectionChanged = false;
106        hitKey(KeyEvent.VK_RIGHT);
107        robot.waitForIdle();
108        if (!checkSelectionChanged(tree, 1)) {
109            throw new RuntimeException("Node should be selected");
110        }
111
112        treeExpanded = false;
113        hitKey(KeyEvent.VK_RIGHT);
114        robot.waitForIdle();
115        if (!isTreeExpanded()) {
116            throw new RuntimeException("Node should be expanded");
117        }
118
119        selectionChanged = false;
120        hitKey(KeyEvent.VK_RIGHT);
121        robot.waitForIdle();
122        if (!checkSelectionChanged(tree, 2)) {
123            throw new RuntimeException("Leaf1 should be selected");
124        }
125
126        selectionChanged = false;
127        hitKey(KeyEvent.VK_RIGHT);
128        robot.waitForIdle();
129        if (!checkSelectionChanged(tree, 2)) {
130            throw new RuntimeException("Leaf1 should be selected");
131        }
132
133        // GO TO LEFT
134        selectionChanged = false;
135        hitKey(KeyEvent.VK_LEFT);
136        robot.waitForIdle();
137        if (!checkSelectionChanged(tree, 1)) {
138            throw new RuntimeException("Node should be selected");
139        }
140
141        treeCollapsed = false;
142        hitKey(KeyEvent.VK_LEFT);
143        if (!isTreeCollapsed()) {
144            throw new RuntimeException("Node should be collapsed");
145        }
146
147        selectionChanged = false;
148        hitKey(KeyEvent.VK_LEFT);
149        robot.waitForIdle();
150        if (!checkSelectionChanged(tree, 0)) {
151            throw new RuntimeException("Root should be selected");
152        }
153
154        treeCollapsed = false;
155        hitKey(KeyEvent.VK_LEFT);
156        robot.waitForIdle();
157        if (!isTreeCollapsed()) {
158            throw new RuntimeException("Root should be collapsed");
159        }
160    }
161
162
163    synchronized public void focusLost(FocusEvent e) {
164    }
165
166    synchronized public void focusGained(FocusEvent e) {
167        focusGained = true;
168        System.out.println("focusGained");
169        listener.notifyAll();
170    }
171
172    private static void createNodes(DefaultMutableTreeNode root) {
173        DefaultMutableTreeNode node = new DefaultMutableTreeNode("Node");
174        node.add(new DefaultMutableTreeNode("Leaf1"));
175        node.add(new DefaultMutableTreeNode("Leaf2"));
176        root.add(node);
177        root.add(new DefaultMutableTreeNode("Leaf3"));
178    }
179
180    synchronized public void valueChanged(TreeSelectionEvent e) {
181        selectionChanged = true;
182        System.out.println("selectionChanged");
183        notifyAll();
184    }
185
186    synchronized public void treeCollapsed(TreeExpansionEvent e) {
187        System.out.println("treeCollapsed");
188        treeCollapsed = true;
189        notifyAll();
190    }
191
192    synchronized public void treeExpanded(TreeExpansionEvent e) {
193        System.out.println("treeExpanded");
194        treeExpanded = true;
195        notifyAll();
196    }
197
198    private static void hitKey(int key) {
199        System.out.println("key " + key + " pressed");
200        robot.keyPress(key);
201        robot.keyRelease(key);
202    }
203
204    private static boolean checkSelectionChanged(JTree tree, int shouldBeSel) {
205        synchronized(listener) {
206            if (!selectionChanged) {
207                System.out.println("waiting for selectionChanged...");
208                try {
209                    listener.wait(5000);
210                } catch (InterruptedException e) {
211                    e.printStackTrace();
212                }
213            }
214        }
215        int selRow = tree.getLeadSelectionRow();
216        System.out.println("Selected row: " + selRow);
217        return selRow == shouldBeSel;
218    }
219
220    private static boolean isTreeExpanded() {
221        synchronized(listener) {
222            if (!treeExpanded) {
223                System.out.println("waiting for treeExpanded...");
224                try {
225                    listener.wait(5000);
226                } catch (InterruptedException e) {
227                    e.printStackTrace();
228                }
229            }
230        }
231        return treeExpanded;
232    }
233
234    private static boolean isTreeCollapsed() {
235        synchronized(listener) {
236            if (!treeCollapsed) {
237                System.out.println("waiting for treeCollapsed...");
238                try {
239                    listener.wait(5000);
240                } catch (InterruptedException e) {
241                    e.printStackTrace();
242                }
243            }
244        }
245        return treeCollapsed;
246    }
247}
248