带有按钮的JavaFX-8 TableView渲染太多了吗?

时间:2014-10-21 07:50:05

标签: java button tableview javafx-8

我想在每行中创建TableView Buttons来删除特定行。因此,我创建了一个扩展TableCell的类,其中包含一个Button。所以我像这样设置列的CellFactory

clmRemoveButtons.setCellFactory(c -> new RemovingCell(clients));

一切正常。我能够删除行,按钮显示正确,但有一个问题。整栏中有按钮。 ObservableList数据中有多少项无关紧要。带有项目的行中的按钮可以正常工作,但是当我点击此范围之外的按钮时,我得到IndexOutOfBoundsException(这是正确的,因为此时没有要删除的数据)。

所以我的问题是,我做错了什么以及如何避免这个问题?

最好的问候

编辑:代码RemovingCell(注意:HoverButton是一个控件,用一些设置(大小等)扩展JavaFX Button,所以没什么特别的。

public class RemovingCell extends TableCell<Client, Client> {
private HoverButton hb = new HoverButton(Color.RED);

public RemovingCell(ObservableList<Client> data) {
    super();
    setAlignment(Pos.CENTER);
    try {
        ImageView imgv = new ImageView(new Image(new FileInputStream(
                "img/Remove.png")));
        imgv.setFitWidth(15);
        imgv.setPreserveRatio(true);
        imgv.setSmooth(true);
        hb.setGraphic(imgv);
        hb.setTooltip(ControlFactory.getTooltip("Klient entfernen"));
        hb.setOnAction(event -> {
            data.remove(getTableRow().getIndex());
        });
        setGraphic(hb);
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    }
}

1 个答案:

答案 0 :(得分:2)

TableView大于包含表中所有数据所需的大小,用空单元格填充额外的空格。在决定是否在其中包含按钮之前,您的TableCell需要检查单元格是否为空。您可以使用单元格emptyProperty()上的侦听器或绑定它来执行此操作:

public class RemovingCell extends TableCell<Client, Client> {
private HoverButton hb = new HoverButton(Color.RED);

public RemovingCell(ObservableList<Client> data) {
    super();
    setAlignment(Pos.CENTER);
    try {
        ImageView imgv = new ImageView(new Image(new FileInputStream(
                "img/Remove.png")));
        imgv.setFitWidth(15);
        imgv.setPreserveRatio(true);
        imgv.setSmooth(true);
        hb.setGraphic(imgv);
        hb.setTooltip(ControlFactory.getTooltip("Klient entfernen"));
        hb.setOnAction(event -> {
            data.remove(getTableRow().getIndex());
        });

        // conditionally set the graphic:
        // setGraphic(hb);

        emptyProperty().addListener( (obs, wasEmpty, isNowEmpty) -> {
            if (isNowEmpty) {
                setGraphic(null);
            } else {
                setGraphic(hb);
            }
        });

        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    }
}

使用绑定即可

graphicProperty().bind(Bindings.when(emptyProperty())
    .then((Node)null)
    .otherwise(hb));

而不是将监听器添加到emptyProperty()。两者之间的选择只是风格问题。