欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Swing圆形进度条

程序员文章站 2022-03-30 16:01:34
...

遇到JProgressBar的setVaule方法连续调用不刷新的问题,就想着用一个进度动画加一个Jlabel去刷新百分比而取代,网上无意看到这个方法,有需要的可以试试。

Swing圆形进度条

1.AnimatedPanel.java

package file;

/* 
 * 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 file;

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.ProjressbarMain.java调用方法:

package file;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;

public class ProjressbarMain {
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setLayout(null);
		InfiniteProgressPanel glasspane = new InfiniteProgressPanel();
		Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setBounds(100, 100, (dimension.width) / 2, (dimension.height) / 2);
		glasspane.setBounds(100, 100, (dimension.width) / 2, (dimension.height) / 2);
		frame.setGlassPane(glasspane);
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent evt) {
				System.exit(0);
			}
		});
		frame.setVisible(true);
		glasspane.start();// 开始动画加载效果
		// glasspane.stop();//关闭动画效果
	}
}

注:文章转载自http://blog.csdn.net/nihaoqiulinhe/article/details/52439486