Tweaking DefaultTreeCellRenderer  
Author Message
Thomas Kellerer





PostPosted: 2006-9-17 19:34:00 Top

java-programmer, Tweaking DefaultTreeCellRenderer Hello,

I'm implementing Drag & Drop for my JTree and I got everything working so far.

There is only one thing that I'd like to add: I would like to highlight the node
that is the current drop target somehow. I did manage to select the node
during my dragEnter() and dragOver() events, but I'd rather not change the
tree's selection during dragging.

So I thought I could customize the TreeCellRenderer used. What I did is the
following:

I extended DefaultTreeCellRenderer and added a method to set the current drop
target row. When creating my tree I set the new renderer as the tree renderer
(which is working because I can see the methods beeing called when adding a
System.out.println())

The I overwrote getTreeCellRendererComponent(). Before calling the
super.getTreeCellRendererComponent() I check if a drop target row is set, and if
it is I pretend the cell is focused:

public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus)
{
boolean drawFocus = hasFocus;
if (this.dropTargetRow != -1 && row == this.dropTargetRow)
{
drawFocus = true;
}
return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
row, drawFocus);
}

But this does not work. I have added debuggin code and the dropTargetRow
variable is set and initialized correctly.

What am I missing here? When I pass a hardcoded true or false to the super call,
it does work (all nodes either always focused or never)

Thanks for any input
Thomas

 
danharrisandrews@gmail.com





PostPosted: 2006-9-17 23:31:00 Top

java-programmer >> Tweaking DefaultTreeCellRenderer Thomas Kellerer wrote:
> What am I missing here? When I pass a hardcoded true or false to the super call,
> it does work (all nodes either always focused or never)
>
> Thanks for any input
> Thomas

Hi Thomas,

Your code looks fine, however, it might be possible that your current
look and feel does not bother drawing the focus. If you look at the
java source for the DefaultTreeCellRenderer you will see that it picks
up some behavior and colors from the UIManager. My suggestion is to try
this (below) instead.

super.getTreeCellRendererComponent(tree, value, sel,
expanded, leaf, row, hasFocus);
if (this.dropTargetRow != -1 && row == this.dropTargetRow)
{
// draw your own just-dropped border on this JLabel here
}
return this;

Cheers,

Dan Andrews
- - - - - - - - - - - - - - - - - - - - - - - -
Ansir Development Limited www.ansir.ca
- - - - - - - - - - - - - - - - - - - - - - - -

 
Thomas Kellerer





PostPosted: 2006-9-17 23:41:00 Top

java-programmer >> Tweaking DefaultTreeCellRenderer email***@***.com wrote on 17.09.2006 17:30:
> Thomas Kellerer wrote:
>> What am I missing here? When I pass a hardcoded true or false to the super call,
>> it does work (all nodes either always focused or never)
>>
>
> Hi Thomas,
>
> Your code looks fine, however, it might be possible that your current
> look and feel does not bother drawing the focus. If you look at the
> java source for the DefaultTreeCellRenderer you will see that it picks
> up some behavior and colors from the UIManager. My suggestion is to try
> this (below) instead.
>
> super.getTreeCellRendererComponent(tree, value, sel,
> expanded, leaf, row, hasFocus);
> if (this.dropTargetRow != -1 && row == this.dropTargetRow)
> {
> // draw your own just-dropped border on this JLabel here
> }
> return this;

Hi Dan,

thanks for your answer. The Look&Feel does support drawing a focus (as I
verified by always passing true as the hasFocus parameter).

But I could get it working nevertheless. When I looked at the source for
DefaultTreeCellRenderer I noticed that a lot of repainting stuff is disabled
"for performance" reasons. Once I called repaint() on the JTree itself after
setting my current dropTargetrow the focus was drawn without any further changes.

Best regards
Thomas

 
 
danharrisandrews@gmail.com





PostPosted: 2006-9-17 23:51:00 Top

