从其控制器外部访问节点JavaFX - MVC [英] Accessing node from outside its controller JavaFX - MVC

查看:249
本文介绍了从其控制器外部访问节点JavaFX - MVC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个天气应用程式。有2个控制器文件的场景。一个是主屏幕,另一个是设置。主FXML包含一个标签,如果用户不想看到额外的信息位,它必须在设置页面打开/关闭。我的问题是如何设置Visible的标签从控制器类的设置页面,如果可能的话。
感谢您的帮助

I'm building a weather application. There are 2 scenes with 2 controller files. One is a main screen and the other one is for "settings". The main FXML contains a label, which must be turned on/off in the settings page, if the user does not want to see that extra bit of information. My question is how to setVisible that label from the controller class of the setting page, if it's possible at all. Thanks for your help

推荐答案

我假设设置场景只有当用户点击按钮主屏幕。我不得不在我的代码最近处理相同的情况。这是一个很好的教程,可以处理这种情况:

I'm assuming the settings scene only comes up when the user clicks a button on the main screen. I have had to handle the same situation in my code recently. Here is a great tutorial that handles this situation:

http://code.makery.ch/library/javafx-2-tutorial/part1/

1。)在您的MainScene控制器将引用主类并调用其函数以弹出设置场景。

1.) In your MainScene Controller you will reference the main class and call its function to pop up the Settings Scene.

2)在您的主类中,您将有一个函数弹出设置场景

2.) In your main class you will have a function that pops up the Settings Scene

3。)设置场景关闭后,它将通过Main类将值传递回MainScene控制器,并根据您可以设置的返回值

3.) After the Settings Scene is closed it will pass the value back to the MainScene Controller through the Main class and based on the returned value you can set the label.

1)。你的主场景的MainController将引用主类和一个通过主类调用设置场景的函数。 p>

1.) Your MainController for your Main scene will have a reference to the main class and a function to call the Settings Scene through the main class.

public class MainController {

@FXML
private Label label;
@FXML
private Button Settings;


// Reference to the main application
private MainApp mainApp;

/**
 * The constructor.
 * The constructor is called before the initialize() method.
 */
public MainController() {
}

/*Tie this function to your button that pops up Settings */

private void handleSettingsButton() { 

      /* Here you call a function in the main class and pass the label
       * to the settings scene controller */

        boolean show = mainApp.showSettingsScene(label);
        if (show) {
                label.isVisible("True");
         }
        else {
                label.isVisible("False");
        }
}

/**
 * Is called by the main application to give a reference back to itself.
 * 
 * @param mainApp
 */
public void setMainApp(MainApp mainApp) {
    this.mainApp = mainApp;


}
}

2。在你的主类中(不要与你的主场景混淆),你加载Main场景并调用setMainApp函数,给你的控制器一个参考回主类。

2.) In your main class (not to be confused with your main scene) you load the Main scene and call the setMainApp function to give your controller a reference back to the Main Class.

    public class MainApp extends Application {

private Stage primaryStage;
private BorderPane rootLayout;

@Override
public void start(Stage primaryStage) {
    this.primaryStage = primaryStage;
    this.primaryStage.setTitle("Main");

 /*Right when the app is loaded the MainScene shows up.*/

    try {
        // Load the root layout from the fxml file
        FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/MainScene.fxml"));
 /* Get a reference to the controller instance of the main Scene */
mainSceneController = loader.getController();
    /*Allow the controller to talk to the main class */
    mainSceneController.setMainApp(this);
        rootLayout = (BorderPane) loader.load();
        Scene scene = new Scene(rootLayout);
        primaryStage.setScene(scene);
        primaryStage.show();
    } catch (IOException e) {
        // Exception gets thrown if the fxml file could not be loaded
        e.printStackTrace();
    }


}

/**
 * Returns the main stage.
 * @return
 */
public Stage getPrimaryStage() {
    return primaryStage;
}

/*This function referenced in your main controller will show the Settings
 *Scene and wait to see what the user has selected for the visible or not 
 *visible selection.  We need to pass the label to it as well, so we
 *accurately load the Settings Scene with the current state of the label
 */

public boolean showSettingsScene(Label label) {
    try {
      // Load the fxml file and create a new stage for the popup
    FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("view/SettingsScene.fxml"));
settingsSceneController = loader.getController();

    /* Here we send the label to the controller instance of the Settings
     * Scene */

    controller.setLabel(label);
    AnchorPane page = (AnchorPane) loader.load();
    Stage dialogStage = new Stage();
    dialogStage.setTitle("Settings");
    dialogStage.initModality(Modality.WINDOW_MODAL);
    dialogStage.initOwner(primaryStage);
    Scene scene = new Scene(page);
    dialogStage.setScene(scene);

/* Show the dialog and wait until the user closes it*/
dialogStage.showAndWait();

 /*Return the value that the user has selected for visible or not */
return controller.isShowOrHide();

   } catch (IOException e) {
// Exception gets thrown if the fxml file could not be loaded
e.printStackTrace();
     return false;
   }
 }

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

3。)您的设置Scene Controller将看起来像以下:

3.) Your Settings Scene Controller will look something like the following:

import...
public class SettingsSceneController{

@FXML  private ComboBox showOrHide;

private Stage dialogStage;
private Boolean show = false;
private Label label;

/**
 * Initializes the controller class. This method is automatically called
 * after the fxml file has been loaded.  
 */
@FXML
private void initialize() {
     ;I don't know what you have, but if you use a Combobox...
     showOrHide.getItems().addAll(
          "Show",
          "Hide",);

}

/**
 * Sets the stage of this dialog.
 * @param dialogStage
 */
public void setDialogStage(Stage dialogStage) {
    this.dialogStage = dialogStage;
}

/*The label that was passed from Main Scene Controller to Main Class to 
 * here is now used in the function to update the Combobox with the
 * current status of the label */
public void setLabel(Label label) {
    this.label = label;
     if(label.isVisible){
          showOrHide.setValue("Show");
          show = true;
     }
     else{
          showOrHide.setValue("Hide"); 
          show = false;
     }
}



/**
 * Returns true if the user clicked OK, false otherwise.
 * @return
 */
public boolean isShowOrHide() {
    return show;
}

/**
 * Called when the user clicks ok. Attach this in Scene Builder,to the OK,
 * Enter or Apply or whatever you called it button of the Settings Scene 
 * It will reflect any change made to the combobox.
 */
@FXML
private void handleOk() {
    if (showOrHide.getValue().toString() == "Show") {
        show= true;
     }
    else{
        show = false;
     }
        dialogStage.close();

}

/**
 * Called when the user clicks cancel if you have a cancel button.
 */
@FXML
private void handleCancel() {
    dialogStage.close();
}


}
}

我把大部分的代码从教程和定制定制到您的解决方案。它是一种弹跳到三个类,但如果你想一点点,你可以看到他们是如何在控制器之间使用主类来促进它的通信。我没有测试这个,但它应该非常接近你需要的。

I took most of this code from the tutorial and custom tailored it to your solution. It is kind of bouncing around to three classes, but if you think on it a little bit you can see how they are communicating between the controllers using the main class to facilitate it. I did not test this, but it should be pretty close to what you need.

这篇关于从其控制器外部访问节点JavaFX - MVC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