【问题标题】:JavaFX - creating custom dialogs using fxmlJavaFX - 使用 fxml 创建自定义对话框
【发布时间】:2017-07-15 14:24:20
【问题描述】:

我是 javafx 的新手,我正在尝试创建自定义对话框/警报。问题是我正在使用 Scene Builder 来设计 GUI,并且我想在每次加载 fxml 文件时修改对话框(即更改标题、标签文本等),所以我想知道是否有一个发送参数和修改舞台/场景的方式,或者我可以实现的任何其他方式。

更具体地说,假设我想在程序中的任何位置处理一个错误,因此我加载了一个新的 fxml 文件,该文件代表我创建的错误对话框,并根据类型修改其中的组件我需要处理的错误,例如 JOptionPane.showMessageDialog(...) in swing。

【问题讨论】:

  • 为什么不直接使用AlertDialog
  • James_D,因为我需要所有不同的设计,而且每个信息都应该是另一种语言(不是英语)
  • 很确定他们可以做到这一点,但无论如何我都会添加一个答案来解决更普遍的问题。

标签: javafx dialog


【解决方案1】:

对于您描述的用例,您可以只使用Dialog API,或作为其中一部分的专用Alert 类。

对于您提出的更一般的问题:

我想知道是否有办法发送参数和更改舞台/场景

这样做的方法是使用文档中描述的custom component 机制。

简而言之,创建一个加载 FXML 文件并定义所需属性的 UI 类型的子类,例如

public class ExceptionPane extends BorderPane {

    private final ObjectProperty<Exception> exception ;

    public ObjectProperty<Exception> exceptionProperty() {
        return exception ;
    }

    public final Exception getException() {
        return exceptionProperty().get();
    }

    public final void setException(Exception exception) {
        exceptionProperty().set(exception);
    }

    @FXML
    private final TextArea stackTrace ;
    @FXML
    private final Label message ;

    public ExceptionPane() throws Exception {

        FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
        loader.setRoot(this);
        loader.setController(this);

        loader.load();

        exception.addListener((obs, oldException, newException) -> {
            if (newException == null) {
                message.setText(null);
                stackTrace.setText(null);
            } else {
                message.setText(newException.getMessage());
                StringWriter sw = new StringWriter();
                newException.printStackTrace(new PrintWriter(sw));
                stackTrace.setText(sw.toString());
            }
        });
    }
}

然后使用 "dynamic root" 定义 FXML:

<!-- imports etc -->

<fx:root type="BorderPane" ...>

    <center>
        <TextArea fx:id="stackTrace" editable="false" wrapText="false" />
    </center>
    <top>
        <Label fx:id="message" />
    </top>
</fx:root>

现在您可以直接在 Java 或 FXML 中使用它:

try {
    // some code...
} catch (Exception exc) {
    ExceptionPane excPane = new ExceptionPane();
    excPane.setException(exc);
    Stage stage = new Stage();
    stage.setScene(new Scene(excPane));
    stage.show();
}

<fx:define fx:id="exc"><!-- define exception somehow --></fx:define>

<ExceptionPane exception="${exc}" />

【讨论】:

  • 非常有帮助。谢谢你:)。
  • 这是旧版本的 fxml 吗?如果我将其放入文件中,我的场景构建器将无法打开 fxml。它抱怨 fx: 前缀
  • @MaxiWu 这是有效的 FXML。我知道 Scene Builder 的早期版本在使用 &lt;fx:define&gt; 时遇到了问题;我已经有一段时间没有在 Scene Builder 上尝试过了。你有什么版本?
  • 我正在使用来自 GLUON 的最新版本。也许我错过了一些重要的
  • 我对此进行了修改,并且场景构建工作正常。 gist.github.com/maxiwu/6e380706130ad79dc4bb346bc65b036c
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 2023-02-03
相关资源
最近更新 更多