I 've got a question about setting the jface's StructuredViewer's useHashlookup = true and editing in respect to refresh( Object element ).

Setting a List<Person> as the viewer's input and having a Person an implemented hashCode() and equals() that mentioned refresh( Object element ) doesn't work if a Person instance within the input model is edited (by reference).

Internally the Structured viewer can't lookup the appropiate widget and thus cannot update/refresh that single swt item. (I do not want to call refresh() as it does "too much")

- How can I enable in-place editing, using hashLookup = true?
- What is the best-practice for that?

On 12/8/2010 13:56, Jens Kreidler wrote:
> Hello,
>
> I 've got a question about setting the jface's StructuredViewer's
> useHashlookup = true and editing in respect to refresh( Object element ).
>
> Setting a List<Person> as the viewer's input and having a Person an
> implemented hashCode() and equals() that mentioned refresh( Object
> element ) doesn't work if a Person instance within the input model is
> edited (by reference).
>
> Internally the Structured viewer can't lookup the appropiate widget and
> thus cannot update/refresh that single swt item. (I do not want to call
> refresh() as it does "too much")
>
> - How can I enable in-place editing, using hashLookup = true?
> - What is the best-practice for that?

You need to implement the IElementComparer for your type and set it via
the setComparer of your viewer.

Thanks Daniel for your reply.
I just had time for looking deeper into this -
ok, using an IElementComparer is a provided way for setting up the internal elementMap of a StructuredViewer - but unfortunately this does not solve an in-place editing for instance.

Assume you have set the TreeViewer's input with a list of a type with ITreeNode's. Each node has a field "element", the payload of the tree node, so treeViewer.setInput( treeNodeList );

A model instance holds that list. A user opens an edit dialog and manipulates - lets say - the element of the ITreeNode index 0.

After editing, you call treeViewer.update( treeNode, null );

This way works fine and fits great in an Model-View-Controller pattern when the treeViewer is configured with useHashlookup = false. But it fails when this is set to false: after the update( node, null ) - call just the hashCode is compared and the appropiate widget cannot be found in via the tree StructuredViewer. No wonder, because the element has been edited in-place and next hashCode is calculated on the edited instance.

So, what can be done? Considering the ITreeNode's elements are DTOs with a technical key, you must implement an IElementComparer that just looks into this technical key? Or is there an other usage possibility? Does any one have an idea, s.th. to discuss?

maybe I just don't understand your scenario very well, but isnt that a problem with the hashCode and equals methods of your viewer's element class?

Here's a test class I bungled together in Helios (as a plugin project with a "RCP application with a view" template). Because you talk about ITreeNodes in your second post (didn't find that interface in the Eclipse APIs), it builds a tree of Node objects that have an id, a text-caption and a list of children. The root node of that tree is thrown into a TreeViewer that has set useHashLookup to true. IMO it should make no difference if you alter a string or any complex type the node references, so there is a button that simply changes the caption of a certain node and then refreshes it in the viewer.

I think Carsten is right this looks very much like a problem in your
hashCode implementation which has to stable during the lifetime of your
instance (it has to use immutable values!) to be used in HashSet/Map!

The only other option is that your IElementComparer uses
System.identityHashCode().