TreeCellEditor: необходимо выбрать ячейку для редактирования, даже если ShouldSelectCell возвращает false

Мне нужно использовать специальный рендерер ячеек для моего JTree, чтобы добавить JLabel в каждую ячейку. А затем разрешите пользователю нажимать на эти метки без необходимости сначала выбирать ячейку.

Итак, я создал Renderer, который возвращает JPanel, который содержит DefaultTreeCellRenderer и 2 JLabel.

    public class TreeNodeRenderer extends DefaultTreeCellRenderer implements TreeCellRenderer
    {
        private JPanel panel1 = new JPanel();
        private JLabel delete = new JLabel("");
        private JLabel upload = new JLabel("");

        public Component getTreeCellRendererComponent(JTree tree, 
                            Object value,
                boolean selected, boolean expanded, boolean leaf, int row,
                boolean hasFocus) 
        {   
            //
            // DELETE label
            //
            delete.setName("delete");
            delete.setIcon(new ImageIcon("Data/trash.png"));

            //
            // UPLOAD label
            //
            upload.setName("upload");
            upload.setIcon(new ImageIcon("Data/app_up.png"));


            DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
            Color backgroundSelectionColor = defaultRenderer.getBackgroundSelectionColor();
            Color backgroundNonSelectionColor = defaultRenderer.getBackgroundNonSelectionColor();

            if(selected)
                panel1.setBackground(backgroundSelectionColor);
            else
                panel1.setBackground(backgroundNonSelectionColor);


            component = (DefaultTreeCellRenderer) super.getTreeCellRendererComponent(tree,
                    value, selected, expanded, leaf, row, hasFocus);

            panel1.add(component);
            panel1.add(delete);
            panel1.add(upload);

            return panel1;
        }
    }

Затем я создал редактор, позволяющий пользователю нажимать на эти ярлыки благодаря MouseListener. Все работает хорошо, за исключением того, что пользователь должен выбрать ячейку, прежде чем нажать на ярлык. Я попытался вернуть «false» с помощью метода «ShouldSelectCell», но он не работает.

Кто-то знает почему?

Вот редактор:

public class TreeNodeEditor extends AbstractCellEditor implements TreeCellEditor
{
    private TreeNodeRenderer renderer;

    public TreeNodeEditor(TreeNodeRenderer treeRenderer)
    {
        this.renderer = treeRenderer;

    //change the cursor when it's over a label  renderer.getDeleteButton().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    renderer.getUploadButton().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));       renderer.getDownloadButton().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

                 //add labels' mouse listeners 
        addLabelMouseListener(renderer.getDeleteButton());
        addLabelMouseListener(renderer.getUploadButton());
    }

    public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row)
    {
        ...

        return renderer.getTreeCellRendererComponent(
                tree, value, isSelected,
                expanded, leaf, row, true);
    }

    public boolean isCellEditable(EventObject anEvent) 
    {
        return true;
    }

    public boolean shouldSelectCell(EventObject anEvent) 
    {
        return false;
    }


    public boolean stopCellEditing() 
    {
        return super.stopCellEditing();
    }

    public void cancelCellEditing() 
    {
        super.cancelCellEditing();
    }

    public void addCellEditorListener(CellEditorListener l)
    {
        super.addCellEditorListener(l);
    }

    public void removeCellEditorListener(CellEditorListener l) 
    {
        super.removeCellEditorListener(l);
    }

    public Object getCellEditorValue() 
    {
        return null;
    }
}

РЕДАКТИРОВАТЬ - Здесь SSCCE:

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.EventObject;

import javax.swing.AbstractCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CellEditorListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;



public class EditJTreeCell extends JFrame
{
    /**
     * 
     */
    private static final long serialVersionUID = 4745146614430249610L;

    private JTree tree;
    private DefaultTreeModel treeModel;
    private DefaultMutableTreeNode root;

    public EditJTreeCell()
    {
        super("Sample");
        root = new DefaultMutableTreeNode("Root folder");
        treeModel = new DefaultTreeModel(root);
        tree = new JTree(treeModel);

        TreeNodeRenderer renderer = new TreeNodeRenderer();
        tree.setCellRenderer(renderer);
        tree.setCellEditor(new TreeNodeEditor());
        tree.setEditable(true);

        //tree creation
        DefaultMutableTreeNode folder = new DefaultMutableTreeNode("folder1");
        DefaultMutableTreeNode file = new DefaultMutableTreeNode("file1");
        folder.add(file);
        file = new DefaultMutableTreeNode("file2");
        folder.add(file);
        root.add(folder);
        folder = new DefaultMutableTreeNode("folder2");
        file = new DefaultMutableTreeNode("file1");
        folder.add(file);
        file = new DefaultMutableTreeNode("file2");
        folder.add(file);
        file = new DefaultMutableTreeNode("file3");
        folder.add(file);
        root.add(folder);

        this.setSize(400, 800);
        this.add(tree);
        this.setVisible(true);
    }

