2015-05-13 5 views
9

Wird @FXML für jede Deklaration oder nur für die erste benötigt?Wird @FXML für jede Deklaration benötigt?

In anderen Worten, sollte ich

@FXML 
public Label timerLabel = new Label(); 
@FXML 
public TextField mainTextField, projectTextField ; 
@FXML 
public Button goButton, deleteAllButton ; 
@FXML 
public ComboBox<String> projectComboBox ; 
@FXML 
public TableView<Entry> mainTable ; 
@FXML 
public TableColumn<Entry, String> titleColumn, timeColumn, dateColumn ; 
@FXML 
public TableColumn<Entry, Boolean> checkColumn, buttonColumn ; 
@FXML 
public checkBox checkAllCheckBox ; 

Oder

@FXML 
public Label timerLabel = new Label(); 
public TextField mainTextField, projectTextField ; 
public Button goButton, deleteAllButton ; 
public ComboBox<String> projectComboBox ; 
public TableView<Entry> mainTable ; 
public TableColumn<Entry, String> titleColumn, timeColumn, dateColumn ; 
public TableColumn<Entry, Boolean> checkColumn, buttonColumn ; 
public checkBox checkAllCheckBox ; 

Vielen Dank!

+3

Ausprobieren beide;) – ItachiUchiha

+0

Ich kann keine Unterschiede sehen: | – Romeo

+0

Ich habe nie die zweite Lösung gesehen. Ich denke, das ist nicht möglich. versuchen Sie es einfach –

Antwort

29

Die Annotation @FXML ermöglicht es einem FXMLLoader, in einer FXML-Datei definierte Werte in Referenzen in der Controller-Klasse einzufügen. Mit anderen Worten, wenn Sie Ihre timerLabel mit @FXML annotieren, wird es durch die FXMLLoader initialisiert, wenn die load() Methode von einem Element in der FXML-Datei mit fx:id="timerLabel" aufgerufen wird. Wie andere in den Kommentaren darauf hingewiesen haben, bedeutet dies, sollten Sie nie Code wie

@FXML 
private Label timerLabel = new Label(); 

Hier schreiben timerLabel wird zuerst auf die Sie im Code erstellen new Label(); initialisiert werden und wird dann fast sofort auf die neu initialisiert werden Wert in der FXML-Datei definiert. Dies ist bestenfalls redundant und im schlimmsten Fall irreführend. Wenn Sie die Variablennamen nicht korrekt an fx:id anpassen, wird Ihre Variable auf die falsche Label verweisen und der Fehler wird sehr schwer zu finden sein.

Um zu Ihrer eigentlichen Frage zu kommen:

Wenn die FXMLLoader die FXML-Datei lädt, wird es alle Elemente zu injizieren versuchen, ein fx:id in den Controller-Attribut haben. Es sieht für

  1. Jedes public Feld mit einem Variablenname das fx:id Attribut übereinstimmt, oder
  2. Jedes Feld (public oder nicht) mit einem Variablennamen das fx:id Attribut passend, die mit @FXML kommentiert wird.

So in Ihrem Beispiel, da alle Felder public sind, können Sie alle @FXML Anmerkungen (auch die erste) auslassen und es wird immer noch funktionieren.

Wenn Sie jedoch gute Praktiken befolgen und Ihre Felder private erstellen, muss jede Deklaration mit @FXML versehen werden, damit die Injektion funktioniert.

So

@FXML 
private Label timerLabel; 
@FXML 
private TextField mainTextField; 

etc funktionieren wird, aber

@FXML 
private Label timerLabel; 
private TextField mainTextField; 

nicht.

+0

Ist eine Injektion erforderlich? Gibt es eine Möglichkeit, den Loader nur nach der Kontrolle zu fragen, die mich interessiert (von fx: id)? – Joel

+0

Nicht sicher, dass ich diese Frage verstehe. Ist das nicht genau was Injektion tut? –

4

für jede

fx:id="somename" 

benötigen Sie ein

@FXML 
public SomeClass somename; 

ich es in einer Zeile zu schreiben bevorzugen, weil es einfacher ist, zu lesen, wenn es viele

@FXML public SomeClass somename; 

ohne

Initialisierung
@FXML 
public Label timerLabel = new Label(); // this is wrong 
+1

wird nicht 'timerLabel = new Label();' durch 'FXMLLoader' überschrieben? – Andrew