据我所了解,使用 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 时是否存在问题?
我认为这种方法有以下好处:
- 控制器的成员变量和方法声明会自动生成。
- 所有成员变量都是 final 和 protected,而不是 non-final 并且要么是public 要么带注解。
- 方法也是如此,它们是 protected,而不是 public 或者带注解。
- 未实现方法或拼写错误将导致编译错误。
- 场景的编程设置可以在构造函数中完成,而不是在
initialize()
方法中完成,因为构造函数会在场景加载并将其元素分配给成员变量之后运行。