BoJack Horseman
BoJack Horseman

Reputation: 4452

How to load a large amount of elements in JavaFX?

I want to create a connect four game in fxml. I have already created the fxml for the board and now I want to load all the "coin fields" which are Buttons with an Image view into my Controller.
From previous experiences with fxml I learned to load an fxml element like this:

@FXML
Button idOfButton;

This is good if I have specific elements that I want to change. But since I have 42 Buttons (6*7) I don't want to do that for every Button Field... Is there any way I can do it in a different way and auto-generate it? I prepared this for-loop but since I don't know what to write into the curly braces it's still pointless :D

Button[] coinButtons = new Button[42];

@FXML
public Button[] loadCoinButtons() {
    for(int x=0; x<7; x++) {
        for(int y=0; y<6; y++) {
        // Stuff that loads the buttons into my buttons array
        }
    }
    return coinButtons;
}

Help is highly appreciated!

Upvotes: 1

Views: 713

Answers (1)

You can create these buttons in the Java code. Not declaring them in FXML doesn't mean they won't belong to your scene. What you have to do is give the fx:id tag to a container in which you would like to put more buttons, declare it in a Controller class with the @FXML annotation and then put some new Nodes there. Look at the simple app below (assuming all the files are in the sample package) - I created some buttons in FXML file and some via the Java code.

Main.java:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

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

sample.fxml:

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>

<VBox fx:id="vBox" fx:controller="sample.Controller" xmlns:fx="http://javafx.com/fxml">
        <Button text="FXML_Button_1"/>
        <Button text="FXML_Button_2"/>
        <Button text="FXML_Button_3"/>
</VBox>

Controller.java:

package sample;

import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;

public class Controller {
  @FXML
  VBox vBox;

  private final int BUTTONS_NUMBER_OF_ROWS = 5;
  private final int BUTTONS_NUMBER_OF_COLUMNS = 5;
  private Button [][] buttons = new Button[BUTTONS_NUMBER_OF_ROWS][BUTTONS_NUMBER_OF_COLUMNS];


  @FXML
  private void initialize() {
    initializeButtonsArray();
    putButtonsOnGrid();
  }

  private void initializeButtonsArray() {
    for (int i = 0 ; i < BUTTONS_NUMBER_OF_COLUMNS ; i++) {
      for (int j = 0 ; j < BUTTONS_NUMBER_OF_ROWS ; j++) {
        buttons[i][j] = new Button("Button_" + i + j);
      }
    }
  }

  private void putButtonsOnGrid() {
    GridPane buttonsGridPane = new GridPane();
    for (int i = 0 ; i < BUTTONS_NUMBER_OF_COLUMNS ; i++) {
      for (int j = 0 ; j < BUTTONS_NUMBER_OF_ROWS ; j++) {
        buttonsGridPane.add(buttons[i][j], i, j);
      }
    }
    vBox.getChildren().add(buttonsGridPane);
  }
}

How does it look like - picture

Upvotes: 1

Related Questions