Java lernen

JavaFX Gleiche Controller-Instanz für inludiertes FXML

Diskutiere Gleiche Controller-Instanz für inludiertes FXML im AWT, Swing, JavaFX & SWT Forum; Hallo zusammen, entweder ich stehe auf dem Schlauch oder es ist tatsächlich eine komplexere Sache in JavaFX: Ich verwende JavaFX (8) mit FXML und...

  1. KrokoDiehl
    KrokoDiehl Aktives Mitglied
    Hallo zusammen,

    entweder ich stehe auf dem Schlauch oder es ist tatsächlich eine komplexere Sache in JavaFX:
    Ich verwende JavaFX (8) mit FXML und möchte in einer - bereits großen - FXML-Datei eine andere inkludieren - hauptsächlich um die Datei nicht größer werden zu lassen.
    Beide sollen aber die gleiche Controller-Instanz verwenden.

    Hier ein Beispiel dass es verdeutlichen soll:
    Code (Java):

    public class DerController {
      ...

      @FXML
      public void buttonImHauptFXMLgeklickt() {
      ... ich werde gefunden
      }

      @FXML
      public void buttonImSubFXMLgeklickt() {
      ... mich findet es nicht
      }
    }
     
    Die Haupt-FXML-Datei welche den Controller hat:
    Code (Text):

    <VBox ...>
      <!-- viele UI-Komponenten -->
      <Button text="Haupt fxml" onAction="#buttonImHauptFXMLgeklickt" />

      <HBox>
      <fx:include source="subFxml.fxml" />
      </HBox>
    </VBox>
     
    Die Sub-FXML-Datei welche inkludiert wird:
    Code (Text):

    <GridPane ....>
      <!-- diverse UI-Kompenten -->
      <Button text="Sub fxml" onAction="#buttonImSubFXMLgeklickt" />
    </GridPane>
     
    Geladen wird die Haupt-FXML-Komponenten über FXMLLoader wo ich die Controller-Instanz auch direkt setze. Das heißt der Controller wird nicht vom FXML instanziiert.
    Für die inkludierte FXML-Datei möchte ich nun auch gerne die gleiche Controller-Instanz verwenden.

    Starte ich das Ganze jedoch nach dem obigen Schema, bekomme ich folgenden Fehler:
    Code (Text):
    Caused by: javafx.fxml.LoadException: No controller specified.
    Die Stelle ist auch eindeutig: Dort wo im Sub-FXML die onAction-Deklaration ist hat er keinen Controller.

    Kennt jemand eine Lösung oder hat sonstige Meinungen dazu? Ich kenne schon ein paar Workarounds, die arbeiten aber alle ohne ein fx:inlcude sondern laden das Sub-FXML separat und bauen die UI dann im Code zusammen.


    Vielen Dank im Voraus!
     
  2. knilch
    knilch Aktives Mitglied
    Hi,
    Ja, du kannst in ein include den selben Controller wie die "Hauptview" verwenden. Siehe nachfolgend ein Beispiel mit 3 FXMLs und 1.Controller.
    ChildView1.fxml und ChildView2.fxml sind im MainView.fxml included. Alle 3 FXMLs benutzen den MainViewController.
    MainView.fxml:
    Code (Text):
    <?xml version="1.0" encoding="UTF-8"?>

    <?import javafx.scene.control.*?>
    <?import java.lang.*?>
    <?import java.net.*?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.VBox?>

    <AnchorPane prefHeight="280.0" prefWidth="500.0"
        xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2"
        fx:controller="test11.MainViewController">
        <children>
            <VBox prefHeight="280.0" prefWidth="500.0"
                AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
                AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                <children>
                    <fx:include fx:id="child1" source="ChildView1.fxml" />
                    <fx:include fx:id="child2" source="ChildView2.fxml" />
                </children>
            </VBox>
        </children>
    </AnchorPane>
    MainViewController.java:
    Code (Java):
    package test11;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.scene.Node;
    import javafx.scene.Parent;
    import javafx.scene.control.Button;
    import javafx.scene.layout.AnchorPane;

    public class MainViewController {
        @FXML
        private Parent view;
        @FXML
        private AnchorPane child1;
        @FXML
        private AnchorPane child2;

        @FXML
        private Button button1;
        @FXML
        private Button button2;
        @FXML
        private Button button3;
        @FXML
        private Button button4;
       
        @FXML
        protected void handleButtonEvent(ActionEvent event) {
            String parentName = ((Node) event.getSource()).getParent().getParent().getId();
            System.out.println("ChildViewController: " + ((Button)event.getSource()).getText() + " von " + parentName + " wurde gedrückt...");
        }

        @FXML
        void initialize() {
            System.out.println("MainViewController.initialize()");
        }
    }
    ChildView1.fxml:
    Code (Text):
    <?xml version="1.0" encoding="UTF-8"?>

    <?import javafx.scene.control.*?>
    <?import java.lang.*?>
    <?import java.net.*?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.control.Button?>

    <AnchorPane fx:id="child1" id="child1" prefHeight="244.0" prefWidth="568.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="test11.MainViewController">
        <children>
            <HBox id="hBox1" layoutX="32.0" layoutY="14.0" prefHeight="51.0" prefWidth="200.0" spacing="10.0">
                <children>
                    <Button fx:id="button1" prefHeight="37.0" text="Button 1" onAction="#handleButtonEvent" />
                    <Button fx:id="button2" prefHeight="37.0" text="Button 2" onAction="#handleButtonEvent" />
                </children>
            </HBox>
        </children>
    </AnchorPane>
    ChildView2.fxml:
    Code (Text):
    <?xml version="1.0" encoding="UTF-8"?>

    <?import javafx.scene.control.*?>
    <?import java.lang.*?>
    <?import java.net.*?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.control.Button?>

    <AnchorPane fx:id="child2" id="child2" prefHeight="244.0" prefWidth="568.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="test11.MainViewController">
        <children>
            <HBox id="hBox2" layoutX="32.0" layoutY="14.0" prefHeight="51.0" prefWidth="200.0" spacing="10.0">
                <children>
                    <Button fx:id="button3" prefHeight="37.0" text="Button 3" onAction="#handleButtonEvent" />
                    <Button fx:id="button4" prefHeight="37.0" text="Button 4" onAction="#handleButtonEvent" />
                </children>
            </HBox>
        </children>
    </AnchorPane>
    Main.java:
    Code (Java):
    package test11;

    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;

    public class Main extends Application {

        public void start(Stage primaryStage) {
            try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("MainView.fxml"));
                Parent rootElement = (Parent) loader.load();
                Scene scene = new Scene(rootElement, 800, 600);
                primaryStage.setTitle("JavaFX");
                primaryStage.setScene(scene);
                primaryStage.show();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        public static void main(String[] args) {    
            launch(args);
        }
    }
    Vielleicht wäre es aber besser, für jedes fxml einen separaten Controller zu erstellen, damit es übersichtlicher strukturiert werden kann... (ist nur so meine Meinung... ;-) )
     
    Zuletzt bearbeitet: 30. Dez. 2015
Die Seite wird geladen...

Gleiche Controller-Instanz für inludiertes FXML - Ähnliche Themen

Array, Geburtsdatum, Vergleichen
Array, Geburtsdatum, Vergleichen im Forum Java Basics - Anfänger-Themen
JList Elemente mit Strings vergleichen
JList Elemente mit Strings vergleichen im Forum Java Basics - Anfänger-Themen
Versionsnummern vergleichen
Versionsnummern vergleichen im Forum Java Basics - Anfänger-Themen
int[]'s vergleichen
int[]'s vergleichen im Forum Java Basics - Anfänger-Themen
Haskell Strings vergleichen
Haskell Strings vergleichen im Forum Softwareentwicklung
Thema: Gleiche Controller-Instanz für inludiertes FXML