gpt4 book ai didi

java - 当 setLabelsClipped 为真时,顶点标签绘制在顶点之外、滚动条上方和其他组件上

转载 作者:行者123 更新时间:2023-11-30 09:17:53 27 4
gpt4 key购买 nike

我已经使用 JGraph 一段时间了,当您将标签裁剪设置为 true 时,似乎出现了绘画问题:

Overpainting example

以下简化示例显示了您可能会搞砸的实际应用程序中的问题:

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

值得注意的是,重绘只发生在顶点的范围内。以下是剪掉的名字:

Not Clipped

还有裁剪:

Clipped

我现在正在查看 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);
}

如果我们绘制标签正在使用的裁剪区域,我们可以看出问题所在。

Bogus Clipping Area

实际上,我们应该只绘制原始 Canvas 和新裁剪矩形的交集。此图像显示了裁剪矩形在被新裁剪矩形践踏之前的样子:

Original Clipping Area

解决这个问题很简单:

        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,我的修复也默认他们的实现。可能不需要,因为不能保证裁剪适用于矩形以外的任何东西:

http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/Graphics.html#setClip(java.awt.Shape)

看来代码在 github 上,所以希望我能把修复推送到那里:

https://github.com/jgraph/jgraphx

关于java - 当 setLabelsClipped 为真时,顶点标签绘制在顶点之外、滚动条上方和其他组件上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18776252/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com