• 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/

  • 相关阅读:
    codevs1288 埃及分数
    codevs1792 分解质因数
    dp
    JAVA大数贪心
    求最长不重叠子串
    初识后缀数组
    dp
    两数相除,判断小数位是否有限位
    构造二分图匹配
    建立多个树状数组
  • 原文地址:https://www.cnblogs.com/LiuYanYGZ/p/9333158.html
Copyright © 2020-2023  润新知