我希望完成一个JavaFX对话框。我将控制器类添加到准备好的FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.image.Image?>
<Dialog fx:id="dialog"
fx:controller="myapp.AddDialogController"
xmlns:fx="http://javafx.com/fxml">
<dialogPane>
<DialogPane prefWidth="400.0" prefHeight="300.0">
<stylesheets>
<URL value="@/css/styles.css" />
</stylesheets>
<content>
<VBox>
<Label text="Add some content here..."></Label>
</VBox>
</content>
</DialogPane>
</dialogPane>
</Dialog>
现在,当我尝试使用桌面环境提供的X按钮关闭对话框时,没有任何反应。我做错了什么?
答案 0 :(得分:4)
解决方案 - 在对话框中添加按钮
见答案:
我还建议在JavaFX Alert中至少设置一个CANCEL_CLOSE按钮或OK_DONE按钮,否则用户可能很难实际关闭警报,因为对话框可能无法响应用户期望的按键操作。
尝试使用窗口框架中的操作系统X按钮来关闭舞台时也是如此。
背景资讯
要进一步了解该行为,请阅读Dialog javadoc中的对话框结束规则:
了解Dialog关闭时会发生什么很重要 以及如何关闭对话框,特别是在异常关闭时 情况(例如在对话框标题中单击&#39; X&#39;按钮时 栏,或操作系统特定的键盘快捷键(如 输入了Windows上的alt-F4)。幸运的是,结果是 在这些情况下定义明确,可以最好地总结在 以下要点:
- JavaFX对话框只能关闭&#39;异常&#39; (如上所述)有两种情况:
- 当对话框只有一个按钮或
时- 当对话框有多个按钮时,只要其中一个按钮满足以下要求之一:
- 该按钮的
ButtonType
ButtonBar.ButtonData
类型为ButtonBar.ButtonData.CANCEL_CLOSE
。- 该按钮有
ButtonType
,ButtonBar.ButtonData
在调用ButtonBar.ButtonData.isCancelButton()
时返回true。- 在所有其他情况下,对话框将拒绝回复所有关闭请求,保持打开状态,直到用户点击其中一个 对话框的DialogPane区域中的可用按钮。
- 如果对话框异常关闭,并且对话框中包含符合上述两个条件之一的按钮,则对话框将 尝试将result属性设置为从中返回的值 使用第一个匹配的ButtonType调用结果转换器。
- 如果由于任何原因结果转换器返回null,或者如果仅存在一个非取消按钮时关闭对话框,则 result属性为null,
showAndWait()
方法将返回Optional.empty()
。后面的这一点意味着,如果您使用其中任何一个 选项2或选项3(如本课程前面所述 文档),Optional.ifPresent(java.util.function.Consumer)
lambda永远不会被调用,代码将继续执行,就好像 该对话框根本没有返回任何值。
因此,如果对话框中没有按钮,则无法关闭...
回答后续问题
我可以从FXML设置按钮类型吗?
也许,我不知道,我从未尝试过。无论如何我不会建议,而是建议只从代码中设置按钮类型。老实说,我可能只会在FXML中定义对话框的内容窗格(例如,只是FXML的VBox部分及其子元素),并将其余的封闭Dialog定义留在Java代码中。我很惊讶在FXML中定义一个Dialog甚至可以工作,但它确实:-)但是,你不能用Dialog作为SceneBuilder中的根XML元素打开FXML(并且能够使用SceneBuilder定义你的UI是IMO首先使用FXML的最佳原因之一)。
示例解决方案
以下是对话框对话框定义的示例,可以通过对话框中的按钮或按键组合或单击操作系统提供的对话框中的关闭图标来关闭该对话框:
AddDialogController.java
package myapp.ui;
public class AddDialogController {}
DialogDisplayApp.java
package myapp.ui;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
public class DialogDisplayApp extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"add-dialog.fxml"
)
);
stage.setScene(new Scene(new VBox(new Label("Main Window")), 600, 400));
stage.show();
Dialog dialog = loader.load();
dialog.getDialogPane().getButtonTypes().addAll(
ButtonType.CLOSE
);
dialog.initOwner(stage);
dialog.showAndWait();
}
public static void main(String[] args) {
launch(args);
}
}
的myapp / UI /附加dialog.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Dialog?>
<?import javafx.scene.control.DialogPane?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<Dialog fx:id="dialog"
fx:controller="myapp.ui.AddDialogController"
xmlns:fx="http://javafx.com/fxml">
<dialogPane>
<DialogPane prefWidth="400.0" prefHeight="300.0">
<content>
<VBox>
<Label text="Add some content here..."></Label>
</VBox>
</content>
</DialogPane>
</dialogPane>
</Dialog>