java-programmer >> Tweaking DefaultTreeCellRenderer email***@***.com wrote:
> Hi Thomas,
>
> Your code looks fine, however, it might be possible that your current
> look and feel does not bother drawing the focus. If you look at the
> java source for the DefaultTreeCellRenderer you will see that it picks
> up some behavior and colors from the UIManager. My suggestion is to try
> this (below) instead.
>
> super.getTreeCellRendererComponent(tree, value, sel,
> expanded, leaf, row, hasFocus);
> if (this.dropTargetRow != -1 && row == this.dropTargetRow)
> {
> // draw your own just-dropped border on this JLabel here
> }
> return this;

On second thought you indicated that the focus is shown, so it is not a
look and feel issue. I can't see the problem in your original code,
however, I think it might still be preferable to highlight the dropped
node differently than a focused node. I assume you have put in some
debugging to insure you are getting into your if statement and that the
dropTargetRow assigned correctly.

 
 
danharrisandrews@gmail.com





PostPosted: 2006-9-18 0:05:00 Top

java-programmer >> Tweaking DefaultTreeCellRenderer Thomas Kellerer wrote:
> But I could get it working nevertheless. When I looked at the source for
> DefaultTreeCellRenderer I noticed that a lot of repainting stuff is disabled
> "for performance" reasons. Once I called repaint() on the JTree itself after
> setting my current dropTargetrow the focus was drawn without any further changes.
>
> Best regards
> Thomas

Hi Thomas,

I was wrong. You got it working - right on! Seems like you shouldn't
have to call repaint though. In the past I have found that when you
change the structure of your tree you get better results when your
TreeModel fires the events indicating the exact changes. Not sure how
you implemented changing the tree's structure, but if it's working for
you that's the important thing.

Cheers,

Dan Andrews
- - - - - - - - - - - - - - - - - - - - - - - -
Ansir Development Limited www.ansir.ca
- - - - - - - - - - - - - - - - - - - - - - - -

 
 
Thomas Kellerer





PostPosted: 2006-9-18 0:20:00 Top

java-programmer >> Tweaking DefaultTreeCellRenderer

email***@***.com wrote on 17.09.2006 18:05:
> Thomas Kellerer wrote:
>> But I could get it working nevertheless. When I looked at the source for
>> DefaultTreeCellRenderer I noticed that a lot of repainting stuff is disabled
>> "for performance" reasons. Once I called repaint() on the JTree itself after
>> setting my current dropTargetrow the focus was drawn without any further changes.
>>
>> Best regards
>> Thomas
>
> Hi Thomas,
>
> I was wrong. You got it working - right on! Seems like you shouldn't
> have to call repaint though. In the past I have found that when you
> change the structure of your tree you get better results when your
> TreeModel fires the events indicating the exact changes. Not sure how
> you implemented changing the tree's structure, but if it's working for
> you that's the important thing.
>
Well the repaint() call is only need for indicating the target of the drop
operation during the drag events, not for the actual drop operation.

I do feel the repaint shouldn't be necessary as well, but as long as it's
working I don't really care ;)

Cheers
Thomas
 
 
Babu Kalakrishnan





PostPosted: 2006-9-19 22:49:00 Top

java-programmer >> Tweaking DefaultTreeCellRenderer Thomas Kellerer wrote:
>
> Well the repaint() call is only need for indicating the target of the
> drop operation during the drag events, not for the actual drop operation.
>
> I do feel the repaint shouldn't be necessary as well, but as long as
> it's working I don't really care ;)
>

Swing's policy is to repaint a component only if something has changed
(as indicated by events from the model it receives or from the
container). A drag event doesn't constitute a "change" per se - so it
is upto you to specify that it should perform a repaint.

From a performance point of view, you could also ask for a selective
repaint of only the cell in question only by using the variant of the
repaint method that specifies an area to be repainted.


BK