【问题标题】:controlsfx Dialogs deprecated for what?不推荐使用controlsfx 对话框是为了什么?
【发布时间】:2014-10-13 13:28:10
【问题描述】:

ControlsFX 类 Dialogs 被标记为已弃用。

改用什么?

【问题讨论】:

    标签: java javafx javafx-8 controlsfx


    【解决方案1】:

    现在使用 java 8 update 60,即使使用旧的非弃用版本的 controlsfx 也不起作用。因此,解决方案是使用 java 8 update 40 中包含的 javafx 的本机对话 API(不需要 3rd 方库)。它们不像控件 fx 那样直接且功能丰富。但是为了更快的编码,你可以创建一个包装类,就像我做的这样:

    package br.atualy.devolucaodevenda.util;
    
    import javafx.scene.control.*;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextArea;
    import javafx.scene.input.KeyCode;
    import javafx.scene.input.KeyEvent;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.Priority;
    import javafx.stage.StageStyle;
    
    import java.awt.*;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Optional;
    
    public class FxDialogs {
    
        public static void showInformation(String title, String message) {
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.initStyle(StageStyle.UTILITY);
            alert.setTitle("Information");
            alert.setHeaderText(title);
            alert.setContentText(message);
    
            alert.showAndWait();
        }
    
        public static void showWarning(String title, String message) {
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.initStyle(StageStyle.UTILITY);
            alert.setTitle("Warning");
            alert.setHeaderText(title);
            alert.setContentText(message);
    
            alert.showAndWait();
        }
    
        public static void showError(String title, String message) {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.initStyle(StageStyle.UTILITY);
            alert.setTitle("Error");
            alert.setHeaderText(title);
            alert.setContentText(message);
    
            alert.showAndWait();
        }
    
        public static void showException(String title, String message, Exception exception) {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.initStyle(StageStyle.UTILITY);
            alert.setTitle("Exception");
            alert.setHeaderText(title);
            alert.setContentText(message);
    
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            exception.printStackTrace(pw);
            String exceptionText = sw.toString();
    
            Label label = new Label("Details:");
    
            TextArea textArea = new TextArea(exceptionText);
            textArea.setEditable(false);
            textArea.setWrapText(true);
    
            textArea.setMaxWidth(Double.MAX_VALUE);
            textArea.setMaxHeight(Double.MAX_VALUE);
            GridPane.setVgrow(textArea, Priority.ALWAYS);
            GridPane.setHgrow(textArea, Priority.ALWAYS);
    
            GridPane expContent = new GridPane();
            expContent.setMaxWidth(Double.MAX_VALUE);
            expContent.add(label, 0, 0);
            expContent.add(textArea, 0, 1);
    
            alert.getDialogPane().setExpandableContent(expContent);
    
            alert.showAndWait();
        }
    
        public static final String YES = "Yes";
        public static final String NO = "No";
        public static final String OK = "OK";
        public static final String CANCEL = "Cancel";
    
        public static String showConfirm(String title, String message, String... options) {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.initStyle(StageStyle.UTILITY);
            alert.setTitle("Choose an option");
            alert.setHeaderText(title);
            alert.setContentText(message);
    
            //To make enter key press the actual focused button, not the first one. Just like pressing "space".
            alert.getDialogPane().addEventFilter(KeyEvent.KEY_PRESSED, event -> {
                if (event.getCode().equals(KeyCode.ENTER)) {
                    event.consume();
                    try {
                        Robot r = new Robot();
                        r.keyPress(java.awt.event.KeyEvent.VK_SPACE);
                        r.keyRelease(java.awt.event.KeyEvent.VK_SPACE);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
    
            if (options == null || options.length == 0) {
                options = new String[]{OK, CANCEL};
            }
    
            List<ButtonType> buttons = new ArrayList<>();
            for (String option : options) {
                buttons.add(new ButtonType(option));
            }
    
            alert.getButtonTypes().setAll(buttons);
    
            Optional<ButtonType> result = alert.showAndWait();
            if (!result.isPresent()) {
                return CANCEL;
            } else {
                return result.get().getText();
            }
        }
    
        public static String showTextInput(String title, String message, String defaultValue) {
            TextInputDialog dialog = new TextInputDialog(defaultValue);
            dialog.initStyle(StageStyle.UTILITY);
            dialog.setTitle("Input");
            dialog.setHeaderText(title);
            dialog.setContentText(message);
    
            Optional<String> result = dialog.showAndWait();
            if (result.isPresent()) {
                return result.get();
            } else {
                return null;
            }
    
        }
    
    }
    

    使用对话框:

    FxDialogs.showInformation("Hi", "Good Morning y'all!");
    if (FxDialogs.showConfirm("Choose one baby!", "Can i ask you a question?", FxDialogs.YES, FxDialogs.NO).equals(FxDialogs.YES)) {
        FxDialogs.showWarning(null, "Pay attention to my next question!");
        String answer = FxDialogs.showTextInput("Are you a pink elephant disguised as a flying pig?", "Tell me!", "No");
        FxDialogs.showError(null, "You should not have said " + answer + "!");
        FxDialogs.showException("Now i'm angry", "I'm going home...", new RuntimeException("Exception caused by angry dinossaurs"));
    }
    

    【讨论】:

    • 您见过并尝试过吗? “对于 JavaFX 8u60 及更高版本的用户,请下载 ControlsFX 8.40.10-SNAPSHOT 版本。”
    • 较新的版本(至少不久前)已弃用 Dialogs 类,他们是否在此版本上修复了它?我在maven上找不到那个版本,最后一个是maven central上的8.40.9。我可以找到这个 jar,我需要在我的本地存储库中手动安装它吗?
    • 正如文件名所暗示的,它是一个快照版本,因此您不太可能在 maven Central 上找到它。所以你必须以某种方式手动安装它。我不知道这些变化是什么,但至少 8u60 似乎是必要的,否则他们不会在他们的网站上提及它。
    【解决方案2】:

    这篇博文解释了一切:

    http://fxexperience.com/2014/09/announcing-controlsfx-8-20-7/

    自 8.0.6 于 5 月 29 日发布以来,此版本一直在酝酿中——基本上是四个月。这对我们来说并不常见(我们通常有更快的版本),但 Eugene 和我都分心于一项重大任务——将 ControlsFX 对话框 API 和实现提升到 JavaFX 本身的下一个版本中(它将出现在 JavaFX 8u40 ,尽管 API 与您在 ControlsFX 8.0.6 中看到的有很大不同)。最终结果是我们迭代了一堆 API 设计工作(参见 RT-12643),但这些工作都没有使 ControlsFX 受益,但它占用了我们所有的时间。

    在 JavaFX 8u40 对话框 API 完成后(仅在 8 月中旬),我们制定了如何继续使用 ControlsFX 对话框的计划。从本质上讲,我们认为在 ControlsFX 中维护一个与 JavaFX 8u40 中的差异如此之大的对话框 API 是不明智的。因此,我们制定的计划是弃用旧的 ControlsFX API,将 JavaFX 对话框 API 分叉到一个名为 openjfx-dialogs 的新项目中,并使用新 API 重新创建 ControlsFX 包含的附加功能(但 JavaFX 本身缺乏) (这包括进度、字体选择器、命令链接、登录等对话框)。

    【讨论】:

    • 感谢您的链接。 controlsfx 真的是一个糟糕的决定。新的库是 GPL,不能在大多数应用程序中使用。因此,这两个 API 有不同的关注点,旧的 API 真的不应该被弃用......
    • 根据bitbucket.org/controlsfx/openjfx-dialogs,许可证是 GPL 加上 Classpath-Exception,这意味着它可以用于商业应用。 (免责声明:IANAL)
    • @ArtjomB。是的,但是您的评论是在编辑前 3 个月以上,以使其成为可行的答案。嗯嗯,整理好了,答案很好,最终目的是什么
    猜你喜欢
    • 2011-10-12
    • 2011-05-14
    • 2016-02-23
    • 2017-11-04
    • 2011-10-22
    • 2011-04-11
    • 2021-10-12
    • 2012-12-07
    • 2012-05-16
    相关资源
    最近更新 更多