在 IntelliJ 的停靠面板中显示时,Graphstream 渲染偶尔会消失
Graphstream rendering disappears sporadically when displayed in docked panel of IntelliJ
我正在将图形流 (www.graphstream-project.org) 集成到 JetBrains MPS(即 IntelliJ)中。图表显示在 IntelliJ 的 "tool window" 中(侧面的面板,请参见屏幕截图)。
如果面板处于 "floating" 模式(未停靠),则此操作没有问题(就像独立使用 graphstream 时一样,即在 JFrame 中)。但在 "docked" 模式下(如屏幕截图所示)在某些情况下图形会消失,即工具 window 显示空白区域。
我无法重现导致问题的确切原因,但它似乎与 UI 相关。有时调整停靠面板的大小或在 IntelliJ 的一些完全不相关的部分显示工具提示会触发 "disappearing",有时不会。如果再次聚焦(例如单击空白区域),图表总是会重新出现。
我觉得这是 IntelliJ 中的一个错误,但如果有任何关于如何进一步调查该问题的想法(我可以从哪里开始调试等...),我将不胜感激。
代码 - 简短版本:有一个 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 工具 window。我制作了一个简短的视频剪辑来说明这一点,请参阅 YouTube。
我不知道 "trigger" 可能是什么。我假设存在一些竞争条件/线程相关的问题。
我发现只有在 ToolWindowsPane.paintChildren()
的上下文中调用图形流 ViewPanel
的 paintComponent()
时才会擦除绘图。在大多数情况下,paintComponent()
的调用方式不同(堆栈中的方法较少,尤其是 ToolWindowsPane
中没有)。
ToolWindowsPane.paintChildren()
似乎每次在 IntelliJ 中某处显示工具提示时都会被调用,例如。因此,绕过这个问题的一个肮脏的 hack 是实现一个自定义 ViewPanel
并覆盖 paintComponent
。这很容易,因为可以扩展图形流的 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);
}
}
我正在将图形流 (www.graphstream-project.org) 集成到 JetBrains MPS(即 IntelliJ)中。图表显示在 IntelliJ 的 "tool window" 中(侧面的面板,请参见屏幕截图)。
如果面板处于 "floating" 模式(未停靠),则此操作没有问题(就像独立使用 graphstream 时一样,即在 JFrame 中)。但在 "docked" 模式下(如屏幕截图所示)在某些情况下图形会消失,即工具 window 显示空白区域。
我无法重现导致问题的确切原因,但它似乎与 UI 相关。有时调整停靠面板的大小或在 IntelliJ 的一些完全不相关的部分显示工具提示会触发 "disappearing",有时不会。如果再次聚焦(例如单击空白区域),图表总是会重新出现。
我觉得这是 IntelliJ 中的一个错误,但如果有任何关于如何进一步调查该问题的想法(我可以从哪里开始调试等...),我将不胜感激。
代码 - 简短版本:有一个 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 工具 window。我制作了一个简短的视频剪辑来说明这一点,请参阅 YouTube。
我不知道 "trigger" 可能是什么。我假设存在一些竞争条件/线程相关的问题。
我发现只有在 ToolWindowsPane.paintChildren()
的上下文中调用图形流 ViewPanel
的 paintComponent()
时才会擦除绘图。在大多数情况下,paintComponent()
的调用方式不同(堆栈中的方法较少,尤其是 ToolWindowsPane
中没有)。
ToolWindowsPane.paintChildren()
似乎每次在 IntelliJ 中某处显示工具提示时都会被调用,例如。因此,绕过这个问题的一个肮脏的 hack 是实现一个自定义 ViewPanel
并覆盖 paintComponent
。这很容易,因为可以扩展图形流的 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);
}
}