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

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.
cathalmchaleAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

zzynxSoftware engineerCommented:
You'll have to use your own TreeCellRenderer
0
zzynxSoftware engineerCommented:
Sorry, I meant TreeCellEditor
0
cathalmchaleAuthor Commented:
yeah i have my own tree cell editor  extends DefaultTreeCellEditor
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

zzynxSoftware engineerCommented:
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
zzynxSoftware engineerCommented:
>> yeah i have my own tree cell editor  extends DefaultTreeCellEditor
Can you post the code
0
cathalmchaleAuthor Commented:
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
zzynxSoftware engineerCommented:
This could inspire you: Editing Trees with Custom User Objects: http://www.phptr.com/articles/article.asp?p=26327&seqNum=25
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
zzynxSoftware engineerCommented:
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
cathalmchaleAuthor Commented:
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
zzynxSoftware engineerCommented:
>> 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
cathalmchaleAuthor Commented:
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
cathalmchaleAuthor Commented:
Anyway of getting an appropriate visual component from the Default editor to return?? would that work??
0
zzynxSoftware engineerCommented:
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
cathalmchaleAuthor Commented:
>>  A (dirty) shortcut that you (maybe) could take is:

it looked reasonable to me, but the fu*ker isn't working! :(
0
zzynxSoftware engineerCommented:
>> 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
zzynxSoftware engineerCommented:
I think you'll have to read the document I linked to ;°)
I'm sure the solution is in
0
cathalmchaleAuthor Commented:
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
zzynxSoftware engineerCommented:
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
cathalmchaleAuthor Commented:
will do thanks
0
zzynxSoftware engineerCommented:
Success
0
cathalmchaleAuthor Commented:
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
zzynxSoftware engineerCommented:
>> ya, got that working !!!!!! thanks a lot.
Good!!!

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


0
zzynxSoftware engineerCommented:
And it doesn't work if you just omit that code?
0
zzynxSoftware engineerCommented:
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
zzynxSoftware engineerCommented:
That piece of code is pasted by mistake. Ignore it.
e.g.
    setTextSelectionColor(this.getTextSelectionColor());
is just obsolete.
0
cathalmchaleAuthor Commented:
>> 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
zzynxSoftware engineerCommented:
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
cathalmchaleAuthor Commented:
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
zzynxSoftware engineerCommented:
Thanks Cathal.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.