classbuttonjavafxalignmentgridpane

How to align four buttons in one row using GridPane in JavaFx


I have a gridPane which is centre aligned.But four buttons in GridPane contain gaps between. How to get rid of this? What I have done is

GridPane grid= new GridPane();
   
   grid.setAlignment(Pos.CENTER); 
    grid.setVgap(5); 
    grid.setHgap(5);
    grid.add(label1, 0, 0); 
  grid.add(tf1, 1, 0); 
  grid.add(label2, 0, 1);       
  grid.add(tf2, 1, 1); 
  grid.add(btn1,0,2);
  grid.add(btn2,1,2);
  grid.add(btn3,2,2);
  grid.add(btn4,3,2);
  //Setting size of scene 
   Scene scene = new Scene(grid, 370, 170);      
    primaryStage.setScene(scene);
    primaryStage.show();

Buttons appear as: View Image

There is a gap after two buttons. How to remove that gap?


Solution

  • By default in a GridPane, each column is sized to the preferred width of the widest element (and similarly, each row is sized to the preferred height of the tallest element). Since your second button is in the same column as the text fields, which are by default wider than the button, that column's width will be determined by the width of the text fields.

    How you fix this depends on the actual behavior you want. If you really want the second button to be in the same column as the text fields, you can remove the gap either by making the button grow to the full width of the column:

    public class GridPaneTest extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            GridPane grid = new GridPane();
            
            Label label1 = new Label("Label 1");
            Label label2 = new Label("Label 2");
            TextField tf1 = new TextField();
            TextField tf2 = new TextField();
            Button btn1 = new Button("Button 1");
            Button btn2 = new Button("Button 2");
            Button btn3 = new Button("Button 3");
            Button btn4 = new Button("Button 4");
            
            grid.setAlignment(Pos.CENTER);
            grid.setVgap(5);
            grid.setHgap(5);
            grid.add(label1, 0, 0);
            grid.add(tf1, 1, 0);
            grid.add(label2, 0, 1);
            grid.add(tf2, 1, 1);
            grid.add(btn1, 0, 2);
            grid.add(btn2, 1, 2);
            btn2.setMaxWidth(Double.POSITIVE_INFINITY);
            GridPane.setFillWidth(btn2, true);
            grid.add(btn3, 2, 2);
            grid.add(btn4, 3, 2);
            // Setting size of scene
            Scene scene = new Scene(grid, 370, 170);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            Application.launch(args);
        }
    
    }
    

    enter image description here

    or by making the text fields preferred size smaller (so the column's width is determined by the button):

    public class GridPaneTest extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            GridPane grid = new GridPane();
            
            Label label1 = new Label("Label 1");
            Label label2 = new Label("Label 2");
            TextField tf1 = new TextField();
            tf1.setPrefColumnCount(0);
            TextField tf2 = new TextField();
            tf2.setPrefColumnCount(0);
            Button btn1 = new Button("Button 1");
            Button btn2 = new Button("Button 2");
            Button btn3 = new Button("Button 3");
            Button btn4 = new Button("Button 4");
            
            HBox buttons = new HBox(5, btn1, btn2, btn3, btn4);
    
            grid.setAlignment(Pos.CENTER);
            grid.setVgap(5);
            grid.setHgap(5);
            grid.add(label1, 0, 0);
            grid.add(tf1, 1, 0);
            grid.add(label2, 0, 1);
            grid.add(tf2, 1, 1);
            grid.add(btn1, 0, 2);
            grid.add(btn2, 1, 2);
            grid.add(btn3, 2, 2);
            grid.add(btn4, 3, 2);
            // Setting size of scene
            Scene scene = new Scene(grid, 370, 170);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            Application.launch(args);
        }
    
    }
    

    enter image description here

    Alternatively, you can make the text fields fill all three columns occupied by buttons 2-4 (using the version of the add method that takes a column and row span, as well as an index):

    public class GridPaneTest extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            GridPane grid = new GridPane();
            
            Label label1 = new Label("Label 1");
            Label label2 = new Label("Label 2");
            TextField tf1 = new TextField();
            TextField tf2 = new TextField();
            Button btn1 = new Button("Button 1");
            Button btn2 = new Button("Button 2");
            Button btn3 = new Button("Button 3");
            Button btn4 = new Button("Button 4");
            
    
            grid.setAlignment(Pos.CENTER);
            grid.setVgap(5);
            grid.setHgap(5);
            grid.add(label1, 0, 0);
            grid.add(tf1, 1, 0, 3, 1);
            grid.add(label2, 0, 1);
            grid.add(tf2, 1, 1, 3, 1);
            grid.add(btn1, 0, 2);
            grid.add(btn2, 1, 2);
            grid.add(btn3, 2, 2);
            grid.add(btn4, 3, 2);
            // Setting size of scene
            Scene scene = new Scene(grid, 370, 170);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            Application.launch(args);
        }
    
    }
    

    enter image description here

    Note in this last version, the width of the cell containing the labels is the same as the width of the cell containing the first button, which is probably not what you want either. Probably the best approach is to put the buttons in a HBox, and let that HBox span the full width of the grid pane (which now only has two columns):

    public class GridPaneTest extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            GridPane grid = new GridPane();
            
            Label label1 = new Label("Label 1");
            Label label2 = new Label("Label 2");
            TextField tf1 = new TextField();
            TextField tf2 = new TextField();
            Button btn1 = new Button("Button 1");
            Button btn2 = new Button("Button 2");
            Button btn3 = new Button("Button 3");
            Button btn4 = new Button("Button 4");
            
            HBox buttons = new HBox(5, btn1, btn2, btn3, btn4);
    
            grid.setAlignment(Pos.CENTER);
            grid.setVgap(5);
            grid.setHgap(5);
            grid.add(label1, 0, 0);
            grid.add(tf1, 1, 0);
            grid.add(label2, 0, 1);
            grid.add(tf2, 1, 1);
            grid.add(buttons, 0, 2, 2, 1);
            // Setting size of scene
            Scene scene = new Scene(grid, 370, 170);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            Application.launch(args);
        }
    
    }
    

    enter image description here