|
在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);
}
}
|