简体   繁体   English

在 FXML 中查看注入

[英]View Injection in FXML

@Override
    public void start(Stage stage) throws Exception {
        

BorderPane root = FXMLLoader.load(getClass().getClassLoader().getResource("mainView.fxml"));

When i run this it doesnt show the injected views当我运行它时,它不显示注入的视图

Im building a new application with JavaFX for the main page im using 3 views build by 3 fxml files each view has its controller.我使用 JavaFX 为主页构建一个新应用程序,我使用由 3 个 fxml 文件构建的 3 个视图,每个视图都有其 controller。 for the main page i want to inject the three fxml files in a mainView.fxml via fx:include the mainView.fxml has also a controller how can i do that?对于主页,我想通过 fx 在 mainView.fxml 中注入三个 fxml 文件:包括 mainView.fxml 还有一个 controller 我该怎么做?

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>

<fx:root alignment="CENTER_LEFT" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="93.0" prefWidth="600.0" style="-fx-min-width: 800; -fx-min-height: 100; -fx-spacing: 30;" type="javafx.scene.layout.HBox" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label fx:id="title" alignment="CENTER" prefHeight="91.0" prefWidth="179.0" style="-fx-label-padding: 20; -fx-line-spacing: 20;" text="News" textFill="#00a4f2">
         <font>
            <Font name="Arial Black" size="36.0" />
         </font>
         <opaqueInsets>
            <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
         </opaqueInsets></Label>
      <Button fx:id="refresh" alignment="CENTER" contentDisplay="CENTER" mnemonicParsing="false" style="-fx-alignment: CENTER; -fx-background-color: #66a6ff;" text="Button" textAlignment="CENTER">
         <opaqueInsets>
            <Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
         </opaqueInsets></Button>
      <Button fx:id="stat" alignment="CENTER" mnemonicParsing="false" style="-fx-background-color: #feada6;" text="Button">
         <opaqueInsets>
            <Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
         </opaqueInsets></Button>
   </children>
</fx:root>

This is per example the topView.fxml这是每个示例 topView.fxml

package ch.bfh.spacenews;

import java.io.IOException;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;

public class TopBarController extends HBox {

    @FXML
    public Label title;
    @FXML
    public Button refresh;
    @FXML
    public Button stat;
    
    TopBarController(){
        FXMLLoader load = new FXMLLoader(getClass().getClassLoader().getResource("topView.fxml"));
        load.setRoot(this);
        load.setController(this);
        try {
            System.out.println("TopBarController");
            load.load();
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}

This is the corresponding controller of the topView.fxml这是topView.fxml对应的controller

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>


<BorderPane fx:controller="ch.bfh.spacenews.mainController" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
   <top>
      <fx:include fx:id="topBar" source="topView.fxml"/>
   </top>
   
   <center>
    <fx:include fx:id="article" source="sample.fxml"/>
   </center>
   
   <right>
      <fx:include fx:id="seacrh" source="searchView.fxml"/>  
   </right>
</BorderPane>

This is where i want to inject the topView.fxml这是我要注入 topView.fxml 的地方

package ch.bfh.spacenews;


import javafx.fxml.FXML;



public class mainController {
    
    @FXML
    TopBarController topBarController;
    @FXML
    ArticleController articleController;
    @FXML
    SearchController searchController;
    
    @FXML
    public void initialize() {
        
    }

}

And this is the Controller of the mainView.fxml where i want to inject the topView.fxml这是我想注入 topView.fxml 的 mainView.fxml 的 Controller

In the FXML custom component pattern the controller classes also serve as the wrapper for the view, by subclassing an appropriate Node subclass.FXML 自定义组件模式中,controller 类还可以作为视图的包装器,通过子类化适当的Node子类。 This means you can just instantiate them directly in the FXML via the FXMLLoader .这意味着您可以通过FXMLLoader直接在 FXML 中实例化它们。 For example, the <TopBarController> element instructs the FXMLLoader to instantiate the TopBarController by calling its no-argument constructor.例如, <TopBarController>元素指示FXMLLoader通过调用其无参数构造函数来实例化TopBarController That constructor, as per your code, loads topView.fxml , etc. There is no need to use <fx:include> , which is an instruction for the FXMLLoader to load another FXML file, since you already have code in your TopBarController to do that.该构造函数根据您的代码加载topView.fxml等。无需使用<fx:include> ,这是FXMLLoader加载另一个 FXML 文件的指令,因为您的TopBarController中已经有代码要做那。

So your main view FXML file should look like:因此,您的主视图 FXML 文件应如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>

<?import ch.bfh.spacenews.TopBarController?>
<!-- other imports... -->


<BorderPane fx:controller="ch.bfh.spacenews.MainController" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
   <top>
      <TopBarController fx:id="topBar" />
   </top>
   
   <center>
    <ArticleController fx:id="article" />
   </center>
   
   <right>
      <SearchController fx:id="search" />  
   </right>
</BorderPane>

And the corresponding controller is而对应的controller是

package ch.bfh.spacenews;


import javafx.fxml.FXML;



public class MainController {
    
    @FXML
    TopBarController topBar;
    @FXML
    ArticleController article;
    @FXML
    SearchController search;
    
    @FXML
    public void initialize() {
        
    }

}

Note that it's really critical to follow standard naming conventions here.请注意,在此处遵循标准命名约定非常重要。 The FXMLLoader explicitly relies on the case of an element to determine if it's referring to a class name or a property name. FXMLLoader显式依赖元素的大小写来确定它是引用 class 名称还是属性名称。

Main class: Launch.java主class:Launch.java

public class Launch extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Controller.show(stage);
    }

    public static void main(String[] args) {
        launch(args);
    }
}

You can add view from controller:您可以从 controller 添加视图:

public class Controller {
    public BorderPane mainPane; // fx:id of your pane
    public static Stage current;

    public static void show(Stage stage) {
        this.current = stage;
        Scene scene = null;
        BorderPane pane = null;
        try {
            scene = new Scene(FXMLLoader.load(getClass().getResource("mainView.fxml")));
            pane = (BorderPane) scene.lookup("#mainPane");

            // Add .fxml view to mainView
            pane.setCenter(FXMLLoader.load(getClass().getResource("sample.fxml")));
            pane.setTop(FXMLLoader.load(getClass().getResource("topView.fxml")));
            pane.setRight(FXMLLoader.load(getClass().getResource("searchView.fxml")));

        } catch (IOException e) {
            e.printStackTrace();
        }

        stage.setTitle("MainView");
        stage.setScene(scene);
        stage.show();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM