javamatrixjavafxstackpane

Matrix of Buttons (How to Create and Arrange) in JavaFX


This is my first program written in JavaFX (as opposed to Swing). I'm starting small by simply displaying data sets in a matrix of buttons (I do not wish to use a Table just yet).

package matrixjavafx;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.util.Random;    // required for random number generation
/**
 *
 * @author Matt
 */

public class MatrixJavaFX extends Application {

Button[][] matrix; //names the grid of buttons

@Override
public void start(Stage primaryStage) {

    int SIZE = 10;
    int length = SIZE;
    int width = SIZE;

    StackPane root = new StackPane();

    matrix = new Button[width][length]; // allocates the size of the matrix

    // runs a for loop and an embedded for loop to create buttons to fill the size of the matrix
    // these buttons are then added to the matrix
    for(int y = 0; y < length; y++)
    {
            for(int x = 0; x < width; x++)
            {
                Random rand = new Random(); // Creates new Random object for generating random numbers

                // The following variables are generated using Random object rand.
                // rand.nextInt(2) generates a double ranging from 0.000 to 0.999.
                // setting the target variable to be an integer  truncates the range to 0 - 1.
                int rand1 = rand.nextInt(2); // Declare and initialize random integer (0 - 1) + 1

                matrix[x][y] = new Button(/*"(" + rand1 + ")"*/); //creates new random binary button     
                matrix[x][y].setText("(" + rand1 + ")");   // Sets the text inside the matrix

                matrix[x][y].setOnAction(new EventHandler<ActionEvent>() {

                    @Override
                    public void handle(ActionEvent event) {
                        System.out.println("Random Binary Matrix (JavaFX)");
                    }
                });

                root.getChildren().add(matrix[x][y]);
            }
    }        


    Scene scene = new Scene(root, 500, 500);

    primaryStage.setTitle("Random Binary Matrix (JavaFX)");
    primaryStage.setScene(scene);
    primaryStage.show();
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {

    greeting(); // Greets the User and explains the purpose of the program

    launch(args); // Opens the window that generates and displays the matrix

    //new MatrixSwingGUI(width, length); // makes new MatrixSwing with 2 parameters

    thanks(); // Thanks User and indicates that the program is about to close

}

public static void greeting()
{
    // Greets the User and displays the program's purpose
    System.out.println("Welcome to the Random Matrix Generator\n");
    System.out.println("The purpose of this program is to generate and display "
        + "\na 10 x 10 matrix of random 0's, and 1's.");

}

public static void thanks() // Thanks User and indicates that the program is about to close
{
    System.out.println("\nGoodbye and Thank You for using the Random Matrix Generator\n\n");
} // End thanks method

}

The heart of the problem seems to be the following line, since by default all of the buttons are stacking on top of each other in the center of the pane.

StackPane root = new StackPane();

That said, I would like the buttons to align side by side for all of length and width, resulting in an n x m matrix. What should be done to accomplish this? What additional javafx.scene.* files need to be imported?


Solution

  • The basic problem is the Layout that you have chosen for the project. You can get an in-depth knowledge about layouts, that javafx support over here

    StackPane stacks all the Nodes that you pass it. I would suggest you to use GridPane inplace of StackPane.

    GridPane root = new GridPane();
    

    To add the nodes, use

    root.add(matrix[x][y], y, x);
    

    P.S. I would also advice you to rename your buttons, to give you more clarity on button representing row's and column's of the matrix. You can use something as, though its totally optional ! :)

    matrix[x][y].setText(x + "," + y);