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/

Java Swing 创建转圈的进度提示框的更多相关文章

  1. Java Swing创建自定义闪屏:在闪屏上添加Swing进度条控件(转)

    本文将讲解如何做一个类似MyEclipse启动画面的闪屏,为Java Swing应用程序增添魅力. 首先看一下效果图吧, 原理很简单,就是创建一个Dialog,Dialog有一个进度条和一个Label ...

  2. 「小程序JAVA实战」小程序 loading 提示框与页面跳转(37)

    转自:https://idig8.com/2018/09/02/xiaochengxujavashizhanxiaochengxu-loading-tishikuangyuyemiantiaozhua ...

  3. 如何使用CSS创建巧妙的动画提示框

    当你的用户需要一些额外的上下文来放置图标,或者当他们需要一些保证来点击按钮,或者可能是一个复活节彩蛋的标题来搭配一个图片时,工具提示是一个很好的方法来增强用户界面.现在让我们来制作一些动画工具提示,只 ...

  4. JAVA swing中JPanel如何实现分组框的效果以及设置边框颜色 分类: Java Game 2014-08-16 12:21 198人阅读 评论(0) 收藏

    代码如下: import java.awt.FlowLayout; import java.awt.Frame; import java.awt.GridLayout; import javax.sw ...

  5. Java Swing界面编程(28)---复选框:JCheckBox

    程序能够通过JRadioButton实现单选button的功能,那么要实现复选框的功能,则必须使用JCheckBox完毕. package com.beyole.util; import java.a ...

  6. Java Swing应用程序 JComboBox下拉框联动查询

    在web项目中,通过下拉框.JQuery和ajax可以实现下拉框联动查询. 譬如说,当你查询某个地方时,页面上有:省份:<下拉框省份> 市区:<下拉框市区> 县乡:<下拉 ...

  7. 第三方框架MBProgressHUD-----实现各种提示框

    程序运行显示如下 : 点击按钮实现对应的提示框: 这里只截取了其中一张图,有兴趣的可以自己运行程序,查看其他的几种提示框哟!!! 第三方框架MBProgressHUD的下载地址:https://git ...

  8. java swing 添加 jcheckbox复选框

    总体上而言,Java Swing编程有两大特点:麻烦.效果差. 麻烦是说由于设计器的使用不方便(如果您希望使用窗体设计器通过快速拖拽控件建立您的Java Swing GUI程序,请您使用MyEclip ...

  9. Android开发 ---构建对话框Builder对象,消息提示框、列表对话框、单选提示框、多选提示框、日期/时间对话框、进度条对话框、自定义对话框、投影

    效果图: 1.activity_main.xml 描述: a.定义了一个消息提示框按钮 点击按钮弹出消息 b.定义了一个选择城市的输入框 点击按钮选择城市 c.定义了一个单选提示框按钮 点击按钮选择某 ...

随机推荐

  1. New Concept English three (50)

    31 39 The New Year is a time for resolutions. Mentally, at least, most of us could compile formidabl ...

  2. New Concept English there (60)

    33w/m 43 Punctuality is a necessary habit in all public affairs in civilized society. Without it, no ...

  3. 远程激活.NET REFLECTOR(不能断网)

    由于是远程连接的服务器,使用.Net Reflector注册机激活时,不能断网. 如何禁止Reflector连接她的激活服务器,可进行如下操作: 1.添加hosts: 0.0.0.0 red-gate ...

  4. I.MX6 make menuconfig进入x86模式

    /************************************************************************ * I.MX6 make menuconfig进入x ...

  5. sklearn_算法选择

  6. [Luogu3727]曼哈顿计划E

    luogu 题意(简化版) 给你一棵树,每个点上有一个\(SG\)值,问你是否存在一条路径使得\(SG\)异或和为\(0\). sol 可以当做每个点的稳定值就是这个点上的石子数量. 很显然我们只需要 ...

  7. 隐藏select中的“请选择”项

    <select> <option value="" style="display: none">请选择</option> & ...

  8. 虚拟环境中的django及相关包安装

    1.先进入虚拟环境 pyenv activate virtualenvname. 2.安装django软件包 安装命令: pip install django==1.7 查看安装结果: python ...

  9. Composer + thinkphp5.1安装与使用

    Composer 是 PHP 的一个依赖管理工具.我们可以在项目中声明所依赖的外部工具库,Composer 会帮你安装这些依赖的库文件,有了它,我们就可以很轻松的使用一个命令将其他人的优秀代码引用到我 ...

  10. mysql 自增id

    在开发的时候遇到了 自增id变成2147483647 莫名其妙 然后发现是自己没把自增id改为 无符号的原因 把无符号勾上就ok了