JavaFX 在 VBox 内更改 Pane。

huangapple go评论77阅读模式
英文:

JavaFX changing Pane within VBox

问题

以下是您提供的内容的中文翻译:

我有一个名为mainView.fxml的文件,其中包含3个单独的fxml文件。我的mainView设计如下(VBox),将由start方法加载。

+------------------------+
+ 菜单(menu.fxml)        +
+------------------------+
+ 工具栏(toolbar.fxml)    +
+------------------------+
+                        +
+ 仪表板XYZ               +
+(dashboarXYZ.fxml)      +
+------------------------+

通过单击工具栏的图标,contentXYZ将使用不同的fxml文件的内容进行更新。非常基础的东西。

我的mainView.fxml

<VBox fx:id="mainView" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.test.controller.MainController">
    <children>
        <fx:include fx:id="menu" source="menu.fxml" />
        <fx:include fx:id="menuToolbar" source="menuToolbar.fxml" />
        <fx:include fx:id="contentXYZ" source="contentXYZ.fxml" />
    </children>
</VBox>

mainController

@FXML
private AnchorPane dashboardHome;
@FXML
private VBox mainView;

public void loadContent() throws IOException {

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/com/example/test/view/courseView.fxml"));
    AnchorPane newPane = fxmlLoader.load();

    System.out.println(mainView.getChildren()); // is null!!

    // 将加载的FXML文件设置为我们主右侧窗格的内容
    // mainView.getChildren().set(2, newPane);

}

结果是一个NullPointerException: 不能调用"javafx.scene.layout.VBox.getChildren()"因为"this.mainView"为空。

感谢您的帮助。谢谢。

英文:

I have a mainView.fxml which includes 3 separate fxml files. My mainView is designed like that (VBox) and will be loaded by the start method.

+------------------------+
+ menu (menu.fxml)       +
+------------------------+
+ toolbar (toolbar.fxml) +
+------------------------+
+                        +
+ dashboardXYZ           +
+ (dashboarXYZ.fxml)     +
+------------------------+

By clicking an icon of the toolbar the contentZYZ shall be updated with the content of different fxml files. Pretty basic stuff.

My mainView.fxml

&lt;VBox fx:id=&quot;mainView&quot; maxHeight=&quot;-Infinity&quot; maxWidth=&quot;-Infinity&quot; minHeight=&quot;-Infinity&quot; minWidth=&quot;-Infinity&quot; prefHeight=&quot;400.0&quot; prefWidth=&quot;600.0&quot; xmlns=&quot;http://javafx.com/javafx/20.0.1&quot; xmlns:fx=&quot;http://javafx.com/fxml/1&quot; fx:controller=&quot;com.example.test.controller.MainController&quot;&gt;
&lt;children&gt;
    &lt;fx:include fx:id=&quot;menu&quot; source=&quot;menu.fxml&quot; /&gt;
    &lt;fx:include fx:id=&quot;menuToolbar&quot; source=&quot;menuToolbar.fxml&quot; /&gt;
    &lt;fx:include fx:id=&quot;contentXYZ&quot; source=&quot;contentXYZ.fxml&quot; /&gt;
&lt;/children&gt;

</VBox>

mainController

@FXML
private AnchorPane dashboardHome;
@FXML
private VBox mainView;


public void loadContent() throws IOException {

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(&quot;/com/example/test/view/courseView.fxml&quot;));
    AnchorPane newPane = fxmlLoader.load();

    System.out.println(mainView.getChildren()); // is null!!

    // Set the loaded FXML file as the content of our main right-side pane
    //mainView.getChildren().set(2, newPane);

}

Results in a

NullPointerException: Cannot invoke &quot;javafx.scene.layout.VBox.getChildren()&quot; because &quot;this.mainView&quot; is null

I appreciate any help. Thanks.

答案1

得分: 3

由于您在一个控制器实例中,但加载器与另一个控制器实例绑定在一起。我认为您可能在其他地方手动创建了MainController实例并调用了loadContent()。

如果您想在MainController中保留loadContent()方法,您可以尝试以下两种方法之一。

方法1: 从FXMLLoader控制器访问节点

@FXML
private AnchorPane dashboardHome;
@FXML
private VBox mainView;

public void loadContent() throws IOException{

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/com/example/test/view/courseView.fxml"));
    AnchorPane newPane = fxmlLoader.load();
    MainController controller = (MainController) fxmlLoader.getController();

    System.out.println(controller.mainView.getChildren()); 
}

方法2: 将当前控制器实例设置为加载器的控制器。

为此,您需要首先在FXML文件中删除控制器声明,因为我们手动将控制器设置为加载器。

@FXML
private AnchorPane dashboardHome;
@FXML
private VBox mainView;

public void loadContent() throws IOException{

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/com/example/test/view/courseView.fxml"));
    fxmlLoader.setController(this);
    AnchorPane newPane = fxmlLoader.load();

    System.out.println(mainView.getChildren()); 
}
英文:

It is because you are in one controller instance, but the loader is tied with a different controller instance. I think you might have created your MainContrller instance manually elsewhere and calling loadContent().

If you want to keep the loadContent() method in MainController , you can try one of the below two approaches.

Approach #1: Accessing the nodes from FXMLLoader controller

@FXML
private AnchorPane dashboardHome;
@FXML
private VBox mainView;

public void loadContent() throws IOException{

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(&quot;/com/example/test/view/courseView.fxml&quot;));
    AnchorPane newPane = fxmlLoader.load();
    MainController controller = (MainController) fxmlLoader.getController();

    System.out.println(controller.mainView.getChildren()); 
}

Approach #2: Setting the current controller instance as the controller to the loader.

For this you need to first remove the controller declaration in the fxml file. Because we set the controller manually to the loader.

@FXML
private AnchorPane dashboardHome;
@FXML
private VBox mainView;

public void loadContent() throws IOException{

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(&quot;/com/example/test/view/courseView.fxml&quot;));
    fxmlLoader.setController(this);
    AnchorPane newPane = fxmlLoader.load();
    
    System.out.println(mainView.getChildren()); 
}

huangapple
  • 本文由 发表于 2023年7月27日 19:52:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76779466.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定