JavaFX可重用FXML代码段

编程入门 行业动态 更新时间:2024-10-11 17:19:40
本文介绍了JavaFX可重用FXML代码段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在实现一个选项卡式部分,其中每个选项卡都包含一个表视图。在此表视图中,无论选择哪个选项卡,都会有一个列的子集,但某些选项卡将包含其他列(以编程方式处理)。

I am implementing a tabbed section where each tab will contain a table view. Within this table view, there is a subset of columns that will be rendered regardless of which tab is selected but some tabs will include additional columns (handled programmatically).

由于这些原因,每个标签需要有一个单独的控制器,但我想知道是否可以在每个标签中重复使用标签FXML的内部内容必须复制并粘贴代码。我正在思考一个可重用的组件,我可以在另一个FXML文件中定义它,并且只包含在选项卡部分中。

For these reasons, each tab needs to have a separate controller but I was wondering if it was possible for me to reuse the inner contents of the tab FXML in each tab without having to copy and paste the code. I am thinking along the lines of a reusable component that I could define in another FXML file and just include in the tab section.

具体来说,我想将下面代码中的内容部分放在一个文件中,并在每个文件中引用它,这样我就不必进行更改如果我想在将来改变某些内容,请访问多个文件。我认为这可以通过编程方式实现,但如果可能的话我更喜欢FXML解决方案。

Specifically, I'd like to have the content section in the code below in a single file and just reference it in each file so I don't have to make changes to multiple files if I want to change something in the future. I think this can possibly be achieved programmatically, but I would prefer an FXML solution if possible.

<Tab xmlns:fx="javafx/fxml/1" xmlns="javafx/javafx/8" fx:controller="com.SpecificController" id="specificTab" text="Specific Tab Name"> <content> <JFXTreeTableView fx:id="commonTableView" VBox.vgrow="ALWAYS"> <columns> <JFXTreeTableColumn fx:id="nameColumn" text="Name"/> <JFXTreeTableColumn fx:id="positionColumn" text="Position"/> <JFXTreeTableColumn fx:id="teamColumn" text="Team"/> <JFXTreeTableColumn fx:id="selectColumn" text="Select"/> </columns> </JFXTreeTableView> </content> </Tab>

推荐答案

我绝不是JavaFX专家,但我能够提出这个解决方案。

I am by no means a JavaFX expert, but I was able to come up with this solution.

这是一个MCVE,所以你可以完全重新创建这个示例应用程序并运行它以查看它的实际效果。

This is an MCVE, so you can recreate this sample application completely and run it to see it in action.

此示例对可重用的FXML节点使用 AnchorPane ,但您可以修改它以使用选项卡而不是。我发现重用内容本身有点简单。

This sample uses an AnchorPane for the reusable FXML node, but you could modify it to use a Tab instead. I find reusing the content itself to be a bit simpler, though.

我使用简单的接口来定义我们的标签控件;这允许我们编写一个方法来为每个 Tab 设置内容和单个控制器。

I am using a simple Interface to define our tab controllers; this allows us to write one method that sets the content and the individual controller for each Tab.

Main.java:

import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; import java.io.IOException; public class Main extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { try { // Load the main layout FXMLLoader loader = new FXMLLoader(getClass().getResource("MainLayout.fxml")); // Show the Stage primaryStage.setWidth(700); primaryStage.setHeight(500); primaryStage.setScene(new Scene(loader.load())); primaryStage.show(); } catch (IOException e) { e.printStackTrace(); } } }

FXML文件:

MainLayout.fxml:

<?xml version="1.0" encoding="UTF-8"?> <?import javafx.geometry.Insets?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="javafx/javafx/9.0.1" xmlns:fx="javafx/fxml/1" fx:controller="sample.reusableTabs.MainController"> <VBox alignment="TOP_CENTER" prefHeight="400.0" prefWidth="600.0" spacing="10.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <padding> <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> </padding> <Label style="-fx-font-size: 150%; -fx-font-weight: bold;" text="Reusable Tab Content Sample"/> <Separator prefWidth="200.0"/> <TabPane fx:id="tabPane" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" VBox.vgrow="ALWAYS"> <Tab fx:id="tab1" text="Tab #1"/> <Tab fx:id="tab2" text="Tab #2"/> <Tab fx:id="tab3" text="Tab #3"/> </TabPane> </VBox> </AnchorPane>

TabContent.fxml:

<?xml version="1.0" encoding="UTF-8"?> <?import javafx.geometry.Insets?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="javafx/javafx/9.0.1" xmlns:fx="javafx/fxml/1"> <VBox alignment="CENTER" prefHeight="400.0" prefWidth="600.0" spacing="20.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <Label text="Look - reusable Tab contents!"/> <Button fx:id="btnTestController" mnemonicParsing="false" text="Test Controller"/> <padding> <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> </padding> </VBox> </AnchorPane>

控制器:

MainController.java:

import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import java.io.IOException; public class MainController { @FXML private TabPane tabPane; @FXML private Tab tab1; @FXML private Tab tab2; @FXML private Tab tab3; @FXML private void initialize() { // Our TabPane has 3 Tabs. Let's populate them with content, reusing our TabContent.fxml file setTabContent(tab1, new Tab1Controller()); setTabContent(tab2, new Tab2Controller()); setTabContent(tab3, new Tab3Controller()); } /** * Sets the content of Tab to the TabContent.fxml document * * @param tab The Tab whose content we wish to set * @param controller The controller for this particular Tab's content */ private void setTabContent(Tab tab, TabController controller) { // Load our TabContent.fxml file and set it as the content of the Tab that was passed to this method try { FXMLLoader loader = new FXMLLoader(getClass().getResource("TabContent.fxml")); // Set the controller for this specific tab loader.setController(controller); // Set the content of the passed Tab to this FXML content tab.setContent(loader.load()); } catch (IOException e) { e.printStackTrace(); } } }

Tab1Controller:

import javafx.fxml.FXML; import javafx.scene.control.Button; public class Tab1Controller implements TabController { @FXML private Button btnTestController; @FXML private void initialize() { // Set our button to print out which controller is being used btnTestController.setOnAction(event -> System.out.println("Hello, from Controller #1!")); } }

只需复制此控制器再多两次 Tab2Controller.java 和`Tab3Controller.java

Just duplicate this controller two more times for Tab2Controller.java and `Tab3Controller.java

结果:

点击测试控制器按钮将打印出 Hello,来自控制器#2!,确认每个Tab的内容由他们自己的控制器控制。

Clicking on the Test Controller button will print out Hello, from Controller #2!, confirming each Tab's contents are controlled by their own controller.

更多推荐

JavaFX可重用FXML代码段

本文发布于:2023-07-19 12:48:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1156702.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:代码   JavaFX   FXML

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!