JTree cell editor receives mouse clicks differently depending on OS

前端 未结 3 1794
伪装坚强ぢ
伪装坚强ぢ 2021-01-22 02:08

I\'ve created a tree cell renderer/editor framework that is admittedly a little bit hacky, but it works perfectly on Windows and Linux. The image below illustrates a sample set

3条回答
  •  花落未央
    2021-01-22 02:52

    I'm not sure I understand the requirement, but the example below adds a convenient key binding and works with either single-click approach shown here. I've chosen to override canEditImmediately(), as suggested by kleopatra, subject to her caveats concerning usability.

    tree image

    import java.awt.Component;
    import java.awt.EventQueue;
    import java.awt.event.KeyEvent;
    import java.awt.event.MouseEvent;
    import java.net.URL;
    import java.util.EventObject;
    import javax.imageio.ImageIO;
    import javax.swing.Icon;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTree;
    import javax.swing.KeyStroke;
    import javax.swing.SwingUtilities;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeCellEditor;
    import javax.swing.tree.DefaultTreeCellRenderer;
    
    /**
     * @see https://stackoverflow.com/a/15738813/230513
     * @see https://stackoverflow.com/q/15625424/230513
     */
    public class Test {
    
        private static Icon one;
        private static Icon two;
    
        private void display() {
            JFrame f = new JFrame("Test");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            final JTree tree = new JTree();
            for (int i = 0; i < tree.getRowCount(); i++) {
                tree.expandRow(i);
            }
            final TreeRenderer renderer = new TreeRenderer();
            tree.setCellRenderer(renderer);
            tree.setCellEditor(new TreeEditor(tree, renderer));
            tree.setEditable(true);
            tree.getInputMap().put(
                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "startEditing");
            f.add(new JScrollPane(tree));
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        private static class TreeRenderer extends DefaultTreeCellRenderer {
    
            @Override
            public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean sel, boolean exp, boolean leaf, int row, boolean hasFocus) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
                String s = node.getUserObject().toString();
                if ("colors".equals(s)) {
                    setOpenIcon(one);
                    setClosedIcon(one);
                } else if ("sports".equals(s)) {
                    setOpenIcon(two);
                    setClosedIcon(two);
                } else {
                    setOpenIcon(getDefaultOpenIcon());
                    setClosedIcon(getDefaultClosedIcon());
                }
                super.getTreeCellRendererComponent(
                    tree, value, sel, exp, leaf, row, hasFocus);
                return this;
            }
        }
    
        private static class TreeEditor extends DefaultTreeCellEditor {
    
            public TreeEditor(JTree tree, DefaultTreeCellRenderer renderer) {
                super(tree, renderer);
            }
    
            @Override
            public Component getTreeCellEditorComponent(JTree tree, Object value,
                boolean isSelected, boolean exp, boolean leaf, int row) {
                Component c = super.getTreeCellEditorComponent(
                    tree, value, isSelected, exp, leaf, row);
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
                String s = node.getUserObject().toString();
                if ("colors".equals(s)) {
                    editingIcon = one;
                } else if ("sports".equals(s)) {
                    editingIcon = two;
                }
                return c;
            }
    
            @Override
            protected boolean canEditImmediately(EventObject event) {
                if ((event instanceof MouseEvent)
                    && SwingUtilities.isLeftMouseButton((MouseEvent) event)) {
                    MouseEvent me = (MouseEvent) event;
    
                    return ((me.getClickCount() >= 1)
                        && inHitRegion(me.getX(), me.getY()));
                }
                return (event == null);
            }
        }
    
        public static void main(String[] args) throws Exception {
            one = new ImageIcon(ImageIO.read(
                new URL("http://i.imgur.com/HtHJkfI.png")));
            two = new ImageIcon(ImageIO.read(
                new URL("http://i.imgur.com/w5jAp5c.png")));
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Test().display();
                }
            });
        }
    }
    

提交回复
热议问题