JavaFX 警报及其大小

JavaFX Alerts and their size

最近,JavaFX 推出了警报 (Java 8u40)。

考虑下面的代码示例。我怎样才能显示比几个词更长的完整消息?我的消息 (contentText 属性) 在结尾处被 ... 截断,我认为警报没有正确调整其大小。

在装有 Oracle JDK 8u40 的 Linux 机器上,我只看到文本 This is a long text. Lorem ipsum dolor sit amet,在某些情况下它太短了。

当然,用户可以手动调整 Alert window 的大小,相应地显示文本,但这对用户来说一点都不友好。

编辑:Windows 7 和 Linux(JDK 来自 Oracle)的屏幕截图:

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


public class TestAlert extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Alert a = new Alert(AlertType.INFORMATION);
        a.setTitle("My Title");
        a.setHeaderText("My Header Text");
        a.setResizable(true);
        String version = System.getProperty("java.version");
        String content = String.format("Java: %s.\nThis is a long text. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.", version);
        a.setContentText(content);
        a.showAndWait();
    }
}

前段时间我做了以下解决方法:

Alert dialog = new Alert(Alert.AlertType.ERROR);
dialog.setHeaderText("Connection Failed");
dialog.setContentText(this.getException().getMessage());

//FIXME: Remove after release 8u40
dialog.setResizable(true);
dialog.getDialogPane().setPrefSize(480, 320);

dialog.showAndWait();

如您所见,我只是设置了可调整大小标志并设置了首选大小。

但这很奇怪,因为 8u40 中的这个错误 should be fixed。您使用的是最新版本的 8u40 吗?

更新:

在 8u40 中未修复。 Should be fixed稍后。

这是没有幻数、调整大小等的更好解决方法:

Alert alert = new Alert(AlertType.ERROR, "content text");
alert.getDialogPane().getChildren().stream().filter(node -> node instanceof Label).forEach(node -> ((Label)node).setMinHeight(Region.USE_PREF_SIZE));

此解决方案适用于 Windows、Linux 和 Mac。

我做了以下解决方法:

Alert alert = new Alert(AlertType.INFORMATION, "Content here", ButtonType.OK);
alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
alert.show();

所以window会根据内容自动调整大小

另一个解决方案是子类化 Alert 并在那里应用所需的样式,例如:

class SubAlert extends Alert {
    {
        setHeaderText("");
        getDialogPane().getStylesheets().add("some_stylesheet");
        getDialogPane().getStyleClass().add("style_class");
        getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
    }

    SubAlert(AlertType alertType) {
        super(alertType);
    }

    SubAlert(AlertType type, String title, String content) {
        super(type);
        setTitle(title);
        setContentText(content);
    }
}

这样您就不必为创建的每个警报重复操作。

版本 15 仍然唯一的解决方法是:

dialog.setResizable(true);
dialog.getDialogPane().setPrefSize(377, 233);
Platform.runLater(() -> dialog.setResizable(false));