我想这是一个简单的问题,但这是漫长的一天工作,我现在无法想出正确的方法。
我有3个FXML文件。
Menge.fxml
Start.fxml
Suche.fxml
我像往常一样从Main.java开始
@Override
public void start(Stage primaryStage) {
try {
AnchorPane root = (AnchorPane)FXMLLoader.load(getClass().getResource("Start.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
在MainController
内,我有以下ActionListener
@FXML
void actionListenerMenge(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Menge.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
所以我通过FXMLLoader打开Suche.fxml
。
现在我的Suche-View中有一个button
,它打开另一个场景,用户应该搜索特定的数据记录。
@FXML
void actionListenerSuche(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Suche.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
SucheController
我通过FXMLLoader再次加载MengeController
FXMLLoader loader = new FXMLLoader(getClass().getResource("Menge.fxml"));
try {
Parent root = loader.load();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MengeController controller = (MengeController)loader.getController();
我想修改TextField
@ MengeController
内的值,以便从我的Menge.fxml
更新视图。但是如果我做的话
controller.setTextFieldValue("abc")
它没有更新。我知道这一定是因为我已经加载MengeController
两次,所以有两个实例。但我不知道如何只加载一次或注入它来更新TextField
内的MengeController
。
答案 0 :(得分:1)
选项1:观察SucheController
:
在SucheController
中定义属性。而不是尝试将引用返回到MengeController
,只需设置属性:
public class SucheController {
private final ObjectProperty<Foo> foo = new SimpleObjectProperty<>();
public ObjectProperty<Foo> fooProperty() {
return foo() ;
}
public final Foo getFoo() {
return fooProperty().get();
}
public final void setFoo(Foo foo) {
fooProperty().set(foo);
}
// ...
@FXML
private void someHandlerMethod() {
// FXMLLoader loader = new FXMLLoader(getClass().getResource("Menge.fxml"));
// try {
// Parent root = loader.load();
// } catch (IOException e) {
// e.printStackTrace();
// }
// MengeController controller = (MengeController)loader.getController();
setFoo(...);
}
}
显然将Foo
替换为表示用户在此处提供的任何数据的类型,并相应地命名属性和方法......
现在加载Suche.fxml时,只需获取对控制器的引用并观察属性。然后,您可以直接在MengeController
本身更新文本字段:
@FXML
void actionListenerSuche(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Suche.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
SucheController sucheController = loader.getController();
sucheController.fooProperty().addListener((obs, oldFoo, newFoo) -> {
someTextField.setText(newFoo.getSomeValue());
// ...
});
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
选项2:将对MengeController
的引用直接传递给SucheController
:
另一个选项,我不喜欢它涉及控制器之间的更多耦合,只是将对MengeController
的引用传递给SucheController
:
public class SucheController {
private MengeController mengeController ;
public void setMengeController(MengeController mengeController) {
this.mengeController = mengeController ;
}
// ...
@FXML
private void someHandlerMethod() {
mengeController.setTextFieldValue("abc");
}
}
然后加载Suche.fxml的MengeController
中的代码看起来像
@FXML
void actionListenerSuche(ActionEvent event) {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Suche.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
SucheController sucheController = fxmlLoader.getController();
sucheController.setMengeController(this);
Stage stage = new Stage();
stage.setScene(new Scene(root1));
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}