我创建了一个未修饰
的Alert
,并且我希望内容在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
?
最佳答案
使用:
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();
根据您的评论进行更新。
我最初使用 Java 10.0.2 尝试过此操作,但我只是尝试使用 Java 8u181,它仍然对我有用。我注意到在您的 MCVE 中您使用的是新 DialogPane
,而我使用的是最初随 Alert
附带的 DialogPane
>。请注意,仅当 Node
是 Scene
的一部分时,applyCss()
方法才有效。显然,一旦 DialogPane
成为 Alert
的一部分,它就会成为 Scene
的一部分。因此,避免 NullPointerException 的一种方法是使用 Alert
附带的 DialogPane
,就像我一样。
如果您仍想使用自己的 DialogPane
,则只需在调用 applyCss()
之前调用 alert.setDialogPane
即可。但请注意,当我尝试此操作时,调用 lookup(".graphic-container")
仍然返回 null
。我猜想 Node
只出现在原始 DialogPane
上。删除该 lookup
调用修复了该问题,而另一个 lookup
调用(对于 .button-bar > .container
)仍然按预期工作。
所有这些看起来都是不应该依赖的实现行为,但它在 Java 8 和 Java 10 上都适用于我。不过,我会在更改 Java 版本时查看此代码,以防万一。
关于javafx - 如何垂直居中Alert/DialogPane的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51883825/