JavaFX - 如何在另一个控制器的控制器中使用方法? [英] JavaFX - How to use a method in a controller from another controller?
问题描述
使用SceneBuilder。我有两个阶段,每个阶段都有一个控制器:stage1Controller,stage2Controller。
Stage1Controller:
class Stage1Controller {
@FXML
private MenuItem translate;
@FXML
私人菜单文件;
@FXML
私人菜单编辑;
@FXML
private菜单帮助;
@FXML
private void handleTranslate(ActionEvent event){
translateFirstStage();
//如何访问stage2Controller setLabel()?
}
private void translateFirstStage(){
file.setText(Fichier);
edit.setText(Modifier);
help.setText(Aide);
}
}
Stage2Controller:
public class Stage2Controller {
@FXML
private Label lb;
private void setLabel(String string){
lb.setText(string);
}
}
这里是如何在Main中加载fxml文件。 java类使用2种方法(在Start(Stage primaryStage)方法中调用):
public void firstStage(){
try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage1.fxml));
rootLayout =(BorderPane)loader.load();
//显示包含根布局的场景。
场景scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch(IOException e){
e.printStackTrace();
}
}
public void secondStage(){
try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage2.fxml));
XD =(AnchorPane)loader.load();
//显示包含根布局的场景。
场景scene =新场景(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}
- handleTranslate事件)方法用作第一阶段中的MenuItem翻译的OnAction方法,它在两个阶段翻译视图。
如何将setLabel放在handleTranslate方法中?谢谢 快速和脏的方式是给予 Stage1Controller
引用
Stage2Controller
:
public class Stage1Controller {
private final Stage2Controller stage2Controller;
public void setStage2Controller(Stage2Controller stage2Controller){
this.stage2Controller = stage2Controller;
}
// ...
@FXML
private void handleTranslate(ActionEvent event){
translateFirstStage
stage2Controller.setLabel(...);
}
//其他代码如前...
}
b $ b
现在在您的主要应用程式:
public class MainApp extends Application {
private Stage1Controller stage1Controller;
private Stage2Controller stage2Controller;
@Override
public void start(Stage primaryStage){
firstStage();
secondStage();
stage1Controller.setStage2Controller(stage2Controller);
// ...
}
public void firstStage(){
try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage1.fxml));
rootLayout =(BorderPane)loader.load();
stage1Controller = loader.getController();
//显示包含根布局的场景。
场景scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch(IOException e){
e.printStackTrace();
}
}
public void secondStage(){
try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage2.fxml));
XD =(AnchorPane)loader.load();
stage2Controller = loader.getController();
//显示包含根布局的场景。
场景scene =新场景(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}
// ...
}
一个更可靠的方法是,让两个控制器访问共享模型类,存储数据。如果使用JavaFX observable属性表示数据,控制器可以监听他们关心的属性的更改。例如:
public class Model {
private final StringProperty text = new SimpleStringProperty ...);
public StringProperty textProperty(){
return text;
}
public final void setText(String text){
textProperty()。set(text);
}
public final String getText(){
return textProperty()。get();
}
//所需的其他属性...
}
b $ b
现在你的控制器看起来像这样:
public class Stage1Controller {
私人模型模型;
public void setModel(Model model){
this.model = model;
}
@FXML
private void handleTranslate(ActionEvent event){
translateFirstStage();
model.setText(...); //值将出现在stage2控制器的标签中!
}
// ...
}
和
public class Stage2Controller {
@FXML
private Label lb;
私人模型;
public void setModel(Model model){
lb.textProperty()。unbind();
this.model = model;
lb.textProperty()。bind(model.textProperty());
}
// ...
}
<在这种情况下,你的主要应用程序看起来像:
public class MainApp extends Application {
private final Model = new Model();
@Override
public void start(Stage primaryStage){
// ...
}
public void firstStage
try {
//从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage1.fxml));
rootLayout =(BorderPane)loader.load();
Stage1Controller controller = loader.getController();
controller.setModel(model);
//显示包含根布局的场景。
场景scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch(IOException e){
e.printStackTrace();
}
}
public void secondStage(){
try {
}从fxml文件加载根布局。
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource(view / stage2.fxml));
XD =(AnchorPane)loader.load();
Stage2Controller controller = loader.getController();
controller.setModel(model);
//显示包含根布局的场景。
场景scene =新场景(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch(IOException e){
e.printStackTrace();
}
}
}
Working with SceneBuilder. I have 2 stages, each one with a controller: stage1Controller, stage2Controller.
Stage1Controller :
public class Stage1Controller {
@FXML
private MenuItem translate;
@FXML
private Menu file;
@FXML
private Menu edit;
@FXML
private Menu help;
@FXML
private void handleTranslate (ActionEvent event){
translateFirstStage();
//HOW TO ACCESS THE stage2Controller setLabel()??
}
private void translateFirstStage(){
file.setText("Fichier");
edit.setText("Modifier");
help.setText("Aide");
}
}
Stage2Controller:
public class Stage2Controller {
@FXML
private Label lb;
private void setLabel(String string){
lb.setText("string");
}
}
Here is how both fxml files are loaded in Main.java class using 2 methods (called in Start(Stage primaryStage) method):
public void firstStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage1.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void secondStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage2.fxml"));
XD = (AnchorPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
- The handleTranslate(ActionEvent event) method is used as an OnAction method for the MenuItem translate in the first Stage, it translates the view in both stages.
How Can i put setLabel in handleTranslate Method ? Thanks
The "quick and dirty" way is to give the Stage1Controller
a reference to the Stage2Controller
:
public class Stage1Controller {
private final Stage2Controller stage2Controller ;
public void setStage2Controller(Stage2Controller stage2Controller) {
this.stage2Controller = stage2Controller ;
}
// ...
@FXML
private void handleTranslate (ActionEvent event){
translateFirstStage();
stage2Controller.setLabel(...);
}
// other code as before ...
}
Now in your main app:
public class MainApp extends Application {
private Stage1Controller stage1Controller ;
private Stage2Controller stage2Controller ;
@Override
public void start(Stage primaryStage) {
firstStage();
secondStage();
stage1Controller.setStage2Controller(stage2Controller);
// ...
}
public void firstStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage1.fxml"));
rootLayout = (BorderPane) loader.load();
stage1Controller = loader.getController();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void secondStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage2.fxml"));
XD = (AnchorPane) loader.load();
stage2Controller = loader.getController();
// Show the scene containing the root layout.
Scene scene = new Scene(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
// ...
}
A more robust approach to this, though, is to let both controllers access a shared model class, storing the data. If you represent the data using JavaFX observable properties, the controllers can listen for changes on the properties they care about. For example:
public class Model {
private final StringProperty text = new SimpleStringProperty("Initial text...");
public StringProperty textProperty() {
return text ;
}
public final void setText(String text) {
textProperty().set(text);
}
public final String getText() {
return textProperty().get();
}
// other properties as needed...
}
Now your controllers will look like this:
public class Stage1Controller {
private Model model ;
public void setModel(Model model) {
this.model = model ;
}
@FXML
private void handleTranslate (ActionEvent event){
translateFirstStage();
model.setText(...); // value will appear in stage2 controller's label!
}
// ...
}
and
public class Stage2Controller {
@FXML
private Label lb ;
private Model model ;
public void setModel(Model model) {
lb.textProperty().unbind();
this.model = model ;
lb.textProperty().bind(model.textProperty());
}
// ...
}
And in this case your main app looks like:
public class MainApp extends Application {
private final Model = new Model();
@Override
public void start(Stage primaryStage) {
// ...
}
public void firstStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage1.fxml"));
rootLayout = (BorderPane) loader.load();
Stage1Controller controller = loader.getController();
controller.setModel(model);
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public void secondStage() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("view/stage2.fxml"));
XD = (AnchorPane) loader.load();
Stage2Controller controller = loader.getController();
controller.setModel(model);
// Show the scene containing the root layout.
Scene scene = new Scene(XD);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这篇关于JavaFX - 如何在另一个控制器的控制器中使用方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!