2017-05-18 2 views
3

아래의 예제 코드에서는 파일 해시를 계산하는 데 사용합니다. 그래서 진행 상황을 보여주는 Jprogressbar를 시작합니다. 그러나 때로는 99 %에서 중지하고 때로는 실행되지 않습니다.JProgressbar는 어떻게 작동해야합니까?

이미 다른 자습서와 코드 예제를 읽었습니다.

구문 오류 또는 다른 것일 수 있습니까? 여기에 당신은 또한 당신의 ProgressBar를 업데이트해야합니다 -

감사

package progressbartest; 

    import java.awt.BorderLayout; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.beans.PropertyChangeEvent; 
    import java.beans.PropertyChangeListener; 
    import java.io.BufferedReader; 
    import java.io.File; 
    import java.io.FileInputStream; 
    import java.io.FileReader; 
    import java.io.IOException; 
    import java.security.MessageDigest; 
    import java.security.NoSuchAlgorithmException; 
    import java.util.logging.Level; 
    import java.util.logging.Logger; 
    import javax.swing.JButton; 
    import javax.swing.JFileChooser; 
    import javax.swing.JFrame; 
    import javax.swing.JLabel; 
    import javax.swing.JPanel; 
    import javax.swing.JProgressBar; 
    import javax.swing.JTextField; 
    import javax.swing.SwingWorker; 

    public class ProgressBarTest implements ActionListener, PropertyChangeListener{ 
    JFrame f; 
    JPanel p; 
    BorderLayout bdl; 
    JButton cf; 
    JTextField tf1; 
    JLabel ls; 
    JProgressBar progressBar; 
    JFileChooser fc; 
    File sf; 
    FileInputStream fis; 
    String hexRes1; 
    String hexRes2 = ""; 
    private Task task; 
    private int progress; 
    String selection; 

    public static void main(String[] args) { 
    new ProgressBarTest().startApp();// TODO code application logic here 
    } 

    private void startApp() { 
    f = new JFrame(); 
    p = new JPanel(); 
    bdl = new BorderLayout(); 
    cf = new JButton("Check-File"); 
    ls = new JLabel(); 
    tf1 = new JTextField(); 
    progressBar = new JProgressBar(0, 100); 
    progressBar.setValue(0); 
    progressBar.setStringPainted(true); 

    p.setLayout(bdl); 
    p.add(BorderLayout.NORTH, cf); 
    p.add(BorderLayout.CENTER, ls); 
    p.add(BorderLayout.WEST, tf1); 
    p.add(BorderLayout.SOUTH, progressBar); 

    fc = new JFileChooser(); 
    cf.addActionListener(this); 

    f.getContentPane().add(p); 
    //f.pack(); 
    f.setTitle("ProgressTest"); 
    f.setSize(950,350); 
    f.setResizable(false); 
    f.setVisible(true); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) throws NullPointerException { 
//System.out.println(javax.swing.SwingUtilities.isEventDispatchThread()); 
    //choose a file when the button cf is clicked 
    if (e.getSource() == cf) { 
     int returnVal = fc.showOpenDialog(p); 
     fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 
     if (returnVal == JFileChooser.APPROVE_OPTION)  
     sf = fc.getSelectedFile(); 
     //empty the values 
     tf1.setText(""); 
     hexRes2 = ""; 
    //start the task to calculate the file 
     task = new Task(); 
     task.addPropertyChangeListener(this); 
     task.execute(); 
     ls.setText("Wait !"); 
    } 
    } 


    class Task extends SwingWorker<Void, Void> { 
    /* 
    * Main task. Executed in background thread. 
    */ 
    @Override 
    public Void doInBackground() throws InterruptedException, IOException { 
    //progressbar variables to go thru the file 
    setProgress(0); 
    int progress = 0; 
    BufferedReader br = new BufferedReader(new FileReader(sf)); 
    String line = br.readLine(); 
    long readLength = 0; 
    long totalLength = sf.length(); 
    double lengthPerPercent = 100.0/totalLength; 
    //Thread.sleep(1000); 
    //while the line of the file isn't empty execute 
    try { 
     while (line != null) { 
     //Thread.sleep(100); 
     fis = new FileInputStream(sf); 
     //digest calculation 
     MessageDigest md = MessageDigest.getInstance("MD5"); 

     byte[] b = new byte[1024]; 
     int i; 
     while((i = fis.read(b)) >= 0) { 
     md.update(b, 0, i); 
     } while(i != -1) 
     fis.close(); 
     byte[] ba = md.digest(); 

     for (int j = 0; j < ba.length; j++) { 
     hexRes1 = Integer.toHexString((ba[j] & 255) | 256).substring(1); 
     hexRes2 += hexRes1; 
     } 
    // calculate progress. 
    readLength += line.length(); 
    progress = (int) (lengthPerPercent * readLength); 
    setProgress(Math.min(progress, 100)); 
    line = br.readLine(); 
    } //printing the value 
    tf1.setText(hexRes2); 

    } catch (IOException | NoSuchAlgorithmException ex) { 
    Logger.getLogger(ProgressBarTest.class.getName()).log(Level.SEVERE, null, ex); 
    } catch (NullPointerException ex) {f.repaint(); 
    } finally {fis.close();} 
    return null; 
     //System.out.println(javax.swing.SwingUtilities.isEventDispatchThread()); 
    } 
} 
    /* 
    * Executed in event dispatching thread 
    */ 
    public void done() { 
    progressBar.setValue(0); 
    ls.setText("Done!\n"); 
    } 
    /** 
    * Invoked when task's progress property changes. 
    */ 
    public void propertyChange(PropertyChangeEvent evt) { 
    if (evt.getPropertyName().equals("progress")) { 
    int progress = (Integer) evt.getNewValue(); 
    progressBar.setValue(progress); 
    } 
    }  
    } 
