tags:

views:

73

answers:

3

Hi, 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.

+2  A: 

I agree with Johannes that updating your UI from a different Thread is likely not to work well. There are mechanisms like SwingWorker and SwingUtilities.invokeLater that 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() or repaint(), 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.

Carl Smotricz
+4  A: 

If you are doing a lot of effects, you might use a swing animation library, like Trident. Here's how to fade out a label.

   JLabel label = ....;
   Timeline timeline = new Timeline(label);
   timeline.addPropertyToInterpolate("background", label.getBackground(), 
     new Color(label.getBackground().getRGB(), true));
   timeline.addPropertyToInterpolate("foreground", label.getForeground(), 
      new Color(label.getForeground().getRGB(), true));
   timeline.play();

EDIT: Updated to change the foreground/background colors, which are properties on label. However, for production code I would wrap the label in a container that can apply alpha to it's children, then you can fade in/out a component in a component-neutral way. There is a component for this in one of the animation kits, but I cannot find it right now...

mdma
And that works even though a label has no such thing as an opacity property?
Joey
Even though there is no such property on the label, using Trident is the simpleset way to accomplish this.
eugener
+1  A: 

Here's an example using alpha transparency to fade a text message.

trashgod