Reputation: 462
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. In short P should come exactly below C in second row of gridpane.
Upvotes: 1
Views: 1069
Reputation: 82451
Note that the widest node in every column is responsible to determine the start x coordinate. 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:
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();
}
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.
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>
Upvotes: 2