我可以从FXML自动生成控制器类吗?

时间:2014-02-05 10:52:51

标签: javafx code-generation fxml

据我了解,当使用 FXML 描述 Java FX 场景时,手动编写控制器类,然后可以从中引用它的成员变量和方法。 .fxml个文件。使用FXMLLoader加载场景时,成员变量将设置为相应的场景元素,并且方法会自动连接到相应的事件。这可以工作,但非常麻烦,因为需要在两个地方进行更改,任何错误只会在运行时出现。

我见过其他GUI框架,它允许您从场景描述生成控制器作为抽象类,需要实现它来访问场景元素和处理事件。我的意思的一个例子:

我会创建以下.fxml文件(例如使用 JavaFX Scene Builder ):

<AnchorPane ... >
  <children>
     <Button fx:id="button" ... text="Button" onAction="#buttonPressed" />
  </children>
</AnchorPane>

在我的构建过程中,将创建以下.java文件(例如,使用 Maven 插件):

abstract class TestController {
    protected final Parent root;
    protected final Button button;

    {
        // Load test.fxml file
        // Assign scene elements to root and button
        // Attach event handler to the button that calls buttonClicked()
    }

    protected abstract void buttonClicked(ActionEvent event);
}

然后我可能会多次创建该控制器的具体实现:

final class TestControllerImpl extends TestController {
    TestControllerImpl(String buttonLabel) {
        button.setText(buttonLabel);
    }

    @Override
    protected void buttonClicked(ActionEvent event) {
        button.setText("I've been clicked! What a great day!");
    }
}

是否有一个项目的目标是这样做?或者这种方法是否存在应用于 FXML 的问题?

我从这种方法中看到了以下好处:

  • 自动生成成员变量和控制器方法的声明。
  • 所有成员变量都是最终受保护,而非非最终以及 public 或带注释。< / LI>
  • 方法相同,它们是受保护的,而不是 public 或带注释。
  • 不实现方法或拼错它的名称将导致编译器错误。
  • 场景的编程设置可以在构造函数中完成而不是initialize()方法,因为构造函数将在加载场景并将其元素分配给成员变量后运行

8 个答案:

答案 0 :(得分:9)

现在,SceneBuilder,NetBeans和Eclipse都支持此功能。请注意,这在NetBeans和SceneBuilder中开箱即用,但在Eclipse中,您首先需要e(fx)clipse插件。

SceneBuilder: 在编辑器中打开FXML文件后,进入菜单选择“View”和“Show Sample Controller Skeleton”。

蚀: 打开fxml文件,使内容显示在代码编辑窗格中(您应该看到fxml为明文xml,Eclipse内部语法突出显示,而不是在SceneBuilder中以可视方式呈现)。右键单击Eclipse中的代码,选择“Code”,然后选择“Generate Controller”。

的NetBeans: 在NetBeans中,它更容易,右键单击项目资源管理器中的fxml文件,然后选择“Make Controller”。

答案 1 :(得分:8)

我所知道的并不是你提出的问题。

可能这个答案可能会随着时间的推移而过时。

替代技术

JRuby使用稍微不同的方法实现了大部分概述的好处 - 它使用jRuby的动态编程魔法在运行时动态地从FXML自动创建Ruby类成员。

Tom Schindl编写了一个从FXML生成Java代码的工具。在这个答案中列出的方法中,汤姆的工具似乎最接近你的问题。

SceneBuilder骷髅

来自FXML的类似Java代码生成器可在SceneBuilder View | Show Sample Controller Skeleton功能中使用,该功能在此blog post中有所描述。当我使用SceneBuilder时,我一直使用这个功能,并试着保持我的控制器非常轻,所以它们几乎都是来自SceneBuilder骨架特征的自动生成代码。

虽然因为它没有将生成的代码与手写代码完全分离,所以有点烦人,因此当您对FXML进行更新并想要生成新骨架并复制并粘贴它时需要小心现有Controller的部分内容(加上这是一个稍微容易出错的手动操作,需要一点开发人员的时间)。

如果您想查看其工作原理,可以使用

Source code for SceneBuilder

潜在的构建工具插件

这样的代码生成功能可能会对JavaFX生态系统中的一些现有构建工具进行有价值的补充,例如JavaFX Maven pluginJavaFX Gradle plugin(或者它本身就是一个单独的插件)。

未来发展

我相信Oracle还在为未来的JavaFX版本(后Java 8)开发FXML的功能扩展,它将FXML直接编译为Java字节代码(类文件),绕过Java源代码步骤。这种功能可能会实现您概述的大部分好处。

答案 2 :(得分:6)

NetBeans版本8可以使用。

打开FXML,转到Source并单击generate controller。

编辑:现在可以在任何IDE中完成,Eclipse需要一个插件思想。

答案 3 :(得分:1)

据我所知,netbeans中存在两种解决方案。

首先,netbeans的内部功能“Make Controller”,您可以通过鼠标右键单击fxml文档来查看。它将生成可与FXMLLoader一起使用的控制器类。应在fxml文档中指示控制器的java文件名。 (左侧面板 - &gt;控制器 - &gt;控制器类)

Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

第二,netbeans的插件“FXML 2 JAVA Converter”,你可以从菜单中安装(工具 - &gt;插件 - &gt;可用插件 - &gt; FXML 2 JAVA转换器)。您可以在fxml文档上单击鼠标右键,看到“生成抽象类”菜单项。它将从fxml文档生成源代码,您可以将其用作抽象类,而不使用像普通JavaFX项目那样的FXMLLoader而不是JavaFXML项目。

答案 4 :(得分:1)

对于Intellij Idea IDE用户,可以使用FXMLManager进行救援。查看插件homepage

“在.fxml文件上单击鼠标右键时,将出现新的菜单项“从FXML更新控制器”。 单击此项将修改FXML Java Controller:

  • 删除FXML及其获取器/设置器中缺少的所有@FXML字段
  • 添加Controller中缺少的所有@FXML字段
  • @弃用FXML中缺少的所有ActionEvent方法
  • 创建Controller缺少的所有ActionEvent方法”

答案 5 :(得分:0)

@Feuermurmel
没有任何方法可以为particula .fxml文件自动生成控制器类 你应该在场景构建器中使用anotation @fxml和set(bind)定义动态声明变量和方法。

答案 6 :(得分:0)

现在您可以使用Eclipse轻松做到这一点。只需执行以下简单步骤:

  1. 转到您要为其创建控制器的fxml文件
  2. 右键单击并单击源
  3. 点击生成控制器

Click here to see the Picture of How to do it.

答案 7 :(得分:0)

如果您使用的是 IntelliJ ide,则可能必须尝试使用​​FXML Helper插件。

首先,从文件|安装插件。设置... |插件。安装重新启动ide之后,现在右键单击 .fxml 文档,然后选择FXML Helper菜单。就这些。