如何在加载bin文件时显示JProgressBar组件?加载bin文件的进度条
我只能发现迭代箱解决方案可读取和我使用的对象读取,如:
CustomObj test = (CustomObj) in.readObject();
干杯
如何在加载bin文件时显示JProgressBar组件?加载bin文件的进度条
我只能发现迭代箱解决方案可读取和我使用的对象读取,如:
CustomObj test = (CustomObj) in.readObject();
干杯
如果你不能测量过程的进展,那么你就可以只指定进度条的“不确定模式”。在这种模式下,进度条会指示它正在工作,但过程的完成是未知的。
JProgressBar progress = new JProgressBar();
progress.setIndeterminate(true);
子类java.io.FilteredInputStream
数被读取的字节数,您ObjectInputStream
和底层之间InputStream
插入被读取。
您可以通过对运行计数进行采样或使用内置于您的子类中的回调来更新进度栏。
实施例:
public class CountingInputStream extends FilteredInputStream {
private int numBytes;
public CountingInputStream(InputStream inputStream){
this(inputStream);
}
public int getNumBytes(){
return numBytes;
}
@Override
public int read() {
int b = super.read();
if(b != -1){
countBytes(1);
}
return b;
}
@Override
public int read(byte[] b){
int n = super.read(b);
if(n >= 0){
countBytes(n);
}
return n;
}
@Override
public int read(byte[] b, int off, int len){
int n = super.read(b, off, len);
if(n >= 0){
countBytes(n);
}
return n;
}
private void countBytes(int n){
numBytes += n;
}
}
它可以象下面被使用(假定InputStream is
数据的源)。:
InputStream is = ...;
CountingInputStream cis = new CountingInputStream(is)
ObjectInputStream ois = new ObjectInputStream(cis);
ois.readObject();
可以从不同的线程进行采样cis.getNumBytes()
(可能与一个Swing计时器)并使用返回值更新JProgressBar
我建议做两件事:
InputStream
并将所有内容委托给原始流(几个方法除外),并在read()方法中确保通知某个侦听器。actionPerformed
方法中执行任务)。因此,您需要将工作委托给另一个线程,例如使用SwingWorker。如果你不这样做,那么用户界面将会冻结,反馈将无法被用户查看。这就是说,它可能看起来很复杂或不平凡。因此,这里举一些简短的例子,说明所有这些和工作:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class TestProgressBar {
// Some simple listener interface to get a callback as bytes are being read
public static interface ProgressListener {
public void notifyByteRead();
}
// The wrapping input stream that will call the listener as bytes are being read
public static class ProgressInputStream extends InputStream {
private InputStream in;
@Override
public int read() throws IOException {
int read = in.read();
if (read > -1) {
// Here we notify the listener
listener.notifyByteRead();
}
return read;
}
@Override
public long skip(long n) throws IOException {
return in.skip(n);
}
@Override
public int available() throws IOException {
return in.available();
}
@Override
public void close() throws IOException {
in.close();
}
@Override
public void mark(int readlimit) {
in.mark(readlimit);
}
@Override
public void reset() throws IOException {
in.reset();
}
@Override
public boolean markSupported() {
return in.markSupported();
}
private ProgressListener listener;
public ProgressInputStream(InputStream in, ProgressListener listener) {
this.in = in;
this.listener = listener;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
init();
}
});
}
public static void init() {
// 1. Let's create a big object with lots of data
List<Long> object = new ArrayList<Long>();
Random random = new Random();
for (int i = 0; i < 1e6; i++) {
object.add(random.nextLong());
}
// 2. We write it to a temp file
File tempFile = null;
ObjectOutputStream oos = null;
try {
tempFile = File.createTempFile("Test", ".bin");
tempFile.deleteOnExit();
FileOutputStream fos = new FileOutputStream(tempFile);
oos = new ObjectOutputStream(new BufferedOutputStream(fos));
oos.writeObject(object);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} finally {
try {
if (oos != null) {
oos.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (tempFile == null) {
System.exit(1);
}
// 3. Now let's build a UI to load that
final File theFile = tempFile;
JFrame frame = new JFrame("Test ghost text");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
final JProgressBar bar = new JProgressBar(0, (int) tempFile.length());
JButton button = new JButton("load");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
bar.setValue(0);
// Declare and implement a Swing worker that will run in another thread
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>() {
@Override
protected void process(List<Integer> chunks) {
// Here we are on the EDT, so we can safely notify the progressbar
super.process(chunks);
bar.setValue(bar.getValue() + chunks.size());
}
@Override
protected Void doInBackground() throws Exception {
// Here we are not in the EDT, we perform the task but don't modify anything in the UI
ProgressInputStream pis = new ProgressInputStream(new BufferedInputStream(new FileInputStream(theFile)),
new ProgressListener() {
@Override
public void notifyByteRead() {
publish(1); // the value that is sent here could be anything, we don't use it.
}
});
ObjectInputStream ois = new ObjectInputStream(pis);
try {
List<Long> readObject = (List<Long>) ois.readObject();
System.err.println("Loaded " + readObject.size() + " long values");
} catch (Exception e) {
e.printStackTrace();
} finally {
pis.close();
}
return null;
}
};
// Start the worker
worker.execute();
}
});
panel.add(bar);
panel.add(button, BorderLayout.EAST);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
我会看看,非常感谢你的答案.. 加载可能很长或没有, 有没有什么,我可以使用输出对象使用进度条箱? 干杯 – nervousDev
@ user3738319通过扩展OutputStream来使用相同的原则。 –
你能给一个示例代码吗? – nervousDev