当前位置: 首页 > 知识库问答 >
问题:

Java“复选框节点树示例”DefaultMutableNode没有任何侦听器?

陶飞英
2023-03-14

我在向现有树添加新节点时遇到问题。我的树基于您可以在链接中看到的CheckBoxNodeTreeSample:

http://www.java2s.com/Code/Java/Swing-JFC/CheckBoxNodeTreeSample.htm

我只是想通过做“标准”的事情来添加一个新节点:

DefaultTreeModel model = (DefaultTreeModel) this.view.getResultTree().getModel();
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("newNode");
        root.add(newNode);
        model.reload(root);

这很好,添加了一个新节点,但与其他现有节点不同的是,我无法单击该复选框,它不可单击。我试图打印新节点和现有节点的路径,如下所示:

newNode
Model.CheckBoxNode[Person,..../true]

我试图解决这个问题已经有一段时间了,但我不知道如何解决这个问题。。如果能帮上忙,我们将不胜感激!:)

我应该尝试像这样添加向量吗?这可能就是标准溶液不起作用的原因吗?我一直在尝试,但模型不喜欢向量、对象或类似的东西。。铸造也不起作用。这是树的初始化,以及它们如何使用向量和checkboxnodes:

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);

共有2个答案

夹谷浩博
2023-03-14

我做了一个SSCCE。有一个按钮,你可以点击添加一个新的节点,带有一个复选框,但它是不可点击的。我没有在任何地方创建jcheckbox,所以我真的不明白应该在哪里放置一个额外的侦听器,也不明白为什么它不在编辑器中使用getTreeCellEditorComponent()?

我还尝试了一种稍微不同的方法,即使用model。insertNodeInto(),但仍然无法单击该复选框。我相信我应该能够创建checkboxNode而不是DefaultMutableTreeNode,但JTree模型不希望这样,因此试图将其转换为DefaultMutableTreeNode。。无论如何,谢谢你迄今为止的帮助!

更新:因为新节点不是CheckBoxNode类型。因此,侦听器不能在节点上工作。所以现在我正在寻找解决方案来创建一个CheckBoxNode[],将其添加到一个向量,然后将其添加为一个节点(这是可能的!)。这就是作者制作JTree的方式,所以我猜类似的东西可能就是答案!

 import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    import java.awt.event.MouseEvent;
    import java.util.EventObject;
    import java.util.Vector;

import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
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;
import javax.swing.tree.TreePath;

    public class CheckBoxNodeTreeSample {

    private static JTree tree;

  public static void main(String args[]) {
    JFrame frame = new JFrame("CheckBox Tree");

    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);
    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.NORTH);

    JPanel buttonPanel = new JPanel();
    JButton button = new JButton("new node");
    buttonPanel.add(button);
    frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
    button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
            DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New node");
            root.add(newNode);
            model.reload();


        }
    });

    frame.setSize(300, 450);
    frame.setVisible(true);
  }
}

class CheckBoxNodeRenderer implements TreeCellRenderer {
  private JCheckBox leafRenderer = new JCheckBox();

  private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();

  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;
  }
}

class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {

  CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();

  ChangeEvent changeEvent = null;

  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;
  }

  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 {
  String text;

  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;
  }

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

class NamedVector extends Vector {
  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]);
    }
  }

  public String toString() {
    return "[" + name + "]";
  }
}
姬正文
2023-03-14

以防你找不到合适的答案,下面是一篇我询问并回答了如何构建复选框树的帖子:

链接

这可能对你有帮助

 类似资料:
  • 我在这里使用这个示例代码创建一个JTree,其中所有的叶子都有一个复选框。我遇到的问题是,我还需要能够选择节点对象,而不必勾选复选框。在我的用例中,勾选复选框将使某些内容可见或隐藏,但选择节点将允许在UI的单独部分编辑对象。最好的方法是什么?是否可以检测何时单击复选框的“框”部分,或者是否选中节点? 我看到的另一个错误是,当文件夹有子元素时,文件夹左侧的指示器正确显示文件夹已打开: 但是如果'文件

  • 问题内容: 我想将Listener放在上。我寻找信息,它是这样的: 问题在于Eclipse认为它是的,并且不起作用。我怎样才能解决这个问题? 问题答案: 你可以这样做:

  • 我正在努力学习RCP中的TreeViewer。我为此写了一小段代码。 我的代码哪里有问题? 谢了!

  • 我在我的一个工作流应用程序中使用了Camunda BPMN2.0。在我的一个服务任务中,我在start事件中创建了一个执行侦听器,在create事件中创建了一个任务侦听器。我不确定在开始时同时分配这些是否合适。如果是正确的,它们中的哪一个将首先执行--执行监听器或任务监听器,分别在start或create事件中执行?

  • 问题内容: 每当尝试从中进行选择时,我都试图触发一个事件。 我遇到的问题是没有明显的方法。 我尝试使用,但从未触发。 没有覆盖的模型,我没有想法。 如何通知有关 选择更改的通知? 编辑:我要道歉。事实证明,我使用的是行为不佳的子类,但由于你的回答是好的,因此我将保留该问题。 问题答案: 它应该响应,如下所示: 正确地指出了也可以。但是,你可能会得到 ,一个用于取消选择先前选择的项目,另一个用于选择

  • 如果我没弄错的话,树通常是一个列表,其中的元素按特定顺序排列。孩子们不在他们自己的子列表中,他们都在同一个列表中。 所以,我试图创建一个Tree类,其中包含TreeNodes(类)使用Tree类中的List。 我如何跟踪父母/孩子/叶子?如果父母“父母1”,有两个孩子“孩子A”和“孩子B”,我如何将他们联系在一起?