2014-06-20 128 views
0

如何在加载bin文件时显示JProgressBar组件?加载bin文件的进度条

我只能发现迭代箱解决方案可读取和我使用的对象读取,如:

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

干杯

回答

1

如果你不能测量过程的进展,那么你就可以只指定进度条的“不确定模式”。在这种模式下,进度条会指示它正在工作,但过程的完成是未知的。

JProgressBar progress = new JProgressBar(); 
progress.setIndeterminate(true); 
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(); 

可以从不同的线程进行采样cis.getNumBytes()(可能与一个Swing计时器)并使用返回值更新JProgressBar

+0

你能给一个示例代码吗? – nervousDev

1

我建议做两件事:

  1. 在您的原始输入流周围创建一个包装类,以便您可以监视从它读取的字节。基本上,您扩展了InputStream并将所有内容委托给原始流(几个方法除外),并在read()方法中确保通知某个侦听器。
  2. 我想,如果你想要一个进度条,这意味着加载操作需要一段时间,你想提供反馈给用户。长时间运行的任务不能直接在EDT上运行(因此通常,您不能在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); 
    } 
} 
+0

我会看看,非常感谢你的答案.. 加载可能很长或没有, 有没有什么,我可以使用输出对象使用进度条箱? 干杯 – nervousDev

+0

@ user3738319通过扩展OutputStream来使用相同的原则。 –