Swing特效-漸顯效果
能不能讓Swing控件也有漸隱和漸顯的效果呢,答案當然是肯定的。這里也要說明一下Swing這些高級特性的實現機制。Swing里的特效不是靠調用一個方法就可以實現的,而是要我們自己去寫這些方法,主要還是重寫Swing的public void paint(Graphics g)方法。Swing的一切樣式說白了都是利用paint方法“畫”上去的,所以說Swing比較慢,當然如果我們考慮Swing主要用來做客戶端顯示的,稍微慢一點也是可以接受的。
下面說Swing的控件的漸顯效果,我想原理還是蠻簡單的,不斷改變控件的透明度即可。即g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); 下面是完整的控件代碼,該控件您可以認為是一個類似JPanel的容器:
package com.zakisoft.frame;
import java.awt.AlphaComposite;
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.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Timer;
/**
* @author zakisoft.com
*
*/
public class ZPanel extends javax.swing.JComponent implements ActionListener {
private static final long serialVersionUID = 1L;
private BufferedImage image;
private static final int ANIMATION_FRAMES = 100;
private static final int ANIMATION_INTERVAL = 10;
private int frameIndex;
// 時鐘
private Timer timer;
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
private int imgWidth;
private int imgHeight;
public int getImgWidth() {
return imgWidth;
}
public void setImgWidth(int imgWidth) {
this.imgWidth = imgWidth;
}
public int getImgHeight() {
return imgHeight;
}
public void setImgHeight(int imgHeight) {
this.imgHeight = imgHeight;
}
public ZPanel() {
}
public void setImagePath(String imgPath) {
// 該方法不推薦使用,該方法是懶加載,圖像并不加載到內存,當拿圖像的寬和高時會返回-1;
// image = Toolkit.getDefaultToolkit().getImage(imgPath);
try {
// 該方法會將圖像加載到內存,從而拿到圖像的詳細信息。
image = ImageIO.read(new FileInputStream(imgPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
setImgWidth(image.getWidth(this));
setImgHeight(image.getHeight(this));
}
public void paintComponent(Graphics g) {
int x = 0;
int y = 0;
if (null == image) {
return;
}
g.drawImage(image, x, y, image.getWidth(null), image.getHeight(null),
null);
}
public void paint(Graphics g) {
if (isAnimating()) {
// 根據當前幀顯示當前透明度的內容組件
float alpha = (float) frameIndex / (float) ANIMATION_FRAMES;
Graphics2D g2d = (Graphics2D) g;
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha));
// Renderer渲染機制
super.paint(g2d);
} else {
// 如果是第一次,啟動動畫時鐘
frameIndex = 0;
timer = new Timer(ANIMATION_INTERVAL, this);
timer.start();
}
}
// 判斷當前是否正在進行動畫
private boolean isAnimating() {
return timer != null && timer.isRunning();
}
// 關閉時鐘,重新初始化
private void closeTimer() {
if (isAnimating()) {
timer.stop();
frameIndex = 0;
timer = null;
}
}
// 動畫時鐘處理事件
public void actionPerformed(ActionEvent e) {
// 前進一幀
frameIndex++;
if (frameIndex >= ANIMATION_FRAMES)
// 最后一幀,關閉動畫
closeTimer();
else
// 更新當前一幀
repaint();
}
}
import java.awt.AlphaComposite;
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.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Timer;
/**
* @author zakisoft.com
*
*/
public class ZPanel extends javax.swing.JComponent implements ActionListener {
private static final long serialVersionUID = 1L;
private BufferedImage image;
private static final int ANIMATION_FRAMES = 100;
private static final int ANIMATION_INTERVAL = 10;
private int frameIndex;
// 時鐘
private Timer timer;
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
private int imgWidth;
private int imgHeight;
public int getImgWidth() {
return imgWidth;
}
public void setImgWidth(int imgWidth) {
this.imgWidth = imgWidth;
}
public int getImgHeight() {
return imgHeight;
}
public void setImgHeight(int imgHeight) {
this.imgHeight = imgHeight;
}
public ZPanel() {
}
public void setImagePath(String imgPath) {
// 該方法不推薦使用,該方法是懶加載,圖像并不加載到內存,當拿圖像的寬和高時會返回-1;
// image = Toolkit.getDefaultToolkit().getImage(imgPath);
try {
// 該方法會將圖像加載到內存,從而拿到圖像的詳細信息。
image = ImageIO.read(new FileInputStream(imgPath));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
setImgWidth(image.getWidth(this));
setImgHeight(image.getHeight(this));
}
public void paintComponent(Graphics g) {
int x = 0;
int y = 0;
if (null == image) {
return;
}
g.drawImage(image, x, y, image.getWidth(null), image.getHeight(null),
null);
}
public void paint(Graphics g) {
if (isAnimating()) {
// 根據當前幀顯示當前透明度的內容組件
float alpha = (float) frameIndex / (float) ANIMATION_FRAMES;
Graphics2D g2d = (Graphics2D) g;
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha));
// Renderer渲染機制
super.paint(g2d);
} else {
// 如果是第一次,啟動動畫時鐘
frameIndex = 0;
timer = new Timer(ANIMATION_INTERVAL, this);
timer.start();
}
}
// 判斷當前是否正在進行動畫
private boolean isAnimating() {
return timer != null && timer.isRunning();
}
// 關閉時鐘,重新初始化
private void closeTimer() {
if (isAnimating()) {
timer.stop();
frameIndex = 0;
timer = null;
}
}
// 動畫時鐘處理事件
public void actionPerformed(ActionEvent e) {
// 前進一幀
frameIndex++;
if (frameIndex >= ANIMATION_FRAMES)
// 最后一幀,關閉動畫
closeTimer();
else
// 更新當前一幀
repaint();
}
}
我們利用控件的public void paint(Graphics g)方法,來設置控件的透明度,然后利用super.paint(g2d)方法重繪頁面;重繪時系統會自動調用public void actionPerformed(ActionEvent e)方法,我們在這里來改變控件的透明度,并且判斷控件是否加載完畢,加載完畢就停止計時器。
下圖是加載時界面:
全站熱搜