I am working on a simple BeatBox, where different sounds play depending on the checkboxes that were selected.
The program is supposed to have 256 checkboxes, displayed on a 16x16 grid. So when I build the GUI through direct code (i.e without fxml or the scene builder), I can easily create a simple loop to create the 256 checkboxes, add them to a list so that I can use them later, and add them to the grid.
I am trying to change that approach and do it with the scene builder or coding directly on the fxml file, but I can't figure out a way of doing it, and I don't even know if that is possible. Trying to figure out that, I came across this doubt: - Is there a way to create a list of some type of widget, populated with loads of components (for my given example, a list with 256 CheckBoxes), through fxml or scene builder, and then have a reference to the list on my Controller class?
I really don't like the idea of dragging-and-dropping 256 Checkboxes on the scene builder, or even make 256 tags on the fxml. And I think that that feature could be useful for many other cases. So if that is possible, I'd love a help on it.
Thanks in advance!
The FXML format does not provide a way to declare elements in a loop. As Scene Builder is simply a WYSIWYG editor for FXML files it also doesn't provide this functionality, nor does it provide a shortcut to declaring and configuring 256 elements (e.g. via a dialog or something). This is one of those cases where adding the nodes in code is the proper solution.
To do this you'll need to link your FXML file to a controller. From there you can create all 256 CheckBox
es inside the initialize
method. This method comes from the Initializable
interface, though since JavaFX 8 you no longer need to actually implement the interface. Instead, you just declare a no-arg method named initialize
(see this) and annotate it with @FXML
if non-public
.
Here's a small example:
FXML File
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<!-- replace with your root -->
<HBox xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.example.Controller">
<GridPane fx:id="grid"/>
<!-- other elements... -->
</HBox>
Controller
package com.example;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.GridPane;
public class Controller {
@FXML private GridPane grid;
private CheckBox[][] boxes; // for access by grid coordinates
@FXML
private void initialize() {
boxes = new CheckBox[16][16];
for (int row = 0; row < boxes.length; row++) {
for (int col = 0; col < boxes[0].length; col++) {
CheckBox box = new CheckBox();
grid.add(box, col, row);
boxes[row][col] = box;
}
}
}
}