Jtree renderers
I'm having problems writing a custom JTree renderer.
I have created code for a tree that displays checkboxes for true/false =
data (represented by checkboxnode types) and one for text and numerical =
=
data which will use a spinner. Problems occur in getCellEditorValue() wh=
en =
I try to filter out the type of renderer to deal with the input. This is=
=
due to the getLeafRenderer() method.
It only returns leafRenderer, and I can't work out a way of getting it t=
o =
return the different types of renderer instead of just one. It needs to =
=
return leafRenderer when it is a checkbox (which works fine if you chang=
e =
the method's return type to JCheckBox as it was in the example) and =
leafSpinRenderer when it is a spinner. There are other ways of finding o=
ut =
the values, but they reflect the old value (this is in the event handler=
=
and looks messy and incorrect).
Most of the examples of checkbox node trees don't have any explanation o=
f =
how the code works, so I'm flying blind.
class CharacterNodeRenderer implements TreeCellRenderer {
private JCheckBox leafRenderer = new JCheckBox();
private JSpinner leafSpinRenderer = new JSpinner();
private DefaultTreeCellRenderer nonLeafRenderer = new =
DefaultTreeCellRenderer();
Color selectionBorderColor, selectionForeground, selectionBackgroun=
d,
textForeground, textBackground;
// ********* this was originally written as protected JCheckBox =
getLeafRenderer() in example code.\
protected Object getLeafRenderer() {
return leafRenderer;
}
public CharacterNodeRenderer() {
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 va=
lue,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus) {
Component returnValue;
if (leaf & (((DefaultMutableTreeNode) value).getUserObject() =
instanceof CheckBoxNode)) {
String stringValue = tree.convertValueToText(value, selec=
ted,
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);
}
//for checkboxes, read the state from the data and set box
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;
//read data for stats and set values
} else if (leaf & (((DefaultMutableTreeNode) =
value).getUserObject() instanceof Stat)) {
Object userObject = ((DefaultMutableTreeNode) =
value).getUserObject();
Stat node = (Stat) userObject;
leafSpinRenderer.setValue(node.get());
returnValue = leafSpinRenderer;
} else {
returnValue = =
nonLeafRenderer.getTreeCellRendererComponent(tree,
value, selected, expanded, leaf, row, hasFocus);
}
return returnValue;
}
}
class CharacterNodeEditor extends AbstractCellEditor implements =
TreeCellEditor {
CharacterNodeRenderer renderer = new CharacterNodeRenderer();
ChangeEvent changeEvent = null;
JTree tree;
public CharacterNodeEditor(JTree tree) {
this.tree = tree;
}
public Object getCellEditorValue() {
if (renderer.getLeafRenderer() instanceof JCheckBox){
// ************* this secton works fine if its returning a JCheckBox, bu=
t =
I don't always want it to.
JCheckBox checkbox = renderer.getLeafRenderer();
CheckBoxNode checkBoxNode = new CheckBoxNode(checkbox.getText=
(),
checkbox.isSelected());
return checkBoxNode;
}
else if (renderer.getLeafRenderer() instanceof JSpinner)
{
// ************* I was going to add different return types for different=
=
node renderers, as you can see
// JSpinner statbox = renderer.getLeafRenderer();
// Stat statnode = new Stat(statbox.getValue());
}
}
@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());
System.out.println(path);
if (path != null) {
Object node = path.getLastPathComponent();
if ((node != null) && (node instanceof =
DefaultMutableTreeNode)) {
DefaultMutableTreeNode treeNode = =
(DefaultMutableTreeNode) node;
Object userObject = treeNode.getUserObject();
returnValue = ((treeNode.isLeaf()) && ((userObjec=
t =
instanceof CheckBoxNode) || (userObject instanceof Stat)));
}
}
}
return returnValue;
}
/*
public boolean isCellEditable(EventObject event) {
boolean returnValue = super.isCellEditable(event);
if (returnValue) {
Object node = tree.getLastSelectedPathComponent();
if ((node != null) && (node instanceof TreeNode)) {
TreeNode treeNode = (TreeNode) node;
returnValue = treeNode.isLeaf();
}
}
return returnValue;
}
*/
public Component getTreeCellEditorComponent(JTree tree, Object valu=
e,
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);
}
else if (editor instanceof JSpinner)
{
((JSpinner) editor).addItemListener(itemListener);
}
return editor;
}
}