【问题标题】:JavaFX how to set the text of a label in the calling controller, from the called controllerJavaFX如何在调用控制器中设置标签的文本,来自被调用的控制器
【发布时间】:2017-08-31 01:37:03
【问题描述】:

我是 JavaFX(和 Java)新手,也是 StackOverflow 新手,所以如果我弄错了,我提前道歉!

我正在尝试创建一个具有主场景的应用程序,该场景将多个不同的场景加载为窗格。每个不同的场景都由主场景上的一个按钮加载(更像是一个选项卡式窗格)。

我在主屏幕上有一个用于显示错误消息的标签。我希望场景在遇到错误时更新主场景的标签文本,但我正在努力了解如何做到这一点。我已经用谷歌搜索并尝试了许多建议,但均无济于事。有人能告诉我我做错了什么吗?非常感谢!

我创建了一个测试应用程序来显示我正在尝试做的事情。我正在使用 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”。我做错了什么?

【问题讨论】:

    标签: java javafx-8 fxml netbeans-8


    【解决方案1】:

    据我了解,您想从 FXMLView1Controller 调用 FXMLMainControllersetSystemMessage() 函数。问题是要这样做,您需要参考主控制器。所以,你需要提供一个。

    这是可能的解决方案之一。您从主控制器的 initialize 函数加载 FXMLView1.fxml。因此,您可以获得控制器,在负载中分配。这是一个例子:

        FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLView1.fxml"));
        try {
            paneView1 = loader.load();
            FXMLView1Controller view1Controller = loader.getController();
        }
        catch (IOException e) {
             ...
        }
    

    现在你有了 view1Controller。你可以做任何你想做的事。我建议你添加一个 ma​​inController 字段并做

     view1Controller.mainController = this;
    

    以后需要的时候,

     mainController.setSystemMessage(message);
    

    【讨论】:

    • 非常感谢,效果很好。除了这一行,我理解了所有内容:“view1Controller.mainController = this;”。那实际上是做什么的?当我添加它时,NetBeans 添加了“FXMLMainController mainController;”在 FXMLView1Controller 代码中。当我 println 时,我可以看到它设置为“testapp.FXMLMainController@2a13b30e”。我如何可以从 FXMLMainController 代码访问 mainController 变量?再次感谢!
    • 抱歉,一分钱刚刚掉——现在我有了对 View1 控制器的引用,我可以设置其中一个变量。将其设置为“this”后,View 1 Controller 现在可以引用回主控制器。我现在明白了。可爱的解决方案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 2016-06-15
    相关资源
    最近更新 更多