JavaFX如何在调用控制器中设置标签文本,来自被调用控制器
JavaFX how to set the text of a label in the calling controller, from the called controller
我是 JavaFX(和 Java)新手,也是新手 Whosebug 用户,所以如果我有任何错误,我提前道歉!
我正在尝试创建一个应用程序,它有一个主场景,可以将几个不同的场景加载为窗格。每个不同的场景都由主场景上的一个按钮加载(就像一个选项卡式窗格)。
我在主屏幕上有一个用于显示错误消息的标签。我希望场景在遇到错误时更新主场景的标签文本,但我很难知道如何做到这一点。我用谷歌搜索并尝试了数十条建议但无济于事。有人可以告诉我我做错了什么吗?非常感谢!
我已经创建了一个测试应用程序来展示我正在尝试做的事情。我正在使用 JavaSE8 和 NetBeans8.2。
主应用程序:
public class TestApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLMain.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FXMLMain.fxml
<AnchorPane fx:id="anchorMain" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testapp.FXMLMainController">
<children>
<AnchorPane fx:id="anchorView" prefHeight="400.0" prefWidth="400.0" />
<Button fx:id="btnLoadView1" layoutX="476.0" layoutY="39.0" mnemonicParsing="false" onAction="#loadView1" text="Load view 1" />
<Label fx:id="lblSystemMessage" layoutX="411.0" layoutY="145.0" text="label for system messages" />
</children>
</AnchorPane>
FXMLMainController.java
public class FXMLMainController implements Initializable {
@FXML
private AnchorPane anchorMain;
@FXML
private AnchorPane anchorView;
@FXML
private Button btnLoadView1;
@FXML
private Label lblSystemMessage;
Pane paneView1;
@Override
public void initialize(URL url, ResourceBundle rb) {
//Load View 1
try {
paneView1 = FXMLLoader.load(getClass().getResource("FXMLView1.fxml"));
} catch (IOException ex) {
Logger.getLogger(FXMLMainController.class.getName()).log(Level.SEVERE, null, ex);
}
anchorMain.getChildren().add(paneView1);
paneView1.setVisible(false);
//Load Views 2, 3, 4 et al.
}
@FXML
private void loadView1(ActionEvent event) {
paneView1.setVisible(true);
}
public void setSystemMessage (String text) {
System.out.println("received text " + text);
lblSystemMessage.setText(text);
System.out.println("lblSystemMessage.getText() is " + lblSystemMessage.getText());
}
}
FXMLView1.fxml
<AnchorPane id="AnchorPane" fx:id="anchorView1" prefHeight="400.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testapp.FXMLView1Controller">
<children>
<Label layoutX="64.0" layoutY="45.0" text="This is view 1" />
<Button fx:id="btnView1SimulateError" layoutX="64.0" layoutY="122.0" mnemonicParsing="false" onAction="#view1SimulateError" text="Simulate error" />
</children>
</AnchorPane>
FXMLView1Controller.java
public class FXMLView1Controller implements Initializable {
@FXML
private AnchorPane anchorView1;
@FXML
private Button btnView1SimulateError;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private void view1SimulateError(ActionEvent event) {
System.out.println("simulating error from View 1");
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLMain.fxml"));
try {
Parent root = loader.load();
} catch (IOException ex) {
Logger.getLogger(FXMLView1Controller.class.getName()).log(Level.SEVERE, null, ex);
}
FXMLMainController mainController = loader.getController();
mainController.setSystemMessage("FRED");
}
}
当我 运行 应用程序并单击 btnLoadView1 然后单击 btnView1SimulateError 时,我从 FXMLMainController 中的 setSystemMessage 方法得到以下输出:
simulating error from View 1
received text FRED
lblSystemMessage.getText() is FRED
但是主场景中的标签文字没有更新为"FRED"。我做错了什么?
据我了解,您想从 FXMLView1Controller 调用 FXMLMainController 的 setSystemMessage()
函数。问题是要这样做,您需要有一个对主控制器的引用。所以,你需要提供一个。
这是可能的解决方案之一。您从主控制器的 initialize
函数加载 FXMLView1.fxml。因此,您可以获得控制器,在负载中分配。这是一个例子:
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLView1.fxml"));
try {
paneView1 = loader.load();
FXMLView1Controller view1Controller = loader.getController();
}
catch (IOException e) {
...
}
现在你有了 view1Controller。你可以为所欲为。我建议你在其中添加一个 mainController 字段并执行
view1Controller.mainController = this;
以后需要时,
mainController.setSystemMessage(message);
我是 JavaFX(和 Java)新手,也是新手 Whosebug 用户,所以如果我有任何错误,我提前道歉!
我正在尝试创建一个应用程序,它有一个主场景,可以将几个不同的场景加载为窗格。每个不同的场景都由主场景上的一个按钮加载(就像一个选项卡式窗格)。
我在主屏幕上有一个用于显示错误消息的标签。我希望场景在遇到错误时更新主场景的标签文本,但我很难知道如何做到这一点。我用谷歌搜索并尝试了数十条建议但无济于事。有人可以告诉我我做错了什么吗?非常感谢!
我已经创建了一个测试应用程序来展示我正在尝试做的事情。我正在使用 JavaSE8 和 NetBeans8.2。
主应用程序:
public class TestApp extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLMain.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FXMLMain.fxml
<AnchorPane fx:id="anchorMain" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testapp.FXMLMainController">
<children>
<AnchorPane fx:id="anchorView" prefHeight="400.0" prefWidth="400.0" />
<Button fx:id="btnLoadView1" layoutX="476.0" layoutY="39.0" mnemonicParsing="false" onAction="#loadView1" text="Load view 1" />
<Label fx:id="lblSystemMessage" layoutX="411.0" layoutY="145.0" text="label for system messages" />
</children>
</AnchorPane>
FXMLMainController.java
public class FXMLMainController implements Initializable {
@FXML
private AnchorPane anchorMain;
@FXML
private AnchorPane anchorView;
@FXML
private Button btnLoadView1;
@FXML
private Label lblSystemMessage;
Pane paneView1;
@Override
public void initialize(URL url, ResourceBundle rb) {
//Load View 1
try {
paneView1 = FXMLLoader.load(getClass().getResource("FXMLView1.fxml"));
} catch (IOException ex) {
Logger.getLogger(FXMLMainController.class.getName()).log(Level.SEVERE, null, ex);
}
anchorMain.getChildren().add(paneView1);
paneView1.setVisible(false);
//Load Views 2, 3, 4 et al.
}
@FXML
private void loadView1(ActionEvent event) {
paneView1.setVisible(true);
}
public void setSystemMessage (String text) {
System.out.println("received text " + text);
lblSystemMessage.setText(text);
System.out.println("lblSystemMessage.getText() is " + lblSystemMessage.getText());
}
}
FXMLView1.fxml
<AnchorPane id="AnchorPane" fx:id="anchorView1" prefHeight="400.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testapp.FXMLView1Controller">
<children>
<Label layoutX="64.0" layoutY="45.0" text="This is view 1" />
<Button fx:id="btnView1SimulateError" layoutX="64.0" layoutY="122.0" mnemonicParsing="false" onAction="#view1SimulateError" text="Simulate error" />
</children>
</AnchorPane>
FXMLView1Controller.java
public class FXMLView1Controller implements Initializable {
@FXML
private AnchorPane anchorView1;
@FXML
private Button btnView1SimulateError;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private void view1SimulateError(ActionEvent event) {
System.out.println("simulating error from View 1");
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLMain.fxml"));
try {
Parent root = loader.load();
} catch (IOException ex) {
Logger.getLogger(FXMLView1Controller.class.getName()).log(Level.SEVERE, null, ex);
}
FXMLMainController mainController = loader.getController();
mainController.setSystemMessage("FRED");
}
}
当我 运行 应用程序并单击 btnLoadView1 然后单击 btnView1SimulateError 时,我从 FXMLMainController 中的 setSystemMessage 方法得到以下输出:
simulating error from View 1
received text FRED
lblSystemMessage.getText() is FRED
但是主场景中的标签文字没有更新为"FRED"。我做错了什么?
据我了解,您想从 FXMLView1Controller 调用 FXMLMainController 的 setSystemMessage()
函数。问题是要这样做,您需要有一个对主控制器的引用。所以,你需要提供一个。
这是可能的解决方案之一。您从主控制器的 initialize
函数加载 FXMLView1.fxml。因此,您可以获得控制器,在负载中分配。这是一个例子:
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLView1.fxml"));
try {
paneView1 = loader.load();
FXMLView1Controller view1Controller = loader.getController();
}
catch (IOException e) {
...
}
现在你有了 view1Controller。你可以为所欲为。我建议你在其中添加一个 mainController 字段并执行
view1Controller.mainController = this;
以后需要时,
mainController.setSystemMessage(message);