JavaFX使用FXMLLoader加载fxml文件。其原理应该与Java.lang.ClassLoader类似,但有很大不同。ClassLoader加载中间代码,在运行环境中生成类对象,而FXMLLoader一方面加载xml格式的文本文件,一方面还要加载由该fxml文件指定的Controller。JavaFX应该建立有一种互动机制,把二者粘合在一起。
一般,使用FXMLLoader加载fxml文件的方法可以分为两类:1、利用FXMLLoader的类方法;2、利用对象方法。
一、类方法
FXMLLoader中有如下类方法,可以简单几行代码实现fxml文件的加载:
二、对象方法
相比之下,利用对象方法,可以更加灵活的加载fxml文件,但是代码要复杂一点。如下:
采用这种方法有一个很实用的好处,即可以得到Controller:
如果程序有多个界面,比如登录窗口、主数据窗口、或者图表窗口等等,可以由此增强对各个窗口的操控能力。
还有,设置路径基准也很有用处。
在fxml文件中设置css文件,使用的是相对路径,而setLocation就是设置路径的基准。使用类方法的时候,默认把所加载的fxml文件的位置作为基准,setLocation却可以设置不同于当前文件的路径。
这样,你可以根据需要,把不同的fxml文件分别放在不同的包中,只要你设置了唯一的路径基准,所有fxml中指定的css文件就可以使用同样的相对路径。
利用这个功能,我们还加载项目外的fxml文件。这里是我写的一个例子,其中hello1.fxml和hello2.fxml两个文件可以放在硬盘里的任何地方,都能加载。在hello1.fxml中更是指定了css文件,hello1.fxml不可能和FxmlSelection.fxml处于同一目录,但是它们却使用同样的相对路径指定css文件。
下图是例子的运行结果:
一般,使用FXMLLoader加载fxml文件的方法可以分为两类:1、利用FXMLLoader的类方法;2、利用对象方法。
一、类方法
利用类方法比较简单快捷,代码如下:
URL url = getClass().getResource("Example1.fxml");
Parent root = FXMLLoader.load(url);
Scene scene = new Scene(root, 300, 200);
stage.setTitle("User Login");
stage.setScene(scene);
stage.show();
FXMLLoader中有如下类方法,可以简单几行代码实现fxml文件的加载:
static <T> T load(java.net.URL location)
static <T> T load(java.net.URL location,
java.util.ResourceBundle resources)
static <T> T load(java.net.URL location,
java.util.ResourceBundle resources,
BuilderFactory builderFactory)
static <T> T load(java.net.URL location,
java.util.ResourceBundle resources,
BuilderFactory builderFactory,
Callback<java.lang.Class<?>, java.lang.Object> controllerFactory)
static <T> T load(java.net.URL location,
java.util.ResourceBundle resources,
BuilderFactory builderFactory,
Callback<java.lang.Class<?>,java.lang.Object> controllerFactory,
java.nio.charset.Charset charset)
二、对象方法
相比之下,利用对象方法,可以更加灵活的加载fxml文件,但是代码要复杂一点。如下:
private Initializable replaceSceneContent(String fxml) throws Exception {
FXMLLoader loader = new FXMLLoader(); // 创建对象
loader.setBuilderFactory(new JavaFXBuilderFactory()); // 设置BuilderFactory
loader.setLocation(Main.class.getResource(fxml)); // 设置路径基准
try {
InputStream in = Main.class.getResourceAsStream(fxml);
AnchorPane page = (AnchorPane) loader.load(in); // 对象方法的参数是InputStream,返回值是Object
Scene scene = new Scene(page, 800, 600);
stage.setScene(scene);
stage.sizeToScene();
return (Initializable) loader.getController(); // 可以得到Controller
} finally {
in.close();
return null;
}
}
AnchorPane page = (AnchorPane) loader.load(in);
采用这种方法有一个很实用的好处,即可以得到Controller:
return (Initializable) loader.getController();
如果程序有多个界面,比如登录窗口、主数据窗口、或者图表窗口等等,可以由此增强对各个窗口的操控能力。
还有,设置路径基准也很有用处。
loader.setLocation(Main.class.getResource(fxml)); // 设置路径基准
在fxml文件中设置css文件,使用的是相对路径,而setLocation就是设置路径的基准。使用类方法的时候,默认把所加载的fxml文件的位置作为基准,setLocation却可以设置不同于当前文件的路径。
这样,你可以根据需要,把不同的fxml文件分别放在不同的包中,只要你设置了唯一的路径基准,所有fxml中指定的css文件就可以使用同样的相对路径。
利用这个功能,我们还加载项目外的fxml文件。这里是我写的一个例子,其中hello1.fxml和hello2.fxml两个文件可以放在硬盘里的任何地方,都能加载。在hello1.fxml中更是指定了css文件,hello1.fxml不可能和FxmlSelection.fxml处于同一目录,但是它们却使用同样的相对路径指定css文件。
<stylesheets>
<URL value="@main.css" />
</stylesheets>
下图是例子的运行结果:
源代码下载:http://download.csdn.net/detail/u012994553/6641887