【问题标题】:Java Swing - Translucent ComponentsJava Swing - 半透明组件
【发布时间】:2011-06-26 08:38:24
【问题描述】:

我最近问了一个关于半透明组件的问题,该组件导致奇怪的伪影似乎无法正确更新。我收到的答案导致工件消失,但以半透明为代价。

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

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

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

所以,这是我的推测:

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

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

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

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

谢谢!

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

【问题讨论】:

    标签: user-interface swing components transparency translucency


    【解决方案1】:

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

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

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

    【讨论】:

    • 我已经覆盖了 JPanel 类以允许自定义背景。带有背景的 JPanel 是我框架的内容窗格。无论如何添加到覆盖的 JPanel 并强制不透明组件重绘会更好吗?这样我就不必覆盖我正在使用的所有组件。
    • 我添加了一种替代方法,尽管它可能并不理想。
    • 嘿,它有效! img408.imageshack.us/img408/186/help3i.png 非常感谢您的帮助。我不应该有任何圆角要处理,真的,所以这一切都很好。如果我这样做了,for 循环上的一点选择性会很适合我,很可能。
    猜你喜欢
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多