Jak utworzyć wiele kontrolerów javafx z różnymi plikami fxml?
Przeglądałem kilka blogów i innych pytań stackoverflow i nie widzę bezpośredniej odpowiedzi na moje pytanie. Tworzę klienta javafx gui i chcę, aby mój pasek menu był jednym kontrolerem w jednym fxml, a następnie chcę, aby obszar zawartości był dodatkowymi plikami fxml. Ekran logowania będzie jednym fxml, po ekranie logowania będzie główna Zawartość aplikacji i to będzie w jednym fxml. Jak mam to zrobić?
Po prostu nie chcę mieć cały mój kod do logowania, paska menu i głównej zawartości w tym samym pliku. To jest obraz tego, nad czym pracuję:
4 answers
Użyj FXML jako komponentów, używając niestandardowej klasy java jako FX: root i jako FX: controller Twojego pliku FXML: http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm
Aby to zrobić, musisz wywołać konstruktor swojej niestandardowej klasy java FXMLLoader, która załaduje Twój FXML. Zaletą jest zmiana sposobu ładowania komponentów FXML.
Klasyczny sposób instancjowania komponentów przez FXMLLoader z zagnieżdżonymi kontrolerami to: FXML first, then controller for each część.
W tej technice jest to: controller first, then FXML for each component. I nie będziesz ładować FXML bezpośrednio w FXML, zaimportujesz swoje niestandardowe klasy java w FXML.
Jest to lepsza abstrakcja (nie trzeba wiedzieć, jak komponent jest zaimplementowany, gdy importujesz je do FXML) i pomaga ponownie używać kodu, jak to jest jak implementacja niestandardowego widżetu z obsługą FXML. Aby komponent mógł być wielokrotnego użytku, upewnij się, że implementacja nie jest ściśle powiązana z innymi części, lub użyć IOC do tego (na przykład, z integracją Spring z JavaFX). W ten sposób będziesz mógł bez obaw zaimportować komponent do dowolnej części aplikacji (tak jak widżet DateInput) i nie zduplikujesz kodu.
W Twoim przypadku będziesz miał:
public class MenuBox extends VBox {
@FXML
private LoginBox loginBox;
@FXML
private ProfilesBox profilesBox;
public MenuBox() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("menu.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public class LoginBox extends VBox {
public LoginBox() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("login.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public class ProfilesBox extends VBox {
public ProfilesBox() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("profiles.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
I zaimportujesz LoginBox i ProfilesBox w menu.fxml, który zarządza globalnym układem strony:
<?import com.foo.bar.LoginBox ?>
<?import com.foo.bar.ProfilesBox ?>
<fx:root type="javafx.scene.layout.VBox"
xmlns:fx="http://javafx.com/fxml">
<!-- Stuff here to declare the menu bar-->
<HBox>
<ProfilesBox fx:id="profilesBox"/>
<LoginBox fx:id="loginBox"/>
</HBox>
</fx:root>
Login.fxml i profile.fxml zawiera tylko podstawowe składniki.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-14 12:31:47
-
Możesz dołączyć dokumenty FXML jeden w drugim - powinno to pomóc w oddzieleniu logiki projektu
Oznacza to, że możesz mieć zagnieżdżone Kontrolery - po jednym dla każdego dokumentu.
Z dokumentacji, możesz teraz skonfigurować kod tak, aby logika mogła być oddzielona od kontrolera głównego (jeśli zajdzie taka potrzeba).
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-13 05:53:57
Potrzebowałem wyskakującego okna o podobnych wymaganiach(większa kontrola nad węzłami i układem).
Po zapoznaniu się z zaleceniami znalazłem rozwiązanie, które może być przydatne.Najpierw utworzyłem drugi dokument fxml i drugi kontroler (w NetBeans, New - > Empty FXML ... - >Użyj Kontrolera Java - > Utwórz Nowy...).
Małym wyzwaniem było wymyślenie, jak zbudować scenę w głównym kontrolerze i podłączyć ją do kontrolera popup.
Link przekazujący parametry JavaFX FXML daje naprawdę dobre spostrzeżenia i techniki.
Końcowy kod wygląda tak (mam nadzieję, że komuś pomoże):
// Anchor Pane from the popup
@FXML
AnchorPane anchorPanePopup;
@FXML
private void soneButtonAction(ActionEvent event) throws IOException {
Stage newStage = new Stage();
AnchorPane anchorPanePopup = (AnchorPane) FXMLLoader.load(getClass().getResource("Popup_FXML.fxml"));
Scene scene = new Scene(anchorPanePopup);
newStage.setScene(scene);
newStage.initModality(Modality.APPLICATION_MODAL);
newStage.setTitle("Dialog Window");
newStage.showAndWait();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:16
package javafxapplication11;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.stage.Stage;
public class FXMLDocumentController implements Initializable {
@FXML
private CheckBox c1;
@FXML
private CheckBox c2;
public void clicked1(ActionEvent e) throws IOException {
Parent home_page_parent
=FXMLLoader.load(getClass().getResource("AddDcuFXML.fxml"));
Scene home_page_scene = new Scene(home_page_parent);
Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
app_stage.hide(); //optional
app_stage.setScene(home_page_scene);
app_stage.show();
}
public void clicked2(ActionEvent e) throws IOException {
Parent home_page_parent
=FXMLLoader.load(getClass().getResource("ViewDCU.fxml"));
Scene home_page_scene = new Scene(home_page_parent);
Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
app_stage.hide(); //optional
app_stage.setScene(home_page_scene);
app_stage.show();
}
public void clicked3(ActionEvent e) throws IOException {
Parent home_page_parent
=FXMLLoader.load(getClass().getResource("ViewDCU.fxml"));
Scene home_page_scene = new Scene(home_page_parent);
Stage app_stage = (Stage) ((Node) e.getSource()).getScene().getWindow();
app_stage.hide(); //optional
app_stage.setScene(home_page_scene);
app_stage.show();
}
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
// TODO Auto-generated method stub
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-12 00:25:33