Почему при перерисовке мерцает прозрачное окно
Я пытаюсь создать окно (круг) сглаженной формы таким же образом, как и этот ответ, но он страдает той же проблемой: при перерисовке, как толькоpaintComponent
вызывается, окно исчезает, чтобы снова появиться после возврата вызова.
Я не знаю, связано ли это с моей конкретной машиной или с тем фактом, что я запускаю Ubuntu вместо Windows, в Xorg вместо Wayland или OpenJDK вместо Oracle. На другом компьютере, где все эти элементы отличаются от моего рабочего ПК, эта проблема не возникает.
Минимальный пример:
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
}
}
Что пробовал:
- JWindow вместо JFrame
- JComponent вместо JPanel
- Непрозрачная панель JPanel (мерцание прекращается, но прозрачные пиксели накапливаются почти до непрозрачности)
- Одинарная / двойная буферизация
- С / без AlwaysOnTop
- По умолчанию LAF системы и Nimbus
- С Bufferstrategy вместо paintComponent: кадр перестает быть прозрачным, но я, вероятно, не знаю, что делаю.