Ändern von Teilen der Szene ist einfach. In der Hauptszene platzieren Sie einen Container, in dem Sie verschiedene Ansichten dynamisch laden. Hier ist ein Beispiel nach Ihrer Beschreibung für ein allgemeines "statisches" Menü:
Dies ist die grundlegende Ansicht. In mainView
werden die verschiedenen Ansichten geladen (Standard ist view_a.fxml) und über das Menü Ansicht> Show View X geändert. Die IDs, die ich der einzelnen MenuItem
zugewiesen habe, sind die Namen der FXML
zu ladenden Dateien.
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="View">
<items>
<MenuItem fx:id="view_a" mnemonicParsing="false" text="Show View A" onAction="#handleChangeView"/>
<MenuItem fx:id="view_b" mnemonicParsing="false" text="Show View B" onAction="#handleChangeView"/>
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<BorderPane fx:id="mainView">
<center>
<fx:include source="view_a.fxml"/>
</center>
</BorderPane>
</center>
</BorderPane>
Dies ist eine der Ansichten (view_a.fxml). Der andere ist derselbe, also werde ich es nicht zeigen. In diesen Ansichten ist es interessant, dass ich keinen Controller spezifiziere, weil ich später den Controller auf dem Hauptrahmen verwende (das ist gut für kleine Dinge, aber für große Projekte ist es schön, verschiedene Controller zu verwenden).
<AnchorPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml">
<children>
<Label text="View A"/>
</children>
</AnchorPane>
Der Controller selbst ist nichts besonderes. Es kommt noch hinzu, eine „.fxml“ auf die ID der Option, die ausgewählt wird, lädt die FXML
Datei mit dem resultierenden Namen, und legt sie in dem mainView
Zentrum
public class Controller {
@FXML
private BorderPane mainView;
@FXML
private void handleChangeView(ActionEvent event) {
try {
String menuItemID = ((MenuItem) event.getSource()).getId();
FXMLLoader loader = new FXMLLoader(getClass().getResource(menuItemID + ".fxml"));
loader.setController(this);
mainView.setCenter(loader.load());
}
catch (IOException e) {
e.printStackTrace();
}
}
}
[ 'BorderPane'] (https: // docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html) kann in dieser Situation nützlich sein. – Sedrick
@SedrickJefferson Aber würde mich das nicht erfordern, die Kinder des BorderPane MANUELL zu entfernen und hinzuzufügen? Ich suche nach einem "SubScene", wo ich eine Methode wie .setRoot() aufrufen könnte, um eine von SceneBuilder generierte FXML-Datei anzuhängen. –
@ M.Benamar: 'SubScene.setRoot' oder' BorderPane.setCenter' sollte in Bezug auf die Komplexität keinen großen Unterschied machen. – fabian