Swing Graphstream渲染在IntelliJ的停靠面板中显示时会偶尔消失

Swing Graphstream渲染在IntelliJ的停靠面板中显示时会偶尔消失,swing,intellij-idea,awt,graphstream,mps,Swing,Intellij Idea,Awt,Graphstream,Mps,我正在将graphstream(www.graphstream-project.org)集成到JetBrains MPS(即IntelliJ)中。图形显示在IntelliJ的“工具窗口”中(侧面的面板,请参见屏幕截图) 如果面板处于“浮动”模式(未停靠),则其工作不会出现问题(与graphstream单独使用时完全相同,即在JFrame中)。但在“停靠”模式下(如屏幕截图),图形在某些情况下消失,即工具窗口显示空白白色区域 我无法重现问题的确切原因,但它似乎与用户界面有关。有时调整停靠面板的大

我正在将graphstream(www.graphstream-project.org)集成到JetBrains MPS(即IntelliJ)中。图形显示在IntelliJ的“工具窗口”中(侧面的面板,请参见屏幕截图)

如果面板处于“浮动”模式(未停靠),则其工作不会出现问题(与graphstream单独使用时完全相同,即在JFrame中)。但在“停靠”模式下(如屏幕截图),图形在某些情况下消失,即工具窗口显示空白白色区域

我无法重现问题的确切原因,但它似乎与用户界面有关。有时调整停靠面板的大小或在IntelliJ的某些完全无关的部分显示工具提示会触发“消失”,有时则不会。如果图形再次聚焦,则图形始终会重新显示(例如,单击空白白色区域)

我觉得这是IntelliJ中的一个bug,但是如果有任何想法可以进一步研究这个问题(我可以从哪里开始调试等等),我将不胜感激

代码-简短版本:有一个JPanel包含由graphstream使用Viewer.getDefaultView()创建的DefaultView实例。这将移交给MPS/IntelliJ API

完整代码:

// 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;
/编辑:

在进一步调查这个问题时,我发现一定有什么东西会触发错误的行为。一开始一切正常,但过了一段时间,事情变得奇怪,并继续这样做,直到我重新创建IntelliJ工具窗口。我制作了一个短片来说明这一点,请参见


我不知道什么是“导火索”。我假设存在与争用条件/线程相关的问题。

我可以发现,只有在
ToolWindowsPane.paintChildren()
的上下文中调用graphstream
视图面板的
paintComponent()
时,才会删除图形。在大多数情况下,
paintComponent()
的调用是不同的(堆栈上的方法更少,尤其是
ToolWindowsPane
中的任何方法)

例如,每当IntelliJ中某个地方显示工具提示时,似乎都会调用
ToolWindowsPane.paintChildren()
。因此,解决这个问题的一个棘手的方法是使用覆盖的
paintComponent
实现一个自定义
ViewPanel
。这很容易,因为graphstream的
DefaultView
可以扩展

下面的代码查看调用层次结构,并在必要时发出
repaint()
。这解决了问题,但会导致额外的渲染工作,但在我的案例中,这似乎不是问题

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); 
  } 

}
公共类CustomView扩展了DefaultView{
公共CustomView(查看器、字符串标识符、抓取器抓取器){
超级(查看器、标识符、抓取器);
} 
@凌驾
公共组件(图形g){
StackTraceElement[]stackElements=Thread.currentThread().getStackTrace();
对于(inti=0;i
与此完全不同吗?没有。如前所述:在垃圾神的链接示例中,JFrame没有问题。问题只发生在停靠的IntelliJ窗口中。我上面的例子是完整的。您需要MPS(=IntelliJ)来重现该问题。在链接的示例中,您可以看到“显示”JFrame的代码,在我的例子中,这部分是由IntelliJ完成的。可能问题的原因就在那里。所以我想知道如何进一步调试它。与另一个线程中的
GRAPH\u有什么不同吗?
?很好,我当然试过了。没有区别…强制重新绘制(例如切换应用程序或从关联菜单中选择“调整大小”)是否会恢复显示?是否可以尝试此项检查EDT违规?