gpt4 book ai didi

Javafx IllegalArgumentException : Children : Duplicate children added

转载 作者:行者123 更新时间:2023-12-02 03:35:43 26 4
gpt4 key购买 nike

即使我只向表中添加一项内容,我似乎也无法弄清楚为什么会显示重复的子项添加错误。

有 3 个主要类:

  1. WindowTease:加载舞台并调用 loadTable() 方法
  2. InventoryController:标准fxml Controller ,并包含通用loadTable()方法
  3. InventoryCell:我用它来为每列 setcellfactory() 。

    引起:java.lang.IllegalArgumentException:子项:添加了重复的子项:parent = TableRow@6c41701f[styleClass=cell indexed-cell table-row-cell]'null'

这是我的 Controller :

public class InventoryController {

@FXML protected TableView mainTable;

public <U> void loadTable(TableCell<U, Component> cellFactory){

mainTable.getColumns().clear();

final String[] propertyName = {"id", "invCategory", "quantity", "description", "perItem", "icon"};
final String[] columnName = {"ID", "Category", "Quantity", "Description", "Price (Per Item)", "Process"};

for (int i = 0; i < propertyName.length; i++) {
TableColumn<U, Component> column = new TableColumn<>(columnName[i]);
column.setCellValueFactory(new PropertyValueFactory<>(propertyName[i]));
column.setCellFactory(param -> cellFactory); //this is the culprit
//column.setCellFactory(param -> new InventoryCell()); //this shows with no problem
mainTable.getColumns().add(column);
}

ObservableList<Inventory> items = FXCollections.observableArrayList();
mainTable.getItems().clear();

for (int i = 0; i < 1; i++) {
Inventory inve = new Inventory(
new ID("WSS", i), new Describer("Click me !!"),
new PercentQuantity(i, 100), new Describer("Click me !!"), new Price(Currency.CHINESE_YEN, i*1000.00),
new HoverIcon("images/assignment_returned.png"));
mainTable.getItems().add(inve);
}

}

这是应用程序类:

public class WindowTease extends Application {

@Override
private void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader());
loader.setLocation(WindowTease.class.getResource("/layouts/inventory.fxml"));
InventoryController controller = new InventoryController();
loader.setController(controller);
Parent root = loader.load();
Scene scene = new Scene(root);

controller.loadTable(new InventoryCell());

primaryStage.setScene(scene);
primaryStage.show(); //Caused by: java.lang.RuntimeException: Exception in Application start method
}

最后 InventoryCell 扩展了 TableCell :

public class InventoryCell extends TableCell<Inventory, Component>{

@Override
protected void updateItem(Component item, boolean empty) {
if (item == null || empty) return;
super.updateItem(item, empty);
Object node = item.getNode();
if (node instanceof Node) {
Node graphix = ((Node)node);
HBox box = new HBox(graphix);
setText("");
setGraphic(box);

} else if (node instanceof String) {
setText((String)node);
setGraphic(null);
}
}
}

更新:罪魁祸首肯定是 tablecolumn.setCellFactory(cellfactory);

最佳答案

它被称为 cellFactory,而不是 cellContainer,原因如下:

TableView 使用其 TableColumncellFactory 创建节点来显示列的数据。对显示的每一行执行一次此操作。

如果您现在每次都返回相同的 TableCell 实例,那么稍后当 TableViewSkin 最终组装布局时,最终会达到这样的情况:

SomeParent
|
|--TableRow1
| |
| |--InventoryCell1
|
|--TableRow2
|
|--InventoryCell1

这是不允许的,因为 InventoryCell1 不得在场景图中包含多次。

因此,您必须确保为工厂的每次调用返回不同的 TableCell 实例。

param -> cellFactory

只会返回 TableCell 的实例,该实例会一遍又一遍地传递给 loadTable 方法。

使用 java 8 引用方法,您可以轻松创建工厂:

public <U> void loadTable(Supplier<TableCell<U, Component>> cellFactory){
...
column.setCellFactory(param -> cellFactory.get());
controller.loadTable(InventoryCell::new);

关于Javafx IllegalArgumentException : Children : Duplicate children added,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37474433/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com