javafx - 在Controller中加载FXML文件,但也使用NetBeans的“Make Controller”

时间:2017-06-11 19:21:19

标签: javafx netbeans fxml

在尝试加载FXML文件时,通常会执行以下操作:

FXMLLoader loader = FXMLLoader.load(getClass().getResource("File.fxml"));
Region root = loader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.show();

然而,当我试图将加载代码放入控制器以“调用方便”时,我做了以下事情:

public Controller()
{
   FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml));
   loader.setController(this);
   Parent root = loader.load();
   Stage stage = new Stage();
   stage.setScene(new Scene(root));
   stage.show();
}

这非常好用,因为现在我只需要调用构造函数来创建新窗口。

但我必须删除

fx:controller="package.Class"
FXML文件中的

属性,因为在我调用

时抛出异常(“javafx.fxml.LoadException:controller已设置”)
fxmlloader.setController(this);

构造函数中的方法。 由于我使用NetBeans及其“Make Controller”功能(右键单击FXML文件),因为缺少属性,无法创建控制器类。

要点:

我想要实现的是在FXML(对于NetBeans)中设置“fx:controller”属性的方法,并且还能够在Controller类中方便地加载FXML。

这是可能的,还是需要某种创建FXML窗口的包装类?

提前致谢。

1 个答案:

答案 0 :(得分:3)

你可以这样做:

public Controller()
{
   FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml));
   loader.setControllerFactory(type -> {
       if (type == Controller.class) {
           return this ;
       } else {
           try {
               return type.newInstance();
           } catch (RuntimeException e) {
               throw e ;
           } catch (Exception e) {
               throw new RuntimeException(e);
           }
       }
   });
   Parent root = loader.load();
   Stage stage = new Stage();
   stage.setScene(new Scene(root));
   stage.show();
}

这将允许您(事实上,您将需要)在FXML文件中具有fx:controller属性。基本上它的作用是指定FXMLLoader可用于从指定类获取控制器实例的函数。在这种情况下,如果FXML Loader正在查找Controller类的对象,则返回当前对象,否则只创建指定类的新对象。