Java Swing - Translucent Components causing Artifacts

寵の児 提交于 2019-12-04 04:21:02

问题


I'm currently working on a group project for a college course, and I've hit a bit of a stumbling block. The program we have decided to implement is a Peer-to-Peer chat client with a central server for storing and sharing usernames, etc. I've been assigned to do the GUI.

A friend jokingly suggested that I include "a flaming background!" So I decided to do just that, but to have a user-chosen background image. As is, only bits and pieces of the background image would be visible with all the components over top of it, so I decided to try to implement translucency.

This is where my problem lies:

When sending information from the input box to the chat window, or when navigating the friends list, or scrolling the chat window, strange artifacts are left behind. These artifacts are sometimes translucent "ghosts" of the Send button, sometimes part of the menu, or old text. It looks to me like the whole frame is not getting redrawn properly, but I'm not sure of how that works.

For components that implement JTextComponent, I'm setting their selection color to be a translucent color. For other components, I'm setting the background to be translucent. I have a function, setTranslucency(Component com) that looks at a component, sets its translucency depending on what it is, then sees if it is a container of some sort and sets the translucency of each item recursively.

Now, the way that I've found to fix this problem is to drag the window out of sight (such as minimizing or dragging the window off-screen and back).

So,

1) Is there a way to force the entire window to update like it does when I drag it off of the screen or minimize it?

or,

2) Am I doing it wrong in the first place? If so, how would I fix it?

Here's a picture for reference:

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


回答1:


You need to tell Swing that the components are translucent, so it does also paint the background when repainting the changed components. For this, your components have to return false from the isOpaque() method (this can be achieved by setOpaque(false) when no subclass overwrites isOpaque to do something else).

With this, it should work without any manual repainting of everything, as the other answers proposed. (I already did this once.)

Edit: The reason for this is that Swing uses an optimized repainting-algorithm, repainting only these components which really need repainting (for example, a JTextField after some input) or components in front of such ones, as long as they are opaque. When a component needing repainting is not opaque (= filling its whole space with non-translucent color), also repainting of the components behind them is necessary.




回答2:


myComponent.revalidate();
myComponent.repaint();
Not sure if it "force" the redraw, but it ask it to do it when possible.




回答3:


Try JFrame.repaint(). That should work. If you want custom designing of your JFrame then you will have to override paint() method of JFrame. Additionally, if you want each component to be custom designed you will have to override the paint() method of each of your GUI component. Couple of things to note:

  1. You do not have to call paint() for any GUI component. You only need to call repaint().
  2. In case you do the overriding of the other GUI components [JButton, JTextField...], you do not have to call their repaint() method. The parent Container's [JFrame, JPanel...] repaint() will do the job.


来源:https://stackoverflow.com/questions/4980246/java-swing-translucent-components-causing-artifacts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!