    public static void main(String[] args) 
    {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
        new EditJTreeCell();
    }
}

class TreeNodeRenderer extends DefaultTreeCellRenderer implements TreeCellRenderer
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private JPanel panel1 = new JPanel();
    private JLabel delete = new JLabel("DELETE");
    private JLabel upload = new JLabel("UPLOAD");

    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean selected, boolean expanded, boolean leaf, int row,
            boolean hasFocus) 
    {   
        //
        // DELETE label
        //
        delete.setName("delete");
        delete.setIcon(new ImageIcon("trash.png"));
        //addLabelMouseListener(delete);
        //
        // UPLOAD label
        //
        upload.setName("upload");
        upload.setIcon(new ImageIcon("app_up.png"));
        //addLabelMouseListener(upload);


        DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
        Color backgroundSelectionColor = defaultRenderer.getBackgroundSelectionColor();
        Color backgroundNonSelectionColor = defaultRenderer.getBackgroundNonSelectionColor();

        DefaultTreeCellRenderer component = (DefaultTreeCellRenderer) super.getTreeCellRendererComponent(tree,
                value, selected, expanded, leaf, row, hasFocus);

        if(selected)
        {   
            panel1.setBackground(backgroundSelectionColor);
        }
        else
        {
            panel1.setBackground(backgroundNonSelectionColor);
        }

        panel1.add(component);
        panel1.add(delete);
        panel1.add(upload);

        return panel1;
    }
}

class TreeNodeEditor extends AbstractCellEditor implements TreeCellEditor
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private JLabel button1;
    private JLabel button2;
    private JPanel panel1;
    private DefaultMutableTreeNode node = null;
    private DefaultTreeCellRenderer defaultRenderer;


    public TreeNodeEditor()
    {
        super();
        panel1 = new JPanel();
        defaultRenderer = new DefaultTreeCellRenderer();
        button1 = new JLabel("DELETE");
        button1.setOpaque(true);
        button1.setIcon(new ImageIcon("trash.png"));
        button1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        button1.addMouseListener(new MouseListener() 
        {
            public void mouseClicked(MouseEvent arg0) {
                System.out.println("Delete clicked");
            }
            public void mouseEntered(MouseEvent arg0) {}
            public void mouseExited(MouseEvent arg0) {}
            public void mousePressed(MouseEvent arg0) {}
            public void mouseReleased(MouseEvent arg0) {}

        });
        button2 = new JLabel("UPLOAD");
        button2.setOpaque(true);
        button2.setIcon(new ImageIcon("app_up.png"));
        button2.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        button2.addMouseListener(new MouseListener() 
        {
            public void mouseClicked(MouseEvent arg0) {
                System.out.println("Upload clicked");
            }
            public void mouseEntered(MouseEvent arg0) {}
            public void mouseExited(MouseEvent arg0) {}
            public void mousePressed(MouseEvent arg0) {}
            public void mouseReleased(MouseEvent arg0) {}

        });
    }


    public Component getTreeCellEditorComponent(JTree tree, Object value, 
            boolean isSelected, boolean expanded, boolean leaf, int row)
    {
        //in order to do some actions on a node
        if(value instanceof DefaultMutableTreeNode)
        {
            node = (DefaultMutableTreeNode) value;
        }


         defaultRenderer.getTreeCellRendererComponent(tree,
                    value, isSelected, expanded, leaf, row, true);

        panel1.add(defaultRenderer);
        panel1.add(button1);
        panel1.add(button2);
        return panel1;
    }

    public boolean isCellEditable(EventObject anEvent) 
    {
        return true;
    }

    public boolean shouldSelectCell(EventObject anEvent) 
    {
        return false;
    }


    public boolean stopCellEditing() 
    {
        return super.stopCellEditing();
    }

    public void cancelCellEditing() 
    {
        super.cancelCellEditing();
    }

    public void addCellEditorListener(CellEditorListener l)
    {
        super.addCellEditorListener(l);
    }

    public void removeCellEditorListener(CellEditorListener l) 
    {
        super.removeCellEditorListener(l);
    }

    public Object getCellEditorValue() 
    {
        return null;
    }
}

Ответы на вопрос(3)

Ваш ответ на вопрос