java - 复选框节点树,Swing 中的自定义渲染器

标签 java swing

我一直在尝试实现一个复选框节点树,其中父节点也有复选框。

我已经能够实现该结构了。

但是当我尝试实现 CellEditor 时,我无法检查叶节点。父节点是可检查的,但不能检查叶节点。请给我一些指导。

     /**
     *CheckBoxNodeRenderer.java
     */   

    public class CheckBoxNodeRenderer implements TreeCellRenderer{
public JCheckBox getLeafRenderer()
{
    return leafRenderer;
}
public CheckBoxNodeRenderer() 
{
    Font fontValue;
    fontValue = UIManager.getFont("Tree.font");
    if (fontValue != null) {
        leafRenderer.setFont(fontValue);
    }
    Boolean booleanValue = (Boolean) UIManager
    .get("Tree.drawsFocusBorderAroundIcon");
    leafRenderer.setFocusPainted((booleanValue != null)
            && (booleanValue.booleanValue()));
    selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor");
    selectionForeground = UIManager.getColor("Tree.selectionForeground");
    selectionBackground = UIManager.getColor("Tree.selectionBackground");
    textForeground = UIManager.getColor("Tree.textForeground");
    textBackground = UIManager.getColor("Tree.textBackground");
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
        boolean selected, boolean expanded, boolean leaf, int row,
        boolean hasFocus) 
{
    Component returnValue;
    if (leaf) {
        String stringValue = tree.convertValueToText(value, selected,
                expanded, leaf, row, false);
        if (selected) {
            leafRenderer.setForeground(selectionForeground);
            leafRenderer.setBackground(selectionBackground);
        } else {
            leafRenderer.setForeground(textForeground);
            leafRenderer.setBackground(textBackground);
        }
        if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
            Object userObject = ((DefaultMutableTreeNode) value)
            .getUserObject();
            if (userObject instanceof CheckBoxNode) {
                CheckBoxNode node = (CheckBoxNode) userObject;
                leafRenderer.setText(node.getText());
                leafRenderer.setSelected(node.isSelected());
            }
        }
        returnValue = leafRenderer;
    } else {

        leafRenderer.setText(value.toString());

        leafRenderer.setSelected(selected);
        returnValue = leafRenderer;

    }
    return returnValue;
}
public JCheckBox leafRenderer = new JCheckBox();
private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();
Color selectionBorderColor, selectionForeground, selectionBackground,
textForeground, textBackground;

}

下面的代码是checkBoxNodeEditor.java

   /**
   *CheckBoxNodeEditor.java
   */


public class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
public CheckBoxNodeEditor(JTree tree) {
    this.tree = tree;
}
/**
 * Checkbox node editor for node selection
 */
public  Object getCellEditorValue() {
    GenerateCube.nodeselection();
    return GenerateCube.selectNode;
}
/**
 * Cell Editable
 */
public boolean isCellEditable(EventObject event) {
    boolean returnValue = false;
    if (event instanceof MouseEvent) {
        MouseEvent mouseEvent = (MouseEvent) event;

        path = tree.getPathForLocation(mouseEvent.getX(),
                mouseEvent.getY());
        model = (DefaultTreeModel) (tree.getModel());
        if (path != null) {
                     if(path.getChildCount > 0) {
                     Object node = path.getPathComponent(0);
                      }
                      else{
                           Object node = path.getLastPathComponent();
                          }

            Object node = path.getLastPathComponent();
            if ((node != null) && (node instanceof                           DefaultMutableTreeNode)) {
                DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
                Object userObject = treeNode.getUserObject();
                returnValue = ((treeNode.isLeaf()) && (userObject instanceof CheckBoxNode));
            }
        }
    }
    return returnValue;
}
/**
 * getting Tree Cell Editor Component
 */
public Component getTreeCellEditorComponent(JTree tree, Object value,
        boolean selected, boolean expanded, boolean leaf, int row) {
    Component editor = GenerateCube.renderer.getTreeCellRendererComponent(tree, value,
            true, expanded, leaf, row, true);
    // editor always selected / focused
    ItemListener itemListener = new ItemListener() {
        public void itemStateChanged(ItemEvent itemEvent) {
            if (stopCellEditing()) {
                fireEditingStopped();
            }
        }       };
        if (editor instanceof JCheckBox) {
            ((JCheckBox) editor).addItemListener(itemListener);
        }
        return editor;
}


static int n;
public static  JTree tree;
static DefaultTreeModel model ;
ChangeEvent changeEvent = null;
public static  TreePath path ;
public static String parentstring;

public static DefaultMutableTreeNode nNode;
public static MutableTreeNode node;
String nodeName;

}

最佳答案

也许这段代码可以帮助您使用 TreeCellEditor/Renderer

import java.awt.*;
import java.awt.event.*;
import java.util.EventObject;
import java.util.Vector;
import javax.swing.*;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
//import org.pushingpixels.substance.api.skin.SubstanceOfficeSilver2007LookAndFeel;

public class CheckBoxNodeTreeSample {

    public static void main(String args[]) {
        JFrame frame = new JFrame("CheckBox Tree");
        //setLookAndFeel();
        CheckBoxNode accessibilityOptions[] = {new CheckBoxNode(
            "Move system caret with focus/selection changes", false),
            new CheckBoxNode("Always expand alt text for images", true)};
        CheckBoxNode browsingOptions[] = {
            new CheckBoxNode("Notify when downloads complete", true),
            new CheckBoxNode("Disable script debugging", true),
            new CheckBoxNode("Use AutoComplete", true),
            new CheckBoxNode("Browse in a new process", false)};
        Vector accessVector = new NamedVector("Accessibility",
                accessibilityOptions);
        Vector browseVector = new NamedVector("Browsing", browsingOptions);
        Object rootNodes[] = {accessVector, browseVector};
        Vector rootVector = new NamedVector("Root", rootNodes);
        JTree tree = new JTree(rootVector);
        CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
        tree.setCellRenderer(renderer);
        tree.setCellEditor(new CheckBoxNodeEditor(tree));
        tree.setEditable(true);
        JScrollPane scrollPane = new JScrollPane(tree);
        frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
        frame.setSize(300, 150);
        frame.setVisible(true);
    }

