Zalecane podejście
W odpowiedzi wymieniono różne mechanizmy przekazywania parametrów do kontrolerów FXML.
W przypadku małych aplikacji bardzo polecam przekazywanie parametrów bezpośrednio od dzwoniącego do kontrolera - jest to proste, proste i nie wymaga żadnych dodatkowych ram.
W przypadku większych, bardziej skomplikowanych aplikacji warto zbadać, czy chcesz użyć mechanizmów wstrzykiwania zależności lub magistrali zdarzeń w swojej aplikacji.
Przekazywanie parametrów bezpośrednio od dzwoniącego do kontrolera
Przekaż niestandardowe dane do kontrolera FXML, pobierając kontroler z instancji modułu ładującego FXML i wywołując metodę na kontrolerze, aby zainicjować go wymaganymi wartościami danych.
Coś w rodzaju następującego kodu:
public Stage showCustomerDialog(Customer customer) {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(
new Scene(
(Pane) loader.load()
)
);
CustomerDialogController controller =
loader.<CustomerDialogController>getController();
controller.initData(customer);
stage.show();
return stage;
}
...
class CustomerDialogController {
@FXML private Label customerName;
void initialize() {}
void initData(Customer customer) {
customerName.setText(customer.getName());
}
}
Nowy FXMLLoader jest zbudowany jak pokazano w przykładowym kodzie, tj new FXMLLoader(location)
. Lokalizacja jest adresem URL i możesz wygenerować taki adres URL z zasobu FXML poprzez:
new FXMLLoader(getClass().getResource("sample.fxml"));
Uważaj, aby NIE używać funkcji ładowania statycznego na FXMLLoader, w przeciwnym razie nie będziesz mógł pobrać kontrolera z instancji modułu ładującego.
Instancje FXMLLoader same nigdy nie wiedzą nic o obiektach domeny. Nie przekazujesz bezpośrednio obiektów domeny specyficznych dla aplikacji do konstruktora FXMLLoader, zamiast tego:
- Skonstruuj program FXMLLoader na podstawie znaczników fxml w określonej lokalizacji
- Pobierz kontroler z instancji FXMLLoader.
- Wywołaj metody na pobranym kontrolerze, aby zapewnić kontrolerowi odniesienia do obiektów domeny.
Ten blog (autorstwa innego autora) stanowi alternatywny, ale podobny przykład .
Ustawienie kontrolera w FXMLLoader
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
loader.setController(dialogController);
Pane mainPane = (Pane) loader.load();
Możesz zbudować nowy kontroler w kodzie, przekazując dowolne parametry od twojego programu wywołującego do konstruktora kontrolera. Po zbudowaniu kontrolera możesz ustawić go na instancji FXMLLoader przed wywołaniem load()
instancji metody .
Aby ustawić kontroler na fx:controller
module ładującym (w JavaFX 2.x), NIE MOŻNA również zdefiniować atrybutu w pliku fxml.
Ze względu na ograniczenia fx:controller
definicji w FXML osobiście wolę pobieranie kontrolera z FXMLLoadera niż ustawienie kontrolera w FXMLLoader.
Posiadanie przez kontroler parametrów do pobrania z zewnętrznej metody statycznej
Przykładem tej metody jest odpowiedź Siergieja na Javafx 2.0 How-to Application.getParameters () w pliku Controller.java .
Użyj wstrzykiwania zależności
FXMLLoader obsługuje systemy wstrzykiwania zależności, takie jak Guice, Spring lub Java EE CDI, umożliwiając ustawienie niestandardowej fabryki kontrolerów w FXMLLoader. Zapewnia to wywołanie zwrotne, którego można użyć do utworzenia instancji kontrolera z wartościami zależnymi wprowadzonymi przez odpowiedni system wstrzykiwania zależności.
Przykład aplikacji JavaFX i wstrzykiwania zależności kontrolera za pomocą Springa znajduje się w odpowiedzi na:
Naprawdę ładne, czyste podejście do wstrzykiwania zależności jest zilustrowane przez framework afterburner.fx z przykładową aplikacją hakerską, która go używa. afterburner.fx opiera się na JEE6 javax.inject wykonuje iniekcję zależności .
Użyj magistrali zdarzeń
Greg Brown, oryginalny twórca i implementator specyfikacji FXML, często sugeruje rozważenie zastosowania magistrali zdarzeń, takiej jak Guava EventBus , do komunikacji między kontrolerami utworzonymi przez FXML i inną logiką aplikacji.
EventBus to prosty, ale potężny interfejs API do publikowania / subskrybowania z adnotacjami, który pozwala POJO komunikować się ze sobą w dowolnym miejscu w JVM bez konieczności odwoływania się do siebie.
Dalsze pytania i odpowiedzi
przy pierwszej metodzie, dlaczego zwracasz scenę? Metoda może być również nieważna, ponieważ już dajesz komendę show (); tuż przed etapem powrotu; Jak planujesz użycie, zwracając stół montażowy
Jest to funkcjonalne rozwiązanie problemu. Etap jest zwracany z showCustomerDialog
funkcji, aby odwołanie do niego mogło zostać zapisane przez klasę zewnętrzną, która może chcieć coś zrobić, na przykład ukryć scenę na podstawie kliknięcia przycisku w oknie głównym w późniejszym czasie. Alternatywne, obiektowe rozwiązanie może zawierać funkcjonalność i odniesienie do etapu wewnątrz obiektu CustomerDialog lub może mieć rozszerzenie Stage CustomerDialog. Pełny przykład zorientowanego obiektowo interfejsu niestandardowego okna dialogowego zawierającego dane FXML, dane kontrolera i modelu wykracza poza zakres tej odpowiedzi, ale może stanowić cenny post na blogu dla każdego, kto chce go utworzyć.
Dodatkowe informacje dostarczone przez użytkownika StackOverflow o nazwie @dzim
Przykład wstrzykiwania zależności rozruchu wiosennego
Pytanie jak to zrobić „The Spring Boot Way”, odbyła się dyskusja na temat JavaFX 2, na którą odpowiedziałem w załączonym permalink. Podejście to jest nadal aktualne i przetestowane w marcu 2016 r. Na Spring Boot v1.3.3. UWOLNIENIE:
https://stackoverflow.com/a/36310391/1281217
Czasami możesz chcieć przekazać wyniki dzwoniącemu, w którym to przypadku możesz sprawdzić odpowiedź na powiązane pytanie: