Google Tag Manager

2012/02/06

JCheckBox Node JTree

Code

class CheckBoxNodeEditor extends TriStateCheckBox implements TreeCellEditor {
  private DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
  private final JPanel panel = new JPanel(new BorderLayout());
  private String str = null;
  public CheckBoxNodeEditor() {
    super();
    this.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        // System.out.println("actionPerformed: stopCellEditing");
        stopCellEditing();
      }
    });
    panel.setFocusable(false);
    panel.setRequestFocusEnabled(false);
    panel.setOpaque(false);
    panel.add(this, BorderLayout.WEST);
    this.setOpaque(false);
  }

  @Override public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean isSelected,
      boolean expanded, boolean leaf, int row) {
    JLabel l = (JLabel) renderer.getTreeCellRendererComponent(
      tree, value, true, expanded, leaf, row, true);
    l.setFont(tree.getFont());
    if (value instanceof DefaultMutableTreeNode) {
      this.setEnabled(tree.isEnabled());
      this.setFont(tree.getFont());
      Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
      if (userObject instanceof CheckBoxNode) {
        CheckBoxNode node = (CheckBoxNode) userObject;
        if (node.status == Status.INDETERMINATE) {
          setIcon(new IndeterminateIcon());
        } else {
          setIcon(null);
        }
        l.setText(node.label);
        setSelected(node.status == Status.SELECTED);
        str = node.label;
      }
      // panel.add(this, BorderLayout.WEST);
      panel.add(l);
      return panel;
    }
    return l;
  }

  @Override public Object getCellEditorValue() {
    return new CheckBoxNode(str, isSelected() ? Status.SELECTED : Status.DESELECTED);
  }

  @Override public boolean isCellEditable(EventObject e) {
    if (e instanceof MouseEvent && e.getSource() instanceof JTree) {
      MouseEvent me = (MouseEvent) e;
      JTree tree = (JTree) e.getSource();
      TreePath path = tree.getPathForLocation(me.getX(), me.getY());
      Rectangle r = tree.getPathBounds(path);
      if (r == null) {
        return false;
      }
      Dimension d = getPreferredSize();
      r.setSize(new Dimension(d.width, r.height));
      if (r.contains(me.getPoint())) {
        return true;
      }
    }
    return false;
  }

  @Override public void updateUI() {
    super.updateUI();
    setName("Tree.cellEditor");
    if (panel != null) {
      //panel.removeAll(); // ??? Change to Nimbus LnF, JDK 1.6.0
      panel.updateUI();
      //panel.add(this, BorderLayout.WEST);
    }
    // ???#1: JDK 1.6.0 bug??? @see 1.7.0 DefaultTreeCellRenderer#updateUI()
    // if (System.getProperty("java.version").startsWith("1.6.0")) {
    //   renderer = new DefaultTreeCellRenderer();
    // }
  }
// ...

References