2011-02-13 160 views
2

我最近问了一个关于半透明组件造成奇怪的文物看起来没有正确更新的问题。我收到的答案导致文物消失,但代价是半透明。Java Swing - 半透明组件

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

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

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

所以,这里是我所推测:

-Calling每个所需的组件setOpaque(假)功能,而不是设置一个半透明的颜色没有达到我想要的。

- 设置半透明颜色而不调用setOpaque(false)允许显示半透明背景,但会导致人为现象,让我回到原点。

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

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

谢谢!

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

回答

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

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

+0

我已经覆盖了JPanel类以允许自定义背景。具有背景的JPanel是我的框架的内容窗格。将overpade JPanel加入并强制不透明的组件重新绘制会更好吗?这样我就不必重写我使用的所有组件。 – 2011-02-13 14:41:43