2017-08-09 8 views
1

ソースからコピー先にコピーされるファイルの進行状況を監視したいと考えました。私は​​というキーワードを使っていますが、どういうわけかそれは私の期待通りに動作していない、私のロジックが間違っているかもしれません。あなたが私を助けてくれたら嬉しいです。 私のコードはここにあります。jProgressBarを使用した同期コピー表示

public class Download extends javax.swing.JFrame { 
    int val=0; 
    private Timer t; 
    private ActionListener a; 

/* Creates new form Download */ 
    public Download() { 
     initComponents(); 
     jProgressBar1.setValue(val); 
     a = new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
      if (jProgressBar1.getValue() < val) 
       jProgressBar1.setValue(jProgressBar1.getValue()+1); 
      else 
       t.stop(); 
      }   
     }; 
    } 
    public synchronized void copy(String source,String url) 
    { 
     try {  
     val+=25; 
     t=new Timer(200,a); 
     t.start(); 
     FileInputStream fs = new FileInputStream(source); 
     FileOutputStream os = new FileOutputStream(url); 
     int b; 
     while ((b = fs.read()) != -1) { 
      os.write(b); 
     } 
     os.close(); 
     fs.close(); 
     } catch (Exception E) { 
     E.printStackTrace(); 
     }   
    } 

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
     JFileChooser chooser = new JFileChooser(); 
     chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 
     String url = null; 
     int returnValue = chooser.showDialog(null, "Select"); 
     if (returnValue == JFileChooser.APPROVE_OPTION) { 
     url = chooser.getSelectedFile().getPath(); 
     } else { 
     dispose(); 
     } 
     JOptionPane.showMessageDialog(this,"Wait for Completion"); 

     if(CB1.isSelected()==true) 
     { 
     File f = new File(getClass().getResource("/PCycle/Ele.pdf").getFile()); 
     String source= f.getAbsolutePath(); 
     copy(source,(url+"\\"+CB1.getText()+".pdf")); 
     } 
     if(CB2.isSelected()==true) 
     { 
     File f = new File(getClass().getResource("/PCycle/Mech.pdf").getFile()); 
     String source= f.getAbsolutePath(); 
     copy(source,(url+"\\"+CB2.getText()+".pdf")); 
     } 
     if(CB3.isSelected()==true) 
     { 
     File f = new File(getClass().getResource("/PCycle/Phy.pdf").getFile()); 
     String source= f.getAbsolutePath(); 
     copy(source,(url+"\\"+CB3.getText()+".pdf")); 
     } 
     if(CB4.isSelected()==true) 
     { 
     File f = new File(getClass().getResource("/PCycle/Civil.pdf").getFile()); 
     String source= f.getAbsolutePath(); 
     copy(source,(url+"\\"+CB4.getText()+".pdf")); 
     } 

     JOptionPane.showMessageDialog(this,"Completed"); 

     try { 
      jProgressBar1.setValue(100);     
      Thread.sleep(3000); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(Download.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     System.exit(0); 
    } 
} 

ここで私たちは、「コピー」メソッドを呼び出したときにそれがある場所から別の場所にファイルをコピーし、その前に、それはそれによって上の進行状況をタイマーメソッドを実行する必要があること、このようにロジックを実装してみましたjProgressBarが表示されます。しかし、残念ながら​​を使用した後でも、各ファイルの進捗状況は表示されません。

+0

ストリームから、もしプロセスがほんの些細な時間を要するならば、 – AJNeufeld

答えて

1

問題は、Swingのイベントディスパッチスレッド(EDT)をブロックしていることです。

イベントに応答してEDTがビジーでない場合、スイングはすべて描画を行います。この場合、jButton1ActionPerformedはすべてのファイルがコピーされるまで返されません。だから、が各copy()コールの間に開始されますが、jButton1ActionPerformedは一度も返されていないため、タイマーは期限切れになることはありません。

この場合、SwingWorkerを使用してバックグラウンドスレッドのファイルをコピーします。

  • が作成メインスレッドでタイマーを開始
  • SwingWorkerを開始します。
    • あなたはファイルのコピーを開始します

    • タイマーが切れると、お使いのプログレスバーが進める、と描かれる
  • さらにユーザのアクションをブロックする(またはその他のUIを無効にする)ためにモデルダイアログを開きます。
  • SwingWorker
  • は(EDT上で実行される)done()ある、
    • タイマー
    • ダイアログ(または再イネーブルUI)を却下停止

:バックグラウンドワーカースレッドからUIアイテムを作成またはアクセスしたり、タイマーを作成/開始/停止したりしないでください。これらのアクションは、EDTでのみ実行する必要があります。


ラフ例では、UI要素を無効に示すSwingWorkerを開始、作業者からの公開は、(ダウンロードされているファイル)の進行状況を表示するには、作業者が終了したときにUIを可能にします。

ファイルコピーは3秒のスリープを使用して偽装されます。あなたは自動的に読み取り中に進捗モニターを開く、[ProgressMonitorInputStream](https://docs.oracle.com/javase/8/docs/api/javax/swing/ProgressMonitorInputStream.html)を使用することをお勧めします

package progress; 

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.util.List; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JProgressBar; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 
import javax.swing.Timer; 

@SuppressWarnings("serial") 
public class Download extends JFrame { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(Download::new); 
    } 

    private final JButton downloadBtn = new JButton("Start Download"); 
    private final JProgressBar progressBar = new JProgressBar(); 
    private final Timer timer = new Timer(200, this::timerTick); 

    Download() { 
     super("Download Example"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setSize(400, 300); 
     setLocationByPlatform(true); 

     downloadBtn.addActionListener(this::startDownload); 
     add(downloadBtn, BorderLayout.PAGE_START); 

     progressBar.setStringPainted(true); 
     add(progressBar, BorderLayout.PAGE_END); 

     setVisible(true); 
    } 

    private void startDownload(ActionEvent evt) { 
     downloadBtn.setEnabled(false); 
     timer.start(); 
     DownloadWorker worker = new DownloadWorker("File1", "FileB", "AnotherFile"); 
     worker.execute(); 
    } 

    private void timerTick(ActionEvent evt) { 
     progressBar.setValue(progressBar.getValue()+2); 
    } 

    private class DownloadWorker extends SwingWorker<Void, String> { 

     private final String[] files; 

     DownloadWorker(String ...files) { 
      this.files = files; 

      progressBar.setValue(0); 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      for(String file : files) { 
       publish(file); 

       // Copy the file 
       Thread.sleep(3000); // Pretend copy takes a few seconds 
      } 
      return null; 
     } 

     @Override 
     protected void process(List<String> chunks) { 
      String file = chunks.get(chunks.size()-1); // Just last published filename 
      progressBar.setString("Downloading "+file + " ..."); 
     } 

     @Override 
     protected void done() { 
      progressBar.setString("Complete"); 
      progressBar.setValue(100); 
      timer.stop(); 
      downloadBtn.setEnabled(true); // Re-enable UI 
     } 
    } 
} 
+0

ありがとうございます。 もっと早く例を挙げることができれば、もっと役立つでしょう。 –

+0

例が追加されました。あなたのニーズに合っていれば幸いです。問題のサンプルコードをコード化しようとしたように、プログレスバーはタイマーティックごとに固定量だけ進んでいます。理想的には、コピーしたバイト数を作業者に照会し、実際の進捗率などを計算することができます。 – AJNeufeld

+0

ありがとう、私は変更を適応し、本当に助けになりました。 –

関連する問題