使用表视图附带的垂直滚动条时会发生此问题。这就是我的表格视图:
http://i.stack.imgur.com/w7Wv3.png
使用鼠标滚轮滚动时,没问题。当您使用滚动条上的向上/向下箭头滚动时,它很好。但是,当您实际使用鼠标指针拖动滚动条时,复选框中的选择会搞砸。例如,如果您看到上面链接的图像,则选中第三个复选框。滚动后,现在可以选择第5个复选框或第2个复选框。或者甚至可以选择另外两个检查。
我认为这是表格视图滚动条的刷新/重绘问题。
解决此问题的正确方法是拦截垂直滚动事件,并在用户滚动时手动刷新网格。要做到这一点,我需要能够处理表格的滚动条。像table.getScrollBar()。setEventHandler(this)之类的东西。我无法做到这一点。表格的滚动条似乎是隐藏的。如果我无法进入滚动条,我无法拦截滚动事件,我无法解决此问题。
这是我的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>
以下是来自控制器的相关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();
}
});
这就是PriceCell.java的样子:
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);
}
}
}
感谢。任何帮助表示赞赏。
答案 0 :(得分:0)
不知何故,你的模型连接不好......
PriceCell
试图在一个列中混合两个不同的内容:复选框的布尔值,在呈现单元格时不存储或处理其状态,以及has no field in
Product`,和一个字符串,与检查状态无关。因此,当用户点击支票时,标签不会受到影响。
虽然渲染看起来是正确的,但当您使用鼠标滚动时,checkbok状态将丢失,并且没有回调可以正确找到它。
已经有一个TableCell的实现,其中包含一个复选框:CheckBoxTableCell
。但它只需要Boolean
作为参数,因为它只需要知道状态(选择与否)。您可以为标签添加一些StringConverter
,但这仅与所选状态相关。
要解决此问题,我的建议是:
首先,在Product
中创建一个新字段:
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;
}
添加一个合适的字符串格式化程序:
@Override
public String toString() {
if(isPurchase()){
return forPurchaseImmediateCountAndPrice.get("count") + " ($" + forPurchaseImmediateCountAndPrice.get("price") + ")";
}
return "0";
}
在控制器中:
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
:
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);
}
}
}
有了这个,你不应该再有滚动问题了。
答案 1 :(得分:0)
您可以在更新chekBox单元格值后清除tableView并重新重置项目: 。table.getItems()清除(); table.setItems(getTbleInfo());