我创建了一个名为undecorated的Alert,我希望内容在警报中居中。然而,底部似乎有一些我无法摆脱的填充物。
下面是一个MCVE:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Alert;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
Alert alert = new Alert(Alert.AlertType.NONE);
DialogPane pane = new DialogPane();
HBox contentPane = new HBox(10);
contentPane.setPadding(new Insets(10));
contentPane.setAlignment(Pos.CENTER);
// Add progress indicator and label to contentPane
contentPane.getChildren().addAll(
new ProgressIndicator(ProgressIndicator.INDETERMINATE_PROGRESS) {{
setPrefSize(30, 30);
}},
new Label("Loading ...")
);
// Add border to demonstate the lower padding
contentPane.setStyle("-fx-border-color: black");
pane.setPadding(new Insets(10));
pane.setStyle("-fx-border-color: black");
pane.setContent(contentPane);
alert.setDialogPane(pane);
alert.initStyle(StageStyle.UNDECORATED);
alert.showAndWait();
}
}结果是这个窗口:

如何在没有底部间隙情况下创建Alert或DialogPane?
发布于 2018-08-17 03:49:10
使用:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Alert;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
private static Border createBorder(Paint stroke) {
return new Border(new BorderStroke(stroke, BorderStrokeStyle.SOLID,
null, new BorderWidths(2)));
}
@Override
public void start(Stage primaryStage) throws Exception {
ProgressIndicator indicator = new ProgressIndicator();
indicator.setPrefSize(30, 30);
Label label = new Label("Loading...");
label.setMinWidth(Label.USE_PREF_SIZE);
HBox content = new HBox(10, indicator, label);
content.setBorder(createBorder(Color.BLUE));
content.setPadding(new Insets(10));
content.setAlignment(Pos.CENTER);
Alert alert = new Alert(Alert.AlertType.NONE);
alert.initStyle(StageStyle.UNDECORATED);
alert.getDialogPane().getStylesheets()
.add(getClass().getResource("Main.css").toExternalForm());
alert.getDialogPane().setPadding(new Insets(10));
alert.getDialogPane().setContent(content);
alert.getDialogPane().setBorder(createBorder(Color.RED));
alert.show();
}
}这是Main.css的位置
.dialog-pane .button-bar .container {
-fx-padding: 0px;
}
.dialog-pane:no-header .graphic-container {
-fx-padding: 0px;
}结果如下:

我从here (JavaFX CSS Reference)得到的一些必要的样式类。然而,我主要是通过查看modena.css (那里有用于dialog-pane的样式)了解到这一点的。
如果不想使用外部CSS,可以将alert.getDialogPane().getStylesheets().add(...)替换为:
alert.getDialogPane().applyCss(); // Seems to stop the lookup calls
// from returning null
alert.getDialogPane()
.lookup(".button-bar")
.lookup(".container")
.setStyle("-fx-padding: 0px;");
alert.getDialogPane().lookup(".graphic-container").setStyle("-fx-padding: 0px;");
alert.show();在您的评论后更新。
我最初使用Java10.0.2进行了尝试,但我只是尝试使用Java8u181,它仍然适用于我。我注意到您的MCVE使用的是新的DialogPane,而我使用的是最初随Alert提供的DialogPane。请注意,只有当Node是Scene的一部分时,applyCss()方法才有效。显然,只要DialogPane是Scene的一部分,它就会成为Alert的一部分。因此,可以避免NullPointerExceptions的一种方法是使用Alert附带的DialogPane,就像我所做的那样。
如果你仍然想使用你自己的DialogPane,你只需要在调用applyCss()之前调用alert.setDialogPane。请注意,当我尝试这样做时,调用lookup(".graphic-container")仍然返回null。我猜Node只出现在原始的DialogPane上。移除那个lookup调用修复了它,另一个lookup调用(用于.button-bar > .container)仍然像预期的那样工作。
所有这些看起来都像是不应该依赖的实现行为,但它在我的Java8和Java10上都适用。
https://stackoverflow.com/questions/51883825
复制相似问题