title: JTree rendering with JCheckBox nodes
body: <p>I am attempting to modify the standard Swing JTree to intermingle nodes with and without checkboxes.  This is an example:</p>
  
  <p><img src="https://imgur.com/zkhGi.png" alt="alt text"></p>
  
  <p>When I attempt to check/uncheck one of the checkboxes (the 'User 01' node in this example), the tree loses nodes:</p>
  
  <p><img src="https://imgur.com/IjZOl.png" alt="alt text"></p>
  
  <p>I my code is an adaptation of this example: <a href="http://forums.sun.com/thread.jspa?threadID=5321084&amp;start=13" rel="noreferrer">http://forums.sun.com/thread.jspa?threadID=5321084&amp;start=13</a>.</p>
  
  <p>Instead of embedding a JCheckBox in a DefaultMutableTreeNode like this:</p>
  
  <pre><code>new DefaultMutableTreeNode(new CheckBoxNode("Accessibility", true));
  </code></pre>
  
  <p>I thought it made more sense to create a model node that derived from the DefaultMutableTreeNode, which I call JTreeNode.  This class automatically sets the DefaultMutableTreeNode's UserObject to a JCheckBox.  The class' ShowCheckBox property is used by the TreeCellRenderer to determine if the JCheckBox or DefaultTreeCellRenderer is used.  The JTreeNode is used like this:</p>
  
  <pre><code>    JTreeNode user01 = new JTreeNode("User 01");
      user01.setShowCheckBox(true);
      user01.setSelected(true);
  </code></pre>
  
  <p>I believe the problem is with the class that implements the TreeCellEditor, specifically in the getCellEditorValue() or getTreeCellEditorComponent() methods.  I suspect the issue has something to with the getCellEditorValue() returning a derivative of the DefaultMutableTreeNode, rather than a simpler model instance. </p>
  
  <pre><code>public Object getCellEditorValue() {
  
      JCheckBox checkBox = renderer.getCheckBoxRenderer();
  
      JTreeNode node = new JTreeNode(checkBox.getText());
      node.setShowCheckBox(true);
      node.setSelected(checkBox.isSelected());
      return node;
  
  }
  
  public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, 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;
  
  }
  </code></pre>
  
  <p>Here is the TreeCellRender's getTreeCellRendererComponent() method:</p>
  
  <pre><code>public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
  
      Component component;
  
      //if object being passed for rendering is a JTreeNode that should show a JCheckBox, attempt to render it so
      if (((JTreeNode) value).getShowCheckBox()) {
  
          String stringValue = tree.convertValueToText(value, selected, expanded, leaf, row, false);
  
          //set default JCheckBox rendering
          checkBoxRenderer.setText(stringValue);
          checkBoxRenderer.setSelected(false);    //not checked
          checkBoxRenderer.setEnabled(tree.isEnabled());
  
          if (selected) {
              //removed colorization
              //checkBoxRenderer.setForeground(selectionForeground);
              //checkBoxRenderer.setBackground(selectionBackground);
          }
          else {
              checkBoxRenderer.setForeground(textForeground);
              checkBoxRenderer.setBackground(textBackground);
          }
  
          //DefaultMutableTreeNode
          if ((value != null) &amp;&amp; (value instanceof JTreeNode)) {
  
              //userObject should be a JTreeNode instance
              //DefaultMutableTreeNode
              //Object userObject = ((JTreeNode) value).getUserObject();
  
              //if it is
              //if (userObject instanceof JTreeNode) {
                  //cast as a JTreeNode
                  //JTreeNode node = (JTreeNode) userObject;
                  JTreeNode node = (JTreeNode) value;
  
                  //set JCheckBox settings to match JTreeNode's settings
                  checkBoxRenderer.setText(node.getText());
                  checkBoxRenderer.setSelected(node.isSelected());
  
              //}
  
          }
  
          component = checkBoxRenderer;
  
      }
  
      //if not, render the default
      else {
  
          component = defaultRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
  
      }
  
      return component;
  
  }
  </code></pre>
  
  <p>Any thoughts are greatly appreciated.</p>