JavaFX从一个对话框打开另一个对话框
我的应用程序中存在以下导致问题的工作流: 单击按钮打开对话框>打开对话框>单击对话框中的按钮>显示确认警报>确认后关闭第一个对话框并打开新对话框 第二个对话框不允许输入文本字段。我已经包括了一个显示问题的SSCE。另外一件奇怪的事情是,如果您试图通过单击“X”来关闭第二个对话框,然后关闭警报,那么我就可以在字段中键入JavaFX从一个对话框打开另一个对话框,java,javafx,dialog,alert,Java,Javafx,Dialog,Alert,我的应用程序中存在以下导致问题的工作流: 单击按钮打开对话框>打开对话框>单击对话框中的按钮>显示确认警报>确认后关闭第一个对话框并打开新对话框 第二个对话框不允许输入文本字段。我已经包括了一个显示问题的SSCE。另外一件奇怪的事情是,如果您试图通过单击“X”来关闭第二个对话框,然后关闭警报,那么我就可以在字段中键入 public class DialogTest extends Application { @Override public void start(Stage prima
public class DialogTest extends Application {
@Override
public void start(Stage primaryStage) {
Button button = new Button("Show Dialog");
VBox root = new VBox(10, button);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 350, 120);
primaryStage.setScene(scene);
primaryStage.show();
button.setOnAction(event -> {
Dialog<Pair<String, String>> dialog = getDialog(scene.getWindow(), "Dialog 1", true);
dialog.showAndWait();
});
}
public static void main(String[] args) {
launch(args);
}
public Dialog<Pair<String, String>> getDialog(Window owner, String title, boolean addButton) {
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle(title);
dialog.initOwner(owner);
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
if(addButton) {
Button button = new Button("Show Dialog");
dialog.getDialogPane().setContent(button);
button.setOnAction(event -> {
Alert alert = new Alert(AlertType.CONFIRMATION, "Are you sure?", ButtonType.YES, ButtonType.NO);
alert.initOwner(owner);
if(alert.showAndWait().get() == ButtonType.YES) {
dialog.close();
Dialog<Pair<String, String>> dialog2 = getDialog(owner, "Dialog 2", false);
TextField textField = new TextField();
dialog2.getDialogPane().setContent(textField);
dialog2.getDialogPane().getScene().getWindow().setOnCloseRequest(closeEvent -> {
closeEvent.consume();
if(textField.getText().trim().isEmpty()) {
Alert alert2 = new Alert(AlertType.ERROR, "Please enter a value", ButtonType.OK);
alert2.initOwner(dialog2.getDialogPane().getScene().getWindow());
alert2.showAndWait();
}
});
dialog2.showAndWait();
}
});
}
return dialog;
}
}
public类DialogTest扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
按钮按钮=新按钮(“显示对话框”);
VBox根=新的VBox(10,按钮);
根部设置对齐(位置中心);
场景=新场景(根,350,120);
初级阶段。场景(场景);
primaryStage.show();
按钮。设置操作(事件->{
Dialog=getDialog(scene.getWindow(),“Dialog 1”,true);
dialog.showAndWait();
});
}
公共静态void main(字符串[]args){
发射(args);
}
公共对话框getDialog(窗口所有者、字符串标题、布尔添加按钮){
Dialog=新建Dialog();
对话框。设置标题(标题);
dialog.initOwner(所有者);
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK,ButtonType.CANCEL);
如果(添加按钮){
按钮按钮=新按钮(“显示对话框”);
dialog.getDialogPane().setContent(按钮);
按钮。设置操作(事件->{
Alert Alert=新警报(AlertType.CONFIRMATION,“确定吗?”,ButtonType.YES,ButtonType.NO);
警报。初始所有者(所有者);
if(alert.showAndWait().get()==ButtonType.YES){
dialog.close();
Dialog Dialog 2=getDialog(所有者,“Dialog 2”,false);
TextField TextField=新的TextField();
dialog2.getDialogPane().setContent(文本字段);
dialog2.getDialogPane().getScene().getWindow().setOnCloseRequest(closeEvent->{
closeEvent.consume();
if(textField.getText().trim().isEmpty()){
Alert alert2=新警报(AlertType.ERROR,“请输入值”,ButtonType.OK);
alert2.initOwner(dialog2.getDialogPane().getScene().getWindow());
alert2.showAndWait();
}
});
dialog2.showAndWait();
}
});
}
返回对话框;
}
}
在创建Dialog1的“开始”方法中,应该调用dialog.show()而不是dialog.showAndWait()
i、 e
按钮。设置操作(事件->{
Dialog=getDialog(scene.getWindow(),“Dialog 1”,true);
//dialog.showAndWait();
dialog.show();
});
问题
如前所述,您有一个模态问题
解决方案
下面的代码将演示一个解决方案,其中询问用户是否真的想要打印,以及打印后的结束号码是否正确
(注意,我使用的是来自的类IntField)
导入javafx.application.application;
导入javafx.concurrent.Task;
导入javafx.event.ActionEvent;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Alert;
导入javafx.scene.control.Button;
导入javafx.scene.control.ButtonBar.ButtonData;
导入javafx.scene.control.ButtonType;
导入javafx.scene.control.Dialog;
导入javafx.scene.control.ProgressIndicator;
导入javafx.scene.layout.GridPane;
导入javafx.scene.layout.Region;
导入javafx.scene.layout.StackPane;
导入javafx.scene.layout.VBox;
导入javafx.scene.text.text;
导入javafx.stage.stage;
导入javafx.stage.Window;
公共类DialogTest扩展应用程序{
区域面纱;
进度指标;
IntField startingNumber=新的IntField(0,999999,0);
IntField endingNumber=新的IntField(startingNumber.getValue(),999999,startingNumber.getValue()+1);
ButtonType printButtonType=新的ButtonType(“打印”,ButtonData.OK\u DONE);
阶段性;
@凌驾
公共无效开始(阶段primaryStage){
阶段=初级阶段;
按钮按钮=新按钮(“打印检查”);
VBox框=新的VBox(10,按钮);
框。设置对齐(位置中心);
面纱=新区域();
设置样式(“-fx背景色:rgba(0,0,0,0.3);”;
面纱可见(假);
指示器=新的ProgressIndicator();
指示器。设置最大高度(60);
指示器。设置最小宽度(60);
指示器。设置为可见(假);
StackPane根=新的StackPane(框、面纱、指示器);
根部设置对齐(位置中心);
场景=新场景(根,400400);
初级阶段。场景(场景);
primaryStage.show();
按钮设置动作((事件)->{
对话
=getCheckPrintDialog(primaryStage,“输入起始检查编号”);
dialog.showAndWait()
.filter(结果->结果==printButtonType)
.ifPresent(结果->{
//这仅用于此示例,通常您已经具有此值
endingNumber.setValue(startingNumber.getValue()+1);
打印检查(startingNumber.getValue(),endingNumber.getValue());
});
});
}
公共静态void main(字符串[]args){
发射(args);
}
公共对话框getCheckPrintDialog(窗口所有者,字符串标题){
Dialog=新建Dialog();
dialog.initOwner(所有者);
对话框。设置标题(标题);
dialog.getDialogPane().getButtonTypes().addAll(printButtonType,ButtonType.CANCEL);
按钮btOk=(按钮)dialog.getDialogPane().lookupButton(printButtonType);
btOk.addEventFilter(ActionEvent.ACTION,事件->{
Alert Alert=新警报(Alert.AlertType.CONFIRMATION,“打印支票?您确定吗?”,ButtonType.YES,ButtonType.NO);
alert.showAndWait()
.过滤器(r
button.setOnAction(event -> {
Dialog<Pair<String, String>> dialog = getDialog(scene.getWindow(), "Dialog 1", true);
// dialog.showAndWait();
dialog.show();
});
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.Window;
public class DialogTest extends Application {
Region veil;
ProgressIndicator indicator;
IntField startingNumber = new IntField(0, 999999, 0);
IntField endingNumber = new IntField(startingNumber.getValue(), 999999, startingNumber.getValue() + 1);
ButtonType printButtonType = new ButtonType("Print", ButtonData.OK_DONE);
Stage stage;
@Override
public void start(Stage primaryStage) {
stage = primaryStage;
Button button = new Button("Print Checks");
VBox box = new VBox(10, button);
box.setAlignment(Pos.CENTER);
veil = new Region();
veil.setStyle("-fx-background-color: rgba(0, 0, 0, 0.3);");
veil.setVisible(false);
indicator = new ProgressIndicator();
indicator.setMaxHeight(60);
indicator.setMinWidth(60);
indicator.setVisible(false);
StackPane root = new StackPane(box, veil, indicator);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
button.setOnAction((event) -> {
Dialog<ButtonType> dialog
= getCheckPrintDialog(primaryStage, "Enter starting check number");
dialog.showAndWait()
.filter(result -> result == printButtonType)
.ifPresent(result -> {
// this is for this example only, normaly you already have this value
endingNumber.setValue(startingNumber.getValue() + 1);
printChecks(startingNumber.getValue(), endingNumber.getValue());
});
});
}
public static void main(String[] args) {
launch(args);
}
public <R extends ButtonType> Dialog getCheckPrintDialog(Window owner, String title) {
Dialog<R> dialog = new Dialog<>();
dialog.initOwner(owner);
dialog.setTitle(title);
dialog.getDialogPane().getButtonTypes().addAll(printButtonType, ButtonType.CANCEL);
Button btOk = (Button) dialog.getDialogPane().lookupButton(printButtonType);
btOk.addEventFilter(ActionEvent.ACTION, event -> {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "Print Checks? Are you sure?", ButtonType.YES, ButtonType.NO);
alert.showAndWait()
.filter(result -> result == ButtonType.NO)
.ifPresent(result -> event.consume());
});
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
Text from = new Text("Starting Number:");
grid.add(from, 0, 0);
grid.add(startingNumber, 1, 0);
dialog.getDialogPane().setContent(grid);
return dialog;
}
private void printChecks(int from, int to) {
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
Thread.sleep(5000);
return null;
}
};
task.setOnSucceeded((event) -> {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "Has the last check, the number: " + endingNumber.getValue() + "?", ButtonType.YES, ButtonType.NO);
alert.initOwner(stage);
Button btnNo = (Button) alert.getDialogPane().lookupButton(ButtonType.NO);
btnNo.addEventFilter(ActionEvent.ACTION, e -> {
Dialog<ButtonType> newEndNum = new Dialog<>();
newEndNum.setTitle("Enter the ending check number");
newEndNum.initOwner(stage);
newEndNum.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
Text toUser = new Text("Ending Number:");
grid.add(toUser, 0, 0);
grid.add(endingNumber, 1, 0);
newEndNum.getDialogPane().setContent(grid);
newEndNum.showAndWait().filter(result -> result == ButtonType.CANCEL)
.ifPresent(result -> e.consume());
});
alert.showAndWait();
});
veil.visibleProperty().bind(task.runningProperty());
indicator.visibleProperty().bind(task.runningProperty());
new Thread(task).start();
}
}
public Dialog<Pair<String, String>> getDialog(Window owner, String title, boolean addButton) {
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle(title);
dialog.initOwner(owner);
dialog.getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
if (addButton) {
Button button = new Button("Show Dialog");
dialog.getDialogPane().setContent(button);
button.setOnAction(event -> {
Alert alert = new Alert(AlertType.CONFIRMATION, "Are you sure?", ButtonType.YES, ButtonType.NO);
alert.initOwner(owner);
if (alert.showAndWait().get() == ButtonType.YES) {
// dialog.close(); // supressed this and placed at the bottom
Dialog<Pair<String, String>> dialog2 = getDialog(owner, "Dialog 2", false);
TextField textField = new TextField();
dialog2.getDialogPane().setContent(textField);
dialog2.getDialogPane().getScene().getWindow().setOnCloseRequest(closeEvent -> {
closeEvent.consume();
if (textField.getText().trim().isEmpty()) {
Alert alert2 = new Alert(AlertType.ERROR, "Please enter a value", ButtonType.OK);
alert2.initOwner(dialog2.getDialogPane().getScene().getWindow());
alert2.showAndWait();
}
});
dialog2.showAndWait();
dialog.close(); // new location
}
});
}
return dialog;
}