Java 当setLabelsClipped为true时,顶点标签在顶点外部、滚动条上方和其他组件上绘制
我使用JGraph已经有一段时间了,当您将“标签剪裁”设置为true时,似乎存在绘画问题: 下面的简化示例显示了您可以处理的活动应用程序中的问题:Java 当setLabelsClipped为true时,顶点标签在顶点外部、滚动条上方和其他组件上绘制,java,paint,repaint,jgraph,jgraphx,Java,Paint,Repaint,Jgraph,Jgraphx,我使用JGraph已经有一段时间了,当您将“标签剪裁”设置为true时,似乎存在绘画问题: 下面的简化示例显示了您可以处理的活动应用程序中的问题: import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph;
/** it's an app! */
public class GraphApp extends JFrame {
private mxGraph graph;
private mxGraphComponent graphComponent;
private boolean labelsClipped = false;
/** @return the splitpane */
public JSplitPane getSplitpane() {
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
graph = new mxGraph();
graph.getModel().beginUpdate();
graph.removeCells(graph.getChildCells(graph.getDefaultParent(), true, true));
for (int i = 0; i < 10; i++)
graph.insertVertex(null, null, "very_very_long_vertex_" + i, 10 * i, 10 * i, 100, 50);
graph.getModel().endUpdate();
graph.setLabelsClipped(labelsClipped);
graphComponent = new mxGraphComponent(graph);
JTextArea area = new JTextArea("There's overpaint below this text."); //$NON-NLS-1$
splitPane.add(graphComponent, JSplitPane.LEFT);
splitPane.add(area, JSplitPane.RIGHT);
splitPane.setDividerLocation(70);
return splitPane;
}
private JButton getButton() {
JButton button = new JButton(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
labelsClipped = !labelsClipped;
graph.setLabelsClipped(labelsClipped);
GraphApp.this.repaint();
}
});
button.setText("Swap setLabelsClipped");
return button;
}
private JPanel getPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(getSplitpane(), BorderLayout.CENTER);
panel.add(getButton(), BorderLayout.SOUTH);
return panel;
}
public static void main(String[] args) {
GraphApp app = new GraphApp();
app.add(app.getPanel());
app.setPreferredSize(new Dimension(300, 100));
app.setVisible(true);
app.pack();
}
}
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.event.ActionEvent;
导入javax.swing.AbstractAction;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JSplitPane;
导入javax.swing.JTextArea;
导入com.mxgraph.swing.mxGraphComponent;
导入com.mxgraph.view.mxgraph;
/**这是一个应用程序*/
公共类GraphApp扩展了JFrame{
私有图;
私有mxGraphComponent graphComponent;
私有布尔标签clipped=false;
/**@返回拆分窗格*/
公共JSplitPane getSplitpane(){
JSplitPane splitPane=新的JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
graph=新的mxGraph();
graph.getModel().beginUpdate();
removeCells(graph.getChildCells(graph.getDefaultParent(),true,true));
对于(int i=0;i<10;i++)
插入顶点(null,null,“非常非常长的顶点”+i,10*i,10*i,100,50);
graph.getModel().endUpdate();
图形。setLabelsClipped(labelsClipped);
graphComponent=新的mxGraphComponent(图形);
JTextArea=新的JTextArea(“此文本下面有一个overpaint”);//$NON-NLS-1$
添加(graphComponent,JSplitPane.LEFT);
添加(area,JSplitPane.RIGHT);
splitPane.setDividerLocation(70);
返回拆分窗格;
}
私有JButton getButton(){
JButton button=newjbutton(newabstractAction(){
@凌驾
已执行的公共无效操作(操作事件e){
labelsClipped=!labelsClipped;
图形。setLabelsClipped(labelsClipped);
GraphApp.this.repaint();
}
});
button.setText(“交换SetLabelClipped”);
返回按钮;
}
私有JPanel getPanel(){
JPanel panel=newjpanel(newborderlayout());
添加(getSplitpane(),BorderLayout.CENTER);
panel.add(getButton(),BorderLayout.SOUTH);
返回面板;
}
公共静态void main(字符串[]args){
GraphApp=新的GraphApp();
app.add(app.getPanel());
应用程序设置首选尺寸(新尺寸(300100));
app.setVisible(真);
app.pack();
}
}
值得注意的是,二次着色只发生在顶点的范围内。以下是带有剪裁的名称:
在剪辑时:
我现在正在查看JGraphx源代码,以了解问题所在。以前有人解决过这个问题吗?显然,设置graph.setLabelsClipped(false)可以解决这个问题,但我不希望顶点标签溢出到顶点的边界上。我找到了问题所在 从com.mxgraph.view.mxgraph中,如果添加这一点绘制代码,您可以看到剪辑被错误地设置为矩形,如我的示例所示,该矩形可能位于实际图形组件之外
if (clippedCanvas instanceof mxGraphics2DCanvas)
{
System.out.println("setting new clip");
Graphics g = ((mxGraphics2DCanvas) clippedCanvas).getGraphics();
clip = g.getClip();
g.setClip(newClip);
((mxGraphics2DCanvas) clippedCanvas).paintRectangle(((mxGraphics2DCanvas) clippedCanvas).getGraphics().getClipBounds(), Color.GREEN, Color.WHITE);
}
如果我们绘制标签使用的剪裁区域,我们可以看到问题所在
实际上,我们应该只绘制原始画布和新剪切矩形的交点。此图显示了被新矩形踩踏之前的剪切矩形:
解决方法很简单:
if (clippedCanvas instanceof mxGraphics2DCanvas)
{
Graphics g = ((mxGraphics2DCanvas) clippedCanvas).getGraphics();
clip = g.getClip();
if (clip instanceof Rectangle)
{
g.setClip(newClip.intersection((Rectangle) clip));
}
else
{
g.setClip(newClip);
}
}
我很想知道原始代码是否有意地进行了剪辑设置。我有点怀疑
我的修正也默认为他们的实现,如果有人用他们的剪辑形状做了一些古怪的事情,就像一种CYA。可能不需要剪切,因为不能保证使用矩形以外的任何对象:
代码似乎存在于github上,因此希望我能将修复推送到那里:
这是JGraphX 1.12.0.2中的内容,我正在下载最新版本,看看是否在以后的版本中解决过。看起来它仍然存在于JGraphX-2_1_1_2中。