谁能解释一下为什么这不起作用?
循环(应该(在VBox
内、ScrollPane
内、BorderPane
内(中心位置(内创建一个重复的VBox
模式,每个模式都有从数据库中提取的不同数据。
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();
}
}
}
这是基于VBox
构建的自定义节点,应使用上述方法将其添加到EquipmentPanels
VBox 中。
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);
}
}
PaneEquipment
对象/节点的 FXML:
<?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>
根据我的测试,一切正常,除了程序运行时没有显示equipmentPane
,我只是得到一个空白的滚动窗格。 数据库和链表工作正常。 更新字段方法工作正常。 打印无例外。
如果我用这个替换equipmentPaneBuiler
循环,它会正确显示:
try {
VBox vbox = new VBox();
Label label = new Label();
vbox.getChildren().add("text");
EquipmentPanels.getChildren().add(vbox);
} catch (Exception e) {
e.printStackTrace();
}
所以我认为这是我的自定义节点的问题,但我只是无法弄清楚。
您没有 100% 正确实施自定义组件方法。
在您的情况下,在执行PaneEquipment
构造函数期间存在 2 个不同的VBox
es(或VBox
派生对象(。正在构造的对象和由FXMLLoader
创建的VBox
。FXMLLoader
创建的VBox
包含内容,但被忽略,您只添加空PaneEquipment
。
要正确实现该方法,您需要使用PaneEquipment
作为根,并将 fxml 的根元素替换为<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);
}
}