Jak mogę przekazać parametry do dodatkowego okna w javafx? Czy istnieje sposób komunikowania się z odpowiednim kontrolerem?
Na przykład: użytkownik wybiera klienta z TableView
i otwiera się nowe okno, pokazujące informacje o kliencie.
Stage newStage = new Stage();
try
{
AnchorPane page = (AnchorPane) FXMLLoader.load(HectorGestion.class.getResource(fxmlResource));
Scene scene = new Scene(page);
newStage.setScene(scene);
newStage.setTitle(windowTitle);
newStage.setResizable(isResizable);
if(showRightAway)
{
newStage.show();
}
}
newStage
byłoby nowe okno. Problem polega na tym, że nie mogę znaleźć sposobu, aby powiedzieć kontrolerowi, gdzie ma szukać informacji o kliencie (przekazując identyfikator jako parametr).
Jakieś pomysły?
Odpowiedzi:
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:
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: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:
Ten blog (autorstwa innego autora) stanowi alternatywny, ale podobny przykład .
Ustawienie kontrolera w FXMLLoader
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.
Dalsze pytania i odpowiedzi
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:
źródło
W tym przykładzie użyjemy 5 plików:
Wszystkie pliki są wymienione w całości na dole tego postu.
Cel: wykazać przekazywanie wartości od
Controller1
doController2
i odwrotnie.Przebieg programu:
TextField
, aButton
i aLabel
. KiedyButton
kliknięciu drugie okno jest ładowane i wyświetlane, w tym tekst wprowadzony wTextField
.TextField
, aButton
i aLabel
.Label
Wyświetli tekst wprowadzony wTextField
na pierwszym miejscu.TextField
i kliknięciu jejButton
, pierwsza scenaLabel
jest aktualizowana, aby pokazać wprowadzony tekst.Jest to bardzo prosta demonstracja, która z pewnością może oznaczać pewną poprawę, ale powinna wyjaśnić tę koncepcję bardzo wyraźnie.
Sam kod jest również komentowany z pewnymi szczegółami o tym, co się dzieje i jak.
Main.java:
Controller1.java:
Controller2.java:
Layout1.fxml:
Layout2.fxml:
źródło
loader.setController(this)
i dodanie kontrolera do pliku FXML powoduje awarię aplikacjiloader.getController()
Klasa javafx.scene.Node ma parę metod setUserData (Object) i Object getUserData ()
Którego możesz użyć, aby dodać swoje informacje do Węzła.
Możesz więc wywołać page.setUserData (informacje);
Kontroler może sprawdzić, czy ustawione są informacje. W razie potrzeby można również użyć ObjectProperty do przesyłania danych wstecz.
Zapoznaj się z dokumentacją tutaj: http://docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html Przed frazą „W pierwszej wersji uchwytButtonAction () jest oznaczony @FXML aby umożliwić wywołanie znaczników zdefiniowanych w dokumencie kontrolera. W drugim przykładzie pole przycisku jest opatrzone adnotacjami, aby umożliwić modułowi ładującemu ustawienie swojej wartości. Metoda initialize () jest podobnie opisana. ”
Musisz więc powiązać kontroler z węzłem i ustawić dane użytkownika w węźle.
źródło
Oto przykład przekazywania parametrów do dokumentu fxml przez przestrzeń nazw.
Zdefiniuj wartość
External Text
dla zmiennej przestrzeni nazwlabelText
:źródło
FXMLLoader.CONTROLLER_KEYWORD
,FXMLLoader.LOCATION_KEY
,FXMLLoader.RESOURCES_KEY
i dowolny ciąg znaków używany jako wartość dlafx:id
atrybutu.To działa ..
Pamiętaj, że po pierwszym wydrukowaniu wartości przechodzącej otrzymasz null, możesz jej użyć po załadowaniu systemu Windows, to samo dla wszystkiego, co chcesz zakodować dla dowolnego innego komponentu.
źródło
Musisz utworzyć jedną klasę kontekstu.
Musisz tylko ustawić wystąpienie kontrolera podczas inicjalizacji za pomocą
i możesz go używać z całej aplikacji, używając tylko
Teraz możesz przekazać parametr do dowolnego kontrolera z całej aplikacji.
źródło
Tak, możesz.
Musisz dodać w pierwszym kontrolerze:
Następnie w drugim zadeklaruj klienta, a następnie u dołu kontrolera:
źródło
Oto przykład użycia kontrolera wprowadzonego przez Guice'a.
Oto konkretne wdrożenie modułu ładującego:
Zauważ, że ten przykład ładuje widok do środka BoarderPane, który jest korzeniem Sceny na stole montażowym. Nie ma to znaczenia dla przykładu (szczegóły implementacji mojego konkretnego przypadku użycia), ale postanowiłem go zostawić, ponieważ niektórzy mogą uznać go za użyteczny.
źródło
Możesz zdecydować się na użycie publicznej listy obserwowalnej do przechowywania danych publicznych lub po prostu utworzyć publiczną metodę ustawiania do przechowywania danych i pobierania z odpowiedniego kontrolera
źródło
Po co odpowiadać na 6-letnie pytanie?
Jedną z najbardziej podstawowych koncepcji pracy z dowolnym językiem programowania jest nawigacja z jednego okna (formularza, strony lub strony) do drugiego. Również podczas tej nawigacji programista często chce przekazywać dane z jednego (okna, formularza lub strony) i wyświetlać lub wykorzystywać przekazane dane.
Podczas gdy większość odpowiedzi tutaj zawiera dobre lub doskonałe przykłady, jak to osiągnąć, myśleliśmy, że będziemy to robić wycięcie, dwa lub trzy
Powiedzieliśmy trzy, ponieważ będziemy nawigować między trzema (okno, formularz lub strona) i używać pojęcia zmiennych statycznych do przekazywania danych wokół (okna, formularza lub strony)
Będziemy również zawierać kod decyzyjny podczas nawigujemy
Uruchom kontroler
Page One Controller
Page Two Controller
Poniżej znajdują się wszystkie pliki FXML
źródło