Java Swing 创建转圈的进度提示框
Java Swing 创建转圈的进度提示框
摘自 https://blog.csdn.net/nihaoqiulinhe/article/details/52439486
总是觉得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/
Java Swing 创建转圈的进度提示框的更多相关文章
- Java Swing创建自定义闪屏:在闪屏上添加Swing进度条控件(转)
本文将讲解如何做一个类似MyEclipse启动画面的闪屏,为Java Swing应用程序增添魅力. 首先看一下效果图吧, 原理很简单,就是创建一个Dialog,Dialog有一个进度条和一个Label ...
- 「小程序JAVA实战」小程序 loading 提示框与页面跳转(37)
转自:https://idig8.com/2018/09/02/xiaochengxujavashizhanxiaochengxu-loading-tishikuangyuyemiantiaozhua ...
- 如何使用CSS创建巧妙的动画提示框
当你的用户需要一些额外的上下文来放置图标,或者当他们需要一些保证来点击按钮,或者可能是一个复活节彩蛋的标题来搭配一个图片时,工具提示是一个很好的方法来增强用户界面.现在让我们来制作一些动画工具提示,只 ...
- 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 ...
- Java Swing界面编程(28)---复选框:JCheckBox
程序能够通过JRadioButton实现单选button的功能,那么要实现复选框的功能,则必须使用JCheckBox完毕. package com.beyole.util; import java.a ...
- Java Swing应用程序 JComboBox下拉框联动查询
在web项目中,通过下拉框.JQuery和ajax可以实现下拉框联动查询. 譬如说,当你查询某个地方时,页面上有:省份:<下拉框省份> 市区:<下拉框市区> 县乡:<下拉 ...
- 第三方框架MBProgressHUD-----实现各种提示框
程序运行显示如下 : 点击按钮实现对应的提示框: 这里只截取了其中一张图,有兴趣的可以自己运行程序,查看其他的几种提示框哟!!! 第三方框架MBProgressHUD的下载地址:https://git ...
- java swing 添加 jcheckbox复选框
总体上而言,Java Swing编程有两大特点:麻烦.效果差. 麻烦是说由于设计器的使用不方便(如果您希望使用窗体设计器通过快速拖拽控件建立您的Java Swing GUI程序,请您使用MyEclip ...
- Android开发 ---构建对话框Builder对象,消息提示框、列表对话框、单选提示框、多选提示框、日期/时间对话框、进度条对话框、自定义对话框、投影
效果图: 1.activity_main.xml 描述: a.定义了一个消息提示框按钮 点击按钮弹出消息 b.定义了一个选择城市的输入框 点击按钮选择城市 c.定义了一个单选提示框按钮 点击按钮选择某 ...
随机推荐
- 网络编程基础--协程--greenlet切换---gevent自动识别 IO ---
协程: 1 单线程来实现并发---协程: 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程, 即协程是由用户程序自己控制调度的 只 ...
- hdu4121 poj4001 Xiangqi(模拟)
模拟题考验coding能力,一定要思路清晰,按照模块化思想,有哪些情况,需要哪些功能都要事先分析好了.高手的模拟题代码往往结构很清晰,功能模块写成函数,没有过多重复代码,让人一看便明. 方法选择的好坏 ...
- uva11609(组合数学,快速幂)
先选人,再从这些人里选一个队长,方案总数:C(i,1)*C(n,i)(其中i从1到n)的总和. 这个公式显然不能在时限内暴力算出来,需要变形和推导出更简单的来. 用到组合数里面这个公式:C(n,k)* ...
- PHP学习之数组Array操作和键值对操作函数(一)
PHP 中的数组实际上是一个有序映射.映射是一种把 values关联到 keys 的类型.此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种实现),字典,集合, ...
- BZOJ1280: Emmy卖猪pigs
BZOJ1280: Emmy卖猪pigs https://lydsy.com/JudgeOnline/problem.php?id=1280 分析: 这题感觉还好,因为是有时间顺序,所以拆点做最大流即 ...
- Python函数-eval()
eval(source[, globals[, locals]]) 作用: 将字符串str当成有效的表达式来求值并返回计算结果.参数:source:一个Python表达式或函数compile()返回的 ...
- HIVE-分区表详解以及实例
HIVE中的分区表是什么,我们先看操作,然后再来体会. 创建一个分区表,分区的单位时dt和国家名 hive> create table logs(ts bigint,line string) & ...
- angular +H5 上传图片 与预览图片
//index.html <form class="form-horizontal"> <div class="panel panel-default& ...
- 异常:SQL Error: 1064, SQLState: 42000
在MySQL中,有很多字符被MySQL保留了.如果你用来做列名或者表名就会出现问题. 我这里出现的问题是采用了order作为表明,这是一个保留字,所以出现问题.
- 用Python+Django1.9在Eclipse环境下开发web网站
最近想学习一下python django, 按网上各位大神们的说明,试着做了一下,这里记录下来,做个笔记. 参考 http://www.cnblogs.com/linjiqin/p/3595891.h ...