如何在加载bin文件时显示JProgressBar组件?
我只能找到迭代bin读取的解决方案,而且我使用的对象读取如下:
CustomObj test = (CustomObj) in.readObject();
干杯
答案 0 :(得分:1)
如果无法衡量流程的进度,则只能指定进度条的“不确定模式”。在此模式下,进度条将指示它正在工作,但该过程的完成未知。
JProgressBar progress = new JProgressBar();
progress.setIndeterminate(true);
答案 1 :(得分:1)
子类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();
您可以从其他线程(可能使用Swing计时器)对cis.getNumBytes()
进行采样,并使用返回的值更新JProgressBar
答案 2 :(得分:1)
我建议做两件事:
InputStream
并将所有内容委托给原始流(除了一些方法),并且在read()方法中,你确保通知一些监听器。actionPerformed
方法执行任务)。因此,您需要使用SwingWorker将工作委托给另一个Thread。如果您不这样做,则UI将冻结,用户将无法查看反馈。这就是说,它看似复杂或不平凡。因此,这里有一些简短的例子,说明了所有这些并起作用:
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);
}
}