我有一个带有标签firstLabel
的主屏幕。有一个按钮openSecondWindow
。
按下该按钮会打开一个新窗口,同时将第一个按钮保留在屏幕上。
第二个窗口将包含TextField
和Button setFirstLabel
。当用户在文本字段中输入文本并点击按钮时,第一个窗口中的文本将被更改。
我应该如何从第二个窗口的控制器访问第一个窗口的控制器类?
如何确保每次只打开每个窗口的一个实例? (没有重复)
答案 0 :(得分:1)
我为你做了一个小例子。
如果单击按钮上的第1阶段以打开第二个舞台,则按钮将被禁用,因此您无法再打开一个舞台。
如果在Stage2上的TextField中键入一些文本并单击其中的“更新”按钮,则会更新第1阶段的TextField,并关闭第二个阶段。
以下是代码:
firstWindow.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="de.professional_webworkx.jfx.twowindows.controller.FirstController">
<children>
<TextField fx:id="textField" layoutX="50.0" layoutY="189.0" prefWidth="500.0" promptText="Waiting for input from second Stage..." />
<Button fx:id="openBtn" layoutX="441.0" layoutY="304.0" mnemonicParsing="false" text="open 2 Stage" />
</children>
</AnchorPane>
第二个fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<AnchorPane id="AnchorPane" fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="de.professional_webworkx.jfx.twowindows.controller.SecondController">
<children>
<TextField fx:id="textField" layoutX="50.0" layoutY="66.0" prefWidth="243.0" promptText="Type some text" />
<Button fx:id="updateBtn" layoutX="50.0" layoutY="118.0" mnemonicParsing="false" text="update Text on Stage 1" />
</children>
</AnchorPane>
FirstController
package de.professional_webworkx.jfx.twowindows.controller;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
/**
*
* @author Patrick Ott <Patrick.Ott@professional-webworkx.de>
* @version 1.0
*/
public class FirstController implements Initializable {
@FXML
Button openBtn;
@FXML
TextField textField;
private boolean secondOpen;
private Stage secondStage;
FirstController firstController;
public FirstController() {
}
@Override
public void initialize(URL url, ResourceBundle rb) {
this.firstController = this;
System.out.println(firstController);
openBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
if(!secondOpen) {
openBtn.setDisable(true);
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("second.fxml"));
Parent load = loader.load();
SecondController controller = (SecondController) loader.getController();
controller.setFirstController(firstController);
Scene scene = new Scene(load);
secondStage = new Stage();
secondStage.setScene(scene);
secondStage.show();
secondOpen = true;
} catch (IOException ex) {
Logger.getLogger(FirstController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
});
}
public void updateText(final String text) {
this.textField.setText(text);
}
public void secondClosed() {
this.secondOpen = false;
this.openBtn.setDisable(false);
secondStage.close();
}
}
SecondController
package de.professional_webworkx.jfx.twowindows.controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
/**
*
* @author Patrick Ott <Patrick.Ott@professional-webworkx.de>
* @version 1.0
*/
public class SecondController implements Initializable {
@FXML
AnchorPane mainPane;
@FXML
TextField textField;
@FXML
Button updateBtn;
private FirstController firstController;
@Override
public void initialize(URL url, ResourceBundle rb) {
updateBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
String text = textField.getText();
firstController.updateText(text);
firstController.secondClosed();
}
});
}
public void setFirstController(final FirstController firstController) {
this.firstController = firstController;
}
}
然后开始
package de.professional_webworkx.jfx.twowindows;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* @author Patrick Ott <Patrick.Ott@professional-webworkx.de>
*/
public class TwoStages extends Application {
@Override
public void start(Stage primaryStage) {
try {
Parent load = FXMLLoader.load(getClass().getResource("firstWindow.fxml"));
Scene scene = new Scene(load);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException ex) {
Logger.getLogger(TwoStages.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
魔术是将FirstController对象移交给SecondController,您可以在第一个舞台上更新TextField。
希望这会有所帮助。
帕特里克