我假设设置场景仅在用户单击主屏幕上的按钮时出现。我最近不得不在我的代码中处理同样的情况。这是处理这种情况的一个很好的教程:
http://code.makery.ch/library/javafx-2-tutorial/part1/
1.) 在您的 MainScene 控制器中,您将引用主类并调用其函数以弹出设置场景。
2.) 在您的主类中,您将拥有一个弹出设置场景的功能
3.) 设置场景关闭后,它会通过 Main 类将值传回 MainScene 控制器,并根据返回的值设置标签。
1.) Main 场景的 MainController 将具有对主类的引用和一个通过主类调用设置场景的函数。
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.) 在您的主类(不要与主场景混淆)中,您加载主场景并调用 setMainApp 函数为您的控制器提供对主类的引用。
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.) 您的设置场景控制器将如下所示:
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();
}
}
}
我从教程中获取了大部分代码,并根据您的解决方案对其进行了定制。它有点像三个类,但如果你稍微思考一下,你会看到它们是如何使用主类在控制器之间进行通信以促进它的。我没有对此进行测试,但它应该非常接近您的需要。