理论...
好了,根据您的需要,我的第一个建议是把重点放在淡入和淡出单个图像。如果你能够理解如何做到这一点,那么将三张图像逐个(一个接一个地)褪色就简单多了。
动画是随时间变化的错觉。所以,你首先需要在一段时间内改变alpha
的状态。因为Swing既是单线程的,也不是线程安全的,所以这给你一个基本的选择,一个Swing Timer
。
这会在Event Dispatching Thread的上下文中定期生成更新,这些触发器可以安全地用于Swing并从内部更新UI。
由于在硬件上的差异(和操作系统的),我会避免固定利率褪色(即,当你申请一个固定delta
到alpha
和重复,直到你达到你的target
)。这种方法会在不同的系统上产生不希望的结果。
根据我的经验,基于时间的解决方案通常会产生更一致的结果。基于时间的方法指出,动画将在指定的时间段内运行,在Timer
的每个勾号上,我们计算数量进展并将其应用于我们的状态(我们知道我们需要从0-1开始淡入图像,所以很容易计算基于进程)
器的基本实现
这听起来都在实践中找到状态......,但我们究竟要如何应用它。因为解决方案并不总是很简单,所以我会专注于制作专门的课程来执行操作。
public class FadePane extends JPanel {
private BufferedImage source;
private Timer timer;
private float alpha = 1.0f;
private int duration = 2000; // 2 seconds
private Long startTime;
private boolean fadeOut = false;
private FadeListener fadeListener;
public FadePane(BufferedImage source) {
this.source = source;
timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime == null) {
startTime = System.currentTimeMillis();
fadeStarted();
}
long diff = System.currentTimeMillis() - startTime;
alpha = (float)diff/(float)duration;
if (alpha > 1.0) {
timer.stop();
alpha = 1.0f;
fadeCompleted();
}
if (fadeOut) {
alpha = 1.0f - alpha;
}
repaint();
}
});
}
public void setFadeListener(FadeListener listener) {
fadeListener = listener;
}
public boolean isFadeOut() {
return fadeOut;
}
protected void fadeStarted() {
if (fadeListener != null) {
fadeListener.fadeStarted(this);
}
}
protected void fadeCompleted() {
if (fadeListener != null) {
fadeListener.fadeCompleted(this);
}
}
public void setSource(BufferedImage img) {
source = img;
}
public void reset() {
timer.stop();
alpha = 0;
startTime = null;
}
public void fadeIn() {
reset();
fadeOut = false;
timer.start();
}
public void fadeOut() {
reset();
fadeOut = true;
timer.start();
}
@Override
public Dimension getPreferredSize() {
return source == null ? new Dimension(200, 200) : new Dimension(source.getWidth(), source.getHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
int x = (getWidth() - source.getWidth())/2;
int y = (getHeight() - source.getHeight())/2;
g2d.drawImage(source, x, y, this);
g2d.dispose();
}
}
FadePane
的需要source
图像,并且根据调用该方法时,会褪色它或缩小历时2秒。
您可以通过简单地改变通过setSource
方法source
图像和褪色或缩小的新形象,这取决于你以后想要的结果重复使用FadePane
。
FadePane
的还提供了一个观察者,当淡变操作开始并完成该通知...
public interface FadeListener {
public void fadeStarted(FadePane pane);
public void fadeCompleted(FadePane pane);
}
这可以被用于改变用户界面的状态(禁用/启用的功能),其以及当您想要切换图像时
Runnable示例...
这个例子简单允许用户褪色相同的图像和缩小,但它不会是难以产生图像的List
其中它们通过FadeListener
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
BufferedImage source = ImageIO.read(...);
FadePane fadePane = new FadePane(source);
JButton btn = new JButton("Fade");
btn.addActionListener(new ActionListener() {
private boolean fadeOut = true;
@Override
public void actionPerformed(ActionEvent e) {
if (fadeOut) {
fadePane.fadeOut();
} else {
fadePane.fadeIn();
}
fadeOut = !fadeOut;
}
});
fadePane.setFadeListener(new FadeListener() {
@Override
public void fadeStarted(FadePane pane) {
btn.setEnabled(false);
}
@Override
public void fadeCompleted(FadePane pane) {
// Set next image and start the
// fade process again
btn.setEnabled(true);
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(fadePane);
frame.add(btn, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public interface FadeListener {
public void fadeStarted(FadePane pane);
public void fadeCompleted(FadePane pane);
}
public class FadePane extends JPanel {
private BufferedImage source;
private Timer timer;
private float alpha = 1.0f;
private int duration = 2000; // 2 seconds
private Long startTime;
private boolean fadeOut = false;
private FadeListener fadeListener;
public FadePane(BufferedImage source) {
this.source = source;
timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (startTime == null) {
startTime = System.currentTimeMillis();
fadeStarted();
}
long diff = System.currentTimeMillis() - startTime;
alpha = (float)diff/(float)duration;
if (alpha > 1.0) {
timer.stop();
alpha = 1.0f;
fadeCompleted();
}
if (fadeOut) {
alpha = 1.0f - alpha;
}
repaint();
}
});
}
public void setFadeListener(FadeListener listener) {
fadeListener = listener;
}
protected void fadeStarted() {
if (fadeListener != null) {
fadeListener.fadeStarted(this);
}
}
protected void fadeCompleted() {
if (fadeListener != null) {
fadeListener.fadeCompleted(this);
}
}
public void setSource(BufferedImage img) {
source = img;
}
public void reset() {
timer.stop();
alpha = 0;
startTime = null;
}
public boolean isFadeOut() {
return fadeOut;
}
public void fadeIn() {
reset();
fadeOut = false;
timer.start();
}
public void fadeOut() {
reset();
fadeOut = true;
timer.start();
}
@Override
public Dimension getPreferredSize() {
return source == null ? new Dimension(200, 200) : new Dimension(source.getWidth(), source.getHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
int x = (getWidth() - source.getWidth())/2;
int y = (getHeight() - source.getHeight())/2;
g2d.drawImage(source, x, y, this);
g2d.dispose();
}
}
}
改变你的意思是类似[this](https://stackoverflow.com/questions/20346661/java-fade-in-and-out-of-images/20347600#20347600)和[this](https://stackoverflow.com /问题/ 34119221/Java的渐入和出两个jpanels-在最相同的时间/ 34123681#34123681) – MadProgrammer