我的 TableView 包含一些数字数据。当我说通过按钮编辑值时,它将单元格的背景更改为绿色。当没有足够的行使表可滚动时,这种方法很有效。一旦表格变得(或从一开始)可滚动,它就会开始表现得很奇怪。它会更改已编辑项目的背景,但它会更改在向下滚动之前不可见的项目的背景。但是,当我调试时,更改背景的代码仅被调用一次。我认为当可滚动破坏并重新创建单元格时,它必须对表格视图做一些事情,或者也许我误解了某些东西并且我做错了。
Example:
I've edited second row.
And when I scrolled down just a little bit, this one had different background as well. (they both have it same time)
代码:
型号类别:
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();
}
}
}
Grid:
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 行)