'Repainting a dirty region interfere with graphics2D clipbounds
In the following reproducer, I am reproducing what I'm seeing in the graphical interface.
I'd like to repaint a dirty region of a canvas (a JPanel), because a full repaint introduces more latencies.
However when the repaint (dirty rectangle) function is invoked, it causes some issues with nested Graphics2D objects. In particular
This code may mis-use clip bounds, but I wasn't expecting this "artifact" upon the creation of the sub (nested) graphic context.
What would be the proper way to deal with clips, nested graphic contexts, and the dirty region (or rectangle) repaint in this situation.
My intuition tells me the code should compute its shape without using the clipping area.
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);
}
}
}
EDIT by moving the fill above drawRect
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|



