我可以制作一个JLabel
淡入淡出,但是如何让多个标签一个接一个地淡出?这是我目前的代码。
public void fadeIn(final JLabel jLabel) {
jLabelList.add(jLabel);
jLabelBackPanel.add(jLabelList.get(jLabelList.size() - 1));
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
int c = 0;
for(int i = 0; i < 255; i++) {
Thread.sleep(1000);
jLabel.setForeground(new Color(
jLabel.getForeground().getRed(),
jLabel.getForeground().getGreen(),
jLabel.getForeground().getBlue(),
c++));
}
return null;
}
}.execute();
}
上面的代码一次会淡出大约9个标签,然后是9个以上等等。我无法弄清楚如何让一个标签等到最后一个标签完成淡入。
答案 0 :(得分:3)
现在,可能有几种方法可以做到,但这基本上就是我提出来的......
首先,我创建了一个自定义标签,它使用javax.swing.Timer
从起始alpha值进展到目标alpha值(即0-1到淡入)。
对于这个标签,我添加了一个简单的waitFor
方法,该方法一直等到达到目标值。这是通过简单的对象监视器实现的。非常重要的是,永远不要在事件调度线程...
接下来,我使用我想要显示的文本创建了一系列这些标签,并将每个标签添加到输出中。
然后我开始单独Thread
并重复列表,淡化每个标签并使用waitFor
等待它显示...
import java.awt.AlphaComposite;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FadingLabels {
public static void main(String[] args) {
new FadingLabels();
}
public FadingLabels() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
final List<FadingLabel> labels = new ArrayList<>(25);
labels.add(new FadingLabel("A "));
labels.add(new FadingLabel("long "));
labels.add(new FadingLabel("time "));
labels.add(new FadingLabel("ago "));
labels.add(new FadingLabel("in "));
labels.add(new FadingLabel("a "));
labels.add(new FadingLabel("galaxy "));
labels.add(new FadingLabel("far, "));
labels.add(new FadingLabel("far, "));
labels.add(new FadingLabel("away"));
labels.add(new FadingLabel("..."));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
for (FadingLabel label : labels) {
frame.add(label);
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
for (FadingLabel label : labels) {
label.fadeIn();
label.waitFor();
}
}
}).start();
}
});
}
public class FadingLabel extends JLabel {
protected static final int TIME = 1000;
protected final Object fadeLock = new Object();
private float targetAlpha;
private float alpha = 0;
private Timer timer;
private long startTime;
private float fromAlpha;
public FadingLabel() {
init();
}
public FadingLabel(String text, Icon icon, int horizontalAlignment) {
super(text, icon, horizontalAlignment);
init();
}
public FadingLabel(String text, int horizontalAlignment) {
super(text, horizontalAlignment);
init();
}
public FadingLabel(String text) {
super(text);
init();
}
public FadingLabel(Icon image, int horizontalAlignment) {
super(image, horizontalAlignment);
init();
}
public FadingLabel(Icon image) {
super(image);
init();
}
protected void init() {
timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (alpha < 1f) {
long now = System.currentTimeMillis();
long diff = now - startTime;
float progress = (float) diff / (float) TIME;
float distance = targetAlpha - fromAlpha;
alpha = (float) (distance * progress);
alpha += fromAlpha;
if (alpha > 1f) {
timer.stop();
alpha = 1f;
}
} else {
alpha = 1f;
timer.stop();
}
repaint();
if (!timer.isRunning()) {
synchronized (fadeLock) {
fadeLock.notifyAll();
}
}
}
});
timer.setInitialDelay(0);
}
protected void fadeTo(float target) {
Runnable run = new Runnable() {
@Override
public void run() {
timer.stop();
fromAlpha = alpha;
targetAlpha = target;
if (targetAlpha != alpha) {
startTime = System.currentTimeMillis();
timer.start();
} else {
repaint();
}
}
};
if (EventQueue.isDispatchThread()) {
run.run();
} else {
EventQueue.invokeLater(run);
}
}
public void fadeIn() {
fadeTo(1f);
}
public void fadeOut() {
fadeTo(0f);
}
public void waitFor() {
if (EventQueue.isDispatchThread()) {
throw new IllegalStateException("Calling waitFor while within the EDT!");
}
synchronized (fadeLock) {
try {
fadeLock.wait();
} catch (InterruptedException ex) {
}
}
}
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
super.paint(g2d);
g2d.dispose();
}
}
}
动画部分使用固定的时间进度,而不是固定的增量。这允许动画更加可变,这取决于OS可能发生的过头。基本上这意味着动画每次都会在固定的时间段内进展