我的问题是如何使第一张图像消失,然后第二张图像消失,然后第三张图像出现。我尝试到处改变,但没有任何效果。一切立刻就出来了。有人可以告诉我我应该改变哪一部分吗?
import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class FadeOutImage2 extends JPanel implements ActionListener{
Image myImage = new ImageIcon("C:\\Users\\NUR\\Pictures\\FLOWER1.jpg").getImage();
Image myImage2 = new ImageIcon("C:\\Users\\NUR\\Pictures\\FLOWER2.jpg").getImage();
Image myImage3 = new ImageIcon("C:\\Users\\NUR\\Pictures\\FLOWER3.jpg").getImage();
Timer timer = new Timer (50, this); //setting time to fade
private float alpha = 1f; //alpha value on channel
public FadeOutImage2(){
timer.start();
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
Graphics2D g2d2 = (Graphics2D)g;
Graphics2D g2d3 = (Graphics2D)g;
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha));
g2d2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha));
g2d3.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha));
g2d.drawImage(myImage, 10,10, null); //coordinate
g2d2.drawImage(myImage2, 10,10, null);
g2d3.drawImage(myImage3, 10,10, null);
}
public void actionPerformed(ActionEvent e){
alpha += -0.01f;
if(alpha<=0){
alpha=0;
timer.stop();}
repaint();
}
public static void main(String[] args){
JFrame frame = new JFrame("Fade Out");
frame.add(new FadeOutImage2());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1500,1500);
frame.setVisible(true);
}
}
最佳答案
理论...
好的,根据您的要求,我的第一个建议是专注于单个图像的淡入和淡出。如果您能理解如何做到这一点,那么将三个图像淡入淡出(一个接一个)就会简单得多。
动画是随时间变化的幻觉。因此,您首先需要以某种方式更改 alpha
的状态经过一段时间。由于 Swing 既是单线程的又不是线程安全的,因此您只有一个基本选择:Swing Timer
.
这会定期生成更新,这些更新是在事件调度线程的上下文中触发的,从而可以安全地与 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 秒内淡入或淡出图像。
您可以重复使用 FadePane
只需更改 source
图片来自setSource
方法并使新图像淡入或淡出,具体取决于您想要的结果。
FadePane
还提供了一个观察者,当淡入淡出操作开始和完成时会收到通知...
public interface FadeListener {
public void fadeStarted(FadePane pane);
public void fadeCompleted(FadePane pane);
}
这可用于更改 UI 的状态(禁用/启用功能)以及在需要时切换图像
可运行示例...
这个简单的示例允许用户淡入淡出相同的图像,但生成 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();
}
}
}
关于java - 如何在JPanel中让3张图片淡入淡出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47610086/