我的TableView包含一些数字数据。当我按“按钮”编辑值时,它会将单元格的背景更改为绿色。当没有足够的行来使表可滚动时,这很有效。一旦表变为(或从开始)可滚动,它就开始变得怪异。它会更改已编辑项目的背景,但它会在您向下滚动之前看不到它。但是,当我调试时,更改背景的代码只调用一次。我认为当可滚动破坏并重新创建单元格时,它必须对该tableview执行某些操作,或者我可能误解了某些内容并且我做错了。
当我向下滚动一点点时,这个也有不同的背景。 (他们都有同一时间)
代码: 型号类:
public class Bid {
private DoubleProperty value;
private BooleanProperty valueChanged;
public Bid(double val) {
value = new SimpleDoubleProperty();
valueChanged = new SimpleBooleanProperty();
setValue(val);
value.addListener((observable, old, newVal) -> {
System.out
.println(observable.toString() + " changed value from " + old.doubleValue() + " to " + newVal.doubleValue());
valueChanged.setValue(true);
});
}
public double getValue() {
return value.get();
}
public void setValue(double value) {
this.value.set(value);
}
public DoubleProperty valueProperty() {
return value;
}
public boolean isValueChanged() {
return valueChanged.get();
}
public BooleanProperty valueChangedProperty() {
return valueChanged;
}
public void setValueChanged(boolean valueChanged) {
this.valueChanged.set(valueChanged);
}
@Override
public String toString() {
return "Bid{" +
"value=" + value.getValue() +
'}';
}
}
我的手机(当我第一次遇到这个问题时,我认为它是去除部分的风格,但删除它并没有帮助):
public class BidCell extends TextFieldTableCell<Bid, Double> {
private BooleanProperty newExternalValue;
public BidCell() {
super(new StringConverter<Double>() { // converter used for conversion from/to string
@Override
public String toString(Double object) {
return object.toString();
}
@Override
public Double fromString(String string) {
return Double.valueOf(string);
}
});
newExternalValue = new SimpleBooleanProperty();
newExternalValue.addListener((observable, oldValue, newValue) ->
{
if (newValue) {
String old = this.getStyle();
this.setStyle("-fx-background-color: #99ff99");
System.out.println("Color changed");
Thread thread = new Thread(new StyleRemover(this, old, newExternalValue));
thread.setDaemon(true);
thread.start();
}
});
}
@Override
public void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (getTableRow() != null) {
if (getTableRow().getItem() != null) {
if (item != null && !empty) {
Bid b = getTableRow().getItem() instanceof Bid ? ((Bid) getTableRow().getItem()) : null;
if (b != null) {
if (b.isValueChanged()) {
System.out.println("Setting newExternalValue to true for cell" + this);
newExternalValue.setValue(true);
b.setValueChanged(false);
}
}
}
}
}
}
class StyleRemover implements Runnable {
private BidCell cell;
private String oldStyle;
BooleanProperty newExternalValue;
public StyleRemover(BidCell cell, String oldStyle, BooleanProperty newExternalValue) {
this.cell = cell;
this.oldStyle = oldStyle;
this.newExternalValue = newExternalValue;
}
@Override
public void run() {
try {
Thread.sleep(3000);
cell.setStyle(oldStyle);
newExternalValue.setValue(false);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
网格:
public class Grid {
private TableView<Bid> view;
private TableColumn<Bid, Double> bidStringTableColumn;
ObservableList<Bid> bids;
public TableView<Bid> getView() {
return view;
}
public Grid() {
view = new TableView<>(); // create tableview
bids = FXCollections.observableArrayList(); // fill data for it
bids.addListener((ListChangeListener<Bid>) c -> {
c.next();
if (c.wasAdded()) {
System.out.println("added new value " + c.getAddedSubList().get(0).toString());
}
});
for (double i = 0; i < 10; i += 0.45) {
Bid e = new Bid(i);
bids.add(e);
}
view.setItems(bids);
view.setEditable(true);
bidStringTableColumn = new TableColumn<>("Bid"); // create column with header text "Bid"
bidStringTableColumn.setCellValueFactory(param -> param.getValue().valueProperty()
.asObject()); // value factory for column, determines which property will fill column
bidStringTableColumn.setCellFactory(e -> new BidCell());
view.getColumns().add(bidStringTableColumn); // add column to table
}
public ObservableList<Bid> getBids() {
return bids;
}
编辑:这不仅仅是关于样式,我发现如果我开始编辑那个单元格并向下滚动,那么它也处于编辑模式。一种可能的解决方案可能是以某种方式禁用细胞破坏和重新创建滚动,但我还没有找到一种方法如何做到这一点,我不认为它甚至是可能的。 (我知道这是为了表现,但性能对我们来说并不重要,并且不会有数百万行,最多只有100行)
答案 0 :(得分:0)
我花了一些时间,但我解决了它。 最重要的是这句话
“tableview和listview单元格被重用以呈现不同的行 来源清单的数据。“
这基本上意味着您无法将样式设置为单元格,因为滚动时它用于不同的数据。那是我的错。
最简单的解决方案是将样式存储在模型(Bid)类中,然后在单元格中从那里获取它。 在单元格中制作方法
updateItem
我在updateIndex
和 newExternalValue.addListener((observable, oldValue, newValue) ->
{
checkStyle();
});
以及
sendKeys