Java图形化界面编程超详细知识点(7)——进度条[通俗易懂]

Java图形化界面编程超详细知识点(7)——进度条[通俗易懂]进度条是图形界面中广泛使用的GUI组件,当复制一个较大的文件时,操作系统会显示一个进度条,用于标识复制操作完成的比例

目录

4 JProgressBar、ProgressMonitor、BoundedRangeModel实现进度条

4.1 创建进度条


4 JProgressBar、ProgressMonitor、BoundedRangeModel实现进度条

进度条是图形界面中广泛使用的GUI组件,当复制一个较大的文件时,操作系统会显示一个进度条,用于标识复制操作完成的比例。

4.1 创建进度条

使用JProgressBar创建进度条的步骤:

1.创建JProgressBar对象

public JProgressBar(int orient,int min,int max);

        orient:方向

2.设置属性

setBorderPainted(boolean b);设置进度条是否有边框

setIndeterminate(boolean newValue);设置当前进度条是不是进度不确定的进度条,如果是,则将看到一个滑块在进度条左右移动

setStringPainted(boolean b);设置进度条是否显示当前完成的百分比

3.获取和设置当前进度条的进度状态

setValue(int n);设置当前进度值

double getPercentComplete();获取进度条的完成百分比

String getString();返回进度字符串的当前值 

案例:

        使用JProgressBar完成下图效果:

Java图形化界面编程超详细知识点(7)——进度条[通俗易懂]

public class JProgressTest {
    JFrame jf = new JFrame("测试进度条");

    JCheckBox indeterminate = new JCheckBox("不确定进度");
    JCheckBox noBorder = new JCheckBox("不绘制边框");

    //创建进度条
    JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);

    public void init(){
        //组装视图

        //处理复选框的点击行为
        indeterminate.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取一下indeterminate复选框有没有选中?
                boolean selected = indeterminate.isSelected();

                //设置当前进度条不确定进度
                bar.setIndeterminate(selected);

                bar.setStringPainted(!selected);
            }
        });

        noBorder.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取一下noBorder复选框有没有选中?
                boolean selected = noBorder.isSelected();

                bar.setBorderPainted(!selected);
            }
        });

        Box vBox = Box.createVerticalBox();
        vBox.add(indeterminate);
        vBox.add(noBorder);

        //设置进度条的属性
        bar.setStringPainted(true);
        bar.setBorderPainted(true);

        //把当前窗口的布局方式修改为FlowLayout
        jf.setLayout(new FlowLayout());
        jf.add(vBox);
        jf.add(bar);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

        //通过循环模拟修改进度条的进度
        for (int i = 0; i <= 100; i++) {
            //修改已经完成的工作量,也就是百分比
            bar.setValue(i);

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new JProgressTest().init();
    }
}

        这种耗时操作放在主线程的话,会导致执行耗时操作时,用户无法再进行任何操作,因此最好将耗时操作放入子线程中。

代码改进:

public class JProgressTest2 {

    JFrame jf = new JFrame("测试进度条");

    JCheckBox indeterminate = new JCheckBox("不确定进度");
    JCheckBox noBorder = new JCheckBox("不绘制边框");

    //创建进度条
    JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);


    public void init(){
        //组装视图

        //处理复选框的点击行为
        indeterminate.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取一下indeterminate复选框有没有选中?
                boolean selected = indeterminate.isSelected();

                //设置当前进度条不确定进度
                bar.setIndeterminate(selected);

                bar.setStringPainted(!selected);

            }
        });

        noBorder.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取一下noBorder复选框有没有选中?
                boolean selected = noBorder.isSelected();

                bar.setBorderPainted(!selected);
            }
        });

        Box vBox = Box.createVerticalBox();
        vBox.add(indeterminate);
        vBox.add(noBorder);


        //设置进度条的属性
        bar.setStringPainted(true);
        bar.setBorderPainted(true);

        //把当前窗口的布局方式修改为FlowLayout
        jf.setLayout(new FlowLayout());
        jf.add(vBox);
        jf.add(bar);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

        //开启子线程,模拟耗时操作
        SimulaterActivity simulaterActivity = new SimulaterActivity(bar.getMaximum());
        new Thread(simulaterActivity).start();

        //设置一个定时任务
        Timer timer = new Timer(200, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //读取线程任务对象的当前完成量,设置给进度条
                int current = simulaterActivity.getCurrent();
                bar.setValue(current);
            }
        });
        timer.start();

        //监听进度条的任务变化
        bar.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                int value = bar.getValue();
                if (value == simulaterActivity.getAmount()){
                    timer.stop();
                }
            }
        });
    }

    private class SimulaterActivity implements  Runnable{
        //记录任务总量
        private int amount;

        //记录当前任务的完成量
        private volatile int current;

        public SimulaterActivity(int amount) {
            this.amount = amount;
        }

        public int getAmount() {
            return amount;
        }

        public void setAmount(int amount) {
            this.amount = amount;
        }

        public int getCurrent() {
            return current;
        }

        public void setCurrent(int current) {
            this.current = current;
        }

        @Override
        public void run() {
            //子线程的任务  模拟耗时操作
            while(current<amount){
                try {
                    Thread.currentThread().sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                current++;
            }
        }
    }

    public static void main(String[] args) {
        new JProgressTest2().init();
    }
}

        之前我们学习过,Swing中很多组件的界面与数据都采用了MVC的设计思想:

