Checkbox Javafx2.2:滚动表格时,表格视图中的复选框会混乱

Checkbox Javafx2.2:滚动表格时,表格视图中的复选框会混乱,checkbox,javafx,scroll,tableview,Checkbox,Javafx,Scroll,Tableview,使用表格视图附带的垂直滚动条时会出现此问题。这就是我的表视图的外观: <TableView fx:id="table" prefWidth="650" prefHeight="200" AnchorPane.topAnchor="50" AnchorPane.leftAnchor="0"> <columns> <TableColumn fx:id="nameCol" text="Product Type" prefWidth="125" />

使用表格视图附带的垂直滚动条时会出现此问题。这就是我的表视图的外观:

<TableView fx:id="table" prefWidth="650" prefHeight="200" AnchorPane.topAnchor="50" AnchorPane.leftAnchor="0">
<columns>
    <TableColumn fx:id="nameCol" text="Product Type" prefWidth="125" />
    <TableColumn fx:id="totalCol" text="Total" prefWidth="65" />
    <TableColumn fx:id="entitledCol" text="Entitled"  />
    <TableColumn fx:id="forPurchaseCol" text="For Purchase" prefWidth="125" />
    <TableColumn fx:id="nonImmediate" text="Non Immediate" prefWidth="125" />
</columns>              
</TableView>
public class PriceCell extends TableCell<Product, ObservableMap<String, Number>> {
private CheckBox box = new CheckBox();

@Override
protected void updateItem(ObservableMap<String, Number> countPrice, boolean empty) {
    super.updateItem(countPrice, empty);

    if(countPrice != null) {
        int count = (Integer) countPrice.get("count");
        if(count == 0) {
            setText("0");
        }
        else {
            setText(countPrice.get("count") + " ($" + countPrice.get("price") + ")");
            box.setOnAction(this);
            box.setId(countPrice.get("price").toString());
            setGraphic(box);
        }
    }
    else {
        setText("");
        setGraphic(null);
    }
}
}
当你用鼠标滚轮滚动时,一切正常。当您使用滚动条上的向上/向下箭头滚动时,一切正常。但是,当你用鼠标指针拖动滚动条时,复选框中的选择就会混乱。例如,如果看到上面链接的图像,则选中第三个复选框。滚动后,现在可以选择第5个复选框或第2个复选框。或者甚至可以选择另外两个复选框

我认为这是表视图滚动条的刷新/重新绘制问题

解决这个问题的正确方法是拦截垂直滚动事件,并在用户滚动时手动刷新网格。要做到这一点,我需要能够得到一个处理表的滚动条。类似于table.getScrollBar.setEventHandlerthis的内容。我不能那样做。表的滚动条似乎被隐藏了。如果无法访问滚动条,则无法拦截滚动事件,也无法解决此问题

以下是我的fxml的外观:

<TableView fx:id="table" prefWidth="650" prefHeight="200" AnchorPane.topAnchor="50" AnchorPane.leftAnchor="0">
<columns>
    <TableColumn fx:id="nameCol" text="Product Type" prefWidth="125" />
    <TableColumn fx:id="totalCol" text="Total" prefWidth="65" />
    <TableColumn fx:id="entitledCol" text="Entitled"  />
    <TableColumn fx:id="forPurchaseCol" text="For Purchase" prefWidth="125" />
    <TableColumn fx:id="nonImmediate" text="Non Immediate" prefWidth="125" />
</columns>              
</TableView>
public class PriceCell extends TableCell<Product, ObservableMap<String, Number>> {
private CheckBox box = new CheckBox();

@Override
protected void updateItem(ObservableMap<String, Number> countPrice, boolean empty) {
    super.updateItem(countPrice, empty);

    if(countPrice != null) {
        int count = (Integer) countPrice.get("count");
        if(count == 0) {
            setText("0");
        }
        else {
            setText(countPrice.get("count") + " ($" + countPrice.get("price") + ")");
            box.setOnAction(this);
            box.setId(countPrice.get("price").toString());
            setGraphic(box);
        }
    }
    else {
        setText("");
        setGraphic(null);
    }
}
}
以下是来自控制器的相关java代码:

nameCol.setCellValueFactory(new PropertyValueFactory<Product, String>("productFullName"));
totalCol.setCellValueFactory(new PropertyValueFactory<Product, Integer>("totalCount"));
entitledCol.setCellValueFactory(new PropertyValueFactory<Product, Integer>("entitledImmediateCount"));
forPurchaseCol.setCellValueFactory(new PropertyValueFactory<Product, ObservableMap<String, Number>>(
                                                                                                      "forPurchaseImmediateCountAndPrice"));
