【原文地址:http://blog.ngopal.com.np/2012/01/26/fxml-stuffs-include-and-define/】
今天我想在blog里谈一谈FXML的define和include标签,这两个标签对那些想在程序里使用FXML的人非常有用。FXML是一种XML文件,JavaFX用FXMLLoader来加载它。FXML文件在运行时被加载,并且很容易学习。前一篇blog
里是一些关于FXML的基本介绍,今天这篇blog会教你如何在FXML文件里include另一个FXML。
先来看看<fx:include>
标签,现在假设我们有两个FXML文件Main.fxml和Child.fmxl。
上图中你可以看到,Child.fxml在<fx:define>里被调用到Main.fxml中,<fx:define>被用来在FXML文件里定义变量或实例(variables or instances)。
来个实际的例子,我们写一个包含tab panel的例子,每个tab的内容都是从不同的FXML文件中读取。首先,我们定义包含TabPane的Main.fxml。
Main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.effect.*?>
<?import fxmlstuff.Main?>
<Main xmlns:fx="http://javafx.com/fxml" fx:controller="fxmlstuff.Main" >
<fx:define>
<fx:include source="Home.fxml" fx:id="homeContent" />
<fx:include source="About.fxml" fx:id="aboutContent" />
</fx:define>
<center>
<TabPane fx:id="tabpane" translateY="5" translateX="5" >
<tabs>
<Tab text="HOME" fx:id="homeTab" content="$homeContent" closable="false" />
<Tab text="ABOUT" fx:id="aboutTab" content="$aboutContent" closable="false"/>
</tabs>
</TabPane>
</center>
</Main>
你可以看到,<fx:define>引入了另外两个fmxl文件,Home和About,并且分别为他们定义了fx:id,后面我们在定义Tab的content属性时,直接引用了这两个id:$homeContent,$aboutConten。
现在来看看Main.fxml的FXController类,在Main标签的fx:controller属性中定义的:fxmlstuff.Main
package fxmlstuff;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.BorderPane;
/**
* @author Narayan
*/
public class Main extends BorderPane implements Initializable{
@FXML
private Home homeContent;
@FXML
private About aboutContent;
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}
在这个controller类里,我们只是根据fx:id定义了Home和About实例。
Home.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import fxmlstuff.Home?>
<Home id="homeContent" xmlns:fx="http://javafx.com/fxml"
spacing="10" translateY="40" translateX="20" fx:controller="fxmlstuff.Home" >
<children>
<Label text="Add New Dock of Home" />
<Button text="Add !" onAction="#handleAction" />
</children>
</Home>
Home.java
package fxmlstuff;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.VBox;
/**
* @author Narayan
*/
public class Home extends VBox implements Initializable{
@FXML
private void handleAction(ActionEvent event) {
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}
About.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import fxmlstuff.About?>
<About id="aboutContent" xmlns:fx="http://javafx.com/fxml"
spacing="10" translateY="40" translateX="20" fx:controller="fxmlstuff.About">
<children>
<Label text="Add New Dock of About" />
<Button text="Add !" onAction="#handleButtonAction" />
</children>
</About>
About.java
package fxmlstuff;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.VBox;
/**
* @author Narayan
*/
public class About extends VBox implements Initializable {
@FXML
private void handleButtonAction(ActionEvent event) {
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}
现在,你已经完成了在FXML文件中添加组件,我们创建一个FXML Executor class来运行加载刚才定义的FXML文件。
FXMLTest.java
package fxmlstuff;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* @author Narayan
*/
public class FXMLTest extends Application{
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
Scene scene = new Scene(root,800,600);
stage.setTitle("FXML Test");
stage.setScene(scene);
stage.show();
}
}
运行后的界面应该是这个样子:
这篇blog的后续篇会在接下来的星期里完成,下一篇博客会对上面的程序进行扩展,我们会在Main.fmxl中处理About.fxml和Home.fxml中的组件触发的时间。
分享到:
相关推荐
在编程世界中,预编译器是程序开发过程中的一个重要环节,它负责处理源代码中的特定指令,如`#include`和`#define`。这些指令在实际编译之前进行处理,以帮助简化和优化源代码。让我们深入探讨一下`#include`和`#...
typedef 和 define 的区别 typedef 和 define 是 C/C++ 语言中的两个重要概念,它们都是用于定义标识符或常量的,但它们之间存在着一定的区别。 首先,typedef 用于定义一个标识符或关键字的别名,它是语言编译...
### #define 的使用及其特性 ...通过以上的详细介绍,我们可以看出 `#define` 和 `typedef` 在 C 或 C++ 中各自发挥着重要的作用,根据具体的应用场景选择合适的工具可以使程序变得更加高效、易读和易于维护。
`#define` 和 `typedef` 是 C/C++ 语言中两种不同的类型定义方式,它们各自有不同的特性和用途。 首先,`#define` 是预处理器指令,它的主要功能是在编译之前进行文本替换。这意味着,当你在代码中使用 `#define` ...
`DEFINE_CG_MOTION`和`DEFINE_GRID_MOTION`是UDF编程中用于定义网格运动的两个关键函数。它们是ANSYS Fluent内建的宏,用于在UDF中指定网格如何随时间变化。 1. `DEFINE_CG_MOTION`:这个宏主要用于定义中心点...
标签中的 "define_dpm_erosion"、"dpm"、"udf_erosion"、"fluent" 和 "udf_fluent_dpm" 进一步强调了这个 UDF 是关于 Fluent 中的 DPM 侵蚀模拟。"dpm" 指的是颗粒动力学模型,这是 Fluent 中处理离散颗粒流动的一种...
首先,我们来看`DEFINE-PROPERTY`和`DEFINE-SPECIFIC-HEAT`这两个宏。在FLUENT的UDF编程中,这两个宏用于定义材料的特定属性。`DEFINE-PROPERTY`宏用于创建新的材料属性,例如,你可以通过这个宏来定义不锈钢的导热...
在本文中,我们将详细介绍 #define 指令的用法、实例和注意事项。 定义 ---- #define 指令的基本语法有两种形式: ```c #define identifier token-stringopt #define identifier[( identifieropt, ... , ...
根据提供的文件信息,我们可以提取和总结出以下几个关键的知识点: ### 1. C语言标准库包含 #### `#include <stdio.h>` `stdio.h` 是 C 语言的标准输入输出库,提供了诸如 `printf`, `scanf`, `fopen`, `fclose` ...
在C/C++语言中,typedef和define是两个常用的关键字,虽然它们都可以用来定义别名,但是它们的用法和特点却有很大的区别。 一、typedef的用法 typedef是C/C++语言中的一个关键字,用于定义一个标识符的别名。它是...
在C语言编程中,`define`和`typedef`是两种非常重要的预处理器指令和关键字,它们各自具有独特的用途和优势。本文将深入探讨`define`与`typedef`的区别,以及为什么在某些情况下应优先选择`typedef`。 #### 一、`...
const和define用法 在 C/C++ 编程语言中,const 和 #define 都可以用来定义常量,但是它们之间有着本质的区别。在本文中,我们将详细介绍 const 和 #define 的用法和差异,并讨论为什么 const 正在取代 #define。 ...
在处理复杂边界条件或非线性问题时,`Define Grid Motion`结合UDF的使用可以极大地提高模拟的灵活性和准确性。例如,在涡轮机械、气动弹性力学、生物流体动力学等领域,这种技术被广泛应用于模拟叶片的旋转、物体...
### #define用法完全集锦 #### 一、概述 `#define` 是 C/C++ 预处理器指令中非常重要的一部分,它允许开发者为程序中的常量赋予有意义的名字,简化了代码的阅读与维护。本文将详细介绍 `#define` 的各种用法及其...
在C++和C语言中,预处理器指令`#define`被广泛用于定义宏,这些宏可以包含简单的替换文本,也可以进行复杂的条件判断和参数处理。本文将详细介绍宏定义中的`#`和`##`符号的含义,并通过具体示例来说明它们的应用场景...
使用`#ifndef`、`#define`和`#endif`可以防止头文件被多次包含。当头文件首次被包含时,`__headerfileXXX__`未定义,所以整个头文件会被编译。再次包含时,`__headerfileXXX__`已定义,头文件内容将被跳过。 9. **...
在“第四章 DEFINE宏_UDf宏_UDFdescription_”的PDF文件中,很可能会详细讲解这些概念,并通过实例演示如何创建和应用DEFINE宏,以及如何构建和调试UDFs。文件可能会涵盖以下内容: 1. UDF编程基础:包括UDF的结构...
在程序开发过程中,`#define` 是一个非常常见的预处理器指令,被广泛应用于多种编程语言之中,尤其是在 C 和 C++ 语言中。本文将从多个方面详细介绍 `#define` 的使用方法,并通过具体示例帮助读者更好地理解和应用...
在编程领域,`const`、`#define`与`inline`是三个常用的关键字或预处理器指令,它们各自具有独特的作用和使用场景,掌握它们的区别和正确应用是提升代码质量和效率的重要手段。 #### 1. `const`关键字 `const`...