Reputation: 137
Could anyone please explain why this is not working?
Loop (should) create a repeating pattern of VBox
's inside a VBox
, inside a ScrollPane
, inside a BorderPane
(central position), each with different data drawn from a database.
public void equipmentPaneBuilder(LinkedList<ModelEquipment> list) {
LinkedList<ModelEquipment> equipmentList = list;
for (int i = 0; i < equipmentList.size(); i++) {
ModelEquipment item = equipmentList.get(i);
try {
PaneEquipment equipmentPane = new PaneEquipment();
equipmentPane.updateFields(item.getTechId(), item.getShortName(), item.getLongDesc()); equipmentPane.setId("equipPane" + i);
EquipmentPanels.getChildren().add(equipmentPane);
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is the custom node built on VBox
that should be added to the EquipmentPanels
VBox using the method above.
import javafx.fxml.FXML;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
public class PaneEquipment extends VBox {
@FXML private TextField techId;
@FXML private TextField shortText;
@FXML private TextArea longDesc;
public PaneEquipment() {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/fxml/PaneEquipment.fxml"));
fxmlLoader.setController(this);
try {
fxmlLoader.load();
}
catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public void updateFields(String techIdArg, String shortNameArg, String longDescArg) {
techID.setText(techIdArg);
shortText.setText(shortNameArg);
longDesc.setText(longDescArg);
}
}
FXML for the PaneEquipment
objects/nodes:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0">
<children>
<Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="40.0" text="Tech ID" />
<TextField fx:id="techID" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="150.0" promptText="Tech ID Number" />
<Label layoutX="10.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="92.0" text="Name" />
<TextField fx:id="shortText" layoutX="50.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="465.0" promptText="Short text description (max. 40 characters)" />
</children>
</HBox>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.0">
<children>
<Label prefHeight="132.0" prefWidth="65.0" text="Description" wrapText="true" />
<TextArea fx:id="longDesc" prefHeight="100.0" prefWidth="682.0" promptText="Long text description (max. 300 characters)" wrapText="true" />
</children>
</HBox>
</children>
</VBox>
Based on my testing, everything is working fine, except that the equipmentPane
's are not displaying when the program runs, I just get a blank scroll pane. The database and linked list work fine. The updatefields method works fine. No exception is printed.
If I replace the equipmentPaneBuiler
loop with this, it displays correctly:
try {
VBox vbox = new VBox();
Label label = new Label();
vbox.getChildren().add("text");
EquipmentPanels.getChildren().add(vbox);
} catch (Exception e) {
e.printStackTrace();
}
So I presume it's an issue with my custom node, but I just can't figure it out.
Upvotes: 0
Views: 779
Reputation: 82461
You did not implement the Custom Component approach 100% correctly.
In your case 2 distinct VBox
es (or VBox
-derived objects) exist during the execution of the PaneEquipment
constructor. The object being constructed and the VBox
created by FXMLLoader
. The VBox
created by FXMLLoader
contains the contents but gets ignored and you only add the empty PaneEquipment
.
To implement the approach correctly you need to use PaneEquipment
as root and replace the root element of the fxml with <fx:root>
<fx:root type="javafx.scene.layout.VBox" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0">
<children>
<Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="40.0" text="Tech ID" />
<TextField fx:id="TechID" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="150.0" promptText="Tech ID Number" />
<Label layoutX="10.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="92.0" text="Name" />
<TextField fx:id="ShortText" layoutX="50.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="465.0" promptText="Short text description (max. 40 characters)" />
</children>
</HBox>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.0">
<children>
<Label prefHeight="132.0" prefWidth="65.0" text="Description" wrapText="true" />
<TextArea fx:id="LongDesc" prefHeight="100.0" prefWidth="682.0" promptText="Long text description (max. 300 characters)" wrapText="true" />
</children>
</HBox>
</children>
</fx:root>
public PaneEquipment() {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/fxml/PaneEquipment.fxml"));
fxmlLoader.setController(this);
fxmlLoader.setRoot(this); // add this line
try {
fxmlLoader.load();
}
catch (IOException exception) {
throw new RuntimeException(exception);
}
}
Upvotes: 2