Java FX 更改前一阶段场景中的标签文本

标签 java javafx controller label fxml

我有一个 Main 类启动我的应用程序,它的 MainController 类在 fxml 中指定。当单击Connect按钮时,会打开另一个具有不同场景和 Controller 的窗口。基于操作,我想通过我的 MainController 更改 Label 文本值,但它无法按预期工作。请参阅下面的详细信息。

基本上,我想从 ConnectController 类的 MainController 类中更新 connectedLabel 上的文本,但它不起作用。

Main.java:

public class Main extends Application {

    private static final Logger logger = Logger.getLogger(Main.class.getName());

    @Override
    public void start(Stage primaryStage) {
        try {
            logger.info("Application is starting");
            AnchorPane page = FXMLLoader.load(getClass().getResource("Main.fxml"));

            //BorderPane root = new BorderPane();
            //Scene scene = new Scene(root,400,400);

            Scene scene = new Scene(page);
            scene.getStylesheets().add(getClass().getResource("Main.css").toExternalForm());
            primaryStage.setScene(scene);

            primaryStage.setResizable(false);

            primaryStage.show();

        } catch(Exception e) {
            logger.warning(e.getMessage());
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

}

MainController.java:

    public class MainController implements Initializable {

    private Context context = null;

    @FXML
    Label connectedLabel;
    @FXML
    Button connectButton;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        context = Context.getInstance();
    }

    public void setConnectedLabel(String name) {
        connectedLabel.setText(name);
        connectButton.setText("Disconnect");
    }

    @FXML
    public void connectTokenButton_onMouseClicked() {
        try {
            if (connectTokenButton.getText().equals("Disconnect")) {
                boolean disconnected = context.getToken().disconnectToken();
                if (disconnected) {
                    Alert alert = new Alert(AlertType.INFORMATION);
                    alert.setTitle("Disconnected");
                    alert.setHeaderText(null);
                    alert.setContentText("Succcessfully disconnected!");

                    alert.showAndWait();

                    connectedTokenLabel.setText("N/A");
                    connectTokenButton.setText("Connect");
                }
            } else {
                AnchorPane page = FXMLLoader.load(getClass().getResource("ConnectView.fxml"));

                Stage stage = new Stage();

                Scene scene = new Scene(page);
                scene.getStylesheets().add(getClass().getResource("ConnectView.css").toExternalForm());
                stage.setScene(scene);

                stage.setResizable(false);
                stage.initModality(Modality.APPLICATION_MODAL);
                stage.initOwner(connectedLabel.getScene().getWindow());
                stage.show();

                //Stage thisStage = (Stage) connectedTokenLabel.getScene().getWindow();
                //thisStage.close();
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

ConnectController.java:

public class ConnectController implements Initializable {

    private Context context = null;

    @FXML
    ComboBox<String> selectComboBox;
    @FXML
    PasswordField userPinPasswordField;
    @FXML
    Button cancelButton;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        context = Context.getInstance();
    }

    public void setMainC(Stage stage) {
        mainStage = stage;
    }

    @FXML
    private void connectToken_onMouseClicked() {
        String pin = userPinPasswordField.getText();
        boolean connected = context.connect(selectComboBox.getValue(), pin);        
        if (connected) {

            Alert alert = new Alert(AlertType.INFORMATION);
            alert.setTitle("Connected");
            alert.setHeaderText(null);
            alert.setContentText("Succcessfully connected!");

            alert.showAndWait();

            FXMLLoader myLoader = new FXMLLoader(getClass().getResource("Main.fxml"));
            MainController mainController = myLoader.getController();
            mainController.setConnectedTokenLabel(context.getConnectedName());

            Stage thisStage = (Stage) selectComboBox.getScene().getWindow();
            thisStage.close();
        }
    }
}

从不同 Controller 调用 setConnectedLabel 方法时我做错了什么?

最佳答案

FXMLLoader myLoader = new FXMLLoader(getClass().getResource("Main.fxml"));
MainController mainController = myLoader.getController();
mainController.setConnectedTokenLabel(context.getConnectedName());

如果不调用 FXMLLoaderload 方法,则不会创建任何 Controller 实例,即使在fxml 文件。

但是,在 getController 之前调用 load 不会有帮助,因为 fxml 只是使用不同的 Controller 实例再次加载。

您需要“告诉”ConnectController 它是从哪个MainController 创建的。 (参见Passing Parameters JavaFX FXML)

一种方法是将此代码添加到 ConnectController

private MainController mainController;

public void setMainController(MainController mainController) {
    this.mainController = mainController;
}

并在 connectToken_onMouseClicked() 方法中使用此字段而不是局部变量。

要调用 setter ,请在 connectTokenButton_onMouseClicked() 中加载 View 后访问 Controller :

FXMLLoader loader = new FXMLLoader(getClass().getResource("ConnectView.fxml"));
AnchorPane page = loader.load();
loader.<ConnectController>getController().setMainController(this);

关于Java FX 更改前一阶段场景中的标签文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40959672/

相关文章:

grails - 在Grails中,如何从 Controller 返回到调用当前 View ?

JavaFX MediaPlayer 状态停留在 PLAYING

JavaFX Webview 编码错误

java - MVC架构中如何使用线程?

spring - Spring注解@Controller和@Service一样吗?

java - JSESSIONID 后缀为 .undefined

java - 在 JavaFX 中创建和停止线程

Java实现检查两条线段之间的交点?

java - 在应用程序中,API 响应中收到 400 Bad request

ios - Swift 不允许我设置变量数据