首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Javafx2.2:滚动表格时表格视图中的复选框变得混乱

Javafx2.2:滚动表格时表格视图中的复选框变得混乱
EN

Stack Overflow用户
提问于 2014-11-19 11:05:52
回答 2查看 816关注 0票数 1

使用表视图附带的垂直滚动条时会出现此问题。下面是我的表视图:

http://i.stack.imgur.com/w7Wv3.png

当你用鼠标滚轮滚动时,这是很好的。当您滚动滚动条上的向上/向下箭头时,这是很好的。但是当你实际使用鼠标指针拖动滚动条时,复选框中的选择就会变得混乱。例如,如果您看到上面链接的图像,则会选中第三个复选框。滚动后,可能会选中第五个复选框或第二个复选框。或者甚至可以选择另外两个校验码。

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

解决这个问题的正确方法是截取垂直滚动事件,并在用户滚动时手动刷新网格。为此,我需要能够在表的滚动条上获得一个句柄。类似于table.getScrollBar().setEventHandler(this)。我无法做到这一点。表的滚动条似乎是隐藏的。如果我不能到达滚动条,我就不能截取滚动事件,我也不能解决这个问题。

下面是我的fxml:

代码语言:javascript
复制
<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>

下面是控制器中的相关java代码:

代码语言:javascript
复制
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();
    }
});

这是PriceCell.java的样子:

代码语言:javascript
复制
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);
    }
}
}

谢谢。任何帮助都是非常感谢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-19 20:35:41

不知何故,你的模型没有很好地联系起来。

PriceCell试图在一个单独的列中混合两个不同的内容:复选框的布尔值,它的状态在单元格呈现时不被存储或处理,哪个has no field in产品`,以及一个与检查状态无关的字符串。因此,当用户单击检查时,标签不会受到影响。

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

已经有一个带有复选框的TableCell实现:CheckBoxTableCell。但它只接受Boolean作为参数,因为它只需要知道状态(选中或未选中)。您可以为标签添加一些StringConverter,但这只与所选状态相关。

为了解决这个问题,我的建议是:

首先,在Product中创建一个新字段

代码语言:javascript
复制
private final BooleanProperty purchase = new SimpleBooleanProperty();

public boolean isPurchase() {
    return purchase.get();
}

public void setPurchase(boolean value) {
    purchase.set(value);
}

public BooleanProperty purchaseProperty() {
    return purchase;
}

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

代码语言:javascript
复制
@Override
public String toString() {
    if(isPurchase()){
        return forPurchaseImmediateCountAndPrice.get("count") + " ($" + forPurchaseImmediateCountAndPrice.get("price") + ")";
    }
    return "0";
}

在控制器中:

代码语言:javascript
复制
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

代码语言:javascript
复制
public class PriceCell extends TableCell<Product, Boolean> {
    private final CheckBox box = new CheckBox();

    public PriceCell(){
        box.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent e) {
                getTableView().getItems().get(getIndex()).setPurchase(box.isSelected());
            }
        });
    }

    @Override
    protected void updateItem(Boolean item, boolean empty) {
        super.updateItem(item, empty);

        if(!empty){
            box.setSelected(item);
            setText(getTableView().getItems().get(getIndex()).toString());
            setGraphic(box);
        }
        else {
            setText(null);
            setGraphic(null);
        }
    }
}

有了这个,你应该不会再有滚动的问题了。

票数 0
EN

Stack Overflow用户

发布于 2018-06-01 06:17:59

您可以在更新chekBox单元格值后清除tableView并重置所有项目: table.getItems().clear();table.setItems(getTbleInfo());

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27008237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档