2016-06-12 516 views
0

我開始研究JavaFX FXML應用程序技術。JavaFX FXML訪問成功使用lookup()方法,但不使用@FXML註釋

我使用主類中訪問的一個主舞臺Main.getStage(),它在應用程序開始時使用重寫方法public void start(Stage stage)調用。在內部有兩個public static Scene以在切換它們時保持持久性。

@Override 
public void start(Stage stage) throws Exception { 
    STAGE = stage; 
    LOGIN = new Scene(FXMLLoader.load(getClass().getResource("Login.fxml"))); 
    REGISTER = new Scene(FXMLLoader.load(getClass().getResource("Register.fxml"))); 

    STAGE.setScene(LOGIN); 
    STAGE.setTitle("FXApplication"); 
    STAGE.show(); 
} 

public static Stage getStage() { 
    return STAGE; 
} 

這兩個場景都有相同的控制器類,稱爲MainController。使用:

  • 按鍵採用fx:id="buttonLoginRegister"REGISTER場景
  • 按鍵採用fx:id="buttonRegisterBack"回去給LOGIN之一。

並且兩者具有相同的onClick事件handleButtonAction(ActionEvent event)。 TextFields是用於登錄/註冊用戶名的字段。

​​

我的目標是將值從LOGIN文本字段複製到一個在REGISTER現場。它使用上面的代碼很好用。然而,首先我嘗試訪問另一個場景中的元素:

fieldRegisterUsername.setText(fieldLoginUsername.getText()); 

這是錯誤的。確切地說,fieldRegisterUsernamenull

爲什麼在lookup(String id)方法中發現某些元素而不是@FXML註釋?

+0

通常不鼓勵用於不同FXML(視圖)的共享控制器。如果你只是從JavaFX開始,我特別建議不要這樣做。看看[這個問題](http://stackoverflow.com/questions/17914254/javafx-multiple-fxml-and-1-shared-controller)。 – Itai

+0

這是有爭議的,很多開發人員使用這種方式,並且相同的數字是最簡單的。就我個人而言,在2個小場景中我看不出共享控制器的壞處。我之前已經閱讀過這個鏈接的問題,但是這與我的持久性需求相沖突。 –

+0

不知道我明白你的意思是「需要堅持」。查看我的答案,解釋爲什麼'lookup'在你的情況下起作用。請記住,除非你爲'FXMLLoader'設置了控制器,否則每次調用'load'都會創建一個控制器類的新實例。 – Itai

回答

2

正如我的評論中提到的,在不同視圖之間共享控制器並不是一個好主意,我強烈建議您爲每個視圖製作一個單獨的控制器。

至於你的問題本身 - 你有兩個控制器類的實例,每調用一次FXMLLoader.load。據推測,一個視圖具有fieldLoginUsername TextField,而另一個視圖具有fieldRegisterUsername
如果滿足if聲明的條件,則表示活動場景是登錄場景,因此處理它的控制器是具有fieldLoginUsername的控制器,因此fieldRegisterUsername自然會爲空。

但在if子句中更改活動現場向登記冊之一,所以,當你打電話的時候scene#lookup你指的是其控制器的註冊控制器,一個是確實有fieldRegisterUsername現場的第一線。

如果您在更改活動場景之前調用scene#lookup,您會發現它也會返回null。

如果您必須對控制器使用相同的類,那麼您可能希望確保只有該類的一個實例。這將需要使用FXMLLoader#setController

+0

感謝您的解釋。如果在不同的Scanes之間使用一個控制器是一個壞主意,您是否會建議我使用兩個分離的控制器來實現相同效果?我不知道如何輕鬆傳遞價值。 –

+0

Arjan在對原始問題的評論中鏈接了兩個優秀的答案。 – Itai