    private static void setLookAndFeel() {
        /*SwingUtilities.invokeLater(new Runnable() {

        public void run() {
        try {
        //UIManager.setLookAndFeel(new SubstanceAutumnLookAndFeel());
        UIManager.setLookAndFeel(new SubstanceOfficeSilver2007LookAndFeel());
        } catch (UnsupportedLookAndFeelException e) {
        throw new RuntimeException(e);
        }
        }
        });*/
    }
}

class CheckBoxNodeRenderer implements TreeCellRenderer {

    private JCheckBox leafRenderer = new JCheckBox();
    private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();
    private Color selectionBorderColor, selectionForeground, selectionBackground,
            textForeground, textBackground;

    protected JCheckBox getLeafRenderer() {
        return leafRenderer;
    }

    public CheckBoxNodeRenderer() {
        Font fontValue;
        fontValue = UIManager.getFont("Tree.font");
        if (fontValue != null) {
            leafRenderer.setFont(fontValue);
        }
        Boolean booleanValue = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
        leafRenderer.setFocusPainted((booleanValue != null) && (booleanValue.booleanValue()));
        selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor");
        selectionForeground = UIManager.getColor("Tree.selectionForeground");
        selectionBackground = UIManager.getColor("Tree.selectionBackground");
        textForeground = UIManager.getColor("Tree.textForeground");
        textBackground = UIManager.getColor("Tree.textBackground");
    }

    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean selected, boolean expanded, boolean leaf, int row,
            boolean hasFocus) {
        Component returnValue;
        if (leaf) {
            String stringValue = tree.convertValueToText(value, selected,
                    expanded, leaf, row, false);
            leafRenderer.setText(stringValue);
            leafRenderer.setSelected(false);
            leafRenderer.setEnabled(tree.isEnabled());
            if (selected) {
                leafRenderer.setForeground(selectionForeground);
                leafRenderer.setBackground(selectionBackground);
            } else {
                leafRenderer.setForeground(textForeground);
                leafRenderer.setBackground(textBackground);
            }
            if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
                Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
                if (userObject instanceof CheckBoxNode) {
                    CheckBoxNode node = (CheckBoxNode) userObject;
                    leafRenderer.setText(node.getText());
                    leafRenderer.setSelected(node.isSelected());
                }
            }
            returnValue = leafRenderer;
        } else {
            returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree,
                    value, selected, expanded, leaf, row, hasFocus);
        }
        return returnValue;
    }
}

private class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {

   private  CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
   private  ChangeEvent changeEvent = null;
   private  JTree tree;

    public CheckBoxNodeEditor(JTree tree) {
        this.tree = tree;
    }

    public Object getCellEditorValue() {
        JCheckBox checkbox = renderer.getLeafRenderer();
        CheckBoxNode checkBoxNode = new CheckBoxNode(checkbox.getText(),
                checkbox.isSelected());
        return checkBoxNode;
    }

    @Override
    public boolean isCellEditable(EventObject event) {
        boolean returnValue = false;
        if (event instanceof MouseEvent) {
            MouseEvent mouseEvent = (MouseEvent) event;
            TreePath path = tree.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();
                    returnValue = ((treeNode.isLeaf()) && (userObject instanceof CheckBoxNode));
                }
            }
        }
        return returnValue;
    }

    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);
        // editor always selected / focused
        ItemListener itemListener = new ItemListener() {

            public void itemStateChanged(ItemEvent itemEvent) {
                if (stopCellEditing()) {
                    fireEditingStopped();
                }
            }
        };
        if (editor instanceof JCheckBox) {
            ((JCheckBox) editor).addItemListener(itemListener);
        }
        return editor;
    }
}

class CheckBoxNode {

  private   String text;
   private  boolean selected;

    public CheckBoxNode(String text, boolean selected) {
        this.text = text;
        this.selected = selected;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean newValue) {
        selected = newValue;
    }

    public String getText() {
        return text;
    }

    public void setText(String newValue) {
        text = newValue;
    }

    @Override
    public String toString() {
        return getClass().getName() + "[" + text + "/" + selected + "]";
    }
}

class NamedVector extends Vector {

   private  String name;

    public NamedVector(String name) {
        this.name = name;
    }

    public NamedVector(String name, Object elements[]) {
        this.name = name;
        for (int i = 0, n = elements.length; i < n; i++) {
            add(elements[i]);
        }
    }

    @Override
    public String toString() {
        return "[" + name + "]";
    }
}

关于java - 复选框节点树,Swing 中的自定义渲染器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8971478/

相关文章:

java - JSON 格式说明换行符

java - 使用 ANT 生成元模型时出现错误

java - Spring MVC - 将日期从用户时区转换为 UTC

java - 向 jList Java 添加组件

java - 在 Java 中,在循环中调用字段访问器是否会在循环的每次迭代中创建新的引用?

java - Hibernate 一对多关系

java - 从 mysql 数据库检索数据到文本字段

java - JPanel 上的 paintComponent 不工作

java - 将 JPanel 和 JScrollingPane 添加到 JFrame

Java 和 Swing 以及游戏循环