Java简单案例:JProgressBar与SwingWorker的配合实用

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 17:32   3949   0

在Java中进度条是使用JProgressBar,而JProgressBar需要配合多线程一起使用才会出现动态增加的效果。今天在网上查找资料的时候,发现了《使用Java快速实现进度条》这个blog,主要是使用JProgressBar(Swing内置javax.swing.JProgressBar)和SwingWorker(Swing内置javax.swing.SwingWorker)来实现进度条的滚动,Demo的功能是打开照片。

SwingWorker是个好东西,于是我又找到了另外一篇blog是专门介绍SwingWorker的使用方法。《SwingWorker的使用》详细了介绍了SwingWorker中的参数和函数。使用SwingWorker必须先有一个类来继承它,并带<T, V>两个参数,并重写其中的几个函数doInBackground、process、done


doInBackground:后台跑的主要线程,这个函数必须实现,T作为这个函数的返回类型

process:处理的中间过程,可以不重写。V作为这个函数的参数

done:doInBackground结束后的处理工作,可以不重写。doInBackground的返回值T通过get()函数来获取。



目前的项目暂时不需要那么复杂的功能,只需要实现按下按钮后,在每个循环后都让进度条前进一点。

下面是我代码的简单实现,简单的做了一个for循环,每50毫秒让进度条前进一格,最后结束时,根据doInBackground返回值弹出提示框。

package test;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutionException;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

/***
 * SwingWorker可以帮助我们在后台执行耗时的任务,而避免阻塞我们的应用程序,以让用户感觉不爽。 SwingWorker有2个参数T , V
 * T:为最终结果集 【<T> the result type returned by this SwingWorker's doInBackground
 * and get methods】, 由文档的介绍可以知道这个结果可以被doInBackground和get方法返回。 V:为中间结果集【<V> the
 * type used for carrying out intermediate results by this SwingWorker's publish
 * and process methods】
 * 
 * @author zhangyue
 *
 */
public class MySwingWorker extends SwingWorker<Boolean, Integer> {

 private final static int max = 1000;

 // 显示进度条状态的label
 private JLabel status;
 // 进度条
 private JProgressBar jpb;

 public static void main(String[] args) {
  TestFrame frame = new TestFrame();

  final JLabel label = new JLabel();
//  JScrollPane sp = new JScrollPane(panel);
//  sp.setSize(new Dimension(700, 500));
//  frame.add(sp, BorderLayout.CENTER);

  JPanel stp = new JPanel();
  final JProgressBar jpb = new JProgressBar();
  jpb.setMinimum(1);
  jpb.setMaximum(max);
  stp.add(jpb);
  stp.add(label);
  frame.add(stp, BorderLayout.SOUTH);

  JButton button = new JButton("Begin");
  button.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    MySwingWorker msw = new MySwingWorker(label, jpb);
    msw.execute();
   }
  });

  frame.add(button, BorderLayout.NORTH);

  frame.setVisible(true);
 }

 public MySwingWorker(JLabel status, JProgressBar jpb) {
  super();
  this.status = status;
  this.jpb = jpb;
 }

 /*
  * doInBackground是工作线程,他可以明确调用publich方法(注意publish方法只在SwingWorker类中实现),
  * 以发送中间结果V,然后这个中间结果有被发送到在EDT(事件派发线程)中的 process方法中进行处理。
  */
 @Override
 protected Boolean doInBackground() throws Exception {
  // TODO Auto-generated method stub
  for (int i = 1; i <= max; i++) {
   jpb.setValue(i);
   status.setText(i + " / " + max);
   try {
    Thread.sleep(50);
   } catch (InterruptedException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
   }
  }
  return true;
 }

 /*
  * 当doInBackground处理完后,会自动调用done方法,由T类型的描述那里可以知道,在这个方法中可以调用get方法获取最终结果集
  */
 @Override
 protected void done() {
  try {
   Boolean result = get();
   if (result) {
    JOptionPane.showMessageDialog(null, "Success!");
   } else {
    JOptionPane.showMessageDialog(null, "Failed!");
   }
  } catch (InterruptedException | ExecutionException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

}


package test;

import javax.swing.JFrame;  

public class TestFrame extends JFrame {  
  
  
    public TestFrame(){  
        setTitle("Test Frame");  
        setSize(800,600);  
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    }  
}  



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP