2012-09-10 22 views
1

在Button1被按下時,在以下代碼行中,直到encode()方法的執行完成,Jframe才變爲無響應狀態。但我需要更新顯示進度的Jframe中的進度條。從JButtonActionPerformed中調用耗時的方法

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {         
    try { 
     if (flagState == 0) { 
      WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode()); 
     } else if (flagState == 1) { 
      WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode());    
     } 
    } catch (WavFileException | IOException e) { 
     notes.setText(e.getMessage()); 
    } 
}   

我想這樣做

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {         
    try { 
     if (flagState == 0) { 
      Thread t = new Thread(new Runnable() { 
           public void run() { 
            WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode()); 
           } 
          };) 
      t.start(); 
     } else if (flagState == 1) { 
      Thread t = new Thread(new Runnable() { 
           public void run() { 
            WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode()); 
           } 
          };) 
      t.start(); 
     } 
    } catch (WavFileException | IOException e) { 
     notes.setText(e.getMessage()); 
    } 
} 

和更新從編碼()方法的進度條。

但我明白,這將是一個強大的模塊之間的耦合,我不希望這一點。

我也不認爲每次調用一個新的線程是一個好主意(想到ExecutorService,但不知道如何使用它)。

我該怎麼做才能使它成爲一個體面的代碼?

回答

1

線程肯定是你必須在這裏介紹的東西。任何花費大量時間完成的事情都不應該在awt事件線程中運行。

每次單擊按鈕時產生一個新線程本身並不是一個問題。但是,您應該考慮,即使第一次完成之前,也可能會產生許多執行相同操作的線程。如果你願意,你可以使用Executor,但它可能沒有必要。

至於跟蹤進度,我會添加另一個線程,定期查詢其他線程並根據需要更新進度欄。下面是我如何構造它:

private void Button1ActionPerformed(java.awt.event.ActionEvent evt) { 
    disableButton1(); 
    final Thread t; 
    if (flagState == 0) { 
     t = new Thread(new Runnable() { 
      public void run() { 
       try { 
        WavFile.decode(readWavFile, msg.getText(), key.getText().hashCode()); 
       } catch (WavFileException | IOException e) { 
        notes.setText(e.getMessage()); 
       } 
      } 
     }); 
    } else if (flagState == 1) { 
     t = new Thread(new Runnable() { 
      public void run() { 
       try { 
        WavFile.encode(readWavFile, msg.getText(), key.getText().hashCode()); 
       } catch (WavFileException | IOException e) { 
        notes.setText(e.getMessage()); 
       } 
      } 
     }); 
    } 

    Thread monitor = new Thread(new Runnable() { 
     public void run() { 
      try { 
       while (notComplete(t)) { 
        setProgressBar(getProgress(t)); 
        Thread.sleep(SLEEP_TIME); 
       } 
       t.join(); 
      } finally { 
       enableButton1(); 
      } 
     } 
    }); 

    t.start(); 
    monitor.start(); 
} 
+0

我從來沒有想過監視器線程。 我喜歡這種方法。非常感謝。 – Soumy

+2

'Thread monitor = new Thread(new Runnable(){ ... setProgressBar(getProgress(t));'如果'進度條'意味着'JProgressBar',則應該爲EDT調度該調用。 –

0

多線程是你所需要的,沒有其他好的方法我可以想到不用擔心調用新線程,這就是他們在那裏,jvm有一個線程池準備好使用,這種事情用線程運行真的很好,試試吧!

創建一個擴展Runnable的類,實現run方法或使其調用您當前的方法,這應該足以執行此操作。

此外,您也可以在短時間內睡個好覺,每次睡眠時間結束後檢查狀態,如果過程結束,您可以繼續,如果不能,再回到另一短時間睡覺,那樣您就不會不必多次提問。

我希望它有幫助。

相關問題