【发布时间】:2022-02-04 22:41:41
【问题描述】:
在下面的复制器中,我正在复制我在图形界面中看到的内容。
我想重绘画布的脏区域(JPanel),因为完全重绘会引入更多延迟。
但是,当调用重绘(脏矩形)函数时,它会导致嵌套的 Graphics2D 对象出现一些问题。特别是
这段代码可能会误用剪辑边界,但我没想到会在创建子(嵌套)图形上下文时出现这种“工件”。
在这种情况下,处理剪辑、嵌套图形上下文和脏区域(或矩形)repaint 的正确方法是什么。
我的直觉告诉我,代码应该在不使用剪切区域的情况下计算其形状。
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
public class Reproducer {
public static void main(String[] args) {
var comp = new MyJPanel();
var timer = new Timer(2_000, e -> {
SwingUtilities.invokeLater(comp::bug);
});
timer.start();
timer.setRepeats(true);
SwingUtilities.invokeLater(() -> {
var frame = new JFrame("Reproducer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(300, 300));
frame.setVisible(true);
frame.getContentPane().add(comp);
});
}
private static class MyJPanel extends JPanel {
public MyJPanel() {
setSize(600, 600);
setPreferredSize(getSize());
}
@Override
protected void paintComponent(Graphics g) {
var g2 = (Graphics2D) g;
super.paintComponent(g2);
g2.setColor(Color.cyan);
g2.fill(g2.getClip());
var graphicsBox = (Graphics2D) g2.create(10, 10, 290, 290);
var clipBounds = graphicsBox.getClipBounds();
graphicsBox.setColor(Color.LIGHT_GRAY);
graphicsBox.setStroke(new BasicStroke(2));
graphicsBox.drawRect(clipBounds.x, clipBounds.y, clipBounds.width, clipBounds.height);
graphicsBox.setColor(Color.red);
graphicsBox.fill(new Rectangle2D.Double(clipBounds.x + 2,
clipBounds.y + 2,
clipBounds.width - 2,
clipBounds.height - 2));
graphicsBox.dispose();
var graphicsOverlay = (Graphics2D) g2.create(100, 100, 100, 100);
graphicsOverlay.setColor(Color.YELLOW);
graphicsOverlay.fillOval(10, 10, 60, 60);
graphicsOverlay.dispose();
}
public void bug() {
getVisibleRect();
repaint(100, 100, 100, 100);
}
}
}
通过将fill 移动到drawRect 上方进行编辑
【问题讨论】:
-
所以,“问题”似乎与
g2.create(10, 10, 290, 290)和graphicsBox.getClipBounds()有关。第一个是创建和“翻译和剪辑”上下文,但是,它考虑到了父上下文的原始clip,或者正如文档所说,“它的剪辑区域由原始剪辑的交集决定具有指定矩形的区域” ????.然后,您在这些边界内绘制一个新矩形,但是,由于剪辑,它不会清除旧矩形 -
现在,如果您将
drawRect和fill命令交换为graphicsBox(并调整drawRect以考虑线宽),您可以在它周围得到一个漂亮的正方形.现在,说了这么多,就我个人而言,我不会以这种方式使用getClipBounds,相反,它“应该”用于确定您是否真的需要采取行动(不要在clipBounds如果你不需要) -
我只是不以这种方式使用 getClipBounds,相反,它“应该”用于确定您是否真的需要采取行动(不要在clipBounds 如果你不需要) 好的,这是一个好建议!
标签: java swing awt graphics2d