顶点渲染为 JComponent
Vertex renderered as JComponent
我目前正在尝试将 JGraph 5 应用程序迁移到 JGraphX。我将顶点渲染器实现为具有复杂布局的嵌套 JComponent
。
使用 mxStylesheet
是迄今为止我发现的唯一自定义顶点渲染的方法。 JGraphX 中有渲染器概念吗?是否可以将渲染器实现为 JComponents
?
我在 CustomCanvas.java JGraphX 示例中找到了答案。
此示例适用于非复合组件 (JLabel...),但不适用于复合组件。 paintComponent() 方法是为父组件而不是子组件调用的。这似乎与 CellRendererPane
在此示例中没有父项这一事实有关。添加到 CellRendererPane
到 graphComponent 解决了这个问题(对我来说,canvas 是自然父级,但它似乎不是容器)。
所以,我最初问题的答案是:不,JGraphX 不提供对渲染器的支持,但您似乎可以通过子类化 mxGraph
、mxGraphComponent
和mxInteractiveCanvas
.
最后,可以轻松地扩展此示例,以更常用的方式实现 "renderer" 模式。我没有引入渲染器工厂来保持代码片段简短,但这可能是有道理的。
public class SwingCanvas<USER_OBJECT> extends mxInteractiveCanvas {
private final CellRendererPane rendererPane = new CellRendererPane();
protected mxGraphComponent graphComponent;
public SwingCanvas(SwingMxGraphComponent<USER_OBJECT> graphComponent) {
this.graphComponent = graphComponent;
graphComponent.add(rendererPane);
}
public void drawVertex(mxCellState state, String label) {
SwingMxGraph<USER_OBJECT> graph = graphComponent.getGraph();
VertexRenderer<USER_OBJECT> vertexRenderer = graph.getVertexRenderer();
USER_OBJECT userValue = (USER_OBJECT)((mxCell)state.getCell()).getValue();
JComponent rendererComponent = vertexRenderer.getRendererComponent(graphComponent.getGraph(), userValue);
rendererPane.paintComponent(g, rendererComponent, graphComponent,
(int) state.getX() + translate.x,
(int) state.getY() + translate.y,
(int) state.getWidth(), (int) state.getHeight(), true);
}
}
public interface VertexRenderer<USER_OBJECT> {
/* Provide graph instance just in case...*/
JComponent getRendererComponent(mxGraph graph, USER_OBJECT userObject);
}
public class SwingMxGraph<USER_OBJECT> extends mxGraph {
private VertexRenderer<USER_OBJECT> vertexRenderer;
/* Add the same method override as in sample
...
... */
public VertexRenderer<USER_OBJECT> getVertextRenderer() {
return vertexRenderer;
}
}
我目前正在尝试将 JGraph 5 应用程序迁移到 JGraphX。我将顶点渲染器实现为具有复杂布局的嵌套 JComponent
。
使用 mxStylesheet
是迄今为止我发现的唯一自定义顶点渲染的方法。 JGraphX 中有渲染器概念吗?是否可以将渲染器实现为 JComponents
?
我在 CustomCanvas.java JGraphX 示例中找到了答案。
此示例适用于非复合组件 (JLabel...),但不适用于复合组件。 paintComponent() 方法是为父组件而不是子组件调用的。这似乎与 CellRendererPane
在此示例中没有父项这一事实有关。添加到 CellRendererPane
到 graphComponent 解决了这个问题(对我来说,canvas 是自然父级,但它似乎不是容器)。
所以,我最初问题的答案是:不,JGraphX 不提供对渲染器的支持,但您似乎可以通过子类化 mxGraph
、mxGraphComponent
和mxInteractiveCanvas
.
最后,可以轻松地扩展此示例,以更常用的方式实现 "renderer" 模式。我没有引入渲染器工厂来保持代码片段简短,但这可能是有道理的。
public class SwingCanvas<USER_OBJECT> extends mxInteractiveCanvas {
private final CellRendererPane rendererPane = new CellRendererPane();
protected mxGraphComponent graphComponent;
public SwingCanvas(SwingMxGraphComponent<USER_OBJECT> graphComponent) {
this.graphComponent = graphComponent;
graphComponent.add(rendererPane);
}
public void drawVertex(mxCellState state, String label) {
SwingMxGraph<USER_OBJECT> graph = graphComponent.getGraph();
VertexRenderer<USER_OBJECT> vertexRenderer = graph.getVertexRenderer();
USER_OBJECT userValue = (USER_OBJECT)((mxCell)state.getCell()).getValue();
JComponent rendererComponent = vertexRenderer.getRendererComponent(graphComponent.getGraph(), userValue);
rendererPane.paintComponent(g, rendererComponent, graphComponent,
(int) state.getX() + translate.x,
(int) state.getY() + translate.y,
(int) state.getWidth(), (int) state.getHeight(), true);
}
}
public interface VertexRenderer<USER_OBJECT> {
/* Provide graph instance just in case...*/
JComponent getRendererComponent(mxGraph graph, USER_OBJECT userObject);
}
public class SwingMxGraph<USER_OBJECT> extends mxGraph {
private VertexRenderer<USER_OBJECT> vertexRenderer;
/* Add the same method override as in sample
...
... */
public VertexRenderer<USER_OBJECT> getVertextRenderer() {
return vertexRenderer;
}
}