简体   繁体   中英

JavaFX GridPane Object Alignment

I am trying to use JavaFX to create a scene with the program's title positioned at the top-center, and buttons in a vertical line along the left side of the scene. However, both of these elements are displayed clustered up in the top-right of the scene, instead of where I want them to be.

How can I get these elements to be displayed where I want them to?

Here is how I try to set the program title's position:

  grid.add(gameTitle, 0, 0);
  GridPane.setHalignment(gameTitle, HPos.CENTER);
  GridPane.setValignment(gameTitle, VPos.TOP);

I try to set the VBox object similarly:

  grid.getChildren().add(buttonBox);
  GridPane.setHalignment(buttonBox, HPos.LEFT);
  GridPane.setValignment(buttonBox, VPos.CENTER);

This is what is displayed: 这是显示的

My entire MainMenu class. (This class is called in my Main class to construct the scene):

package scenes;

import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.application.Platform;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.scene.text.Text;

public class MainMenu {
   public Pane getMainMenuPane() {
      // Create the scene grid
      GridPane grid = new GridPane();
      grid.setHgap(10);
      grid.setVgap(10);

      // Set the game title to the top center  
      Text gameTitle = new Text("Bandit King");
      Font titleFont = new Font(75);
      gameTitle.setFont(titleFont);
      //
      grid.add(gameTitle, 0, 0);
      GridPane.setHalignment(gameTitle, HPos.CENTER);
      GridPane.setValignment(gameTitle, VPos.TOP);

      // Create Button objects and put in VBox
      Button[] buttArr = makeButtons();
      VBox buttonBox = new VBox();
      buttonBox.getChildren().addAll(buttArr);
      buttonBox.setSpacing(10);

      // add Button VBox to GridPane
      grid.getChildren().add(buttonBox);
      GridPane.setHalignment(buttonBox, HPos.LEFT);
      GridPane.setValignment(buttonBox, VPos.CENTER);

      return (Pane) grid;
   }

   private Button[] makeButtons() {
      // Create buttons
      Button start = new Button("Start a New Game");
      Button load = new Button("Load a Saved Game");
      Button exit = new Button("Exit the Game");

      // set Button actions
      start.setOnAction( a -> {
         System.out.println("WIP- start game.");
      });
      load.setOnAction( a -> {
         System.out.println("WIP- load game");
      });
      exit.setOnAction( a -> {
         Platform.exit();
         System.exit(0);
      });

      // return Button[] array
      Button[] buttArr = {start, load, exit};
      return buttArr;
   }


}

My Main class (Displays the scene):

package central;

import javafx.stage.Stage;
import scenes.*;
import controllers.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;

public class Main  extends Application {

   // Get scene panes
   private static Pane mainMenu = new MainMenu().getMainMenuPane();

   // Create SceneController object.
   private static Scene scene = new Scene(mainMenu, 1600, 900);
   public static SceneController SceneControl = new SceneController(scene);

   @Override
   public void start(Stage stage) {
      stage.setTitle("Bandit King");
      stage.setScene(scene);
      stage.show();
   }

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


}

The default cell you add the children of a GridPane to is (0, 0) which is what you do in this line:

grid.getChildren().add(buttonBox);

you need to change this to

grid.add(buttonBox, 0, 1);

to set the row index to 1. (There are alternatives to assigning the row index this way, but this is the most convenient option in this case.)

This won't result in the first column taking the full width of the GridPane though. If you also want the first column to take all the width available, you need to specify this by adding ColumnConstraints :

ColumnConstraints constraints = new ColumnConstraints();
constraints.setHgrow(Priority.ALWAYS);

grid.getColumnConstraints().add(constraints);

As far as what I noticed, you added all the nodes in a column and set there positions, but you did not specify how much the column needs to be stretched. GridPane column will not stretch automatically by itself unless specified.

You can debug your program, by enabling the gridLinesVisible of GridPane property to true.

grid.setGridLinesVisible(true);

You need to specify the columnConstraints, to let the GridPane column stretch to the available width.

ColumnConstraints constraint = new ColumnConstraints();
constraint.setHgrow(Priority.ALWAYS);
grid.getColumnConstraints().add(constraint);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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