2

我最近问了一个关于半透明组件的问题,它会导致看起来没有正确更新的奇怪伪影。我收到的答案导致工件消失,但以半透明为代价。

解决方案是——对于每个半透明组件——也调用 setOpaque(false) 函数。这样,Swing 知道它需要重新绘制这些组件背后的背景。

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

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

所以,这是我推测的:

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

- 设置半透明颜色而不调用 setOpaque(false) 可以显示半透明背景,但会导致伪影,让我回到第一格。

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

似乎我将需要覆盖 JFrame 以使其重新绘制其所有组件,而不管不透明度如何。除非我缺少什么……这就是我在这里的原因!

谢谢!

(这里是原始问题的链接,附图片供参考:Java Swing - Translucent Components Making Artifacts

4

1 回答 1

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();
    }
}

这种方法有一个缺点。如果组件有真正透明的部分(例如圆形边框),则其整个背景将被着色。

于 2011-02-13T10:47:56.330 回答