how to evenly distribute elements of a JavaFX VBox
Asked Answered
Q

2

11

Im working with a VBox and added three labels to it. The vertical space between the labels is set with setSpacing() method. But it is a fixed value, say 20. if i change the value to 50, the space will be increased. But it is hard coding.

I want to know whether there is any pre-defined method that i can use so that the labels will be distributed evenly (based on the VBox height). if i resize the window, the labels (i mean, the space between the labels) should be adjusted so that they still are distributed evenly (with same space between any two labels).

As the VBox is set at left side of a BorderPane, i want "lab0" at "Display Line 1", "lab1" at "Display Line 5" and "lab2" at "Display Line 9" (in terms of alignment). In case more TextFields are added, "lab2" should be at last "Display Line X".

my code is here...please mark.

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class MyJavaFx extends Application
{
    public MyJavaFx()
    {
    }

    public void start(Stage primaryStage)
    {
        BorderPane pane = new BorderPane();
        pane.setTop(getRadioButtons());
        pane.setBottom(getPushButtons());
        pane.setLeft(getLeftLabels());
        pane.setRight(getRightLabels());
        pane.setCenter(getTextFields());
        Scene scene=new Scene(pane,1000,800);

        primaryStage.setTitle("Even");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String arg[])
    {
        Application.launch(arg);
    }

    FlowPane getRadioButtons()
    {
        FlowPane pane = new FlowPane();
        pane.setPadding(new Insets(10,10,10,10));
        pane.setHgap(10);
        RadioButton rb[]=new RadioButton[3];
        ToggleGroup radioGroup = new ToggleGroup();
        for(int i=0;i<rb.length;i++)
        {
            rb[i] = new RadioButton("Flag "+(i+1));
            rb[i].setToggleGroup(radioGroup);
            pane.getChildren().add(rb[i]);
        }
        rb[0].setSelected(true);
        pane.setAlignment(Pos.CENTER);
        return pane;
    }

    FlowPane getPushButtons()
    {
        FlowPane pane = new FlowPane();
        pane.setPadding(new Insets(10,30,30,10));
        pane.setHgap(10);
        Button rb[]=new Button[3];
        for(int i=0;i<rb.length;i++)
        {
            rb[i] = new Button("but"+i);
            pane.getChildren().add(rb[i]);
        }
        pane.setAlignment(Pos.BOTTOM_RIGHT);
        return pane;
    }
    VBox getLeftLabels()
    {
        VBox pane = new VBox();
        pane.setPadding(new Insets(10,10,10,10));
        pane.setSpacing(20);
        Label ll[]=new Label[3];
        for(int i=0;i<ll.length;i++)
        {
            ll[i] = new Label("lab"+i);
            pane.getChildren().add(ll[i]);
        }
        ll[0].setAlignment(Pos.TOP_LEFT);
        ll[1].setAlignment(Pos.CENTER_LEFT);
        ll[2].setAlignment(Pos.BOTTOM_LEFT);
        pane.setAlignment(Pos.CENTER_LEFT);
        return pane;
    }

    VBox getRightLabels()
    {
        VBox pane = new VBox();
        pane.setPadding(new Insets(10,10,10,10));
        pane.setSpacing(20);
        Label rb[]=new Label[3];
        for(int i=0;i<rb.length;i++)
        {
            rb[i] = new Label("lab"+i);
            pane.getChildren().add(rb[i]);
        }
        pane.setAlignment(Pos.CENTER_RIGHT);
        return pane;
    }

    VBox getTextFields()
    {
        VBox pane = new VBox();
        pane.setPadding(new Insets(10,10,10,10));
        pane.setSpacing(2);
        TextField tf[]=new TextField[9];
        for(int i=0;i<tf.length;i++)
        {
            tf[i] = new TextField("Display Line "+(i+1));

            pane.getChildren().add(tf[i]);
        }
        pane.setAlignment(Pos.CENTER_RIGHT);
        return pane;
    }
}
Quicken answered 30/11, 2016 at 8:49 Comment(0)
S
13

What you could do is to add "spacers" before and after each label that will always grow or shrink according to the available space thanks to VBox.setVgrow(Node child, Priority value) with Priority.ALWAYS as priority value.

Here is the method that create a "spacer"

private Node createSpacer() {
    final Region spacer = new Region();
    // Make it always grow or shrink according to the available space
    VBox.setVgrow(spacer, Priority.ALWAYS);
    return spacer;
}

Then your code will be:

VBox getTextFields()
{
    VBox pane = new VBox();
    pane.setPadding(new Insets(10,10,10,10));
    TextField tf[]=new TextField[9];
    // Add first spacer
    pane.getChildren().add(createSpacer());
    for(int i=0;i<tf.length;i++)
    {
        tf[i] = new TextField("Display Line "+(i+1));
        pane.getChildren().add(tf[i]);
        // Add a spacer after the label
        pane.getChildren().add(createSpacer());
    }
    pane.setAlignment(Pos.CENTER_RIGHT);
    return pane;
}

About the second part of your question related to the fact that you want to align the labels labX with Display Line X, the simplest way would be to put all the labels that should be in the same row in a common HBox seperated with "spacers" as described above

Spermophile answered 30/11, 2016 at 9:2 Comment(0)
D
0

I was personally looking for a VBOX and I figured a solution.

For a VBOX; Set your elements to a rigid width that means Pref, Max and Min Width are equal. Then, in between them, place panes. Only set the pref width of the panes to max possible reasonable width while the rest, max and min leave USE_COMPUTED_SIZE. The panes will grow and shrink depending on the available space, keeping the elements evenly spaced dynamically.

Diffractometer answered 19/3, 2022 at 20:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.