我最近问了一个关于半透明组件的问题,导致奇怪的伪像似乎没有正确更新。我收到的答案导致文物消失,但代价是半透明。
解决方案是针对每个半透明组件 - 也调用setOpaque(false)函数。通过这种方式,Swing知道需要重新绘制这些组件背后的背景。
然而,这是以我试图实现的半透明为代价的。它导致组件变得透明。
前提是:我正在为聊天客户端设计GUI,而功能请求则是具有背景。我通过遵循用于扩展JPanel类的代码片段成功地完成了后台工作,但后来我希望组件允许后台显示。在设置了它们的半透明度后,更新组件的残余显示在它们不应该存在的位置。我来到这里解决了问题,但现在我遇到了一个新问题。我们在这里。
所以,这就是我所推测的:
为每个所需组件调用setOpaque(false)函数而不设置半透明颜色无法达到我想要的效果。
- 设置半透明颜色而不调用setOpaque(false)允许半透明背景显示,但会导致伪影,让我回到正方形。
所以我需要在透明与无伪影之间的中间地带,以及半透明的工件。也就是说,我想要一个没有伪影的半透明背景(不完全透明)。
似乎我需要覆盖JFrame以使其重新绘制其所有组件,无论不透明度如何。除非有我遗漏的东西......这就是为什么我在这里!
谢谢!
(以下是原始问题的链接,附图片可供参考:Java Swing - Translucent Components causing Artifacts)
答案 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();
}
}
这种方法存在缺点。如果某个组件有一个真正透明的部分(例如圆角边框),那么它的整个背景都会被着色。