Java图形化界面编程超详细知识点(7)——进度条[通俗易懂]

        Swing组件大都将外观显示和内部数据分离,JProgressBar也不例外,JProgressBar组件有一个内置的用于保存其状态数据的Model对象,这个对象由BoundedRangeModel对象表示,程序调用JProgressBar对象的方法完成进度百分比的设置,监听进度条的数据变化,其实都是通过它内置的BoundedRangeModel对象完成的。下面的代码是对之前代码的改进,通过BoundedRangeModel完成数据的设置,获取和监听。

public class JProgressTest3 {

    JFrame jf = new JFrame("测试进度条");

    JCheckBox indeterminate = new JCheckBox("不确定进度");
    JCheckBox noBorder = new JCheckBox("不绘制边框");

    //创建进度条
    JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL,0,100);

    //获取处进度条内置的数据模型对象
    BoundedRangeModel model = bar.getModel();

    public void init(){
        //组装视图

        //处理复选框的点击行为
        indeterminate.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取一下indeterminate复选框有没有选中?
                boolean selected = indeterminate.isSelected();

                //设置当前进度条不确定进度
                bar.setIndeterminate(selected);

                bar.setStringPainted(!selected);

            }
        });

        noBorder.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取一下noBorder复选框有没有选中?
                boolean selected = noBorder.isSelected();

                bar.setBorderPainted(!selected);
            }
        });

        Box vBox = Box.createVerticalBox();
        vBox.add(indeterminate);
        vBox.add(noBorder);


        //设置进度条的属性
        bar.setStringPainted(true);
        bar.setBorderPainted(true);

        //把当前窗口的布局方式修改为FlowLayout
        jf.setLayout(new FlowLayout());
        jf.add(vBox);
        jf.add(bar);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);

        //开启子线程,模拟耗时操作
        SimulaterActivity simulaterActivity = new SimulaterActivity(bar.getMaximum());
        new Thread(simulaterActivity).start();

        //设置一个定时任务
        Timer timer = new Timer(200, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //读取线程任务对象的当前完成量,设置给进度条
                int current = simulaterActivity.getCurrent();
                //bar.setValue(current);
                model.setValue(current);
            }
        });
        timer.start();

        //监听进度条的任务变化
        model.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                int value = model.getValue();
                if (value == simulaterActivity.getAmount()){
                    timer.stop();
                }
            }
        });


    }

    private class SimulaterActivity implements  Runnable{
        //记录任务总量
        private int amount;

        //记录当前任务的完成量
        private volatile int current;

        public SimulaterActivity(int amount) {
            this.amount = amount;
        }

        public int getAmount() {
            return amount;
        }

        public void setAmount(int amount) {
            this.amount = amount;
        }

        public int getCurrent() {
            return current;
        }

        public void setCurrent(int current) {
            this.current = current;
        }

        @Override
        public void run() {
            //子线程的任务  模拟耗时操作
            while(current<amount){
                try {
                    Thread.currentThread().sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                current++;
            }
        }
    }

    public static void main(String[] args) {
        new JProgressTest2().init();
    }
}

4.2 创建进度对话框

        ProgressMonitor的用法与JProgressBar基本相似,只是ProgressMonitor可以直接创建一个进度对话框,它提供了下面的构造器完成对话框的创建:

public ProgressMonitor(Component parentcomponent,Object message,String note,int min,int max);

        parentcomponent:对话框的描述信息

        note:进度的提示信息

        使用ProgressMonitor创建的对话框里包含的进度条是非常固定的,程序甚至不能设置该进度条是否包含边框(总是包含边框),不能设置进度不确定,不能改变进度条的方向(总是水平方向)。

案例: 

        使用ProgressMonitor完成下图效果:

Java图形化界面编程超详细知识点(7)——进度条[通俗易懂]

public class ProgressMonitorTest {
    Timer timer;
    public void init(){
        //创建进度对话框
        ProgressMonitor monitor = new ProgressMonitor(null,"等待任务完成","已完成",0,100);

        SimulaterActivity simulaterActivity = new SimulaterActivity(100);
        new Thread(simulaterActivity).start();


        //设置定时任务
        timer = new Timer(200, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //读取当前任务量,修改进度
                int current = simulaterActivity.getCurrent();
                monitor.setProgress(current);

                //判断用户是否点击了取消按钮,停止定时任务,关闭对话框,退出程序
                if (monitor.isCanceled()){
                    timer.stop();
                    monitor.close();
                    System.exit(0);
                }

            }
        });
        timer.start();

    }

    public static void main(String[] args) {
        new ProgressMonitorTest().init();
    }

    //定义一个线程任务,模拟耗时操作
    private class SimulaterActivity implements Runnable{
        //内存可见
        private volatile int current = 0;
        private int amount;

        public SimulaterActivity(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++;
            }
        }
    }

}

今天的文章Java图形化界面编程超详细知识点(7)——进度条[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/70569.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注