2012-01-23 53 views
0

我一直在嘗試實現複選框節點樹,其中父節點也有複選框。複選框節點樹,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; 

}

回答

2

也許這個代碼可以幫助你的TreeCellEditor /渲染器

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

由於這代碼使用DefaultTreeCellRe nderer爲非葉節點,我不會能夠得到我的父節點的複選框。 – Achilles

+0

@Achilles如果你不需要實現Java Essential Classes中的一些特殊功能,那麼沒有必要停用/重寫一些DefaultXxxEditor/Renderer方法,對於ParentNode你必須禁用treeNode.isLeaf() – mKorbel