Graphstream rendering disappears sporadically when displayed in docked panel of IntelliJ

374 Views Asked by At

I'm integrating graphstream (www.graphstream-project.org) into JetBrains MPS (i.e. IntelliJ). The Graphs are displayed in a "tool window" of IntelliJ (the panels on the side, see screenshot).

graphstream integrated in MPS

If the panel is in "floating" mode (not docked) this works without problems (exactly like when graphstream is used standalone, i.e. in a JFrame). But in the "docked" mode (as in the screenshot) the graph disappears in some cases, i.e. the tool window shows a blank white area.

I couldn't reproduce what exactly causes the problem, but it seems to be UI related. Sometimes resizing the docked panel or showing a tooltip in some totally unrelated part of IntelliJ triggers the "disappearing", sometimes not. The graph always re-appears if it is focused again (e.g. blank white area is clicked).

I feel that this is a bug in IntelliJ, but would appreciate any ideas how to investigate the problem further (where could I start debugging etc...).

Code - short version: there is one JPanel containing the DefaultView instance created by graphstream using Viewer.getDefaultView(). This is handed over to MPS / IntelliJ API.

Full code:

// construct the graph
Graph graph = new SingleGraph("Graph");
graph.addAttribute("ui.quality");
graph.addAttribute("ui.antialias");

// ... calls to graph.addNode(), graph.addEdge() to generate some content

// construct Viewer and ViewPanel (ViewPanel extends JPanel)
Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_GUI_THREAD);
ViewPanel viewPanel = viewer.getDefaultView();

// ViewPanel is added to another JPanel as the latter will include a toolbar later
JPanel panel = new JPanel(new BorderLayout());
panel.add(BorderLayout.CENTER, viewPanel);

// The panel is returned to MPS, which uses the IntelliJ API to
// create respective tool window. This part is not under my control.
// If you think it is relevant please mention it.
return panel;

/edit:

While further investigating this problem I found out that there must be something that triggers erroneous behavior. In the beginning everything works fine, but after some time things behave strange and continue to do so, until I re-create the IntelliJ tool window. I made a short video clip to illustrate this, see YouTube.

I have no clue what might be the "trigger". I assume that there is some race condition / threading related problem.

1

There are 1 best solutions below

0
On BEST ANSWER

I could find out that erasing the drawing only occurs, if paintComponent() of the graphstream ViewPanel is called in the context of ToolWindowsPane.paintChildren(). In most cases paintComponent() is called differently (fewer methods on the stack, especially nothing from ToolWindowsPane).

ToolWindowsPane.paintChildren() seems to be called every time a tooltip is displayed somewhere in IntelliJ, for example. So a dirty hack to circumvent the problem was to implement a custom ViewPanel with overridden paintComponent. This was easy because DefaultView of graphstream can be extended.

The following code looks into the call hierarchy and issues a repaint() if necessary. This solved the problem, but causes extra rendering effort, which however does not seem to be a problem in my case.

public class CustomView extends DefaultView { 

  public CustomView(Viewer viewer, String identifier, GraphRenderer graphRenderer) { 
    super(viewer, identifier, graphRenderer); 
  } 

  @Override 
  public void paintComponent(Graphics g) {  
    StackTraceElement[] stackElements = Thread.currentThread().getStackTrace(); 
    for (int i = 0; i < stackElements.length; i++) { 
      if (stackElements[i].getClassName().equals(ToolWindowsPane.class.getName())) { 
        repaint(); 
        break; 
      } 
    } 
    super.paintComponent(g); 
  } 

}