简体   繁体   English

javafx gridpane中心对齐并对齐所有标签

[英]javafx gridpane center align and justify all labels

The idea is to create a submission form that has many labels centered and justified for example: 这个想法是创建一个提交表单,该表单具有许多居中且合理的标签,例如:

Label 1 is Customer Name and Label 2 is Product Name What I am trying to do is horizontally center align all the labels that's very easy but At the same time I want them justified. 标签1是客户名称 ,标签2是产品名称我想做的是将所有标签水平居中对齐,这很容易,但同时我希望它们对齐。 In short P should come exactly below C in second row of gridpane. 简而言之, P应该恰好在第二行网格中的C之下。

Note that the widest node in every column is responsible to determine the start x coordinate. 请注意,每列中最宽的节点负责确定起始x坐标。 If the nodes are centered, you need to move all nodes by half the difference of the node's width to the max width to the left, which can be achieved using the translateX property: 如果节点居中,则需要将所有节点的宽度向左移动最大宽度的一半,这可以使用translateX属性实现:

Example

@Override
public void start(Stage primaryStage) {
    GridPane gp = new GridPane();
    ColumnConstraints constraints = new ColumnConstraints();
    constraints.setHalignment(HPos.CENTER);
    constraints.setPercentWidth(50);

    gp.getColumnConstraints().addAll(constraints, constraints);
    Random random = new Random();

    Node[][] elements = new Node[2][10];

    for (int x = 0; x < elements.length; x++) {
        final Node[] column = elements[x];
        InvalidationListener sizeListener = o -> {
            // determine max width
            double maxSize = 0;

            for (Node n : column) {
                double width = n.getLayoutBounds().getWidth();
                if (width > maxSize) {
                    maxSize = width;
                }
            }

            // adjust translate
            for (Node n : column) {
                n.setTranslateX((n.getLayoutBounds().getWidth() - maxSize) / 2);
            }
        };

        // fill column with strings of random lenght
        for (int y = 0; y < 10; y++) {
            int charCount = random.nextInt(30);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < charCount; i++) {
                sb.append('a');
            }
            Label text = new Label(sb.toString());
            text.layoutBoundsProperty().addListener(sizeListener);
            column[y] = text;
        }
        gp.addColumn(x, column);
        sizeListener.invalidated(null);
    }

    Scene scene = new Scene(gp);

    primaryStage.setScene(scene);
    primaryStage.show();
}

Edit 编辑

Even though you cannot do this with SceneBuilder, you can apply this kind of alignment to a GridPane from fxml, if you implement the logic to add this functionality in a utility class and use that utility class from the fxml. 即使你不能做到这一点与SceneBuilder,你可以应用这种对齐到GridPane从FXML,如果实现在一个工具类添加此功能,并使用该实用工具类从FXML逻辑。

public final class WeirdAlign {

    private WeirdAlign() {
    }

    public static final Predicate<Node> ALL_PREDICATE = n -> true;

    public static void setCombinedCenterJustify(GridPane gridPane, Predicate<Node> predicate) {
        InvalidationListener listener = o -> {
            Node n = (Node) ((ReadOnlyProperty) o).getBean();
            updateGridPaneColumn(gridPane, getGridPaneColumn(n), predicate);
        };
        ObservableList<Node> children = gridPane.getChildren();

        for (Node n : children) {
            if (predicate.test(n)) {
                n.layoutBoundsProperty().addListener(listener);
            }
        }

        int[] columns = children.stream().filter(predicate).mapToInt(WeirdAlign::getGridPaneColumn).distinct().toArray();
        for (int i : columns) {
            updateGridPaneColumn(gridPane, i, predicate);
        }

        children.addListener((ListChangeListener.Change<? extends Node> c) -> {
            Set<Integer> columnsToUpdate = new HashSet<>();
            while (c.next()) {
                if (c.wasRemoved()) {
                    for (Node n : c.getRemoved()) {
                        if (predicate.test(n)) {
                            n.layoutBoundsProperty().removeListener(listener);
                            columnsToUpdate.add(getGridPaneColumn(n));
                        }
                    }
                }
                if (c.wasAdded()) {
                    for (Node n : c.getAddedSubList()) {
                        if (predicate.test(n)) {
                            n.layoutBoundsProperty().addListener(listener);
                            columnsToUpdate.add(getGridPaneColumn(n));
                        }
                    }
                }
            }
            for (Integer i : columnsToUpdate) {
                updateGridPaneColumn(gridPane, i, predicate);
            }
        });
    }

    /**
     * This method is only here for FXMLLoader.
     */
    public static Predicate<Node> getCombinedCenterJustify(GridPane node) {
        throw new UnsupportedOperationException();
    }

    public static void updateGridPaneColumn(GridPane gridPane, int column, Predicate<Node> predicate) {
        double maxSize = 0;
        for (Node child : gridPane.getChildren()) {
            if (column == getGridPaneColumn(child) && predicate.test(child)) {
                double width = child.getLayoutBounds().getWidth();
                if (width > maxSize) {
                    maxSize = width;
                }
            }
        }
        for (Node child : gridPane.getChildren()) {
            if (column == getGridPaneColumn(child) && predicate.test(child)) {
                child.setTranslateX((child.getLayoutBounds().getWidth() - maxSize) / 2);
            }
        }
    }

    public static int getGridPaneColumn(Node node) {
        Integer c = GridPane.getColumnIndex(node);
        return c == null ? 0 : c;
    }

}
<GridPane xmlns:fx="http://javafx.com/fxml/1" id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" >
    <columnConstraints>
        <ColumnConstraints fx:id="c1" fillWidth="false" halignment="CENTER" percentWidth="50.0" />
        <fx:reference source="c1"/>
    </columnConstraints>
   <children>
      <Label text="abfkaenlgen" />
      <Label text="z7492z4z58z4zu uzu53 9zu59h 5n 54uhn" GridPane.columnIndex="1" GridPane.rowIndex="2" />
      <Label text="bbdnfkbner" GridPane.columnIndex="1" GridPane.rowIndex="1" />
      <Label text="hhhhhddddssaaeeeaaae" GridPane.rowIndex="1" />
      <Label text="gjnwkeibrgbawhgbreökbrgesöbrgsnrgs" GridPane.rowIndex="2" />
   </children>
   <WeirdAlign.combinedCenterJustify>
       <WeirdAlign fx:constant="ALL_PREDICATE"/>
   </WeirdAlign.combinedCenterJustify>
</GridPane>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM