bug8023474.java revision 11111:4ef86895869c
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/*
25 * @test
26 * @bug 8023474
27 * @summary Tests that the first mouse press starts editing in JTree
28 * @author Dmitry Markov
29 * @run main bug8023474
30 */
31
32import javax.swing.*;
33import javax.swing.event.CellEditorListener;
34import javax.swing.tree.DefaultMutableTreeNode;
35import javax.swing.tree.DefaultTreeModel;
36import javax.swing.tree.TreeCellEditor;
37import javax.swing.tree.TreeCellRenderer;
38import java.awt.*;
39import java.awt.event.InputEvent;
40import java.util.EventObject;
41
42public class bug8023474 {
43    private static JTree tree;
44
45    public static void main(String[] args) throws Exception {
46        Robot robot = new Robot();
47        robot.setAutoDelay(50);
48
49        SwingUtilities.invokeAndWait(new Runnable() {
50            public void run() {
51                createAndShowGUI();
52            }
53        });
54
55        robot.waitForIdle();
56
57        Point point = getRowPointToClick(1);
58        robot.mouseMove(point.x, point.y);
59        robot.mousePress(InputEvent.BUTTON1_MASK);
60        robot.mouseRelease(InputEvent.BUTTON1_MASK);
61
62        robot.waitForIdle();
63
64        Boolean result = (Boolean)tree.getCellEditor().getCellEditorValue();
65        if (!result) {
66            throw new RuntimeException("Test Failed!");
67        }
68    }
69
70    private static void createAndShowGUI() {
71        try {
72            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
73        } catch (Exception e) {
74            throw new RuntimeException(e);
75        }
76
77        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
78        DefaultMutableTreeNode item = new DefaultMutableTreeNode("item");
79        DefaultMutableTreeNode subItem = new DefaultMutableTreeNode("subItem");
80
81        root.add(item);
82        item.add(subItem);
83
84        DefaultTreeModel model = new DefaultTreeModel(root);
85        tree = new JTree(model);
86
87        tree.setCellEditor(new Editor());
88        tree.setEditable(true);
89        tree.setRowHeight(30);
90        tree.setCellRenderer(new CheckboxCellRenderer());
91
92        JFrame frame = new JFrame("bug8023474");
93        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
94        frame.add(new JScrollPane(tree));
95        frame.setSize(400, 300);
96        frame.setVisible(true);
97    }
98
99    private static Point getRowPointToClick(final int row) throws Exception {
100        final Point[] result = new Point[1];
101
102        SwingUtilities.invokeAndWait(new Runnable() {
103            public void run() {
104                Rectangle rect = tree.getRowBounds(row);
105                Point point = new Point(rect.x + 10, rect.y + rect.height / 2);
106                SwingUtilities.convertPointToScreen(point, tree);
107                result[0] = point;
108            }
109        });
110        return result[0];
111    }
112
113    private static class Editor extends JPanel implements TreeCellEditor {
114        private JCheckBox checkbox;
115
116        public Editor() {
117            setOpaque(false);
118            checkbox = new JCheckBox();
119            add(checkbox);
120        }
121
122        public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected,
123                                                    boolean expanded, boolean leaf, int row) {
124            checkbox.setText(value.toString());
125            checkbox.setSelected(false);
126            return this;
127        }
128
129        public Object getCellEditorValue() {
130            return checkbox.isSelected();
131        }
132
133        public boolean isCellEditable(EventObject anEvent) {
134            return true;
135        }
136
137        public boolean shouldSelectCell(EventObject anEvent) {
138            return true;
139        }
140
141        public boolean stopCellEditing() {
142            return true;
143        }
144
145        public void cancelCellEditing() {
146        }
147
148        public void addCellEditorListener(CellEditorListener l) {
149        }
150
151        public void removeCellEditorListener(CellEditorListener l) {
152        }
153    }
154
155    private static class CheckboxCellRenderer extends JPanel implements TreeCellRenderer {
156        private JCheckBox checkbox;
157
158        public CheckboxCellRenderer() {
159            setOpaque(false);
160            checkbox = new JCheckBox();
161            add(checkbox);
162        }
163
164        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
165                                                      boolean leaf, int row, boolean hasFocus) {
166            checkbox.setText(value.toString());
167            checkbox.setSelected(false);
168            return this;
169        }
170    }
171}
172