简体   繁体   English

让JLabel消失

[英]Making a JLabel Fade away

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. 告知用户我正在使用jlabel。 I want this jlabel to display the message and fadeaway after a while. 我希望这个jlabel在一段时间后显示消息和后退。 I am using netbeans as my IDE. 我使用netbeans作为我的IDE。

Here is the architecture of my classes. 这是我班级的架构。

Abstract, GUI code 摘要,GUI代码

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 使Jlabel后退的线程

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 :) 谢谢 :)

PS I have set JLabel opaque true. PS我设置了JLabel opaque true。 Is that a problem? 那是问题吗? I want to display the label with its background colour initially and then make it fade away. 我想最初显示带有背景颜色的标签,然后逐渐消失。

If you are doing a lot of effects, you might use a swing animation library, like Trident . 如果你正在做很多效果,你可以使用像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. 但是,对于生产代码,我会将标签包装在一个容器中,该容器可以将alpha应用于它的子项,然后您可以以组件中立的方式淡入/淡出组件。 There is a component for this in one of the animation kits, but I cannot find it right now... 其中一个动画套件中有一个组件,但我现在找不到它......

I agree with Johannes that updating your UI from a different Thread is likely not to work well. 我同意Johannes的观点,即从不同的Thread更新UI可能不会很好。 There are mechanisms like SwingWorker and SwingUtilities.invokeLater that might solve your wrong-thread problems. 有一些机制,如SwingWorkerSwingUtilities.invokeLater ,可以解决您的错误线程问题。

The bigger problem I see, though, is that you're fighting with your JLabel over who paints it. 但是,我看到的更大的问题是,你正在与你的JLabel争论谁。 The JLabel is a normal component, and whenever its container is refreshed it repaints itself, in its usual colors. JLabel是一个普通的组件,每当它的容器被刷新时,它就会以其通常的颜色重新绘制。 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. 当你改变它的颜色时,标签会重新绘制自己,或者你可以使用update()repaint()强制重绘,我会忘记它。

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, ie 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. 只有标签绘画代码在绘图前愚蠢地忘记设置颜色时,您的方法才有效。

probably you could try the API method... 可能你可以试试API方法......

given with com.sun.awt.AWTUtilities tricks! 用com.sun.awt.AWTUtilities技巧给出! :D :d

enter link description here I was also looking for a nice way to change the contents of a JLabel by fading out and in again. 在这里输入链接描述我也在寻找一种通过淡出和再次更改JLabel内容的好方法。 The following code works quite nicely. 以下代码非常好用。 It has no code for fading an icon yet. 它还没有用于淡化图标的代码。 But this should not be too hard. 但这不应该太难。 Please note, that it needs the current version of the TimingFramework (timingframework-swing-4.1) to run. 请注意,它需要运行当前版本的TimingFramework(timingframework-swing-4.1)。

I hope it might be useful. 我希望它可能有用。

import org.jdesktop.core.animation.timing.Animator;
import org.jdesktop.core.animation.timing.TimingSource;
import org.jdesktop.core.animation.timing.TimingTargetAdapter;
import org.jdesktop.swing.animation.timing.sources.SwingTimerTimingSource;

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.TimeUnit;

public class FadingLabel extends JLabel {
    protected Animator animator;
    protected String newLabelText;

    public FadingLabel(String s, Icon icon, int i) {
        super(s, icon, i);
        initAnimator();
    }

    public FadingLabel(String s, int i) {
        super(s, i);
        initAnimator();
    }

    public FadingLabel(String s) {
        super(s);
        initAnimator();
    }

    public FadingLabel(Icon icon, int i) {
        super(icon, i);
        initAnimator();
    }

    public FadingLabel(Icon icon) {
        super(icon);
        initAnimator();
    }

    public FadingLabel() {
        super();
        initAnimator();
    }

    protected void initAnimator() {
        final TimingSource ts = new SwingTimerTimingSource();
        Animator.setDefaultTimingSource(ts);
        ts.init();
        animator = new Animator.Builder().setDuration(250, TimeUnit.MILLISECONDS).setRepeatCount(2).setRepeatBehavior(Animator.RepeatBehavior.REVERSE).setStartDirection(Animator.Direction.BACKWARD).addTarget(new TimingTargetAdapter() {

            @Override
            public void repeat(Animator source) {
                setText(newLabelText);
            }

            @Override
            public void timingEvent(Animator animator, double fraction) {
                int alpha = new Double(255 * fraction).intValue();
                setForeground(new Color(getForeground().getRed(), getForeground().getGreen(), getForeground().getBlue(), alpha));
                repaint();
            }

        }).build();
    }


    @Override
    public void setText(String s) {
        if (animator != null && !animator.isRunning()) {
            newLabelText = s;
            animator.start();
        } else {
            super.setText(s);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM