我正在嘗試使陣列元素以隨機時間段顯示在不同位置(具有淡入和淡出效果)。到目前為止我所做的,制作了一系列文本標簽。進行了過渡。但我不知道如何創建一個 for 回圈,以在 JFrame 的不同位置顯示其他標簽。而且它們不應該同時出現,而是一個接一個地出現。
請幫幫忙?
這是我的代碼:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class FadingLabel {
private int alpha = 255;
private int increment = -5;
public JLabel label = new JLabel("Fading Label");
public JLabel label2 = new JLabel("Fading Label 2");
public JLabel label3 = new JLabel("Fading Label 3");
public JLabel label4 = new JLabel("Fading Label 4");
JLabel labels[] = new JLabel[]{ label, label2, label3 };
Dimension size = label.getPreferredSize();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FadingLabel().makeUI();
}
});
}
public void makeUI() {
new Timer(80, new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i <= 3; i ){
alpha = increment;
if (alpha >= 255) {
alpha = 255;
increment = -increment;
}
if (alpha <= 0) {
try {
Thread.sleep(100);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
alpha = 0;
increment = -increment;
}
label3.setForeground(new Color(0, 0, 0, alpha));
label3.setLocation(50,60);
}
}
}).start();
JFrame frame = new JFrame();
frame.add(labels[2]);
frame.setPreferredSize(new Dimension(700,500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
uj5u.com熱心網友回復:
影片很難,好的影片更難。
步進影片(就像您所做的那樣)并不是特別有效,并且可能會受到中斷(來自作業系統或系統的其他部分)的影響,并且難以擴展。
相反,您應該瞄準基于“持續時間”的影片。在給定的時間段內發生某些事情時,通過這種方式,您可以更輕松地丟掉無法渲染的幀。
一個難以繞過的概念是,您不能在 GUI 的“主執行緒”中執行長時間運行或阻塞的操作,但也不能從“主執行緒”外部更新 UI(在 Swing 中)稱為事件調度執行緒)。
因此,相反,您需要某種方式監視每個標簽,并在它淡出時開始下一個標簽淡入。這就是一個好的觀察者模式(又名偵聽器)的用武之地。
import java.awt.AlphaComposite;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.Instant;
import java.util.EventListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private FadableLabel[] labels = new FadableLabel[]{
new FadableLabel("A long time ago"),
new FadableLabel("in a galaxy far, far, away..."),
new FadableLabel("It is a period of civil war."),
new FadableLabel("Rebel spaceships striking from a hidden base,"),
new FadableLabel("have won their first victory against the evil Galactic Empire"),
new FadableLabel("During the battle,"),
new FadableLabel("Rebel spies managed to steal secret plans to the Empire's ultimate weapon,"),
new FadableLabel("the Death Star")
};
private int labelIndex = -1;
public TestPane() {
setBorder(new EmptyBorder(50, 50, 50, 50));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (FadableLabel label : labels) {
label.setAlpha(0);
add(label, gbc);
}
}
@Override
public void addNotify() {
super.addNotify();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
nextLabel();
}
});
}
@Override
public void removeNotify() {
super.removeNotify();
}
protected void nextLabel() {
labelIndex ;
if (labelIndex >= labels.length) {
return;
}
FadableLabel label = labels[labelIndex];
label.addFadableLableListener(new FadableLableListener() {
@Override
public void didFadeLabelIn(FadableLabel label) {
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.fadeOut();
}
});
timer.setRepeats(false);
timer.start();
}
@Override
public void didFadeLabelOut(FadableLabel label) {
label.removeFadableLableListener(this);
nextLabel();
}
});
label.fadeIn();
}
}
public interface FadableLableListener extends EventListener {
public void didFadeLabelIn(FadableLabel label);
public void didFadeLabelOut(FadableLabel label);
}
public class FadableLabel extends JLabel {
private float alpha = 1.0f;
private Timer fadeTimer;
private FadeRange fadeRange;
private Instant fadeStartedAt;
private Duration desiredFadeTime = Duration.ofMillis(1000);
public FadableLabel() {
super();
}
public FadableLabel(String text) {
super(text);
}
public void addFadableLableListener(FadableLableListener listener) {
listenerList.add(FadableLableListener.class, listener);
}
public void removeFadableLableListener(FadableLableListener listener) {
listenerList.remove(FadableLableListener.class, listener);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
protected void fireDidFadeOut() {
FadableLableListener[] listeners = listenerList.getListeners(FadableLableListener.class);
if (listeners.length == 0) {
return;
}
for (FadableLableListener listener : listeners) {
listener.didFadeLabelOut(this);
}
}
protected void fireDidFadeIn() {
FadableLableListener[] listeners = listenerList.getListeners(FadableLableListener.class);
if (listeners.length == 0) {
return;
}
for (FadableLableListener listener : listeners) {
listener.didFadeLabelIn(this);
}
}
protected void stopFadeTimer() {
if (fadeTimer != null) {
fadeStartedAt = null;
fadeTimer.stop();
}
}
protected void startFadeTimer() {
if (fadeRange == null) {
throw new RuntimeException("Fade range can not be null when starting animation");
}
fadeStartedAt = Instant.now();
fadeTimer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Duration runTime = Duration.between(fadeStartedAt, Instant.now());
double progress = Math.min(1d, Math.max(0d, runTime.toMillis() / (double) desiredFadeTime.toMillis()));
setAlpha(fadeRange.valueAt(progress));
if (progress >= 1.0) {
stopFadeTimer();
if (getAlpha() >= 1.0) {
fireDidFadeIn();
} else {
fireDidFadeOut();
}
}
}
});
fadeTimer.start();
}
public void fadeIn() {
stopFadeTimer();
if (alpha < 1.0) {
fadeRange = new FadeRange(alpha, 1.0f);
startFadeTimer();
}
}
public void fadeOut() {
stopFadeTimer();
if (alpha > 0.0) {
fadeRange = new FadeRange(alpha, 0);
startFadeTimer();
}
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
super.paintComponent(g2d);
g2d.dispose();
}
protected class FadeRange {
private float from;
private float to;
public FadeRange(float from, float to) {
this.from = from;
this.to = to;
}
public float getFrom() {
return from;
}
public float getTo() {
return to;
}
public float getDistance() {
return getTo() - getFrom();
}
public float valueAt(double progress) {
double distance = getDistance();
double value = distance * progress;
value = getFrom();
return (float) value;
}
}
}
}
現在,到你的下一個問題。一個糟糕的方法可能是使用“絕對”或“空”布局
更好的選擇是使用類似GridBagLayout(并且可能EmptyLayout)的東西并隨機Insets化GridBagConstraints. 或者,您可以創建自己的布局管理器來為您完成這項作業
有關一些想法,請參閱JFrame 中被空白部分阻止的絕對定位圖形 JPanel和將 JPasswordField 移動到絕對位置
一個克雷例子
When I say animation is "hard" and it can become complicated very fast, I'm not kidding. To that I end I wrote myself an animation library, which does all the things I keep finding myself doing.
https://github.com/RustyKnight/SuperSimpleSwingAnimationFramework
So, this is an example, based on the above library, which moves the label across a random range, while it's been faded in/out. Without the above library, this kind of work would be, a lot.
import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.util.EventListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import org.kaizen.animation.Animatable;
import org.kaizen.animation.AnimatableAdapter;
import org.kaizen.animation.DefaultAnimatableDuration;
import org.kaizen.animation.curves.AnimationCurve;
import org.kaizen.animation.curves.Curves;
import org.kaizen.animation.ranges.AnimatableRange;
import org.kaizen.animation.ranges.FloatAnimatableRange;
import org.kaizen.animation.ranges.FloatRange;
import org.kaizen.animation.ranges.PointAnimatableRange;
import org.kaizen.animation.ranges.PointRange;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private String[] textValues = new String[] {
"A long time ago",
"in a galaxy far, far, away...",
"It is a period of civil war.",
"Rebel spaceships striking from a hidden base,",
"have won their first victory against the evil Galactic Empire",
"During the battle,",
"Rebel spies managed to steal secret plans to the Empire's ultimate weapon,",
"the Death Star"
};
private int labelIndex = -1;
// You'd need two if you wanted to do cross fades
private FadableLabel label;
private Random rnd = new Random();
// The desired duration of the animation, 1 second for fade in,
// 1 second for fade out and 1 second for delay between swicthing state
private Duration desiredDuration = Duration.ofSeconds(3);
// The desired animation curve (ease in/out)
private AnimationCurve curve = Curves.SINE_IN_OUT.getCurve();
// The movement animator
private DefaultAnimatableDuration animator;
public TestPane() {
setLayout(null);
label = new FadableLabel();
label.setAlpha(0);
add(label);
label.addFadableLableListener(new FadableLableListener() {
@Override
public void didFadeLabelIn(FadableLabel label) {
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.fadeOut();
}
});
timer.setRepeats(false);
timer.start();
}
@Override
public void didFadeLabelOut(FadableLabel label) {
nextText();
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 400);
}
@Override
public void addNotify() {
super.addNotify();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
nextText();
}
});
}
@Override
public void removeNotify() {
stopAnimation();
super.removeNotify();
}
protected void stopAnimation() {
if (animator != null) {
animator.stop();
}
}
protected void nextText() {
stopAnimation();
labelIndex ;
if (labelIndex >= textValues.length) {
return;
}
String text = textValues[labelIndex];
label.setText(text);
label.setSize(label.getPreferredSize());
// Randomise the from and to locations
Point from = new Point(rnd.nextInt(getWidth() - label.getSize().width), rnd.nextInt(getHeight() - label.getSize().height));
Point to = new Point(rnd.nextInt(getWidth() - label.getSize().width), rnd.nextInt(getHeight() - label.getSize().height));
// Generate the range
PointRange range = new PointRange(from, to);
// Setup an animatable range of the PointRange
animator = new PointAnimatableRange(range, desiredDuration, curve, new AnimatableAdapter<Point>() {
@Override
public void animationChanged(AnimatableRange<Point> animatable) {
label.setLocation(animatable.getValue());
}
});
label.setLocation(from);
// Make it so
label.fadeIn();
animator.start();
}
}
public interface FadableLableListener extends EventListener {
public void didFadeLabelIn(FadableLabel label);
public void didFadeLabelOut(FadableLabel label);
}
public class FadableLabel extends JLabel {
private FloatAnimatableRange animator;
private AnimationCurve curve = Curves.SINE_IN_OUT.getCurve();
private Duration desiredDuration = Duration.ofSeconds(1);
private float alpha = 1.0f;
public FadableLabel() {
super();
}
public FadableLabel(String text) {
super(text);
}
public void addFadableLableListener(FadableLableListener listener) {
listenerList.add(FadableLableListener.class, listener);
}
public void removeFadableLableListener(FadableLableListener listener) {
listenerList.remove(FadableLableListener.class, listener);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
protected void fireDidFadeOut() {
FadableLableListener[] listeners = listenerList.getListeners(FadableLableListener.class);
if (listeners.length == 0) {
return;
}
for (FadableLableListener listener : listeners) {
listener.didFadeLabelOut(this);
}
}
protected void fireDidFadeIn() {
FadableLableListener[] listeners = listenerList.getListeners(FadableLableListener.class);
if (listeners.length == 0) {
return;
}
for (FadableLableListener listener : listeners) {
listener.didFadeLabelIn(this);
}
}
protected void stopFadeTimer() {
if (animator != null) {
animator.stop();
}
}
protected void startFadeTimer(FloatRange range, AnimationListener animationListener) {
stopFadeTimer();
animator = new FloatAnimatableRange(range, desiredDuration, curve, new AnimatableAdapter<Float>() {
@Override
public void animationChanged(AnimatableRange<Float> animatable) {
alpha = animatable.getValue();
repaint();
}
@Override
public void animationCompleted(Animatable animator) {
if (animationListener != null) {
animationListener.animationCompleted();
}
}
});
animator.start();
}
public void fadeIn() {
stopFadeTimer();
startFadeTimer(new FloatRange(alpha, 1f), new AnimationListener() {
@Override
public void animationCompleted() {
fireDidFadeIn();
}
});
}
public void fadeOut() {
stopFadeTimer();
startFadeTimer(new FloatRange(alpha, 0f), new AnimationListener() {
@Override
public void animationCompleted() {
fireDidFadeOut();
}
});
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
super.paintComponent(g2d);
g2d.dispose();
}
protected interface AnimationListener {
public void animationCompleted();
}
}
}
The library is based on Netbeans, it wouldn't be hard to just extract the source into some other IDE.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/349025.html
