Skip to content
Advertisement

Achieve Unique Column Width for each Cell in Different Rows with a GridPane?

I am trying to model credit card data in JavaFx using a GridPane:

My model contains 3 rows (Note: each field is comprised of label + text field):

Row 1: First name and last name (4 fields)

Row 2: Credit card number (2 fields)

Row 3: Expiration date – month, year + CVV (6 fields)

See screenshot below:

Card Data Model

I was reading this tutorial which states:

All cells in the same row will have the same height, and all cells in the same column will have the same width. Different rows can have different heights and different columns can have different widths.

Are there any workarounds to to have different size columns on a row by row basis in a GridPane?

Advertisement

Answer

For the specific layout in the image, I would use a VBox with HBox for rows:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.geometry.Insets;
import javafx.geometry.Pos;

public class App extends Application {

    @Override
    public void start(Stage stage) {

        Label lblFirst = new Label("First");
        Label lblLast = new Label("Last");
        Label lblNumber = new Label("Card Number");
        Label lblMonth = new Label("Month");
        Label lblYear = new Label("Year");
        Label lblCVV = new Label("CVV");
        
        TextField txtFirst = new TextField();
        TextField txtLast = new TextField();
        TextField txtNumber = new TextField();
        TextField txtMonth = new TextField();
        TextField txtYear = new TextField();
        TextField txtCVV = new TextField();

        HBox row1 = new HBox(10);
        HBox row2 = new HBox(10);
        HBox row3 = new HBox(10);
        
        row1.getChildren().add(createCell(lblFirst, txtFirst));
        row1.getChildren().add(createCell(lblLast, txtLast));
        
        row2.getChildren().add(createCell(lblNumber, txtNumber));
        
        row3.getChildren().add(createCell(lblMonth, txtMonth));
        row3.getChildren().add(createCell(lblYear, txtYear));
        row3.getChildren().add(createCell(lblCVV, txtCVV));
        
        VBox rows = new VBox(10, row1, row2, row3);
        
        StackPane.setMargin(rows, new Insets(10));
        
        StackPane root = new StackPane(rows);

        Scene scene = new Scene(root);

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

    private static HBox createCell(Label label, TextField text) {
        HBox pane = new HBox(5, label, text);
        label.setMinWidth(Pane.USE_PREF_SIZE);
        text.setMinWidth(50);
        pane.setAlignment(Pos.CENTER);
        HBox.setHgrow(pane, Priority.ALWAYS);
        HBox.setHgrow(text, Priority.ALWAYS);
        return pane;
    }

    public static void main(String[] args) {
        launch();
    }

}

Output:

Advertisement