通过 Java FX Controller 将数据传递到其他视图
Passing data through Java FX Controller to other View
我想这是一个简单的问题,但这是漫长的一天工作,我现在无法找到正确的出路。
我有 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
两次,所以有两个实例。但是我不知道如何只加载一次或注入它来更新 MengeController
.
中的 TextField
选项 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");
}
}
然后 MengeController
中加载 Suche.fxml 的代码看起来像
@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();
}
}
我想这是一个简单的问题,但这是漫长的一天工作,我现在无法找到正确的出路。
我有 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
两次,所以有两个实例。但是我不知道如何只加载一次或注入它来更新 MengeController
.
TextField
选项 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");
}
}
然后 MengeController
中加载 Suche.fxml 的代码看起来像
@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();
}
}