I'm trying to make an anti-aliased shaped window (circle) in the same fashion as this answer, but that one suffers from the same issue: when repainting, as soon as paintComponent
is called, the window disappears, to re-appear after the call returns.
I don't know if this has to do with my particular machine, or the fact that I run Ubuntu instead of Windows, in Xorg instead of Wayland or OpenJDK instead of Oracle. On another computer where all these items are different from my work PC, this issue doesn't occur.
Minimum example:
import java.awt.*;
import java.util.concurrent.*;
import javax.swing.*;
public class AntialiasedWindow extends JPanel {
public static void main(String... args) {
SwingUtilities.invokeLater(() -> {
JFrame f = new JFrame();
f.setUndecorated(true);
f.setBackground(new Color(0, 0, 0, 0));
f.setContentPane(new AntialiasedWindow());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
public AntialiasedWindow() {
super(null);
setOpaque(false);
setPreferredSize(new Dimension(256, 256));
new Timer(250, e->repaint()).start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D)g).setRenderingHints(new RenderingHints(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g.setColor(Color.DARK_GRAY);
g.clearRect(0, 0, getWidth(), getHeight());
g.fillArc(0, 0, getWidth(), getHeight(), 85, 270);
//try { Thread.sleep(100); } catch (InterruptedException ignored) { } // Flickering gets worse with this
}
}
What I tried:
- JWindow instead of JFrame
- JComponent instead of JPanel
- Non-transparent JPanel (flicker stops but transparent pixels accumulate until near opaque)
- Single/double buffering
- With/without alwaysOnTop
- With default, System and Nimbus LAFs
- With Bufferstrategy instead of paintComponent: The frame stops being transparent, but I probably don't know what I'm doing.