如何垂直居中Alert / DialogPane的内容?

时间:2018-08-16 19:04:36

标签: javafx

我创建了一个Alert的{​​{1}},并且我希望内容在警报中居中。但是,底部似乎有些填充物是我无法摆脱的。

这是MCVE:

undecorated

结果是这个窗口:

Screenshot

如何创建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,底部没有空隙?

1 个答案:

答案 0 :(得分:2)

使用:

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;
}

结果如下:

image of alert


我从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中,您使用的是 new DialogPane,而我使用的是DialogPane最初随附的Alert。请注意,仅当applyCss()Node的一部分时,Scene方法才有效。显然,DialogPane一旦成为Scene的一部分,便成为Alert的一部分。因此,可以避免NullPointerException的一种方法是像我一样使用DialogPane随附的Alert

如果您仍然想使用自己的DialogPane,则只需在致电alert.setDialogPane之前先致电applyCss()。请注意,当我尝试这样做时,呼叫lookup(".graphic-container")仍然返回null。我猜Node仅存在于原始DialogPane上。删除该lookup调用可以解决该问题,而其他lookup调用(针对.button-bar > .container)仍然可以正常工作。

所有这些似乎都是不应依赖的实现行为,但它对Java 8和Java 10都适用。我在更改Java版本时会观看此代码,以防万一。