当前位置: 首页 > 面试题库 >

jtree中jcheckbox的多个ITEM_STATE_CHANGED事件

翟淇
2023-03-14
问题内容

有人,请给我解释一下它是如何工作的。这是代码:

package checkboxtree;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
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.JCheckBox;
import javax.swing.JFrame;
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.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

public class CheckBoxNodeTreeSample {
  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);
    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);
  }
}

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());
          System.out.println("setting state");
          System.out.println(node.getText());
          System.out.println(node.isSelected());
          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();
  public static int clickCount = 0;

  ChangeEvent changeEvent = null;

  JTree tree;

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

  public Object getCellEditorValue() {
      System.out.println("getCellEditorValue method called!");
    JCheckBox checkbox = renderer.getLeafRenderer();
    CheckBoxNode checkBoxNode = new CheckBoxNode(checkbox.getText(),
        checkbox.isSelected());
    return checkBoxNode;
  }

  public boolean isCellEditable(EventObject event) {

      System.out.println("isCellEditable method called");

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

      System.out.println("getTreeCellEditorComponent method called!");

      System.out.println(String.valueOf(clickCount++));

    Component editor = renderer.getTreeCellRendererComponent(tree, value,
        true, expanded, leaf, row, true);

    // editor always selected / focused
    ItemListener itemListener = new ItemListener() {
      public void itemStateChanged(ItemEvent itemEvent) {
          JCheckBox item = (JCheckBox)itemEvent.getItem();
          System.out.println(itemEvent.paramString());
          System.out.println("item "+item.getText()+" state Changed!");

          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 + "]";
  }
}

这是输出:

isCellEditable method called
getTreeCellEditorComponent method called!
0
setting state
Use AutoComplete
true
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Use AutoComplete],stateChange=DESELECTED
item Use AutoComplete state Changed!
getCellEditorValue method called!
setting state
Use AutoComplete
false
setting state
Use AutoComplete
false
setting state
Use AutoComplete
false

isCellEditable method called
getTreeCellEditorComponent method called!
1
setting state
Use AutoComplete
false
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Use AutoComplete],stateChange=SELECTED
item Use AutoComplete state Changed!
getCellEditorValue method called!
setting state
Use AutoComplete
true
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Use AutoComplete],stateChange=SELECTED
item Use AutoComplete state Changed!
setting state
Use AutoComplete
true
setting state
Use AutoComplete
true

isCellEditable method called
getTreeCellEditorComponent method called!
2
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=checkboxtree.CheckBoxNode[Use AutoComplete/true]],stateChange=DESELECTED
item checkboxtree.CheckBoxNode[Use AutoComplete/true] state Changed!
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=checkboxtree.CheckBoxNode[Use AutoComplete/true]],stateChange=DESELECTED
item checkboxtree.CheckBoxNode[Use AutoComplete/true] state Changed!
setting state
Use AutoComplete
true
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Use AutoComplete],stateChange=SELECTED
item Use AutoComplete state Changed!
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Use AutoComplete],stateChange=SELECTED
item Use AutoComplete state Changed!
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Use AutoComplete],stateChange=DESELECTED
item Use AutoComplete state Changed!
getCellEditorValue method called!
setting state
Use AutoComplete
false
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Use AutoComplete],stateChange=DESELECTED
item Use AutoComplete state Changed!
ITEM_STATE_CHANGED,item=javax.swing.JCheckBox[,40,84,129x24,invalid,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@b179c3,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],paintBorder=false,paintFocus=false,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=Use AutoComplete],stateChange=DESELECTED
item Use AutoComplete state Changed!
setting state
Use AutoComplete
false
setting state
Use AutoComplete
false

我不明白为什么法 getTreeCellRendererComponent 的方法之后三次叫
getCellEditorValue

以及为什么当我单击它时, JCheckbox会 生成那么多 ITEM_STATE_CHANGED 事件。


问题答案:

关于渲染器:

  • 对getTreeCellRendererComponent的调用次数是不可控制的(只要内部绘画机制认为必要,它就会在树上使用)

至于编辑:

  • 您将在每次对getTreeCellEditorComponent的调用上创建并注册一个新的侦听器…所有有关更改选择状态的通知
  • 更改选择时,itemListener会被调用两次(分别为一次selected / deselected)
  • 选择状态的初始设置也可能触发两次,因此每个监听器的每次点击总共有4个事件
  • 停止编辑的逻辑有点过多:调用super.stopCellEditing已经触发了editStopped :-)

您可能考虑使用ActionListener而不是ItemListener。



 类似资料:
  • 主要内容:1 Java JCheckBox的介绍,2 Java JCheckBox的声明,3 Java JCheckBox的构造方法,4 Java JCheckBox的方法,5 Java JCheckBox的案例1,6 Java JCheckBox的案例2,7 Java JCheckBox的案例31 Java JCheckBox的介绍 JCheckBox类用于创建复选框。它用于打开(true)或关闭(false)选项。单击CheckBox会将其状态从“打开”更改为“关闭”,或从“关闭”更改为“打

  • 我有一个JTree,它的节点由DefaultMutableTreeNode驱动。每个节点都可以验证或不验证。首先,所有节点的图标都是相同的,但当我选择它们并按下verify按钮时,我将更改已验证节点的图标。我希望能够在每个节点上单击和写入,这样就不能使用JLabel显示图标。我编写了以下代码,但它返回NULLException。 数百万,谢谢。

  • I have seen some implementations of sortables list and none really fits my needs. Here is an ultra lightweight jQuery plugin (2.6kb minified!!!!!!!!!) that will do the job right, loads fast and harnes

  • 问题内容: ActionListener和ItemListener均用于通过JCheckBox触发事件? 那么,它们之间有什么区别,在这种情况下,其中一个优先于另一个? 问题答案: 双方还有,在以下情况下都有相同的行为。但是,可以通过调用复选框来触发主要区别。作为编码的做法不都登记以及与以避免不一致。

  • 我想为JTree中的每个节点设置一个不同的图标,实际上我是从数据库中加载每个节点,使用“while”,我将每个图标设置为根、叶或父。这样地: 我的所有声明都是全球性的: 这是我设置节点的代码: makeNode方法如下: 在用我的节点填充treemodel之后,我将模型设置为我的JTree: 但问题是。当我尝试设置图标时。我创建了一个名为myTreeRenler的子类,我使用它: 但它没有设置我想

  • 问题内容: 首先,我为我的英语疏忽表示歉意,我将解释我所有的问题。 首先我要在JTable中拥有JCheckBox。 我正在从列索引0和1的数据库中检索学生ID和学生姓名。我希望第三列应该是“缺席/在场”,这将首先根据JCheckbox值来获取学生是否在场。 这是我的JTable值代码: Attendance.java 此代码可从数据库中获取值,并将其保存到矢量中 AttendanceGUI.ja