?
Solved

TreeCellEditor over-riding the DefaultMutableTreeNodes user objects!!!!

Posted on 2004-11-25
29
Medium Priority
?
368 Views
Last Modified: 2008-02-01
Hi,

ive been intensively debugging (!!) and it turns out that:
i have a tree
i add new nodes - they are being added correctly - DefaultMutableTreeNodes with user objects of a certain object type
  i can add more nodes succesfully and the existing nodes are OK!!

then i edit a node, and next time the renderer is called i stop at a break-point and check the tree-model -> the other tree nodes are intact, but the one i just edited - its user object is of type String !!!!

??? what the hell happened!!  my editor routine is very simple!!
have u come accross such a problem b4?
i can post any code that may help

regards,
Cathal.
0
Comment
Question by:cathalmchale
  • 18
  • 11
29 Comments
 
LVL 37

Expert Comment

by:zzynx
ID: 12673197
You'll have to use your own TreeCellRenderer
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673201
Sorry, I meant TreeCellEditor
0
 

Author Comment

by:cathalmchale
ID: 12673204
yeah i have my own tree cell editor  extends DefaultTreeCellEditor
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 37

Expert Comment

by:zzynx
ID: 12673206
I guess the default cell editor changes your userobject to a String object (the string you typed in)
While you just want the toString() of your userobject to be edited (=some name field of your userobject)
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673208
>> yeah i have my own tree cell editor  extends DefaultTreeCellEditor
Can you post the code
0
 

Author Comment

by:cathalmchale
ID: 12673221
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded,
        boolean leaf, int row)
    {
      if(value instanceof DefaultMutableTreeNode)
      {
        if(((DefaultMutableTreeNode)value).getUserObject() instanceof CollectionFilter)
        {
          currentFilter = (CollectionFilter)((DefaultMutableTreeNode)value).getUserObject();
        }
      }
      return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);
    }

** ALL user-objects should be of type CollectionFilter  (the renderer just uses this objects toString() for rendering

so thats it!!!  then i am implementing CellEditorListener

    public void editingStopped(ChangeEvent e)
    {
      String name = getCellEditorValue().toString().trim();
      if((currentFilter != null) && isValidName(name))
      {
        currentFilter.setName(name);
      }
    }

    public void editingCanceled(ChangeEvent e)
    {
    }
0
 
LVL 37

Accepted Solution

by:
zzynx earned 2000 total points
ID: 12673232
This could inspire you: Editing Trees with Custom User Objects: http://www.phptr.com/articles/article.asp?p=26327&seqNum=25
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673251
Are you aware of the fact that you *always*

      return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);

In those if statements you just set currentFilter???
At least you need to have an else section:


public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
      if(value instanceof DefaultMutableTreeNode)
      {
        if(((DefaultMutableTreeNode)value).getUserObject() instanceof CollectionFilter)
        {
          currentFilter = (CollectionFilter)((DefaultMutableTreeNode)value).getUserObject();
        }
      }
      else                                // <<<<<<<<<
          currentFilter = null;      // <<<<<<<<<
      return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);
    }
0
 

Author Comment

by:cathalmchale
ID: 12673254
yeah i am thinking i shouldnt be returning:
return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);
at the end of my editor,
i can return a text field but then i must worry - what size shouuld it be, what icon etc.  the default editor worried about this for me, but perhaps it is the only way??

still i am quite surprised that the userObject gets changed!!
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673269
>> you *always*
>>      return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);

That means that the default cell editor is used. (Which - I guess - replaces you CollectionFilter userobject with a String userobject

Hence

>> currentFilter.setName(name);

in your editingStopped() function does change the CollectionFilter object, but that one isn't your node's userobject any more
0
 

Author Comment

by:cathalmchale
ID: 12673274
with respect to zzynx post 10:01
>> yea but i even took out my CellEditorListener - so in other words i did nothing except return
 return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);

but it still changes the userObject
0
 

Author Comment

by:cathalmchale
ID: 12673284
Anyway of getting an appropriate visual component from the Default editor to return?? would that work??
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673291
A (dirty) shortcut that you (maybe) could take is:

    public void editingStopped(ChangeEvent e)
    {
      String name = getCellEditorValue().toString().trim();
      if((currentFilter != null) && isValidName(name))
      {
          currentFilter.setName(name);
          currentNode.setUserObject(currentFilter);  // <<<<<<<<<<<<<
      }
    }

    public void editingCanceled(ChangeEvent e) {
         currentNode.setUserObject(currentFilter);  // <<<<<<<<<<<<< Don't know if it is needed here too (What happens now if you press Esc?)
    }


0
 

Author Comment

by:cathalmchale
ID: 12673347
>>  A (dirty) shortcut that you (maybe) could take is:

it looked reasonable to me, but the fu*ker isn't working! :(
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673354
>> it looked reasonable to me, but the fu*ker isn't working! :(

That means that your user object is reset by the default cell editor after editingStopped() is triggered
...
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673358
I think you'll have to read the document I linked to ;°)
I'm sure the solution is in
0
 

