代码之家  ›  专栏  ›  技术社区  ›  Zephyr

如何将警报/对话框窗格的内容垂直居中?

  •  2
  • Zephyr  · 技术社区  · 6 年前

    我创造了一个 Alert 那就是 undecorated

    这是一个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();
    
        }
    }
    

    Screenshot

    如何创建 警觉的 DialogPane

    1 回复  |  直到 6 年前
        1
  •  2
  •   Slaw    6 年前

    使用:

    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里你用的是 DialogPane 而我用的是 一开始是 Alert applyCss() Node Scene . 显然是 场景 警觉的 . 所以有一种方法可以避免 NullPointerException s是使用 对话框窗格 警觉的 就像我一样。

    你只要打个电话 alert.setDialogPane 打电话之前 应用程序() lookup(".graphic-container") 还是回来了 null . 我想是的 只有原件上有 对话框窗格 lookup 电话修好了另一个 查找 .button-bar > .container )仍然按预期工作。

    所有这些看起来都像是不应该依赖的实现行为,但对我来说,它同时适用于Java 8和Java 10。我会在更改Java版本时看到这段代码,以防万一。