bin文件加载的进度条

时间:2014-06-20 20:14:07

标签: java swing loading bin

如何在加载bin文件时显示JProgressBar组件?

我只能找到迭代bin读取的解决方案,而且我使用的对象读取如下:

CustomObj test = (CustomObj) in.readObject();

干杯

3 个答案:

答案 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)

我建议做两件事:

  1. 围绕原始输入流创建包装类,以便您可以监视从中读取的字节数。基本上,你扩展InputStream并将所有内容委托给原始流(除了一些方法),并且在read()方法中,你确保通知一些监听器。
  2. 我想如果你想要一个进度条,这意味着加载操作需要一段时间,你想向用户提供反馈。长时间运行的任务无法直接在EDT上运行(通常,您无法使用actionPerformed方法执行任务)。因此,您需要使用SwingWorker将工作委托给另一个Thread。如果您不这样做,则UI将冻结,用户将无法查看反馈。
  3. 这就是说,它看似复杂或不平凡。因此,这里有一些简短的例子,说明了所有这些并起作用:

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