3

I am using a GraphViewer with SpaceTreeLayoutAlgorithm and trying to update labels/icons of nodes after the graph has been created.

Already tested variants of

viewer.refresh(node, true);

and

viewer.refresh(viewer.getGraphModelNode(node), true);

in combination with the various refresh/redraw methods of the viewer or its graph control, but with no success.

Some more details on viewer usage:

GraphViewer viewer = new GraphViewer(parent, SWT.BORDER);
ArrayContentProvider content = new MyArrayContentProvider(..);

viewer.setContentProvider(content);
LabelProvider glp = new MyGraphLabelProvider(..);
viewer.setLabelProvider(glp);

List<MyNodeClass> nodes = .. //list of all node elements
viewer.setInput(nodes);

TriangleSubgraphFactory subGraphFactory = new TriangleSubgraphFactory();
SpaceTreeLayoutAlgorithm spaceTreeAlg = new SpaceTreeLayoutAlgorithm();

viewer.getGraphControl().setSubgraphFactory(subGraphFactory);
viewer.getGraphControl().setExpandCollapseManager(
    spaceTreeAlg.getExpandCollapseManager());
viewer.setLayoutAlgorithm(spaceTreeAlg, true);

The code works as expected, except for the refreshes i mentioned above.

I think i may be doing something wrong though, as calling viewer.setInput(..) as recommended by Fabian causes errors. I also do not manage to use SpaceTreeLayoutAlgorithm(int direction) with any direction other than TOP_DOWN, otherwise i get a NPE.

Calling viewer.setInput later causes this:

Caused by: java.util.NoSuchElementException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:813)
at java.util.HashMap$KeyIterator.next(HashMap.java:845)
at org.eclipse.zest.core.widgets.custom.TriangleSubgraph.updateFigure(TriangleSubgraph.java:169)
at org.eclipse.zest.core.widgets.custom.TriangleSubgraph$1.defaultHandle(TriangleSubgraph.java:147)
at org.eclipse.zest.layouts.algorithms.TreeLayoutObserver$TreeListener.nodeRemoved(TreeLayoutObserver.java:308)
at org.eclipse.zest.layouts.algorithms.TreeLayoutObserver$1.nodeRemoved(TreeLayoutObserver.java:344)
at org.eclipse.zest.core.widgets.InternalLayoutContext.fireNodeRemovedEvent(InternalLayoutContext.java:399)
at org.eclipse.zest.core.widgets.InternalNodeLayout.dispose(InternalNodeLayout.java:327)
at org.eclipse.zest.core.widgets.Graph.removeNode(Graph.java:977)
at org.eclipse.zest.core.widgets.GraphNode.dispose(GraphNode.java:188)
at org.eclipse.zest.core.viewers.AbstractStructuredGraphViewer.inputChanged(AbstractStructuredGraphViewer.java:494)
at org.eclipse.zest.core.viewers.GraphViewer.inputChanged(GraphViewer.java:136)
at org.eclipse.jface.viewers.ContentViewer.setInput(ContentViewer.java:280)
at org.eclipse.jface.viewers.StructuredViewer.setInput(StructuredViewer.java:1690)

The following works for refreshing, but this can't possibly be the intended usage:

GraphLabelProvider glp
GraphNode n = viewer.getGraphModelNode(node);
n.setText(glp.getText(node));
n.setImage(glp.getImage(node));
Helmuth M.
  • 541
  • 2
  • 11

1 Answers1

2

I'm not sure how you are using the viewer exactly, but the easiest way would probably be to reset the input of your viewer to the new data you want to visualize (which you process in your content and label providers). The graph is automatically updated when you set the input:

viewer.setInput(myChangedDataToBeVisualized);
Fabian Steeg
  • 44,988
  • 7
  • 85
  • 112
  • This would trigger an update of the entire graph? That would be quite inefficient if i only need to update a single node. Am i using the viewer.refresh wrong, how is it supposed to be used if i want to trigger the refresh of a single node? – Helmuth M. May 24 '12 at 19:26
  • Using viewer.setInput later results in exceptions. I added more info about my viewer usage, maybe i am doing something wrong there. – Helmuth M. Jun 05 '12 at 22:49