Meine Application
Klasse sieht so aus:
public class Test extends Application {
private static Logger logger = LogManager.getRootLogger();
@Override
public void start(Stage primaryStage) throws Exception {
String resourcePath = "/resources/fxml/MainView.fxml";
URL location = getClass().getResource(resourcePath);
FXMLLoader fxmlLoader = new FXMLLoader(location);
Scene scene = new Scene(fxmlLoader.load(), 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Das FXMLLoader
erstellt eine Instanz des entsprechenden Controllers (in der FXML
Datei über angegeben fx:controller
), indem zuerst der Standardkonstruktor und dann die initialize
Methode aufgerufen werden:
public class MainViewController {
public MainViewController() {
System.out.println("first");
}
@FXML
public void initialize() {
System.out.println("second");
}
}
Die Ausgabe ist:
first
second
Warum gibt es die initialize
Methode? Was ist der Unterschied zwischen der Verwendung eines Konstruktors oder der initialize
Methode zum Initialisieren der für den Controller erforderlichen Dinge?
Vielen Dank für Ihre Vorschläge!
FXMLLoader
, richtig? Ich sehe also keinen Vorteil darin, auf dieinitialize()
- Methode zu warten . Sobald die FXML geladen ist, hat der folgende Code Zugriff auf die@FXML
Variablen. Sicher, er macht es in der Startmethode und nicht im Konstruktor, würde aberinitialize()
in seinem Fall irgendeinen Nutzen bringen?Die
initialize
Methode wird aufgerufen, nachdem alle mit@FXML
Anmerkungen versehenen Elemente eingefügt wurden. Angenommen, Sie haben eine Tabellenansicht, die Sie mit Daten füllen möchten:class MyController { @FXML TableView<MyModel> tableView; public MyController() { tableView.getItems().addAll(getDataFromSource()); // results in NullPointerException, as tableView is null at this point. } @FXML public void initialize() { tableView.getItems().addAll(getDataFromSource()); // Perfectly Ok here, as FXMLLoader already populated all @FXML annotated members. } }
quelle
Zusätzlich zu den obigen Antworten sollte wahrscheinlich angemerkt werden, dass es einen alten Weg gibt, die Initialisierung zu implementieren. Es gibt eine Schnittstelle namens Initializable aus der fxml-Bibliothek.
import javafx.fxml.Initializable; class MyController implements Initializable { @FXML private TableView<MyModel> tableView; @Override public void initialize(URL location, ResourceBundle resources) { tableView.getItems().addAll(getDataFromSource()); } }
Parameter:
location - The location used to resolve relative paths for the root object, or null if the location is not known. resources - The resources used to localize the root object, or null if the root object was not localized.
Und der Hinweis in den Dokumenten, warum die einfache Verwendung
@FXML public void initialize()
funktioniert:NOTE
Diese Schnittstelle wurde durch die automatische Injektion von Standort- und Ressourceneigenschaften in die Steuerung ersetzt. FXMLLoader ruft nun automatisch alle vom Controller definierten, entsprechend kommentierten no-arg initialize () -Methoden auf. Es wird empfohlen, nach Möglichkeit den Injektionsansatz zu verwenden.quelle