我正在自定义一个JTree,因此一些节点有复选框,使用santhosh tekuri's work作为基础。
所以我的想法是编写一个自定义的TreeCellRenderer,在这种情况下扩展JPanel并实现TreeCellRenderer,然后在getTreeCellRendererComponent方法中,我必须为每个节点决定是否接收复选框。
我已经看到一些典型JTree的其他示例来自定义每个节点图标,但是它们在将每个节点转换为JLabel并获取其文本时进行中继,而这里是JPanel。
这是我的渲染器的样子:
public class CheckTreeCellRenderer extends JPanel implements TreeCellRenderer{
private CheckTreeSelectionModel selectionModel;
private TreeCellRenderer delegate;
private TristateCheckBox checkBox;
protected CheckTreeManager.CheckBoxCustomizer checkBoxCustomer;
public CheckTreeCellRenderer(TreeCellRenderer delegate, CheckTreeSelectionModel selectionModel){
this.delegate = delegate;
this.selectionModel = selectionModel;
this.checkBox = new TristateCheckBox("");
this.checkBox.setOpaque(false);
setLayout(new BorderLayout());
setOpaque(false);
}
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus){
Component renderer = delegate.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
// Inside this if clause, those cells which do not require checkbox will be returned
if({CODE_TO_GET_NODE_TEXT}.startsWith("A")){
return renderer;
}
TreePath path = tree.getPathForRow(row);
if(path != null){
if(checkBoxCustomer != null && !checkBoxCustomer.showCheckBox(path)){
return renderer;
}
if(selectionModel.isPathSelected(path, selectionModel.isDigged())){
checkBox.getTristateModel().setState(TristateState.SELECTED);
}
else{
checkBox.getTristateModel().setState(selectionModel.isDigged() && selectionModel.isPartiallySelected(path) ? TristateState.INDETERMINATE : TristateState.DESELECTED);
}
}
removeAll();
add(checkBox, BorderLayout.WEST);
add(renderer, BorderLayout.CENTER);
return this;
}
}
在这种情况下,我想避免为那些文本以" A"开头的单元格设置一个Tristate复选框。举个例子。但是我找不到从值参数中获取文本的方法。
如果它有帮助,这就是我创建JTree的方式:
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
JTree tree = new JTree(root);
// Add nodes to the tree
DefaultMutableTreeNode friends_node = new DefaultMutableTreeNode("Friends");
friends_node.add(new DefaultMutableTreeNode("Anna"));
friends_node.add(new DefaultMutableTreeNode("Amador"));
friends_node.add(new DefaultMutableTreeNode("Jonas"));
friends_node.add(new DefaultMutableTreeNode("Mike"));
friends_node.add(new DefaultMutableTreeNode("Anthony"));
friends_node.add(new DefaultMutableTreeNode("Maya"));
friends_node.add(new DefaultMutableTreeNode("Pepe Vinyuela"));
root.add(friends_node);
tree.setCellRenderer(renderer = new CheckTreeCellRenderer(tree.getCellRenderer(), new CheckTreeSelectionModel(tree.getModel(), dig)));
有什么想法吗?
答案 0 :(得分:2)
如果您使用的是String userObject = "Anna";
new DefaultMutableTreeNode(userObject);
,那么您可以使用DefaultMutableTreeNode#getUserObject()方法:
@Override public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
Component renderer = delegate.getTreeCellRendererComponent(
tree, value, selected, expanded, leaf, row, hasFocus);
if (value instanceof DefaultMutableTreeNode) {
Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
// Inside this if clause, those cells which do not require checkbox will be returned
if(userObject instanceof String && ((String) userObject).startsWith("A")){
return renderer;
}
//...