使用 JWindow 双缓冲

Double buffering with a JWindow

我正在尝试对透明 JWindow 进行双重缓冲,但似乎使用的技术无效(不同的循环值相互重叠)。

public final class Overlay extends JWindow {

    public static final Color TRANSPARENT = new Color(0, true);
    public static Font standardFont = null;

    public static Overlay open() {
        return new Overlay();
    }

    private Overlay() {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setAlwaysOnTop(true);
        setBounds(0, 0, screenSize.width, screenSize.height);
        setBackground(TRANSPARENT);
    }

    @Override
    public void paint(Graphics g) {
        BufferedImage bufferedImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g2d = bufferedImage.createGraphics();
        paintUs(g2d);

        Graphics2D g2dComponent = (Graphics2D) g;
        g2dComponent.drawImage(bufferedImage, null, 0, 0);
    }

    private void paintUs(Graphics2D g) {
        int height = 420;
        int x = 20;
        g.setColor(TRANSPARENT);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setFont(standardFont == null ? standardFont = g.getFont().deriveFont(17f) : standardFont);
        for (Plugin plugin : Abendigo.plugins()) {
            g.setColor(Abendigo.plugins().isEnabled(plugin) ? Color.GREEN : Color.RED);
            g.drawString(plugin.toString(), x + 5, getHeight() - height);
            height += 20;
        }
        height += 20;
        g.setColor(Color.YELLOW);
        g.drawString("Cycle: " + Abendigo.elapsed + "ms", x, getHeight() - height);
    }

    @Override
    public void update(Graphics g) {
        paint(g);
    }

}

为什么!?!? Swing 组件已经是双缓冲的了吗?简单地创建一个自定义组件,从 JPanel 之类的东西扩展,覆盖它的 paintComponent 并在那里执行您的自定义绘画。确保将组件设置为透明 (setOpaque(false)) 并将其添加到 JWindow

的实例

有关详细信息,请参阅 Painting in AWT and Swing and Performing Custom Painting

您面临的一个直接问题是 Swing windows 已经附加了一系列复合组件(JRootPanecontentPane 等),所有其中的内容可以独立于您 window 进行绘制,这意味着它们可以覆盖您一直试图直接绘制到 window 的所有内容。相反,避免直接绘制到 window 并改用自定义组件。