Java Swing - 透明组件引起的伪影问题

3
我目前正在参与一门大学课程的小组项目,遇到了一些困难。我们决定实现一个点对点聊天客户端,并使用中央服务器来存储和共享用户名等信息。我被分配负责GUI界面。
一个朋友开玩笑建议我加入“燃烧的背景!”,所以我决定这样做,但让用户选择背景图片。由于所有组件都在顶部,因此只有背景图像的部分会可见,因此我决定尝试实现半透明度。
这就是我的问题所在:
当将输入框中的信息发送到聊天窗口时,或者导航好友列表或滚动聊天窗口时,会留下奇怪的伪影。这些伪影有时是透明的“幽灵”发送按钮,有时是菜单的一部分,或旧文本。在我看来,整个框架没有得到正确地重绘,但我不确定它是如何工作的。
对于实现JTextComponent的组件,我将它们的选择颜色设置为半透明颜色。对于其他组件,我将背景设置为半透明。我有一个函数setTranslucency(Component com),它查看一个组件,根据它是什么设置其半透明度,然后查看它是否是某种容器并递归地设置每个项目的半透明度。
现在,我发现解决此问题的方法是将窗口拖出视线范围(例如最小化或将窗口拖到屏幕外并返回)。
所以,
1)是否有一种方法可以强制整个窗口更新,就像我将其拖到屏幕外或将其最小化时那样?
或者,
2)首先我做错了吗?如果是这样,我该如何修复它?
这是一个参考图片:

http://i.stack.imgur.com/4J9GJ.png

3个回答

3
你需要告诉Swing组件是半透明的,这样当重新绘制更改后的组件时,它也会绘制背景。为此,您的组件必须从isOpaque()方法返回false(当没有子类覆盖isOpaque以执行其他操作时,可以通过setOpaque(false)实现此目的)。
有了这个,应该可以在不手动重新绘制所有内容的情况下工作,就像其他答案所建议的那样。(我已经做过一次这样的事情。) 编辑:原因是Swing使用了优化的重绘算法,仅重绘确实需要重绘的组件(例如,JTextField在输入后)或位于其前面的组件,只要它们是不透明的。当需要重绘的组件不是不透明的(即用非半透明颜色填充其整个空间)时,还需要重绘它们后面的组件。

好的,我采纳了你的建议,并决定我的setTranslucency(..)函数在没有调用setOpaque(..)使它们正确重绘的情况下将事物设置为透明。手动设置组件后,它们显示为透明且不不透明,并正确更新。只是我粗心地运行了一遍框架中的组件,没有同时设置它们的不透明度。感谢您的帮助! - Jesse Strickland

0

myComponent.revalidate();
myComponent.repaint();
不确定它是否会“强制”重绘,但它会在可能的时候请求进行重绘。


嗯..JFrame类没有revalidate()函数。我需要为每个要重绘的组件调用revalidate()和repaint()函数吗?我可以这样做,而且我刚刚做了,但它没有起作用。你是说要做这两个(首先重新验证组件,然后重绘它)吗? - Jesse Strickland

0

尝试使用JFrame.repaint()。那应该可以工作。如果您想要自定义设计您的JFrame,那么您将不得不覆盖JFramepaint()方法。此外,如果您想要每个组件都进行自定义设计,则必须覆盖每个GUI组件的paint()方法。需要注意的几点:

  1. 您不必为任何GUI组件调用paint()。您只需要调用repaint()
  2. 如果您覆盖其他GUI组件[JButtonJTextField ...],则不必调用它们的repaint()方法。父级Container的[JFrameJPanel ...] repaint()将完成工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接