Swing Graphstream渲染在IntelliJ的停靠面板中显示时会偶尔消失
我正在将graphstream(www.graphstream-project.org)集成到JetBrains MPS(即IntelliJ)中。图形显示在IntelliJ的“工具窗口”中(侧面的面板,请参见屏幕截图) 如果面板处于“浮动”模式(未停靠),则其工作不会出现问题(与graphstream单独使用时完全相同,即在JFrame中)。但在“停靠”模式下(如屏幕截图),图形在某些情况下消失,即工具窗口显示空白白色区域 我无法重现问题的确切原因,但它似乎与用户界面有关。有时调整停靠面板的大小或在IntelliJ的某些完全无关的部分显示工具提示会触发“消失”,有时则不会。如果图形再次聚焦,则图形始终会重新显示(例如,单击空白白色区域) 我觉得这是IntelliJ中的一个bug,但是如果有任何想法可以进一步研究这个问题(我可以从哪里开始调试等等),我将不胜感激 代码-简短版本:有一个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中)。但在“停靠”模式下(如屏幕截图),图形在某些情况下消失,即工具窗口显示空白白色区域 我无法重现问题的确切原因,但它似乎与用户界面有关。有时调整停靠面板的大
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违规?