【问题标题】:JavaFX Abnormally Closing Alert Returns Incorrect ResultJavaFX 异常关闭警报返回不正确的结果
【发布时间】:2017-01-12 01:05:11
【问题描述】:

我创建了一个 JavaFX Alert 对象,该对象在调用 showAndWait 时会返回意外结果。下面的代码说明了我观察到的行为:

package myPackage;

import java.util.Optional;

import javafx.application.Application;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.stage.Stage;

public class Main extends Application {

    public static void main(final String[] args) {
        launch();
    }

    private static boolean isYes(final Optional<ButtonType> result) {
        return (result.isPresent() && result.get().getButtonData() == ButtonData.YES);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        final Alert alert = new Alert(AlertType.CONFIRMATION,
            "This is a test", ButtonType.NO, ButtonType.YES);
        System.out.println(isYes(alert.showAndWait()) ? "Yes" : "No or Closed");
        System.out.println(isYes(alert.showAndWait()) ? "Yes" : "No or Closed");
    }

}

当我运行上述应用程序时,会显示两个对话框。在第一个对话框上单击“是”,然后关闭(通过单击右上角的“x”)第二个。通过上述步骤,我希望应用程序会打印以下内容:

是的
否或关闭

但是,我实际看到的是:

是的
是的

Dialog documentation 声明“异常关闭条件”(例如单击右上角的小“x”)将“尝试将结果属性设置为通过调用结果转换器返回的任何值第一个匹配的 ButtonType。”鉴于此声明的上下文,我将“匹配 ButtonType”解释为 ButtonType (直接引用文档):

  1. 按钮具有 ButtonType,其 ButtonBar.ButtonData 的类型为 ButtonBar.ButtonData.CANCEL_CLOSE。
  2. 该按钮有一个 ButtonType,其 ButtonBar.ButtonData 在调用 ButtonBar.ButtonData.isCancelButton() 时返回 true。

我对文档的解释不正确,还是 JavaFX 中的错误?不管为什么这不能像我预期的那样工作,在这种情况下有什么办法可以强制“异常关闭条件”返回ButtonType.NO

【问题讨论】:

  • 我注意到,如果我在两次调用 alert.showAndWait() 之间调用 alert.setResult(null),它会按照记录的方式工作(第二次调用的结果是 ButtonType.NO)。是否存在isPresentAlert 为假的情况?
  • 如果您在将NO 按钮映射到null 的警报上设置结果转换器,isPresent 将返回 false (AIUI)。至于你的主要问题,这看起来像一个错误。
  • 似乎不是一个错误。 showAndWait 从未声称要清除 result 属性(事实上,这甚至可能是允许用户在未指定有效输入的情况下指定默认结果的理想行为......)。
  • @fabian 我同意showAndWait 的文档没有声明,但是如果您阅读了Dialog 的文档,它确实如此。在此对话框中,ButtonData.NO.isCancelButton() 为真,符合第二个条件。因此,根据我对文档的阅读,“异常关闭”对话框应始终使用ButtonType.NO 填充结果。我已经确认,在选择“是”按钮之前取消实际上会返回 ButtonType.NO 作为结果。

标签: java javafx dialog modal-dialog javafx-8


【解决方案1】:

这是 JavaFX 中的另一个错误。我已将它报告给 Oracle,它被分配了 Bug ID JDK-8173114。作为一种解决方法,我只是在我的 JavaFX Alert 子类的构造函数中添加了以下行:

setOnShowing(event -> setResult(null));

上述解决方法似乎适用于AlertChoiceDialogTextInputDialog

【讨论】:

    【解决方案2】:

    上述解决方法不适用于 java 8 和 win 10。但这有效:

        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
       // alert.setOnShowing(event -> alert.setResult(null));
        alert.setTitle("Delete similar files?");
        ButtonType okButton = new ButtonType("Yes", ButtonBar.ButtonData.YES);
        ButtonType noButton = new ButtonType("No", ButtonBar.ButtonData.NO);
        ButtonType cancelButton = new ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE);
        alert.getButtonTypes().setAll(okButton, noButton, cancelButton);
        Optional<ButtonType> choose = alert.showAndWait();
        // String text = new String("");
        // if (choose.get() != null)
           // text = choose.get().getText();
        // if (text != null && (text.equals("YES") || text.equals("Yes")))
        if (choose.get() == okButton){
    

    【讨论】:

    • 我对这个答案感到困惑。每次显示对话框时创建一个新的 Alert 对象不会表现出问题中描述的行为。还不清楚注释掉的代码是否重要。要改进此答案,请说明在您的情况下如何接受的答案行为不端,并删除所有注释掉的行,如果它们不是使您的解决方案正常工作所必需的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 2016-02-06
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多