Java Swing - 半透明组件

时间:2011-02-13 07:13:20

标签: user-interface swing components transparency translucency

我最近问了一个关于半透明组件的问题,导致奇怪的伪像似乎没有正确更新。我收到的答案导致文物消失,但代价是半透明。

解决方案是针对每个半透明组件 - 也调用setOpaque(false)函数。通过这种方式,Swing知道需要重新绘制这些组件背后的背景。

然而,这是以我试图实现的半透明为代价的。它导致组件变得透明。

前提是:我正在为聊天客户端设计GUI,而功能请求则是具有背景。我通过遵循用于扩展JPanel类的代码片段成功地完成了后台工作,但后来我希望组件允许后台显示。在设置了它们的半透明度后,更新组件的残余显示在它们不应该存在的位置。我来到这里解决了问题,但现在我遇到了一个新问题。我们在这里。

所以,这就是我所推测的:

为每个所需组件调用setOpaque(false)函数而不设置半透明颜色无法达到我想要的效果。

- 设置半透明颜色而不调用setOpaque(false)允许半透明背景显示,但会导致伪影,让我回到正方形。

所以我需要在透明与无伪影之间的中间地带,以及半透明的工件。也就是说,我想要一个没有伪影的半透明背景(不完全透明)。

似乎我需要覆盖JFrame以使其重新绘制其所有组件,无论不透明度如何。除非有我遗漏的东西......这就是为什么我在这里!

谢谢!

(以下是原始问题的链接,附图片可供参考:Java Swing - Translucent Components causing Artifacts

1 个答案:

答案 0 :(得分:4)

一种选择是覆盖组件并自己绘制背景:

class TranslucentLabel extends JLabel {
    public TranslucentLabel(String text) {
        super(text);
        setOpaque(false);
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(new Color(255, 0, 0, 64));
        Insets insets = getInsets();
        g.fillRect(insets.left, insets.top, 
                getWidth() - insets.left - insets.right, 
                getHeight() - insets.top - insets.bottom);
        super.paintComponent(g);
    }
}

编辑:或者您可以将子组件的半透明背景颜色直接绘制到面板上,然后您不必覆盖组件:

class YourPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g.create();

        // Draw your background image here to g2d.

        g2d.setColor(new Color(255, 0, 0, 64));
        Area area = new Area();
        for (Component component : getComponents()) {
            area.add(new Area(component.getBounds()));
        }
        g2d.fill(area);
        g2d.dispose();
    }
}

这种方法存在缺点。如果某个组件有一个真正透明的部分(例如圆角边框),那么它的整个背景都会被着色。