Author Comment

by:cathalmchale
ID: 12673366
Ok - should i just return my own JTextField??
further, should I then extend JTextFiled implement TreeEditor  or something??

otherwise the code is fine??  i.e. it is perfectly fine to set up a reference to the object i will need when editing stops in the
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {   method????

thanks
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673380
Sorry, I don't have any experience with this kind of tree editing.
I quickly had a look at the article I posted the link to, and there I read that you can just use the DefaultTreeCellEditor.
The clue seemed to be in the tree model.
You should really have a look at it.
0
 

Author Comment

by:cathalmchale
ID: 12673392
will do thanks
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12673419
Success
0
 

Author Comment

by:cathalmchale
ID: 12674050
ya, got that working !!!!!! thanks a lot. not like swing to be complicated ;-)

in my renderer i want to set the fore/back color of the JLabel depending on whether its selected so i just have:

if(selected)
      {
        this.setForeground(this.getTextSelectionColor());
        this.setBackground(this.getBackgroundSelectionColor());
      }
      else
      {
        this.setForeground(this.getTextNonSelectionColor());
        this.setBackground(this.getBackgroundNonSelectionColor());
      }

>>this.setForeground  the JLabel

>>this.getTextSelectionColor()  a DefaultTreeCellRenderer method

but this totally fooks things up. e,g when a node is selected u cant read the text because it's white!!
Why doesnt this work??

again thanks
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12674104
>> ya, got that working !!!!!! thanks a lot.
Good!!!

>>Why doesnt this work??
Thinking. At first sight it should...


0
 
LVL 37

Expert Comment

by:zzynx
ID: 12674112
And it doesn't work if you just omit that code?
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12674170
1) I really think you don't need that.
2) the defaultTreeCellRenderer (which you extend) has

      setTextSelectionColor()
      setTextNonSelectionColor()
and
      setBackgroundSelectionColor()
      setBackgroundNonSelectionColor()

functions. You should use these. If you want to a behaviour ***other*** than the default


      if(selected) {
        setTextSelectionColor(this.getTextSelectionColor());
        setBackgroundSelectionColor(this.getBackgroundSelectionColor());
      }
      else
      {
        setTextNonSelectionColor(this.getTextNonSelectionColor());
        setBackgroundNonSelectionColor(this.getBackgroundNonSelectionColor());
      }
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12674180
That piece of code is pasted by mistake. Ignore it.
e.g.
    setTextSelectionColor(this.getTextSelectionColor());
is just obsolete.
0
 

Author Comment

by:cathalmchale
ID: 12674339
>> If you want to a behaviour ***other*** than the default

i dont, but if i ommit such lines then i dont get any selection color.
for sure the DefaultTreeCellRenderer has these colors associated with them, but presumeably it isnt applying them to the JLabel it extends (or something??)

without the lines i posted:
   JLabel, but stays "unselected" whether i select it or not
with the lines i posted
   JLabel, with incorrect color results!!

my renderer

  private class CellRenderer extends DefaultTreeCellRenderer
  {
    //The following method is declared in the interface and must be defined here.
    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus)
    {
      boolean error = false;
      if(value instanceof DefaultMutableTreeNode)
      {
        if (((DefaultMutableTreeNode) value).getUserObject() instanceof CollectionFilter)
        {
          CollectionFilter cf = (CollectionFilter) ((DefaultMutableTreeNode) value).getUserObject();
          setText(cf.toString());
          // first row is library
          if (cf.getName().equals(Configuration.getInstance().getLIBRARY_NODE()))
            setIcon(IconFactory.getImageIcon(IconFactory.Other.GRAPH));
          else
            setIcon(IconFactory.getImageIcon(IconFactory.Other.GROUP));
        }
        else
          error = true;
      }
      else
        error = true;
     
      if(error)
      {
        this.setText("");
        this.setIcon(null);
      }
      // last but not least!
      if(selected)
      {
        this.setForeground(this.getTextSelectionColor());
        this.setBackground(this.getBackgroundSelectionColor());
      }
      else
      {
        this.setForeground(this.getTextNonSelectionColor());
        this.setBackground(this.getBackgroundNonSelectionColor());
      }
     
      return this;
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12674489
You could of course always

      if(selected) {
        this.setForeground(Color.WHITE);
        this.setBackground(Color.BLUE);
      }
      else {
        this.setForeground(Color.BLACK);
        this.setBackground(Color.WHITE);
      }

or whatever other colors you want.
0
 

Author Comment

by:cathalmchale
ID: 12674605
ok its working perfectly!!
if there is anything anyone's interested in i can post code, otherwise the article zzynx posted is succinctly precise!!

im going to give all points to that post zzynx, but of course all comments were useful,
regards,
Cathal.
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12674629
Thanks Cathal.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
In this post we will learn different types of Android Layout and some basics of an Android App.
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Suggested Courses
Course of the Month13 days, 11 hours left to enroll

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question