半透明JFrame在帧重新打包时会留下渲染瑕疵

时间:2016-11-08 16:33:10

标签: java macos swing

当我在半透明的JFrame中更改JLabel的字体大小或内容时,然后在框架上调用pack(),可以看到之前内容的幻影版本。这只发生在macOS上。相同的代码在Windows上运行正常。

以下是发生的事情的放大示例: enter image description here

这是重现问题的代码;确保JFrame位于白色背景之上,以便更好地查看问题,然后点击" Bigger"和#34;较小的"按钮:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;

public class ScratchSpace {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Test Transparent Frame");
            frame.getRootPane().putClientProperty("apple.awt.draggableWindowBackground", true);
            frame.setUndecorated(true);
            frame.setBackground(new Color(0, 0, 0, 25));

            JPanel contentPane = new JPanel(new FlowLayout());
            contentPane.setOpaque(false);
            contentPane.setBackground(new Color(0, 0, 0, 25));

            JLabel label = new JLabel("Hello cruel world");
            label.setForeground(Color.WHITE);
            contentPane.add(label);

            contentPane.add(new JButton(new AbstractAction("Bigger") {
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setFont(label.getFont().deriveFont(label.getFont().getSize() + 1f));
                    frame.pack();
                }
            }));
            contentPane.add(new JButton(new AbstractAction("Smaller") {
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setFont(label.getFont().deriveFont(label.getFont().getSize() - 1f));
                    frame.pack();
                }
            }));

            frame.setContentPane(contentPane);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}

我尝试将所有组件更改为非透明组件。我打算在打包后重新验证内容窗格。我需要做些什么才能解决这个问题?

1 个答案:

答案 0 :(得分:0)

Swing不知道如何正确绘制透明背景,因此您需要自己进行绘画。

查看Background With Transparency以获取更多信息和一些解决方案。

但是要将帧设置为透明,您应该使用帧的setOpacity(...)方法。查看How to Create Translucent Windows;

上的Swing教程中的部分