2016-02-13 39 views
0

這似乎是一個非常基本的問題,答案在我面前,但我仍然無法弄清楚什麼是錯的。我有一個按鈕,處理單擊事件時,我更改了標籤的樣式和文本。之後,我打電話給完成後再次改變風格的方法。JavaFX按鈕句柄()不調用方法

我的問題是,handle()方法中的樣式更改不會影響我的標籤,而是直接從默認樣式轉換爲connect()設置的樣式。

請注意,這並不是因爲它變化太快,connect()方法通常需要整整一秒才能完成,因爲它連接到遠程服務器。

我嘗試睡覺線程一秒鐘(如果我太慢)inbetween setStyle()和connect(),但無濟於事。我將不勝感激任何幫助,並希望沿途學習。

這是我的代碼:

Button loginButton = new Button(); 

    loginButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent event) { 
      loginStatus.setText("Loggin in..."); 

      //The line below should change the color until connect does it's thing, but it doesn't 
      loginStatus.setStyle("-fx-text-fill:#ffcc00"); 

      connect(username.getText(), password.getText(), serverField.getText()); 
     } 
    }); 

和connect()看起來是這樣的:

private void connect(String username, String password, String server) { 
    try { 
     api = new DiscordBuilder(username, password).build(); 
     api.login(); 
     api.joinInviteId(server); 
     api.getEventManager().registerListener(new ChatListener(api)); 

     //Instead, it goes straight from the old style to the style set below. 
     loginStatus.setStyle("-fx-text-fill:#009933"); 

     loginStatus.setText("Online"); 
    } catch (NoLoginDetailsException e) { 
     loginStatus.setText("No login details!"); 
     loginStatus.setStyle("-fx-text-fill:#cc3300"); 
     e.printStackTrace(); 
    } catch (BadUsernamePasswordException e) { 
     loginStatus.setText("Bad username or password!"); 
     loginStatus.setStyle("-fx-text-fill:#cc3300"); 
     e.printStackTrace(); 
    } catch (DiscordFailedToConnectException e) { 
     loginStatus.setText("Failed to connect!"); 
     loginStatus.setStyle("-fx-text-fill:#cc3300"); 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

回答

1

你需要的是Task

也爲表示here

JavaFX應用程序線程 上實現長時間運行的任務必然使得應用程序的用戶界面反應遲鈍。最佳做法是 在一個或多個後臺線程上執行這些任務,並讓JavaFX應用程序線程處理用戶事件。

使你的代碼看起來應該是這樣

Button loginButton = new Button(); 
    loginButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent event) { 
      loginStatus.setText("Loggin in..."); 
      //The line below should change the color until connect does it's thing, but it doesn't 
      loginStatus.setStyle("-fx-text-fill:#ffcc00"); 
      Task<Void> task = new Task<Void>() { 
       @Override 
       protected Void call() throws Exception { 
        connect(username.getText(), password.getText(), serverField.getText()); 
        return null; 
       } 
      }; 
      new Thread(task).start(); 
     } 
    }); 

,並在你的連接方式與周圍Platform.runLater

Platform.runLater(() -> { 
    loginStatus.setStyle("-fx-text-fill:#009933"); 
    loginStatus.setText("Online"); 
}) ; 
+0

謝謝你的UI更新方法!但是,在connect()方法中調用異常時,我遇到線程錯誤。如果沒有拋出異常,那就沒有問題了,因爲我移動了「成功」結果的setStyle。但是,我將如何處理異常,而不會得到「線程中的異常」Thread-4「java.lang.IllegalStateException:不在FX應用程序線程上; currentThread = Thread-4」? –

+0

我改變了connect()返回一個布爾值,以便我可以將setStyles移出catch子句。它會停止線程異常,但不會告訴我拋出了什麼樣的異常。我覺得我正在接近解決方案,有什麼想法? –

+0

好的,我編輯了我的答案,不要拋出關於在非FX應用程序線程中更新UI的例外... – guleryuz