Java Swing 創建轉圈的進度提示框
摘自 https://blog.csdn.net/nihaoqiulinhe/article/details/52439486
置頂
2016年09月05日 13:40:07
閱讀數:4104
總是覺得Java Swing沒有Android的好,不能自定義組件,實現漂亮的進度提示框,比如那種轉圈的,谷歌了一下竟然發現有大牛實現了類似的額效果:
使用方法:
1.具體只需要兩個類:AnimatedPanel.java, InfiniteProgressPanel.java,具體的內容如下:
AnimatedPanel.java的代碼如下:
-
package com.jframe.ceshi;
-
-
/*
-
* Created on 25 juin 2004
-
* AnimatedPanel.java
-
* Panneau anim茅.
-
*/
-
-
import java.awt.AlphaComposite;
-
import java.awt.Color;
-
import java.awt.Font;
-
import java.awt.Graphics;
-
import java.awt.Graphics2D;
-
import java.awt.Image;
-
import java.awt.RenderingHints;
-
import java.awt.font.FontRenderContext;
-
import java.awt.font.TextLayout;
-
import java.awt.geom.Rectangle2D;
-
import java.awt.image.BufferedImage;
-
import java.awt.image.BufferedImageOp;
-
import java.awt.image.ConvolveOp;
-
import java.awt.image.Kernel;
-
-
import javax.swing.ImageIcon;
-
import javax.swing.JPanel;
-
-
/**
-
* Affiche un panneau anim茅. L'animation consiste en l'highlight d'une image.
-
*
-
* @author Romain Guy
-
*/
-
public
class AnimatedPanel extends JPanel {
-
-
/**
-
*
-
*/
-
private
static
final
long serialVersionUID =
1L;
-
private
float gradient;
-
private String message;
-
private Thread animator;
-
private BufferedImage convolvedImage;
-
private BufferedImage originalImage;
-
private Font font;
-
private
static AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
-
-
/**
-
* Cr茅e un panneau anim茅 contenant l'image pass茅e en param貓tre. L'animation
-
* ne d茅marre que par un appel 脿 start().
-
*
-
* @param message Le message 脿 afficher
-
* @param icon L'image 脿 afficher et 脿 animer
-
* @author Romain Guy
-
*/
-
public AnimatedPanel(String message, ImageIcon icon) {
-
this.message = message;
-
this.font = getFont().deriveFont(
14.0f);
-
-
Image image = icon.getImage();
-
originalImage =
new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
-
convolvedImage =
new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
-
Graphics g = originalImage.createGraphics();
-
g.drawImage(image,
0,
0,
this);
-
g.dispose();
-
-
setBrightness(
1.0f);
-
setOpaque(
false);
-
}
-
-
@Override
-
public void paintComponent(Graphics g) {
-
super.paintComponent(g);
-
-
if (convolvedImage !=
null) {
-
int width = getWidth();
-
int height = getHeight();
-
-
synchronized (convolvedImage) {
-
Graphics2D g2 = (Graphics2D) g;
-
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
-
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
-
-
FontRenderContext context = g2.getFontRenderContext();
-
TextLayout layout =
new TextLayout(message, font, context);
-
Rectangle2D bounds = layout.getBounds();
-
-
int x = (width - convolvedImage.getWidth(
null)) /
2;
-
int y = (
int) (height - (convolvedImage.getHeight(
null) + bounds.getHeight() + layout.getAscent())) /
2;
-
-
g2.drawImage(convolvedImage, x, y,
this);
-
g2.setColor(
new Color(
0,
0,
0, (
int) (gradient *
255)));
-
layout.draw(g2, (
float) (width - bounds.getWidth()) /
2,
-
(
float) (y + convolvedImage.getHeight(
null) + bounds.getHeight() + layout.getAscent()));
-
}
-
}
-
}
-
-
/**
-
* Modifie la luminosit茅 de l'image.
-
*
-
* @param multiple Le taux de luminosit茅
-
*/
-
private void setBrightness(float multiple) {
-
float[] brightKernel = { multiple };
-
RenderingHints hints =
new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
-
BufferedImageOp bright =
new ConvolveOp(
new Kernel(
1,
1, brightKernel), ConvolveOp.EDGE_NO_OP, hints);
-
bright.filter(originalImage, convolvedImage);
-
repaint();
-
}
-
-
/**
-
* Modifie le d茅grad茅 du texte.
-
*
-
* @param gradient Le coefficient de d茅grad茅
-
*/
-
private void setGradientFactor(float gradient) {
-
this.gradient = gradient;
-
}
-
-
/**
-
* D茅marre l'animation du panneau.
-
*/
-
public void start() {
-
this.animator =
new Thread(
new HighlightCycler(),
"Highlighter");
-
this.animator.start();
-
}
-
-
/**
-
* Arr錨te l'animation.
-
*/
-
public void stop() {
-
if (
this.animator !=
null) {
-
this.animator.interrupt();
-
}
-
this.animator =
null;
-
}
-
-
/**
-
* Fait cycler la valeur d'highlight de l'image.
-
*
-
* @author Romain Guy
-
*/
-
class HighlightCycler implements Runnable {
-
-
private
int way =
1;
-
private
final
int LOWER_BOUND =
10;
-
private
final
int UPPER_BOUND =
35;
-
private
int value = LOWER_BOUND;
-
-
@Override
-
public void run() {
-
while (
true) {
-
try {
-
Thread.sleep(
1000 / (UPPER_BOUND - LOWER_BOUND));
-
}
catch (InterruptedException e) {
-
return;
-
}
-
-
value +=
this.way;
-
if (value > UPPER_BOUND) {
-
value = UPPER_BOUND;
-
this.way = -
1;
-
}
else
if (value < LOWER_BOUND) {
-
value = LOWER_BOUND;
-
this.way =
1;
-
}
-
-
synchronized (convolvedImage) {
-
setBrightness((
float) value /
10);
-
setGradientFactor((
float) value / UPPER_BOUND);
-
}
-
}
-
}
-
-
}
-
}
2. InfiniteProgressPanel.java代碼如下:
-
package com.jframe.ceshi;
-
-
import java.awt.Color;
-
import java.awt.Graphics;
-
import java.awt.Graphics2D;
-
import java.awt.RenderingHints;
-
import java.awt.event.MouseEvent;
-
import java.awt.event.MouseListener;
-
import java.awt.font.FontRenderContext;
-
import java.awt.font.TextLayout;
-
import java.awt.geom.AffineTransform;
-
import java.awt.geom.Area;
-
import java.awt.geom.Ellipse2D;
-
import java.awt.geom.Point2D;
-
import java.awt.geom.Rectangle2D;
-
-
import javax.swing.JComponent;
-
-
public
class InfiniteProgressPanel extends JComponent implements MouseListener {
-
/**
-
*
-
*/
-
private
static
final
long serialVersionUID =
1L;
-
protected Area[] ticker =
null;
-
protected Thread animation =
null;
-
protected
boolean started =
false;
-
protected
int alphaLevel =
0;
-
protected
int rampDelay =
300;
-
protected
float shield =
0.70f;
-
protected String text =
"";
-
protected
int barsCount =
14;
-
protected
float fps =
15.0f;
-
-
protected RenderingHints hints =
null;
-
-
public InfiniteProgressPanel() {
-
this(
"");
-
}
-
-
public InfiniteProgressPanel(String text) {
-
this(text,
14);
-
}
-
-
public InfiniteProgressPanel(String text, int barsCount) {
-
this(text, barsCount,
0.70f);
-
}
-
-
public InfiniteProgressPanel(String text, int barsCount, float shield) {
-
this(text, barsCount, shield,
15.0f);
-
}
-
-
public InfiniteProgressPanel(String text, int barsCount, float shield, float fps) {
-
this(text, barsCount, shield, fps,
300);
-
}
-
-
public InfiniteProgressPanel(String text, int barsCount, float shield, float fps, int rampDelay) {
-
this.text = text;
-
this.rampDelay = rampDelay >=
0 ? rampDelay :
0;
-
this.shield = shield >=
0.0f ? shield :
0.0f;
-
this.fps = fps >
0.0f ? fps :
15.0f;
-
this.barsCount = barsCount >
0 ? barsCount :
14;
-
-
this.hints =
new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
-
this.hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
this.hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
-
}
-
-
public void setText(String text) {
-
repaint();
-
this.text = text;
-
}
-
-
public String getText() {
-
return text;
-
}
-
-
public void start() {
-
addMouseListener(
this);
-
setVisible(
true);
-
ticker = buildTicker();
-
animation =
new Thread(
new Animator(
true));
-
animation.start();
-
}
-
-
public void stop() {
-
if (animation !=
null) {
-
animation.interrupt();
-
animation =
null;
-
animation =
new Thread(
new Animator(
false));
-
animation.start();
-
}
-
}
-
-
public void interrupt() {
-
if (animation !=
null) {
-
animation.interrupt();
-
animation =
null;
-
-
removeMouseListener(
this);
-
setVisible(
false);
-
}
-
}
-
-
@Override
-
public void paintComponent(Graphics g) {
-
if (started) {
-
int width = getWidth();
-
int height = getHeight();
-
-
double maxY =
0.0;
-
-
Graphics2D g2 = (Graphics2D) g;
-
g2.setRenderingHints(hints);
-
-
g2.setColor(
new Color(
255,
255,
255, (
int) (alphaLevel * shield)));
-
g2.fillRect(
0,
0, getWidth(), getHeight());
-
-
for (
int i =
0; i < ticker.length; i++) {
-
int channel =
224 -
128 / (i +
1);
-
g2.setColor(
new Color(channel, channel, channel, alphaLevel));
-
g2.fill(ticker[i]);
-
-
Rectangle2D bounds = ticker[i].getBounds2D();
-
if (bounds.getMaxY() > maxY) {
-
maxY = bounds.getMaxY();
-
}
-
}
-
-
if (text !=
null && text.length() >
0) {
-
FontRenderContext context = g2.getFontRenderContext();
-
TextLayout layout =
new TextLayout(text, getFont(), context);
-
Rectangle2D bounds = layout.getBounds();
-
g2.setColor(getForeground());
-
layout.draw(g2, (
float) (width - bounds.getWidth()) /
2,
-
(
float) (maxY + layout.getLeading() +
2 * layout.getAscent()));
-
}
-
}
-
}
-
-
private Area[] buildTicker() {
-
Area[] ticker =
new Area[barsCount];
-
Point2D.Double center =
new Point2D.Double((
double) getWidth() /
2, (
double) getHeight() /
2);
-
double fixedAngle =
2.0 * Math.PI / (barsCount);
-
-
for (
double i =
0.0; i < barsCount; i++) {
-
Area primitive = buildPrimitive();
-
-
AffineTransform toCenter = AffineTransform.getTranslateInstance(center.getX(), center.getY());
-
AffineTransform toBorder = AffineTransform.getTranslateInstance(
45.0, -
6.0);
-
AffineTransform toCircle = AffineTransform.getRotateInstance(-i * fixedAngle, center.getX(), center.getY());
-
-
AffineTransform toWheel =
new AffineTransform();
-
toWheel.concatenate(toCenter);
-
toWheel.concatenate(toBorder);
-
-
primitive.transform(toWheel);
-
primitive.transform(toCircle);
-
-
ticker[(
int) i] = primitive;
-
}
-
-
return ticker;
-
}
-
-
private Area buildPrimitive() {
-
Rectangle2D.Double body =
new Rectangle2D.Double(
6,
0,
30,
12);
-
Ellipse2D.Double head =
new Ellipse2D.Double(
0,
0,
12,
12);
-
Ellipse2D.Double tail =
new Ellipse2D.Double(
30,
0,
12,
12);
-
-
Area tick =
new Area(body);
-
tick.add(
new Area(head));
-
tick.add(
new Area(tail));
-
-
return tick;
-
}
-
-
protected
class Animator implements Runnable {
-
private
boolean rampUp =
true;
-
-
protected Animator(boolean rampUp) {
-
this.rampUp = rampUp;
-
}
-
-
@Override
-
public void run() {
-
Point2D.Double center =
new Point2D.Double((
double) getWidth() /
2, (
double) getHeight() /
2);
-
double fixedIncrement =
2.0 * Math.PI / (barsCount);
-
AffineTransform toCircle = AffineTransform.getRotateInstance(fixedIncrement, center.getX(), center.getY());
-
-
long start = System.currentTimeMillis();
-
if (rampDelay ==
0) {
-
alphaLevel = rampUp ?
255 :
0;
-
}
-
-
started =
true;
-
boolean inRamp = rampUp;
-
-
while (!Thread.interrupted()) {
-
if (!inRamp) {
-
for (
int i =
0; i < ticker.length; i++) {
-
ticker[i].transform(toCircle);
-
}
-
}
-
-
repaint();
-
-
if (rampUp) {
-
if (alphaLevel <
255) {
-
alphaLevel = (
int) (
255 * (System.currentTimeMillis() - start) / rampDelay);
-
if (alphaLevel >=
255) {
-
alphaLevel =
255;
-
inRamp =
false;
-
}
-
}
-
}
else
if (alphaLevel >
0) {
-
alphaLevel = (
int) (
255 - (
255 * (System.currentTimeMillis() - start) / rampDelay));
-
if (alphaLevel <=
0) {
-
alphaLevel =
0;
-
break;
-
}
-
}
-
-
try {
-
Thread.sleep(inRamp ?
10 : (
int) (
1000 / fps));
-
}
catch (InterruptedException ie) {
-
break;
-
}
-
Thread.yield();
-
}
-
-
if (!rampUp) {
-
started =
false;
-
repaint();
-
-
setVisible(
false);
-
removeMouseListener(InfiniteProgressPanel.
this);
-
}
-
}
-
}
-
-
@Override
-
public void mouseClicked(MouseEvent e) {
-
}
-
-
@Override
-
public void mousePressed(MouseEvent e) {
-
}
-
-
@Override
-
public void mouseReleased(MouseEvent e) {
-
}
-
-
@Override
-
public void mouseEntered(MouseEvent e) {
-
}
-
-
@Override
-
public void mouseExited(MouseEvent e) {
-
}
-
}
3.如何在你的Java Swing使用呢,如下步驟:
JFrame frame = new JFrame(); // ... InfiniteProgressPanel glasspane = new InfiniteProgressPanel();
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); glasspane.setBounds(100, 100, (dimension.width) / 2, (dimension.height) / 2); frame.setGlassPane(glasspane); glasspane.start();//開始動畫加載效果 frame.setVisible(true); // Later, to disable,在合適的地方關閉動畫效果 glasspane.stop();參考的兩個鏈接如下:
http://www.javalobby.org/java/forums/t19222.html,http://www.curious-creature.com/2005/02/15/wait-with-style-in-swing/