0

I try to make JTree with custom TreeRenderer

public class TextCellRender implements TreeCellRenderer {
    JPanel panel;
    JTextArea text;
    JLabel label;
    LayoutManager Layout;

    public TextCellRender() {
        text = new JTextArea();
        text.setWrapStyleWord(true);
        text.setLineWrap(true);
        text.setSize(360, text.getPreferredSize().height);
        label = new JLabel();
        panel = new JPanel();
        panel.add(label);
        panel.add(text);
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value, 
            boolean selected, boolean expanded, boolean leaf,
            int row, boolean hasFocus) {
        Component returnValue = null;
        if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
            Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
            if ((userObject instanceof FieldObj)) {
                FieldObj my = (FieldObj) userObject;
                String fieldText = "";

                text.setText(my.valueList);
                label.setText(my.FieldName);

            }
            return panel;
        }
        return returnValue;
    }
}

and with custom Editor

public class TextCellEdit extends AbstractCellEditor implements TreeCellEditor {    

Which getTreeCellEditorComponent return panel as getTreeCellEditorComponent but with JComboBox which Items populates from db. Render and Editor work great I can click on field and comboBox shows with values from db.

public Component getTreeCellEditorComponent(JTree tree, Object value, 
        boolean isSelected, boolean expanded, boolean leaf, int row) {
    if (value != null && value instanceof DefaultMutableTreeNode) {
        Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
        if (userObject instanceof FieldObj) {
            FieldObj my = (FieldObj) userObject;
            box.removeAllItems();
            label.setText(my.FieldName);
            populatebox(my.FieldName);
            box.addItem(my.valueList);
            panel.add(label);
            panel.add(box);
        } else {
            box.addItem("Uknown object type");
        }
        return panel;
    }
}
public Object getCellEditorValue() { 
    System.out.println("getCellEditoValue returns :" + box.getSelectedItem());
    return box.getSelectedItem();
}

But it doesn't save in Render textArea I mean in Render I have panel with:
JLabel (FieldName)
JTextArea (FieldValue)

when I click on JTextArea I have my Editor which has:
JLabel (FieldName)
JComboBox(FieldValues which I have populated from db)

but when I chose something from Edit ComboBox it doesn't save in Render TextArea So the question is how this things should work?

How render component get value from Edit component?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
user1722669
  • 488
  • 2
  • 6
  • 22

1 Answers1

1

When you implement TreeCellEditor you must to override public Object getCellEditorValue() method. That method calls when you cancel/exit from editing. In this method you can save your new value to object that you store in TreeNode. Then your Renderer got edited object with new value in getTreeCellRendererComponent method.

EDIT: Your editor be like that :

public class TextCellEdit extends AbstractCellEditor implements TreeCellEditor {

private JComboBox<Object> box;
private JLabel label;
private JPanel panel;
private FieldObj my;

public Component getTreeCellEditorComponent(JTree tree, Object value,
        boolean isSelected, boolean expanded, boolean leaf, int row) {

    if (value != null && value instanceof DefaultMutableTreeNode) {
        Object userObject = ((DefaultMutableTreeNode) value)
                .getUserObject();
        if (userObject instanceof FieldObj) {
            my = (FieldObj) userObject;
            box.removeAllItems();
            label.setText(my.FieldName);
            populatebox(my.FieldName);
            box.addItem(my.valueList);
            panel.add(label);
            panel.add(box);
        } else {
            box.addItem("Uknown object type");
        }
        return panel;
    }
}

public Object getCellEditorValue() { 
    System.out.println("getCellEditoValue returns :" + box.getSelectedItem());
    my.FieldName = box.getSelectedItem();
    return box.getSelectedItem();
}
}
alex2410
  • 10,904
  • 3
  • 25
  • 41
  • that is not quite true getCellEditorValue() is invoken when i editor component is change but i can't find where Render use it. (I have implemented this method , seems to me it needs for things like validation or other when u need to get changed value) Seems that Render use some Listeners but now i can't find it out. – user1722669 Oct 31 '13 at 12:55
  • It isn't used by Renderer. It only change your object. Renderer read object again and catch changes. EDIT: Renderer in `getTreeCellRendererComponent` always get changed object and shows it. – alex2410 Oct 31 '13 at 12:58
  • thanks for you help. I edit my question (add getCellEditorValue implementation) could u tell what wrong in it pleace it try return box.getSelectedItem().toString() to just for case. first i was think that Render get value but can set it because i return panel , i try return just TextArea from Render, the same result. Also i can't find a good explanation of getCellEditorValue(). – user1722669 Oct 31 '13 at 13:06