| Summary: | [Viewers] TreeViewer calls getElements() instead of getChildren() when inputElement==rootElement | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | sarah.ettritch |
| Component: | UI | Assignee: | Platform-UI-Inbox <Platform-UI-Inbox> |
| Status: | RESOLVED DUPLICATE | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | emoffatt, qualidafial, tom.schindl |
| Version: | 3.3.2 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
Why not create an 'input' whose 'getElements' simply returns your 'root' ? (In reply to comment #1) > Why not create an 'input' whose 'getElements' simply returns your 'root' ? I'm doing that already. But I consider it a workaround to a bug. I would expect to be able to show a tree model in a TreeViewer by calling TreeViewer.setInput(rootOfModel). Having to create a bogus input object to show a tree model in a TreeViewer works, but it's awkward. I'd expect the viewer to handle what's probably its primary use case in a more intuitive and elegant manner. The problem is that TreeViewer is calling getElements() when it should be calling getChildren(). I concur with comment #3. The first time I used TreeViewer I tried the following in my content provider: Object[] getElements(Object inputElement) { return new Object[] { inputElement }; } Object[] getChildren(Object parentElement) { return ((Model)parentElement).getChildren(); } I found it very surprising when TreeViewer gave me the following: Root +-Root +-Root +-Root +-Root ... In my mind this is a leaked implementation detail. (In reply to comment #3) > I concur with comment #3. I concur with comment #2, rather. :) One of these days I'll sit down and teach myself to count.
I just did a quick google ("JFace Viewers input") and came across the following article;
http://www.eclipse.org/articles/Article-TreeViewer/TreeViewerArticle.htm
It has a fairly explicit statement regarding why there are two separate mechanisms:
----------- Start Quote -----------
- public Object[] getElements(Object inputElement)
This is the method invoked by calling the setInput method on the tree viewer. In fact, the getElements method is called only in response to the tree viewer's setInput method and should answer with the appropriate domain objects of the inputElement. The getElements and getChildren methods operate in a similar way. Depending on your domain objects, you may have the getElements simply return the result of calling getChildren. The two methods are kept distinct because it provides a clean way to differentiate between the root domain object and all other domain objects.
---------- End Quote -------------
This is the way that it has been operating since at least May 2002 and we can't arbitrarily change the protocol (i.e. to call 'getChildren()' on a setInput) since this is what we'd call a 'breaking change' (it ma break existing implementatons) I think we might have to live with it.
I've just had the logic behind this explained to me; the 'input' represents an -invisible- root to the tree. While you may think this odd consider that in almost every case where eclipse uses trees there are multiple sub-trees (PackageExplorer, Search results...). Without the invisible root you'd have no 'parent' to add a new sub-tree to.
*** This bug has been marked as a duplicate of bug 9262 ***
|
Posted to eclipse.platform.swt: I'm having a problem with TreeViewer when I want the root node of the model to be visible (root being the node that doesn't have any parents). Expanding the root node always shows the root node as a child. For example, if I expand root, I see root, root. If I expand that, I see root, root, root, etc. From debugging the code, it looks like the structured viewer ultimately calls getElements(), rather than getChildren(), when getting children for the root. Since I want the root to be visible, getElements() returns root, hence the root, root, root, etc. In my case, the inputElement is also a rootElement (actually, it's the only root element). Matthew Halls says: Doing some further digging, it appears that TreeViewer does not make this distinction internally. A single method is used to determine the children of the element (root or otherwise), and inside that method it decides whether to call getElements() or getChildren() based on whether the parent element is "equal" to the viewer's input. Thus getChildren() is never called because the getElements() result is always { input }.