Java Swing 创建转圈的进度提示框

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的代码如下:

  1. package com.jframe.ceshi;
  2. /*
  3. * Created on 25 juin 2004
  4. * AnimatedPanel.java
  5. * Panneau anim茅.
  6. */
  7. import java.awt.AlphaComposite;
  8. import java.awt.Color;
  9. import java.awt.Font;
  10. import java.awt.Graphics;
  11. import java.awt.Graphics2D;
  12. import java.awt.Image;
  13. import java.awt.RenderingHints;
  14. import java.awt.font.FontRenderContext;
  15. import java.awt.font.TextLayout;
  16. import java.awt.geom.Rectangle2D;
  17. import java.awt.image.BufferedImage;
  18. import java.awt.image.BufferedImageOp;
  19. import java.awt.image.ConvolveOp;
  20. import java.awt.image.Kernel;
  21. import javax.swing.ImageIcon;
  22. import javax.swing.JPanel;
  23. /**
  24. * Affiche un panneau anim茅. L'animation consiste en l'highlight d'une image.
  25. *
  26. * @author Romain Guy
  27. */
  28. public class AnimatedPanel extends JPanel {
  29. /**
  30. *
  31. */
  32. private static final long serialVersionUID = 1L;
  33. private float gradient;
  34. private String message;
  35. private Thread animator;
  36. private BufferedImage convolvedImage;
  37. private BufferedImage originalImage;
  38. private Font font;
  39. private static AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
  40. /**
  41. * Cr茅e un panneau anim茅 contenant l'image pass茅e en param猫tre. L'animation
  42. * ne d茅marre que par un appel 脿 start().
  43. *
  44. * @param message Le message 脿 afficher
  45. * @param icon L'image 脿 afficher et 脿 animer
  46. * @author Romain Guy
  47. */
  48. public AnimatedPanel(String message, ImageIcon icon) {
  49. this.message = message;
  50. this.font = getFont().deriveFont(14.0f);
  51. Image image = icon.getImage();
  52. originalImage = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
  53. convolvedImage = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
  54. Graphics g = originalImage.createGraphics();
  55. g.drawImage(image, 0, 0, this);
  56. g.dispose();
  57. setBrightness(1.0f);
  58. setOpaque(false);
  59. }
  60. @Override
  61. public void paintComponent(Graphics g) {
  62. super.paintComponent(g);
  63. if (convolvedImage != null) {
  64. int width = getWidth();
  65. int height = getHeight();
  66. synchronized (convolvedImage) {
  67. Graphics2D g2 = (Graphics2D) g;
  68. g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  69. g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  70. g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
  71. FontRenderContext context = g2.getFontRenderContext();
  72. TextLayout layout = new TextLayout(message, font, context);
  73. Rectangle2D bounds = layout.getBounds();
  74. int x = (width - convolvedImage.getWidth(null)) / 2;
  75. int y = (int) (height - (convolvedImage.getHeight(null) + bounds.getHeight() + layout.getAscent())) / 2;
  76. g2.drawImage(convolvedImage, x, y, this);
  77. g2.setColor(new Color(0, 0, 0, (int) (gradient * 255)));
  78. layout.draw(g2, (float) (width - bounds.getWidth()) / 2,
  79. (float) (y + convolvedImage.getHeight(null) + bounds.getHeight() + layout.getAscent()));
  80. }
  81. }
  82. }
  83. /**
  84. * Modifie la luminosit茅 de l'image.
  85. *
  86. * @param multiple Le taux de luminosit茅
  87. */
  88. private void setBrightness(float multiple) {
  89. float[] brightKernel = { multiple };
  90. RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  91. BufferedImageOp bright = new ConvolveOp(new Kernel(1, 1, brightKernel), ConvolveOp.EDGE_NO_OP, hints);
  92. bright.filter(originalImage, convolvedImage);
  93. repaint();
  94. }
  95. /**
  96. * Modifie le d茅grad茅 du texte.
  97. *
  98. * @param gradient Le coefficient de d茅grad茅
  99. */
  100. private void setGradientFactor(float gradient) {
  101. this.gradient = gradient;
  102. }
  103. /**
  104. * D茅marre l'animation du panneau.
  105. */
  106. public void start() {
  107. this.animator = new Thread(new HighlightCycler(), "Highlighter");
  108. this.animator.start();
  109. }
  110. /**
  111. * Arr锚te l'animation.
  112. */
  113. public void stop() {
  114. if (this.animator != null) {
  115. this.animator.interrupt();
  116. }
  117. this.animator = null;
  118. }
  119. /**
  120. * Fait cycler la valeur d'highlight de l'image.
  121. *
  122. * @author Romain Guy
  123. */
  124. class HighlightCycler implements Runnable {
  125. private int way = 1;
  126. private final int LOWER_BOUND = 10;
  127. private final int UPPER_BOUND = 35;
  128. private int value = LOWER_BOUND;
  129. @Override
  130. public void run() {
  131. while (true) {
  132. try {
  133. Thread.sleep(1000 / (UPPER_BOUND - LOWER_BOUND));
  134. } catch (InterruptedException e) {
  135. return;
  136. }
  137. value += this.way;
  138. if (value > UPPER_BOUND) {
  139. value = UPPER_BOUND;
  140. this.way = -1;
  141. } else if (value < LOWER_BOUND) {
  142. value = LOWER_BOUND;
  143. this.way = 1;
  144. }
  145. synchronized (convolvedImage) {
  146. setBrightness((float) value / 10);
  147. setGradientFactor((float) value / UPPER_BOUND);
  148. }
  149. }
  150. }
  151. }
  152. }

    2. InfiniteProgressPanel.java代码如下:

   

  1. package com.jframe.ceshi;
  2. import java.awt.Color;
  3. import java.awt.Graphics;
  4. import java.awt.Graphics2D;
  5. import java.awt.RenderingHints;
  6. import java.awt.event.MouseEvent;
  7. import java.awt.event.MouseListener;
  8. import java.awt.font.FontRenderContext;
  9. import java.awt.font.TextLayout;
  10. import java.awt.geom.AffineTransform;
  11. import java.awt.geom.Area;
  12. import java.awt.geom.Ellipse2D;
  13. import java.awt.geom.Point2D;
  14. import java.awt.geom.Rectangle2D;
  15. import javax.swing.JComponent;
  16. public class InfiniteProgressPanel extends JComponent implements MouseListener {
  17. /**
  18. *
  19. */
  20. private static final long serialVersionUID = 1L;
  21. protected Area[] ticker = null;
  22. protected Thread animation = null;
  23. protected boolean started = false;
  24. protected int alphaLevel = 0;
  25. protected int rampDelay = 300;
  26. protected float shield = 0.70f;
  27. protected String text = "";
  28. protected int barsCount = 14;
  29. protected float fps = 15.0f;
  30. protected RenderingHints hints = null;
  31. public InfiniteProgressPanel() {
  32. this("");
  33. }
  34. public InfiniteProgressPanel(String text) {
  35. this(text, 14);
  36. }
  37. public InfiniteProgressPanel(String text, int barsCount) {
  38. this(text, barsCount, 0.70f);
  39. }
  40. public InfiniteProgressPanel(String text, int barsCount, float shield) {
  41. this(text, barsCount, shield, 15.0f);
  42. }
  43. public InfiniteProgressPanel(String text, int barsCount, float shield, float fps) {
  44. this(text, barsCount, shield, fps, 300);
  45. }
  46. public InfiniteProgressPanel(String text, int barsCount, float shield, float fps, int rampDelay) {
  47. this.text = text;
  48. this.rampDelay = rampDelay >= 0 ? rampDelay : 0;
  49. this.shield = shield >= 0.0f ? shield : 0.0f;
  50. this.fps = fps > 0.0f ? fps : 15.0f;
  51. this.barsCount = barsCount > 0 ? barsCount : 14;
  52. this.hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
  53. this.hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  54. this.hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
  55. }
  56. public void setText(String text) {
  57. repaint();
  58. this.text = text;
  59. }
  60. public String getText() {
  61. return text;
  62. }
  63. public void start() {
  64. addMouseListener(this);
  65. setVisible(true);
  66. ticker = buildTicker();
  67. animation = new Thread(new Animator(true));
  68. animation.start();
  69. }
  70. public void stop() {
  71. if (animation != null) {
  72. animation.interrupt();
  73. animation = null;
  74. animation = new Thread(new Animator(false));
  75. animation.start();
  76. }
  77. }
  78. public void interrupt() {
  79. if (animation != null) {
  80. animation.interrupt();
  81. animation = null;
  82. removeMouseListener(this);
  83. setVisible(false);
  84. }
  85. }
  86. @Override
  87. public void paintComponent(Graphics g) {
  88. if (started) {
  89. int width = getWidth();
  90. int height = getHeight();
  91. double maxY = 0.0;
  92. Graphics2D g2 = (Graphics2D) g;
  93. g2.setRenderingHints(hints);
  94. g2.setColor(new Color(255, 255, 255, (int) (alphaLevel * shield)));
  95. g2.fillRect(0, 0, getWidth(), getHeight());
  96. for (int i = 0; i < ticker.length; i++) {
  97. int channel = 224 - 128 / (i + 1);
  98. g2.setColor(new Color(channel, channel, channel, alphaLevel));
  99. g2.fill(ticker[i]);
  100. Rectangle2D bounds = ticker[i].getBounds2D();
  101. if (bounds.getMaxY() > maxY) {
  102. maxY = bounds.getMaxY();
  103. }
  104. }
  105. if (text != null && text.length() > 0) {
  106. FontRenderContext context = g2.getFontRenderContext();
  107. TextLayout layout = new TextLayout(text, getFont(), context);
  108. Rectangle2D bounds = layout.getBounds();
  109. g2.setColor(getForeground());
  110. layout.draw(g2, (float) (width - bounds.getWidth()) / 2,
  111. (float) (maxY + layout.getLeading() + 2 * layout.getAscent()));
  112. }
  113. }
  114. }
  115. private Area[] buildTicker() {
  116. Area[] ticker = new Area[barsCount];
  117. Point2D.Double center = new Point2D.Double((double) getWidth() / 2, (double) getHeight() / 2);
  118. double fixedAngle = 2.0 * Math.PI / (barsCount);
  119. for (double i = 0.0; i < barsCount; i++) {
  120. Area primitive = buildPrimitive();
  121. AffineTransform toCenter = AffineTransform.getTranslateInstance(center.getX(), center.getY());
  122. AffineTransform toBorder = AffineTransform.getTranslateInstance(45.0, -6.0);
  123. AffineTransform toCircle = AffineTransform.getRotateInstance(-i * fixedAngle, center.getX(), center.getY());
  124. AffineTransform toWheel = new AffineTransform();
  125. toWheel.concatenate(toCenter);
  126. toWheel.concatenate(toBorder);
  127. primitive.transform(toWheel);
  128. primitive.transform(toCircle);
  129. ticker[(int) i] = primitive;
  130. }
  131. return ticker;
  132. }
  133. private Area buildPrimitive() {
  134. Rectangle2D.Double body = new Rectangle2D.Double(6, 0, 30, 12);
  135. Ellipse2D.Double head = new Ellipse2D.Double(0, 0, 12, 12);
  136. Ellipse2D.Double tail = new Ellipse2D.Double(30, 0, 12, 12);
  137. Area tick = new Area(body);
  138. tick.add(new Area(head));
  139. tick.add(new Area(tail));
  140. return tick;
  141. }
  142. protected class Animator implements Runnable {
  143. private boolean rampUp = true;
  144. protected Animator(boolean rampUp) {
  145. this.rampUp = rampUp;
  146. }
  147. @Override
  148. public void run() {
  149. Point2D.Double center = new Point2D.Double((double) getWidth() / 2, (double) getHeight() / 2);
  150. double fixedIncrement = 2.0 * Math.PI / (barsCount);
  151. AffineTransform toCircle = AffineTransform.getRotateInstance(fixedIncrement, center.getX(), center.getY());
  152. long start = System.currentTimeMillis();
  153. if (rampDelay == 0) {
  154. alphaLevel = rampUp ? 255 : 0;
  155. }
  156. started = true;
  157. boolean inRamp = rampUp;
  158. while (!Thread.interrupted()) {
  159. if (!inRamp) {
  160. for (int i = 0; i < ticker.length; i++) {
  161. ticker[i].transform(toCircle);
  162. }
  163. }
  164. repaint();
  165. if (rampUp) {
  166. if (alphaLevel < 255) {
  167. alphaLevel = (int) (255 * (System.currentTimeMillis() - start) / rampDelay);
  168. if (alphaLevel >= 255) {
  169. alphaLevel = 255;
  170. inRamp = false;
  171. }
  172. }
  173. } else if (alphaLevel > 0) {
  174. alphaLevel = (int) (255 - (255 * (System.currentTimeMillis() - start) / rampDelay));
  175. if (alphaLevel <= 0) {
  176. alphaLevel = 0;
  177. break;
  178. }
  179. }
  180. try {
  181. Thread.sleep(inRamp ? 10 : (int) (1000 / fps));
  182. } catch (InterruptedException ie) {
  183. break;
  184. }
  185. Thread.yield();
  186. }
  187. if (!rampUp) {
  188. started = false;
  189. repaint();
  190. setVisible(false);
  191. removeMouseListener(InfiniteProgressPanel.this);
  192. }
  193. }
  194. }
  195. @Override
  196. public void mouseClicked(MouseEvent e) {
  197. }
  198. @Override
  199. public void mousePressed(MouseEvent e) {
  200. }
  201. @Override
  202. public void mouseReleased(MouseEvent e) {
  203. }
  204. @Override
  205. public void mouseEntered(MouseEvent e) {
  206. }
  207. @Override
  208. public void mouseExited(MouseEvent e) {
  209. }
  210. }
     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/

原文地址:https://www.cnblogs.com/LiuYanYGZ/p/9333158.html