问题
When spending a few minutes tweaking my desktop clock, I discovered a problem that I seem unable to resolve without help... I read some posts with similar problem but solutions did not work for me.
The clock (in typical java form with an Action Listener and Calendar) works just fine. The intended tweak: To set the Frame, ContentPane and Label backgrounds to transparent so only the time/text shows.
What happens is this: When the label background is transparent (or until it's opaque enough by setting the Alpha when Opaque is true), the underlying previous display stay's and does not clear.
To help figure this out, I put together the following code - the time and date Calendar stuff/etc is excluded. This code is just one version of many I tried with/without opaque, placement of calls...etc.
What does make a difference is use of the Action Listener - if the Action Listener is commented/deleted, label's display fine. Un-comment the Action Listener and the problem occurs.
See the images… Any help appreciated… Thanks!
fyi - below: the code sans imports and comments...
Screenshot of clock with black bg

Screenshot of the problem:

public class Clear extends JFrame {
private JPanel contentPane;
Color ppColor = new Color(255, 255, 0, 0); // r,g,b,a
Color lblColor = new Color(225, 200, 200, 0);
Color lbl2Color = new Color(225, 200, 200, 254);
int delay = 1000;
JLabel lblTime = new JLabel("TESTING");
JLabel lblTime2 = new JLabel("XXXXXX");
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
final Clear frame = new Clear();
frame.setVisible(true);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Clear() {
setUndecorated(true);
setBackground(ppColor);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(1680, 975, 128, 74);
contentPane = new JPanel();
contentPane.setBackground(ppColor);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
lblTime.setOpaque(true);
lblTime.setBackground(lblColor);
lblTime.setBounds(0, 0, 125, 30);
contentPane.add(lblTime);
lblTime2.setOpaque(true);
lblTime2.setBackground(lbl2Color);
lblTime2.setBounds(0, 33, 125, 16);
contentPane.add(lblTime2);
ActionListener myTaskPerformer = new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
lblTime.setText("Does it");
lblTime2.setText("work? ");
}
};
new Timer(delay, myTaskPerformer).start();
}
}
回答1:
Swing components do not work well with alpha based colors. They are either completely transparent or completely opaque.
If you specifiy that a component is isOpaque
, but fill it using a translucent (alpha) color, the repaint manager won't update the area behind the component and the Graphics
context will not be cleared properly. Remember, the Graphics
context is shared resource, so everything that was painted before your component will still be painted
You can take a look at Java Swing Graphical Glitches Dealing with Transparency and Images for more details.
However. The simplest solution would be to create a TranslucentPane
, the extends from something like JPanel
, make it transparent (not opaque), override it's paintComponent
method and paint the translucent (alpha) color from within it. Then add your label onto this.
Check out Performing Custom Painting and Painting in AWT and Swing for more details
来源:https://stackoverflow.com/questions/18092049/jlabel-retains-previous-text