JavaFX - 如何在显示舞台之前为所有按钮设置相同的宽度?

cek*_*ock 0 javafx javafx-2

我想为窗格的按钮设置相同的宽度,但在显示舞台之前没有按钮宽度.如何在不显示舞台的情况下获得宽度?

由于未定义宽度而无效的代码示例:

public static HBox createHorizontalButtonBox(final List<Button> buttons, final Pos alignment, final double spacing, final boolean sameWidth) {
    HBox box = new HBox(spacing);
    box.setAlignment(alignment);
    box.getChildren().addAll(buttons);

    if (sameWidth && buttons.size() > 1) {
        double max = maxWidth(buttons);
        for (Button b : buttons) {
            b.setPrefWidth(max);
        }
    }

    return box;
}
Run Code Online (Sandbox Code Playgroud)

jew*_*sea 7

让布局窗格为您进行布局.

如果您使用的布局窗格没有为您提供所需的确切布局,则:

  1. 调整布局窗格及其子节点上的约束.
  2. 撰写多种不同类型的布局窗格.
  3. 使用不同的内置布局窗格类型.
  4. 创建自己的布局窗格类型.

对于您的方法,您有一个参数指示是否调整所有子节点的大小相同.大小相同的所有子节点的窗格是TilePane,因此您可以选择布局元素.一个GridPane也将工作,因为它具有可配置的约束大小元素的大小相同.股票HBox将无法直接使用,因为它没有可以调整所有相同大小的子元素的属性.如果你愿意,你可以将HBox子类化(通过覆盖layoutChildren()).

浆纱

import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.stage.Stage;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class SameSizeButtons extends Application {
    @Override
    public void start(Stage stage) {
        VBox layout = new VBox(
            10,
            createHorizontalButtonBox(
                Arrays.stream("All buttons the same width".split(" "))
                        .map(Button::new)
                        .collect(Collectors.toList()),
                Pos.CENTER,
                10,
                true
            ),
            createHorizontalButtonBox(
                Arrays.stream("All buttons different widths".split(" "))
                        .map(Button::new)
                        .collect(Collectors.toList()),
                Pos.CENTER_RIGHT,
                10,
                false
            )
        );
        layout.setPadding(new Insets(10));
        layout.getChildren().forEach(node ->
            node.setStyle("-fx-border-color: red; -fx-border-width: 1px;")
        );

        stage.setScene(new Scene(layout));
        stage.show();
    }

    public static Pane createHorizontalButtonBox(
            final List<Button> buttons,
            final Pos alignment,
            final double spacing,
            final boolean sameWidth) {

        return sameWidth
                ? createSameWidthHorizontalButtonBox(
                      buttons, 
                      alignment, 
                      spacing
                  )
                : createDifferentWidthHorizontalButtonBox(
                      buttons, 
                      alignment, 
                      spacing
                  );
    }

    private static Pane createSameWidthHorizontalButtonBox(
            List<Button> buttons,
            Pos alignment,
            double spacing)
    {
        TilePane tiles = new TilePane(
                Orientation.HORIZONTAL,
                spacing,
                0,
                buttons.toArray(
                        new Button[buttons.size()]
                )
        );
        tiles.setMinWidth(TilePane.USE_PREF_SIZE);
        tiles.setPrefRows(1);
        tiles.setAlignment(alignment);

        buttons.forEach(b -> {
            b.setMinWidth(Button.USE_PREF_SIZE);
            b.setMaxWidth(Double.MAX_VALUE);
        });

        return tiles;
    }

    private static Pane createDifferentWidthHorizontalButtonBox(
            List<Button> buttons,
            Pos alignment,
            double spacing)
    {
        HBox hBox = new HBox(
                spacing,
                buttons.toArray(
                        new Button[buttons.size()]
                )
        );
        hBox.setAlignment(alignment);

        buttons.forEach(b ->
                        b.setMinWidth(Button.USE_PREF_SIZE)
        );

        return hBox;
    }

    public static void main(String[] args) {
        launch(args);
    }
}  
Run Code Online (Sandbox Code Playgroud)