文章目录
- 7.9 实现进度条
- 7.9.1 创建进度条
- 7.9.2 创建进度对话框
7.9 实现进度条
进度条是图形界面中广泛使用的GUI 组件,当复制一个较大的文件时,操作系统会显示一个进度条,用于标识复制操作完成的比例 : 当启动 Eclipse 等程序时, 因为需要加载较多的资源 , 故而启动速度较慢 , 程序也会在启动过程中显示一个进度条 , 用以表示该软件启动完成的比例
7.9.1 创建进度条
使用JProgressBar创建进度条的步骤:
- 创建JProgressBar对象
public JProgressBar(int orient, int min, int max):
orint:方向
min:最小值
max:最大值
- 设置属性
setBorderPainted(boolean b):设置进度条是否有边框
setIndeterminate(boolean newValue):设置当前进度条是不是进度不确定的进度条,如果是,则将看到一个滑块在进度条中左右移动
setStringPainted(boolean b):设置进度条是否显示当前完成的百分比
- 获取和设置当前进度条的进度状态
setValue(int n):设置当前进度值
double getPercentComplete():获取进度条的完成百分比
String getStrin():返回进度字符串的当前值
案例:
请使用JProgressBar完成下图效果:
我们学习过,其实Swing中很多组件的界面与数据都采用了MVC的设计思想:
Swing 组件大都将外观显示和 内部数据分离 , JProgressBar 也不例外, JProgressBar 组件有一个内置的用于保存其状态数据的Model对象 , 这个对象由BoundedRangeModel对象表示,程序调用JProgressBar对象的方法完成进度百分比的设置,监听进度条的数据变化,其实都是通过它内置的BoundedRangeModel对象完成的。下面的代码是对之前代码的改进,通过BoundedRangeModel完成数据的设置,获取与监听。
演示代码:
public class JProgressTest {
JFrame jf = new JFrame("测试进度条");
//创建一个水平进度条
JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL);
//获取进度条内置的数据模型对象
BoundedRangeModel model = bar.getModel();
JCheckBox indeterminate = new JCheckBox("不确定进度");
JCheckBox noBorder = new JCheckBox("不绘制边框");
public void init(){
Box box = new Box(BoxLayout.Y_AXIS);
box.add(indeterminate);
box.add(noBorder);
jf.setLayout(new FlowLayout());
jf.add(box);
//把进度条添加到jf窗口中
jf.add(bar);
//开启耗时任务
SimulatedActivity simulatedActivity = new SimulatedActivity(100);
new Thread(simulatedActivity).start();
//设置进度条的最大值和最小值
bar.getModel().setMinimum(0);
bar.getModel().setMaximum(simulatedActivity.getAmount());
//设置进度条中绘制完成百分比
bar.setStringPainted(true);
//根据选择决定是否绘制进度条边框
noBorder.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean flag = noBorder.isSelected();
bar.setBorderPainted(!flag);
}
});
//根据选择决定是否是不确定进度条
indeterminate.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
boolean flag = indeterminate.isSelected();
bar.setIndeterminate(flag);
//不绘制百分比,因为之前设置了绘制百分比
bar.setStringPainted(!flag);
}
});
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
//通过定时器,不断的读取simulatedActivity中的current值,更新进度条的进度
Timer timer = new Timer(300, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.setValue(simulatedActivity.getCurrent());
}
});
timer.start();
//监听进度条的变化,如果进度完成为100%,那么停止定时器
bar.getModel().addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if ( model.getValue()==bar.getModel().getMaximum()){
timer.stop();
}
}
});
}
public static void main(String[] args) {
new JProgressTest().init();
}
//定义一个线程任务,模拟耗时操作
private class SimulatedActivity implements Runnable{
//内存可见
private volatile int current = 0;
private int amount;
public SimulatedActivity(int amount) {
this.amount = amount;
}
public int getCurrent() {
return current;
}
public void setCurrent(int current) {
this.current = current;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
@Override
public void run() {
//通过循环,不断的修改current的值,模拟任务完成量
while(current<amount){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
current++;
}
}
}
}
7.9.2 创建进度对话框
ProgressMonitor的用法与JProgressBa 的用法基本相似,只是ProgressMonitor可以直接创 建一个进度对话框,它提供了下面的构造器完成对话框的创建:
public ProgressMonitor(Component parentComponent,Object message,String note, int min,int max):
parentComponent:对话框的父组件
message:对话框的描述信息
note:对话框的提示信息
min:进度条的最小值
max:进度条的最大值
使用 ProgressMonitor 创建的对话框里包含的进度条是非常固定的,程序甚至不能设置该进度条是否包含边框(总是包含边框) , 不能设置进度不确定,不能改变进度条的方向(总是水平方向) 。
案例:
使用ProgressMonitor完成下图效果:
演示代码:
public class ProgressMonitorTest {
Timer timer;
public void init(){
final SimulatedActivity simulatedActivity = new SimulatedActivity(100);
final Thread targetThread= new Thread(simulatedActivity);
targetThread.start();
ProgressMonitor dialog = new ProgressMonitor(null, "等待任务完成", "已完成:", 0, simulatedActivity.getAmount());
//设置定时任务
timer = new Timer(300, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.setProgress(simulatedActivity.getCurrent());
if (dialog.isCanceled()){
timer.stop();
targetThread.interrupt();
System.exit(0);
}
}
});
timer.start();
System.out.println("aaa");
}
public static void main(String[] args) {
new ProgressMonitorTest().init();
}
//定义一个线程任务,模拟耗时操作
private class SimulatedActivity implements Runnable{
//内存可见
private volatile int current = 0;
private int amount;
public SimulatedActivity(int amount) {
this.amount = amount;
}
public int getCurrent() {
return current;
}
public void setCurrent(int current) {
this.current = current;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
@Override
public void run() {
//通过循环,不断的修改current的值,模拟任务完成量
while(current<amount){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
current++;
}
}
}
}