在编辑中返回了意外的值-JTree [英] Unexpected value returned in edit - JTree

查看:82
本文介绍了在编辑中返回了意外的值-JTree的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,有一个示例JTree,在每行上都有两个JToggleButtons,而每个JLabel都包含在Holder (subclass of JPanel)中.

In the code below there is an example JTree that has two JToggleButtons on each row and a JLabel all contained in a Holder (subclass of JPanel).

JTree上的叶子可能如下所示.

A leaf on this JTree might look like the following.

当单击JToggleButtons之一时,单击的切换按钮应更改颜色.但是,如下所示,输出却大不相同.

And when one of the JToggleButtons are clicked, the clicked toggle button should change color. However, the output is very much different, as seen below.

为什么会发生这种情况,我该如何解决该问题?

Why is this occurring and how can I fix the problem?

注意:此返回值可以在public component getTreeCellEditorComponent(...)

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.io.*;
import java.util.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.*;

@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
    private DirectoryExplorer() {
        super("Directory Explorer");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(1, 1));
        createPanel();
        setSize(800,600);
        setVisible(true);
    }

    private void createPanel() {
        DefaultMutableTreeNode colors = new DefaultMutableTreeNode("Colours");
        colors.add(new DefaultMutableTreeNode("Red"));
        colors.add(new DefaultMutableTreeNode("Green"));
        colors.add(new DefaultMutableTreeNode("Blue"));

        DefaultMutableTreeNode falvors = new DefaultMutableTreeNode("Flavours");
        falvors.add(new DefaultMutableTreeNode("Toffee"));
        falvors.add(new DefaultMutableTreeNode("Fudge"));
        falvors.add(new DefaultMutableTreeNode("Chocolate"));

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
        root.add(colors);
        root.add(falvors);
        root.add(new DefaultMutableTreeNode("Leafy"));

        JPanel panel = new JPanel(new GridLayout(1, 1));
        JTree tree = new JTree(root);

        FileNameRenderer fileRender = new FileNameRenderer();
        tree.setCellRenderer(fileRender);

        tree.setCellEditor(new CheckBoxNodeEditor(tree));
        tree.setEditable(true);

        tree.setShowsRootHandles(true);

        panel.add(new JScrollPane(tree));
        getContentPane().add(panel);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new DirectoryExplorer());
    }

    private class FileNameRenderer extends DefaultTreeCellRenderer {
        private DefaultChkBx def = new DefaultChkBx();
        private FavouriteChkBx fav = new FavouriteChkBx();

        protected DefaultChkBx getDefBut() {
            return def;
        }

        protected FavouriteChkBx getFavBut() {
            return fav;
        }

        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            JComponent c = (JComponent) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
            return new Holder((JLabel) c, def, fav);
        }

        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus, boolean defSel, boolean favSel) {
            JComponent c = (JComponent) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
            def.setSelected(defSel);
            fav.setSelected(favSel);
            return new Holder((JLabel) c, def, fav);
        }
    }

    private class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
        FileNameRenderer renderer = new FileNameRenderer();
        ChangeEvent changeEvent = null;
        JTree t;
        TreePath path;
        DefaultChkBx def = renderer.getDefBut();
        FavouriteChkBx fav = renderer.getFavBut();

        public CheckBoxNodeEditor(JTree tree) {
            t = tree;
        }

        public Object getCellEditorValue() {
            def = renderer.getDefBut();
            fav = renderer.getFavBut();

            def.setSelected(def.isSelected());
            fav.setSelected(fav.isSelected());

            Holder checkBoxNode = new Holder(new JLabel((((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject().toString())), def, fav);
            return checkBoxNode;
        }

        public boolean isCellEditable(EventObject event) {
            if(event instanceof MouseEvent) {
                MouseEvent mouseEvent = (MouseEvent) event;
                path = t.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
                if (path != null) {
                    Object node = path.getLastPathComponent();
                    if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
                        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
                        Object userObject = treeNode.getUserObject();
                        return (userObject instanceof String);
                    }
                }
            }
            return false;
        }

        public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) {
            Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);
            ItemListener itemListener = new ItemListener() {
                public void itemStateChanged(ItemEvent itemEvent) {
                    if (stopCellEditing())
                        fireEditingStopped();
                }
            };

            if (editor instanceof Holder) {
                for(Component c : ((Holder) editor).getComponents()) {
                    if(c instanceof DefaultChkBx)
                        ((DefaultChkBx) c).addItemListener(itemListener);
                    else if(c instanceof FavouriteChkBx)
                        ((FavouriteChkBx) c).addItemListener(itemListener);
                }
            }

            return editor;
        }
    }

    private class Holder extends JPanel {
        public Holder(Component c, DefaultChkBx def, FavouriteChkBx fav) {
            setLayout(new GridBagLayout());
            setBackground(Color.BLACK);
            setOpaque(false);
            addComponents(c, def, fav);
        }

        private void addComponents(Component c, DefaultChkBx def, FavouriteChkBx fav) {
            GridBagConstraints gBC = new GridBagConstraints();

            gBC.insets = new Insets(0, 0, 0, 5);
            add(c, gBC);

            gBC.insets = new Insets(0, 0, 0, 0);
            add(def, gBC);
            add(fav, gBC);
        }
    }

    private class DefaultChkBx extends JToggleButton {
        public DefaultChkBx() {
            setUI(new MetalToggleButtonUI() {
                @Override
                protected Color getSelectColor() {
                    return new Color(242, 0, 255);
                }
            });
            setBorder(null);
            setForeground(Color.GRAY);
            setText("Default");
            setFocusPainted(false);
        }
    }

    private class FavouriteChkBx extends JToggleButton {
        public FavouriteChkBx() {
            setUI(new MetalToggleButtonUI() {
                @Override
                protected Color getSelectColor() {
                    return Color.RED;
                }
            });
            setBorder(null);
            setForeground(Color.GRAY);
            setText("Favourite");
            setFocusPainted(false);
        }
    }
}

推荐答案

CheckBoxNodeEditor中,您的getCellEditorValue()应该返回已编辑对象的值(通常是在叶子中显示的String对象).

In CheckBoxNodeEditor, your getCellEditorValue() should return the value of the edited object (typically, the String object that is displayed in the leaf).

相反,您的方法返回Holder的实例.在该对象上调用toString()方法并由树显示(这是您正在看到的"DirectoryExplorer $ Holder [....."显示).

Instead, your method returns an instance of Holder. The toString() method is called on this object and displayed by the tree (this is the "DirectoryExplorer$Holder[....." display that you are seeing).

首先,您可以从此方法返回一个简单的String(例如"Leafy").

As a start you could return a simple String from this method (like "Leafy").

这篇关于在编辑中返回了意外的值-JTree的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