我有以下 setRowFactory
类。我不将其编写为匿名类的原因是因为我在该类中有多个函数,并且我希望该类可重用。其功能是:
- 在 TableView 中突出显示最近添加的交易对象(整行)
- 当价格属性大于 0 时,“价格”单元格会闪烁,此时警告属性变为 true。
公开课贸易{
private ReadOnlyBooleanWrapper caution;
...
// with constructor there is
public Trade(){
...
this.caution = new ReadOnlyBooleanWrapper();
this.caution.bind(this.price.greaterThan(0));
}
...
}
这很好用。当我从 TableView 中删除 Trade 对象时,出现问题。空行继续闪烁,这显然意味着代码没有监视 TableView 的当前状态。
我对 javafx 还很陌生,我认为我缺少 addListener
代码来跟踪 tableView 中所有行的当前状态(如果我错了,请纠正我。)我不知道如何写出来。
代码:
public class AnimatedTransactionLogTableRow<T> extends TableRow<T> {
private static final PseudoClass PS_NEW = PseudoClass.getPseudoClass("new-row");
private static final PseudoClass PS_FLASH = PseudoClass.getPseudoClass("flash-row");
private static final PseudoClass PS_CF = PseudoClass.getPseudoClass("cell-positive");
private final ObjectExpression<T> recentItem;
private final InvalidationListener recentlyAddedListener = fObs -> recentItemChanged();
private final Function<T, BooleanExpression> flashExtractor;
private final ChangeListener<Boolean> flashListener = (fObs, fOld, fNew) -> flasherChanged(fNew);
private final Timeline flashTimeline;
public AnimatedTransactionLogTableRow(ObjectExpression<T> fRecentlyAddedProperty
,Function<T, BooleanExpression> fFlashExtractor
) {
recentItem = fRecentlyAddedProperty;
recentItem.addListener(new WeakInvalidationListener(recentlyAddedListener));
flashExtractor = fFlashExtractor;
flashTimeline = new Timeline(
new KeyFrame(Duration.seconds(0.5), e -> pseudoClassStateChanged(PS_FLASH, true)),
new KeyFrame(Duration.seconds(1.0), e -> pseudoClassStateChanged(PS_FLASH, false)));
flashTimeline.setCycleCount(Animation.INDEFINITE);
}
private void flasherChanged(boolean fNew) {
if (fNew) {
flashTimeline.play();
pseudoClassStateChanged(PS_CF,true);
} else {
flashTimeline.stop();
pseudoClassStateChanged(PS_FLASH, false);
pseudoClassStateChanged(PS_CF,false);
}
}
private void recentItemChanged() {
final T tmpRecentItem = recentItem.get();
pseudoClassStateChanged(PS_NEW, tmpRecentItem != null && tmpRecentItem == getItem());
}
@Override
protected void updateItem(T item, boolean empty) {
System.out.println("getItem(): " + getItem());
if (getItem() != null) {
final BooleanExpression be = flashExtractor.apply(getItem());
if (be != null) {
be.removeListener(flashListener);
}
}
super.updateItem(item, empty);
if (getItem() != null) {
final BooleanExpression be = flashExtractor.apply(getItem());
if (be != null) {
be.addListener(flashListener);
flasherChanged(be.get());
}
}
recentItemChanged();
}
}
最佳答案
我想如果 TableRow
为空,您需要调用 flasherChanged(false);
。
例如:
@Override
protected void updateItem(T item, boolean empty) {
System.out.println("getItem(): " + getItem());
if (getItem() != null) {
final BooleanExpression be = flashExtractor.apply(getItem());
if (be != null) {
be.removeListener(flashListener);
}
}
super.updateItem(item, empty);
if(empty) {
flasherChanged(false);
}
else if (getItem() != null) {
final BooleanExpression be = flashExtractor.apply(getItem());
if (be != null) {
be.addListener(flashListener);
flasherChanged(be.get());
}
}
recentItemChanged();
}
关于javafx:setRowFactory无法检测TableView的当前状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32381754/