I am currently trying to create lists to show on a board (each list has buttons and a title and an additional vbox to store things inside of it). When I create a new list to show it on my board, all the @FXML annotated fields are left with null (but the children of the object exist). The specific line of code is:
ListCtrl listObject = new ListCtrl();
I am suspecting the injector is at fault as I am not really sure how to use it. Here is my code.
List.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="240.0" prefWidth="180.0" style="-fx-border-color: black; -fx-border-width: 10;" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.scenes.ListCtrl">
<children>
<HBox alignment="TOP_RIGHT" prefHeight="19.0" prefWidth="140.0">
<children>
<Button fx:id="listEditButton" mnemonicParsing="false" text="Edit" />
<Button fx:id="listCloseButton" mnemonicParsing="false" text="X" />
</children>
</HBox>
<Label id="listTitle" fx:id="listTitle" alignment="CENTER" prefHeight="17.0" prefWidth="206.0" text="Default List Name" />
<VBox fx:id="cardBox" prefHeight="142.0" prefWidth="140.0" />
<Button id="listAddCard" fx:id="listAddCard" alignment="CENTER" mnemonicParsing="false" prefHeight="25.0" prefWidth="202.0" text="Add card" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</VBox>
The controller of the list
package client.scenes;
import jakarta.inject.Inject;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
public class ListCtrl extends AnchorPane implements Initializable{
@FXML
private Label listTitle;
@FXML
private VBox cardBox;
@FXML
private Button listAddCard;
@FXML
private Button listCloseButton;
@FXML
private Button listEditButton;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
@Inject
public ListCtrl(){
super();
try
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("List.fxml"));
Parent root = loader.load();
//Node n = loader.load();
//this.getChildren().add(n);
} catch (IOException ix){
}
}
/** Sets the text of the title of the list
* @param text
*/
public void setListTitleText(String text) {
listTitle.setText(text);
}
public void addCardToList(Node card){
cardBox.getChildren().add(card);
}
/**
* @return the title of the list
*/
public Label getListTitle() {
return listTitle;
}
/**
* @return the Edit button of the list
*/
public Button getListEditButton() {
return listEditButton;
}
/**
* @return the X button for the list
*/
public Button getListCloseButton() {
return listCloseButton;
}
/**
* @return the list button of the list
*/
public Button getListAddCardButton() {
return listAddCard;
}
}
The part of the code where I am creating a new list
public void refresh() {
mainBoard.getChildren().clear();
var lists = fakeServer.getBoardLists();
data = FXCollections.observableList(lists);
for (BoardList currentList : data) {
ListCtrl listObject = new ListCtrl(); ///Instantiating a new list to be shown
listObject.setListTitleText(currentList.title); //Setting the title of the list
ObservableList<Card> cardsInList =
FXCollections.observableList(fakeServer.getCards(currentList));
for (Card currentCard : cardsInList) {
CardCtrl cardObject = new CardCtrl(); ///Instantiating a new card to be shown
cardObject.setCardTitleText(currentCard.title); //Setting the title of the card
listObject.addCardToList(cardObject); //Adding the card to the list
}
listObject.getListAddCardButton().setOnAction(event -> mainCtrl.showAddCard(currentList));
mainBoard.getChildren().add(listObject);
}
}
I tried looking up information on how to use the injector for objects created through code (so objects which are not already on the main board) and didn't succeed. Thank you in advance!
EDIT:
I changed my refresh method to this:
public void refresh() {
mainBoard.getChildren().clear();
var lists = fakeServer.getBoardLists();
data = FXCollections.observableList(lists);
for (BoardList currentList : data) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("List.fxml"));
ListCtrl listObject = loader.getController(); ///Instantiating a new list to be shown
listObject.setListTitleText(currentList.title); //Setting the title of the list
ObservableList<Card> cardsInList =
FXCollections.observableList(fakeServer.getCards(currentList));
for (Card currentCard : cardsInList) {
CardCtrl cardObject = new CardCtrl(); ///Instantiating a new card to be shown
cardObject.setCardTitleText(currentCard.title); //Setting the title of the card
listObject.addCardToList(cardObject); //Adding the card to the list
}
listObject.getListAddCardButton().setOnAction(event -> mainCtrl.showAddCard(currentList));
//mainBoard.getChildren().add(listObject);
}
}
And now listObject is null. Have I used the loader incorrectly?