I’m writing an application that do some task and inform user upon successful completion of the task. To inform user I am using a jlabel. I want this jlabel to display the message and fadeaway after a while. I am using netbeans as my IDE.
Here is the architecture of my classes.
Abstract, GUI code
abstract class Admin extends JFrame{
protected static jlabel lbl_message= new jlabel("some text");
// other functions and variables
abstarct protected void performButtonClickAction();
}
Class for implementing abstract functions and providing other functionalities.
final class AdminActionPerformer extends Admin{
final public void performButtonClickAction(){
// code for doin the task
if(task is successful){
new Thread(new Fader(Admin.lbl_message)).start();
}
}
public static void main(String[] args) {
new AdminActionPerformer().setVisible(true);
}
}
Thread for making the Jlabel fadeaway
class Fader implements Runnable{
javax.swing.JLabel label;
Color c;
Fader(javax.swing.JLabel label){
this.label=label;
c=label.getBackground();
}
public void run() {
int alpha=label.getGraphics().getColor().getAlpha()-5;
while(alpha>0){
System.out.println(alpha);
alpha-=25;
label.getGraphics().setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha));
label.repaint();
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
Logger.getLogger(Fader.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
But the label does not fadeaway. What am I doing wrong here? Thank you 🙂
P.S. I have set JLabel opaque true. Is that a problem? I want to display the label with its background colour initially and then make it fade away.
I agree with Johannes that updating your UI from a different Thread is likely not to work well. There are mechanisms like
SwingWorkerandSwingUtilities.invokeLaterthat might solve your wrong-thread problems.The bigger problem I see, though, is that you’re fighting with your JLabel over who paints it. The JLabel is a normal component, and whenever its container is refreshed it repaints itself, in its usual colors. This is a case of “whoever paints last, wins.”
Alternative suggestion: Why not just fiddle with the label’s color attribute? If you make the foreground color approach the background color, it will be seen to be fading. The label will either repaint itself when you change its color, or you can force a repaint using
update()orrepaint(), I keep forgetting which.EDIT
I think I see the real reason this doesn’t work. You’re setting the label’s graphics context’s color. This has no effect! Any component that paints parts of itself will set the color, i.e. dip its brush in ink, immediately before drawing anything. And of course the color it sets up for drawing its character glyphs is the original label color. Your method would only work if the label painting code foolishly forgot to set the color before drawing.