我想嵌入自己的自定义控件,这些控件是从其他控件扩展而来的。我想通过扩展而不是通过fx:root type =“ ...”从FXML在Java中扩展它们!当我想使用MVC模式时,我使用了一个自定义ControllerFactory,以便可以将模型传递给控件的构造函数(请参见 AppStarter.java )。在此简单示例中,AppStarter.java加载包含两个TextField的 container.fxml 。这些绑定到我的模型,该模型由ControllerFactory传递给它们。如果在“ textFieldIn”中键入文本,则会更新模型,并在“ textFieldOut”中显示输出。
这很好用,但是我不能使用从另一个控件扩展的控件。我扩展了TextField(请参阅ExtendedTextField.java),并尝试将其嵌入到fxml中(请参见 container.fxml ),并出现了“无法实例化”错误。
我该如何解决这个问题?
AppStarter.java
public class AppStarter extends Application {
private Model model;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
this.model = new Model("model data (string)");
Parent root = null;
try {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/fxml/container.fxml"));
fxmlLoader.setControllerFactory((Class<?> type) -> {
try {
for (Constructor<?> c : type.getConstructors()) {
if (c.getParameterCount() == 1 && c.getParameterTypes()[0] == Model.class) {
return c.newInstance(model);
}
}
// default behavior: invoke no-arg constructor:
return type.newInstance();
} catch (Exception exc) {
throw new RuntimeException(exc);
}
});
root = fxmlLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(root, 300, 100);
stage.setScene(scene);
stage.show();
}
}
container.fxml
<SplitPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml">
<Pane>
<fx:include source="textFieldIn.fxml" fx:id="textFieldIn"/>
</Pane>
<Pane>
<fx:include source="textFieldOut.fxml" fx:id="textFieldOut"/>
<!-- <ExtendedTextField/> **HERE I WANT TO EMBED MY EXTENDED CONTROL INSTEAD** -->
</Pane>
</SplitPane>
textFieldIn.fxml
<TextField xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="gui.TextFieldInController" fx:id="textFieldIn">
</TextField>
textFieldOut.fxml
<TextField xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:id="textFieldOut" fx:controller="gui.TextFieldOutController">
</TextField>
ExtendedTextField.java
public class ExtendedTextField extends TextField {
public ExtendedTextField(Model model) {
this.setText("ExtendedTextField");
}
}