理論...
好了,根據您的需要,我的第一個建議是把重點放在淡入和淡出單個圖像。如果你能夠理解如何做到這一點,那麼將三張圖像逐個(一個接一個地)褪色就簡單多了。
動畫是隨時間變化的錯覺。所以,你首先需要在一段時間內改變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