nonImmediate.setCellValueFactory(new PropertyValueFactory<Product, Integer>("nonImmediateCount"));
forPurchaseCol.setCellFactory(new Callback<TableColumn<Product, ObservableMap<String, Number>>, TableCell<Product, ObservableMap<String, Number>>>() {
    @Override
    public TableCell<Product, ObservableMap<String, Number>> call(TableColumn<Product, ObservableMap<String, Number>> col) {
        return new PriceCell();
    }
});
forPurchaseCol.setCellValueFactory(new PropertyValueFactory<>( "purchase"));
forPurchaseCol.setCellFactory(new Callback<TableColumn<Product, Boolean>, TableCell<Product, Boolean>>() {

    @Override
    public TableCell<Product, Boolean> call(TableColumn<Product, Boolean> col) {
        return new PriceCell();
    }
});
这就是PriceCell.java的样子:

<TableView fx:id="table" prefWidth="650" prefHeight="200" AnchorPane.topAnchor="50" AnchorPane.leftAnchor="0">
<columns>
    <TableColumn fx:id="nameCol" text="Product Type" prefWidth="125" />
    <TableColumn fx:id="totalCol" text="Total" prefWidth="65" />
    <TableColumn fx:id="entitledCol" text="Entitled"  />
    <TableColumn fx:id="forPurchaseCol" text="For Purchase" prefWidth="125" />
    <TableColumn fx:id="nonImmediate" text="Non Immediate" prefWidth="125" />
</columns>              
</TableView>
public class PriceCell extends TableCell<Product, ObservableMap<String, Number>> {
private CheckBox box = new CheckBox();

@Override
protected void updateItem(ObservableMap<String, Number> countPrice, boolean empty) {
    super.updateItem(countPrice, empty);

    if(countPrice != null) {
        int count = (Integer) countPrice.get("count");
        if(count == 0) {
            setText("0");
        }
        else {
            setText(countPrice.get("count") + " ($" + countPrice.get("price") + ")");
            box.setOnAction(this);
            box.setId(countPrice.get("price").toString());
            setGraphic(box);
        }
    }
    else {
        setText("");
        setGraphic(null);
    }
}
}

谢谢。感谢您的帮助

不知怎的,你的模型连接不好

PriceCell试图在一个列中混合两种不同的内容:复选框的布尔值,在呈现单元格时其状态未被存储或处理,并且在Product“”中没有字段,以及与复选状态无关的字符串。因此,当用户单击复选框时,标签不会受到影响

虽然渲染看起来是正确的,但当您使用鼠标滚动时,checkbok状态将丢失,并且没有回调来正确查找它

已经有一个带有复选框的TableCell实现:CheckBoxTableCell。但它只将布尔值作为参数,因为它只需要知道是否选择了状态。您可以为标签添加一些StringConverter,但这仅与选定状态相关

要解决此问题,我的建议如下:

首先,在产品中创建一个新字段:

并添加适当的字符串格式化程序:

@Override
public String toString() {
    if(isPurchase()){
        return forPurchaseImmediateCountAndPrice.get("count") + " ($" + forPurchaseImmediateCountAndPrice.get("price") + ")";
    }
    return "0";
}
在控制器中:

nameCol.setCellValueFactory(new PropertyValueFactory<Product, String>("productFullName"));
totalCol.setCellValueFactory(new PropertyValueFactory<Product, Integer>("totalCount"));
entitledCol.setCellValueFactory(new PropertyValueFactory<Product, Integer>("entitledImmediateCount"));
forPurchaseCol.setCellValueFactory(new PropertyValueFactory<Product, ObservableMap<String, Number>>(
                                                                                                      "forPurchaseImmediateCountAndPrice"));
nonImmediate.setCellValueFactory(new PropertyValueFactory<Product, Integer>("nonImmediateCount"));
forPurchaseCol.setCellFactory(new Callback<TableColumn<Product, ObservableMap<String, Number>>, TableCell<Product, ObservableMap<String, Number>>>() {
    @Override
    public TableCell<Product, ObservableMap<String, Number>> call(TableColumn<Product, ObservableMap<String, Number>> col) {
        return new PriceCell();
    }
});
forPurchaseCol.setCellValueFactory(new PropertyValueFactory<>( "purchase"));
forPurchaseCol.setCellFactory(new Callback<TableColumn<Product, Boolean>, TableCell<Product, Boolean>>() {

    @Override
    public TableCell<Product, Boolean> call(TableColumn<Product, Boolean> col) {
        return new PriceCell();
    }
});

这样,您就不会再有滚动问题了。

您只需在更新chekBox单元格值后清除tableView并重新设置所有项目: table.getItems.clear; table.setItemsgetTbleInfo