+0

같은 파일에서 문제가 발생합니까? –

+0

아니요, 작은 크기에서는 99 %로 멈추고 더 큰 크기는 멈추는 것처럼 보입니다. –

답변

3

while (line != null) { 루프와 함께 BufferedReader 부분을 제거하십시오, 당신은 바이트를 읽고 MD5를 업데이트 바로 읽기 루프를 둡니다. 이러한 변경 후에는 다음과 같이 수 :

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileReader; 
import java.io.IOException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JButton; 
import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 
import javax.swing.JTextField; 
import javax.swing.SwingWorker; 

public class ProgressBarTest implements ActionListener, PropertyChangeListener { 
    JFrame f; 
    JPanel p; 
    BorderLayout bdl; 
    JButton cf; 
    JTextField tf1; 
    JLabel ls; 
    JProgressBar progressBar; 
    JFileChooser fc; 
    File sf; 
    FileInputStream fis; 
    String hexRes1; 
    String hexRes2 = ""; 
    private Task task; 
    private int progress; 
    String selection; 

    public static void main(String[] args) { 
     new ProgressBarTest().startApp();// TODO code application logic here 
    } 

    private void startApp() { 
     f = new JFrame(); 
     p = new JPanel(); 
     bdl = new BorderLayout(); 
     cf = new JButton("Check-File"); 
     ls = new JLabel(); 
     tf1 = new JTextField(); 
     progressBar = new JProgressBar(0, 100); 
     progressBar.setValue(0); 
     progressBar.setStringPainted(true); 

     p.setLayout(bdl); 
     p.add(BorderLayout.NORTH, cf); 
     p.add(BorderLayout.CENTER, ls); 
     p.add(BorderLayout.WEST, tf1); 
     p.add(BorderLayout.SOUTH, progressBar); 

     fc = new JFileChooser(); 
     cf.addActionListener(this); 

     f.getContentPane().add(p); 
     // f.pack(); 
     f.setTitle("ProgressTest"); 
     f.setSize(950, 350); 
     f.setResizable(false); 
     f.setVisible(true); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) throws NullPointerException { 
     // System.out.println(javax.swing.SwingUtilities.isEventDispatchThread()); 
     // choose a file when the button cf is clicked 
     if (e.getSource() == cf) { 
      int returnVal = fc.showOpenDialog(p); 
      fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 
      if (returnVal == JFileChooser.APPROVE_OPTION) 
       sf = fc.getSelectedFile(); 
      // empty the values 
      tf1.setText(""); 
      hexRes2 = ""; 
      // start the task to calculate the file 
      task = new Task(); 
      task.addPropertyChangeListener(this); 
      task.execute(); 
      ls.setText("Wait !"); 
     } 
    } 

    class Task extends SwingWorker<Void, Void> { 
     /* 
     * Main task. Executed in background thread. 
     */ 
     @Override 
     public Void doInBackground() throws InterruptedException, IOException { 
      // progressbar variables to go thru the file 
      setProgress(0); 
      int progress = 0; 
      // BufferedReader br = new BufferedReader(new FileReader(sf)); 
      // String line = br.readLine(); 
      long readLength = 0; 
      long totalLength = sf.length(); 
      double lengthPerPercent = 100.0/totalLength; 
      // Thread.sleep(1000); 
      // while the line of the file isn't empty execute 
      try { 
       // while (line != null) { 
       // Thread.sleep(100); 
       fis = new FileInputStream(sf); 
       // digest calculation 
       MessageDigest md = MessageDigest.getInstance("MD5"); 

       byte[] b = new byte[1024]; 
       int readed; 
       while ((readed = fis.read(b)) >= 0) { 
        md.update(b, 0, readed); 
        // calculate progress.; 
        readLength = readLength + readed; 
        progress = (int) (lengthPerPercent * readLength); 
        setProgress(progress); 
       } 
       setProgress(100); 
       fis.close(); 
       byte[] ba = md.digest(); 

       for (int j = 0; j < ba.length; j++) { 
        hexRes1 = Integer.toHexString((ba[j] & 255) | 256).substring(1); 
        hexRes2 += hexRes1; 
       } 

       // line = br.readLine(); 
       // } //printing the value 
       tf1.setText(hexRes2); 

      } catch (IOException | NoSuchAlgorithmException ex) { 
       Logger.getLogger(ProgressBarTest.class.getName()).log(Level.SEVERE, null, ex); 
      } catch (NullPointerException ex) { 
       f.repaint(); 
      } finally { 
       fis.close(); 
      } 
      return null; 
      // System.out.println(javax.swing.SwingUtilities.isEventDispatchThread()); 
     } 
     /* 
     * Executed in event dispatching thread 
     */ 
     public void done() { 
      progressBar.setValue(0); 
      ls.setText("Done!\n"); 
     } 
    } 


    /** 
    * Invoked when task's progress property changes. 
    */ 
    public void propertyChange(PropertyChangeEvent evt) { 
     if (evt.getPropertyName().equals("progress")) { 
      int progress = (Integer) evt.getNewValue(); 
      progressBar.setValue(progress); 
     } 
    } 
} 
+0

코드를 다시 확인하면 done() 메서드를 스윙 작업자 내부에 배치해야합니다. 그 이유는 실행되지 않았기 때문입니다. –

+0

죄송합니다. 완료된 메소드가 Task 클래스 안에 있고 언급 된 while 루프가 제거되었습니다. 고맙습니다. –

2

당신의 doInBackground() 방법

while(i != -1) 
    fis.close(); 

나에게 매우 의심스러운 두 줄. i-1이 아닌 경우 반복되는 루프가 발생합니다.

fis.close(); 
+0

예, 그렇습니다. 이미 "finally {fis.close();}"가 있습니다. 고맙습니다 –

관련 문제