我试图在ListView中创建自定义单元格,但每次添加新项时,都会执行两次updateItem(TextFlow item,Boolean empty):一次接收null和true,第二次不接收(!)。 null和false)

如果我没有实现setCellFactory方法,那么我可以毫无问题地将项目添加到表中。

ListView without custom cellFactory

但是,当我实现它时,它仅创建10个空单元(内容在哪里?)。

ListView with custom cellFactory

public class Controller implements Initializable {

@FXML
private ListView <TextFlow> console;

private ObservableList<TextFlow> data = FXCollections.observableArrayList();

public void initialize(URL location, ResourceBundle resources) {

    console.setCellFactory(new Callback<ListView<TextFlow>, ListCell<TextFlow>>() {

        @Override
        public ListCell<TextFlow> call(ListView<TextFlow> param) {
            return new ListCell<TextFlow>() {
                @Override
                protected void updateItem(TextFlow item, boolean empty) {
                    super.updateItem(item, empty);

                    if (item != null) {
                        setItem(item);
                        setStyle("-fx-control-inner-background: blue;");
                    } else {
                        System.out.println("Item is null.");
                    }

                }
            };
        }

    });


    for (int i = 0 ; i < 10; i++) {
        Text txt = getStyledText("This is item number " + i + ".");
        TextFlow textFlow = new TextFlow();
        textFlow.getChildren().add(txt);
        data.add(textFlow);
    }

    console.setItems(data);

}

private Text getStyledText (String inputText) {
    Text text = new Text(inputText);
    text.setFont(new Font("Courier New",12));
    text.setFill(Paint.valueOf("#000000"));
    return text;
}
}

最佳答案

可以任意次数地调用updateItem,可以传递不同的项目,并且单元可以从空变为非空,反之亦然。 ListView创建与您在屏幕上看到的单元格差不多的单元格,并用项目填充它们。例如。滚动或修改items列表或调整ListView的大小可能会导致更新。

因此,任何单元都需要能够处理传递给null方法的任意顺序的项目(或updateItem + empty)。

此外,您应该避免自己调用setItem,因为super.updateItem已经这样做了。如果要在单元格中显示项目,请使用setGraphic

@Override
public ListCell<TextFlow> call(ListView<TextFlow> param) {
    return new ListCell<TextFlow>() {
        @Override
        protected void updateItem(TextFlow item, boolean empty) {
            super.updateItem(item, empty);

            if (item != null) {
                setStyle("-fx-control-inner-background: blue;");
                setGraphic(item);
            } else {
                setStyle(null);
                setGraphic(null);
                System.out.println("Item is null.");
            }

        }
    };
}

关于java - JavaFX ListCell updateItem执行两次?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57019434/

10-09 20:48