2015-05-28 46 views
0

如果在執行RMI連接期間如何使我的進度條響應,我已經沒有任何想法了,所以我決定詢問您的幫助。使用Swing進度條的多線程

下面的代碼:

Thread performLogin = new Thread(new Runnable() 
{ 

    @Override 
    public void run() 
    { 
     LoginResult = TryLogin(); 
    } 
}); 

performLogin.start(); 
WaiterFrame.setVisible(true); 
SetProgressDialog(); 

try 
{ 
    performLogin.join(); 
} 
catch(InterruptedException exc) 
{ 
    System.err.println(exc.getLocalizedMessage()); 
} 

if (LoginResult) 
{ ... } 


WaiterFrame.setVisible(false); 
this.dispose(); 

進度條沒有反應 - 在執行performLogin線程沒有動畫,因爲它應該。我試圖在另一個線程上運行進度條框架,但結果相同(以及使用Eventqueue.invokelater())。

回答

1

可能的原因是performLogin.join();阻塞了事件派發線程,導致UI無響應。

Swing(和大多數GUI框架)要記住的兩件事情;

  1. 它是單線程的,如果你的塊EDT出於任何原因,將不再能夠處理新的事件或執行重繪
  2. 它不是線程安全的,所以你永遠不應該修改的狀態意來自EDT外部的UI。

你可以使用一個SwingWorker,這將讓你在後臺線程中運行長時間運行的過程,但提供了一些機制,通過它可以將更新發送回EDT安全的。

Worker Threads and SwingWorker更多細節和Issues with SwingWorker and JProgressBar爲例

1

如果您使用的是Java 8,你可以嘗試這樣的事:

CompletableFuture<LoginResult> loginResult = CompletableFuture.supplyAsync(this::tryLogin); 
WaiterFrame.setVisible(true); 
setProgressDialog(); 
loginResult.thenAccept(lr -> { 
    //do your thing 
    WaiterFrame.setVisible(false); 
}) 

有這取決於你需要做什麼其他選項「thenAccept」。 「然後接受」只消耗未來的內容。

如果Java 8不是一個選項,使用Guava的ListenableFuture和Executors也可以實現同樣的效果。

+0

感謝您的回覆,這個工具看起來非常有用的,但在我的情況沒有結果。在執行TryLogin()方法期間仍然沒有動畫(按照預期進行進度條動畫之後)。 – baka1408

0

非常感謝你MadProgrammer!進度條按照SwingWorker用法的預期工作。我張貼的代碼,如果有人鼓勵在未來同樣的問題:

PerformLogin = new SwingWorker<Boolean, Object>() 
{ 
    @Override 
    protected Boolean doInBackground() throws Exception 
    { 
     LoginResult = TryLogin(); 
     if (LoginResult) 
     { 
      MainF = new MainFrame(); 
      MainF.Connection = DataEntry.TestConnection; 
      MainF.prepareFormToShow(); 
     } 
     return LoginResult; 
    } 

    @Override 
    protected void done() 
    { 
     if (LoginResult == true) 
     { 
      EventQueue.invokeLater(new Runnable() 
       { 
        @Override 
        public void run() 
        { 
         MainF.setVisible(true); 
         WaiterFrame.setVisible(false); 
        } 
       }); 
     } 
     else 
     { 
      setVisible(true); 
      this.cancel(true); 
      JOptionPane.showMessageDialog(null, "Wrong adress!", 
      "Błąd",JOptionPane.WARNING_MESSAGE); 
     } 
    } 

WaiterFrame.setVisible(true); 
PerformLogin.execute(); 
在主線程