Saving TreeViewer state before setInput()
I'm trying to save JFace TreeViewer
expansion state to refresh it after calling setInput()
method. I tried getExpandedElements
, setExpandedElements
, getExpandedTreePaths
, setExpandedTreePaths
methods of TreeViewer
but it doesn't work.
Object[] expandedElements = viewe开发者_C百科r.getExpandedElements();
TreePath[] expandedTreePaths = viewer.getExpandedTreePaths();
viewer.setInput();
viewer.setExpandedElements(expandedElements);
viewer.setExpandedTreePaths(expandedTreePaths);
You need to make sure that your TreeViewer's content provider provides objects that have their hashCode
and equals
methods properly defined. AbstractTreeViewer
needs to be able to compare the old and new objects to determine their expansion state. If hashCode
and equals
aren't provided, it's a simple reference check, which won't work if you've recreated your contents.
As mentioned in this thread, take a look at the late ResourceNavigator
, from the
org.eclipse.ui.views.navigator
package.
("late" because that class is no longer used directly, see the Eclipse Wiki).
It uses a
TreeViewer
, and saves the expanded elements and selected elements, among other state.
The model elements areIResource
objects, which are persisted using theIPersistableElement
/IElementFactory
mechanism.
TheIPersistableElement
adapter is registered againstIResource
in classWorkbenchAdapter
, but this could instead be obtained by the model element implementingIPersistableElement
directly.
The correspondingIElementFactory
is declared in anelementFactory
extension inorg.eclipse.ui.ide
'splugin.xml
.The restored resources know how to get their own children (and parent), via the tree's content provider, so not all elements of the tree need to be persisted.
A similar approach could be used for saving the viewer's input resource.
ForResourceNavigator
, there's a level of indirection here through itsFrameList
's current frame, but if you step through it in the debugger, you'll see that it's essentially doing the same thing.
Small extract (but the rest of the code save also many other things, including selection)
if (frameList.getCurrentIndex() > 0) {
//save frame, it's not the "home"/workspace frame
TreeFrame currentFrame = (TreeFrame) frameList.getCurrentFrame();
IMemento frameMemento = memento.createChild(TAG_CURRENT_FRAME);
currentFrame.saveState(frameMemento);
} else {
//save visible expanded elements
Object JavaDoc expandedElements[] = viewer.getVisibleExpandedElements();
if (expandedElements.length > 0) {
IMemento expandedMem = memento.createChild(TAG_EXPANDED);
for (int i = 0; i < expandedElements.length; i++) {
if (expandedElements[i] instanceof IResource) {
IMemento elementMem = expandedMem
.createChild(TAG_ELEMENT);
elementMem.putString(TAG_PATH,
((IResource) expandedElements[i]).getFullPath()
.toString());
}
}
}
[...]
}
精彩评论