两个加载fxml文件的方法

JavaFX使用FXMLLoader加载fxml文件。其原理应该与Java.lang.ClassLoader类似,但有很大不同。ClassLoader加载中间代码,在运行环境中生成类对象,而FXMLLoader一方面加载xml格式的文本文件,一方面还要加载由该fxml文件指定的Controller。JavaFX应该建立有一种互动机制,把二者粘合在一起。

一般,使用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);


其中loader是FXMLLoader的一个实例化对象,load方法的参数是InputStream,不再是URL。并且,因为返回值是Object,所以赋值前要转型。

采用这种方法有一个很实用的好处,即可以得到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


  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会根据你的要求回答你的问题,不会透露你的任何要求。 单例模式可以保证一个类只有一个实例存在,因此可以用来实现不同fxml文件的控制器的通信。以下是两个fxml文件的控制器的示例代码: 第一个fxml文件的控制器: ```java public class Controller1 { private static Controller1 instance; private String message; private Controller1() {} public static Controller1 getInstance() { if (instance == null) { instance = new Controller1(); } return instance; } public void setMessage(String message) { this.message = message; } public String getMessage() { return message; } } ``` 第二个fxml文件的控制器: ```java public class Controller2 { private Controller1 controller1; public void setController1(Controller1 controller1) { this.controller1 = controller1; } public void showMessage() { System.out.println(controller1.getMessage()); } } ``` 在这个示例中,Controller1是一个单例类,用于存储需要在不同控制器之间共享的数据。Controller2中的setController1方法用于注入Controller1的实例,showMessage方法用于打印Controller1中存储的消息。 在实际使用中,可以在加载fxml文件时创建Controller1的实例并注入到Controller2中,或者在Controller1中添加一个静态方法用于获取实例并注入到Controller2中。 下面是一个示例代码: ```java public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception{ FXMLLoader loader1 = new FXMLLoader(getClass().getResource("sample1.fxml")); Parent root1 = loader1.load(); Controller1 controller1 = Controller1.getInstance(); loader1.setController(controller1); FXMLLoader loader2 = new FXMLLoader(getClass().getResource("sample2.fxml")); Parent root2 = loader2.load(); Controller2 controller2 = loader2.getController(); controller2.setController1(controller1); primaryStage.setScene(new Scene(root2, 300, 275)); primaryStage.show(); controller1.setMessage("Hello World!"); controller2.showMessage(); } public static void main(String[] args) { launch(args); } } ``` 在这个示例中,我们创建了一个Main类,用于加载两个fxml文件,并且在Controller1中设置了消息,然后调用Controller2中的showMessage方法打印消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值