2017-11-23 7 views
2

Ich bin ein totaler Neuling in JavaFX und ich habe keine Anleitung/Antwort zu diesem Thema gefunden.JavaFX/SceneBuilder - Ändern nur der Teil einer Szene

Also im Grunde, was ich tun möchte, ist nur einen Teil meiner Szene zu ändern. Ich möchte oben eine statische Menüleiste behalten und nur den unteren Teil ändern, je nachdem, auf welche Menüschaltfläche geklickt wird. Das heißt, ich brauche verschiedene FXML-Dateien und Controller-Klassen für jede "Seite".

Mit Blick auf die verfügbaren JavaFX-Funktionen dachte ich, SubScene würde den Job machen. Aber nach weiteren Untersuchungen scheint es, dass SubScenes für 3D-Sachen gemacht sind? Also habe ich wirklich keine Ahnung, was ich tun soll.

Jede Hilfe würde sehr geschätzt werden!

+1

[ 'BorderPane'] (https: // docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html) kann in dieser Situation nützlich sein. – Sedrick

+0

@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. –

+0

@ M.Benamar: 'SubScene.setRoot' oder' BorderPane.setCenter' sollte in Bezug auf die Komplexität keinen großen Unterschied machen. – fabian

Antwort

1

Ä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(); 
     } 
    } 
} 
Verwandte Themen