使用文本字段编辑 JTree 的节点

Edit JTree's node with a textfield

我有一个 JTree cho 有一个像这样的渲染器:

public class BrowserNodeRenderer extends DefaultTreeCellRenderer {

    private JLabel label;

    private JPanel panel;

    private JLabel iconLabel;

    private JTextField textField;

    public BrowserNodeRenderer() {
        this.panel = new JPanel();
        final BorderLayout layout = new BorderLayout();
        this.panel.setLayout(layout);
        this.iconLabel = new JLabel();
        this.label = new JLabel();
        this.label.setOpaque(true);

        //Unbold text
        final Font f = this.label.getFont();
        this.label.setFont(f.deriveFont(f.getStyle() & ~Font.BOLD));

        this.panel.add(this.iconLabel);
        this.panel.add(this.label, BorderLayout.CENTER);
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
            boolean leaf, int row, boolean hasFocus) {

        //Editing label and icon depending on rules
        //...

        return panel;
    }
}

当我右键单击一个节点时,会显示一个 JPopup 菜单,其中包含一个用于重命名当前节点的选项。

但我真的不知道如何告诉节点显示一个文本字段来代替要编辑的标签。

您可以使用 TreeCellEditor 作为 JTree 的自定义编辑器。这是编辑节点文本的简单示例:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;

public class TestFrame extends JFrame {

    public static void main(String... s) {
        new TestFrame();
    }

    private JTree t;

    public TestFrame() {
        init();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }


    private void init() {
        t = new JTree();
        t.setEditable(true);
        t.setCellEditor(getEditor());
        JPopupMenu menu = new JPopupMenu();
        JMenuItem item = new JMenuItem("edit");
        item.addActionListener(getEditActionListener());
        menu.add(item);
        t.setComponentPopupMenu(menu);
        t.addMouseListener(getMouseListener());
        add(new JScrollPane(t));
    }

    private TreeCellEditor getEditor() {
        return new DefaultTreeCellEditor(t, (DefaultTreeCellRenderer) t.getCellRenderer()){
            @Override
            public Component getTreeCellEditorComponent(JTree tree,
                    Object value, boolean isSelected, boolean expanded,
                    boolean leaf, int row) {
                System.out.println("editing ");
                return super.getTreeCellEditorComponent(tree, value, isSelected, expanded,leaf, row);
            }
        };
    }


    private MouseListener getMouseListener() {
        return new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                if(e.getButton() == MouseEvent.BUTTON3){
                    int rowForLocation = t.getRowForLocation(e.getPoint().x, e.getPoint().y);
                    if(rowForLocation != -1){
                        t.setSelectionRow(rowForLocation);
                    }
                }
            }
        };
    }


    private ActionListener getEditActionListener() {
        return new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                TreePath selectionPath = t.getSelectionPath();
                t.startEditingAtPath(selectionPath);
            }
        };
    }

}