我有一个带有标签 firstLabel
的主屏幕。有一个按钮openSecondWindow
。
按下该按钮将打开一个新窗口,同时将第一个窗口保留在屏幕上。
- 如何锁定第一个屏幕,以便用户在第二个窗口关闭之前无法与其交互?
第二个窗口将有一个 TextField
和 Button setFirstLabel
。当用户在文本字段中输入文本并单击按钮时,第一个窗口中的文本就会更改。
我应该如何从第二个窗口的 Controller 访问第一个窗口的 Controller 类?
如何确保每次仅打开每个窗口的一个实例? (无重复)
最佳答案
我为你做了一个小例子。
如果您点击按钮上的第 1 个阶段来打开第二个阶段,则该按钮将被禁用,因此您无法再打开一个阶段。
如果您在 Stage2 上的文本字段中输入一些文本并单击此处的“更新”按钮,则第 1 阶段上的文本字段将更新,并且第二个阶段将关闭。
这是代码:
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>
第一个 Controller
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();
}
}
第二个 Controller
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,您就可以更新第一个 Stage 上的 TextField。
希望这会有所帮助。
帕特里克
关于java - 窗与窗的互动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23303578/