我有一个来自fxml构建器的fxml文件构建,我在Java中使用它。
URL resource = getClass().getClassLoader().getResource("fxmlFile.fxml");
FXMLLoader loader = new FXMLLoader(resource, resourceBundle);
Pane rootPane = (Pane) loader.load();
此fxml文件将click事件映射到我的班级;
<Group id="Group" layoutX="0.0" layoutY="0.0" onMouseReleased="#handleThis" scaleX="1.0" scaleY="1.0">
...
<Group/>
所以我在我的类中实现我的处理程序,我们称之为MyClass;
public class MyClass {
public void createScene() throws IOException
{
URL resource = getClass().getClassLoader().getResource("fxmlFile.fxml");
FXMLLoader loader = new FXMLLoader(resource, resourceBundle);
Pane rootPane = (Pane) loader.load();
...
}
@FXML
public void handleThis(ActionEvent event) {
System.out.println("from MyClass");
}
...
}
现在我将MyClass扩展为MyExtendedClass并覆盖handleThis方法;
public class MyExtendedClass extends MyClass {
@Override
public void handleThis(ActionEvent event) {
System.out.println("from MyExtendedClass");
}
}
我的问题是,我无法在扩展类中设法处理handle方法。它不会覆盖它。如何使其“从MyExtendedClass”而不是“从MyClass”打印?
答案 0 :(得分:0)
在MyExtendedClass实例上调用createScene()
时,FXMLLoader会解析FXML文件,读取fx:controller="MyClass"
属性并实例化 MyClass类型的 new 对象即可。这就是为什么总是调用基本方法的原因。 FXMLLoader不了解MyExtendedClass。
有一种 - hackish - 实现你想要的方式(即在MyClass中加载并仍在FXML中定义控制器):
public class MyClass
{
public void createScene()
{
try
{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("FXML.fxml"));
// set a controller factory that returns this instance as controller
// (works in this case, but not recommended)
loader.setControllerFactory(controllerType -> this);
pane = (Pane) loader.load();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
}
实例化控制器并将其传递给FXMLLoader会更清晰
为此,必须从FXML文件中删除fx:controller=""
属性。
public class Main extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
MyClass controller = new MyExtendedClass();
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("FXML.fxml"));
loader.setController(controller);
Pane pane = (Pane) loader.load();
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
或者使用fx:controller="MyClass"
在FXML文件中定义基本类型,让控制器工厂决定实际实现。
public class Main extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("FXML.fxml"));
loader.setControllerFactory(controllerType -> {
if (MyClass.class.equals(controllerType))
return new MyExtendedClass();
else
return null; // return some other controller
});
Pane pane = (Pane) loader.load();
MyClass controller = (MyClass) loader.getController();
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}