javafx:setRowFactory中的多个事件,并结合匿名内部类和lambda表达式
我有两组更改表行外观的事件javafx:setRowFactory中的多个事件,并结合匿名内部类和lambda表达式,java,javafx,Java,Javafx,我有两组更改表行外观的事件 表在某些条件闪烁时闪烁 添加新项时突出显示的表 假设我的TableView被称为table,我的代码结构如下: TableView<Trade> table = ... ; table.setRowFactory( private final BooleanBinding itemIsNewTrade = Bindings.isNotNull(itemProperty()).and(Bindings.equal(itemPropert
TableView
被称为table
,我的代码结构如下:
TableView<Trade> table = ... ;
table.setRowFactory( private final BooleanBinding itemIsNewTrade = Bindings.isNotNull(itemProperty()).and(Bindings.equal(itemProperty(), recentlyAddedTrade));
{
// anonymous constructor:
itemIsNewTrade.addListener((obs, wasNew, isNew) -> pseudoClassStateChanged(newTradePseudoClass, isNew));
}
tv -> {
TableRow<Trade> row = new TableRow<>();
Timeline flasher = new Timeline(
new KeyFrame(Duration.seconds(0.5), e -> {
row.pseudoClassStateChanged(flashHighlight, true);
}),
new KeyFrame(Duration.seconds(1.0), e -> {
row.pseudoClassStateChanged(flashHighlight, false);
})
);
flasher.setCycleCount(Animation.INDEFINITE);
ChangeListener<Boolean> cautionListener = (obs, cautionWasSet, cautionIsNowSet) -> {
if (cautionIsNowSet) {
flasher.play();
} else {
flasher.stop();
row.pseudoClassStateChanged(flashHighlight, false);
}
};
row.itemProperty().addListener((obs, oldItem, newItem) -> {
if (oldItem != null) {
oldItem.cautionProperty().removeListener(cautionListener);
}
if (newItem == null) {
flasher.stop();
row.pseudoClassStateChanged(flashHighlight, false);
} else {
newItem.cautionProperty().addListener(cautionListener);
if (newItem.cautionProperty().get()) {
flasher.play();
} else {
flasher.stop();
row.pseudoClassStateChanged(flashHighlight, false);
}
}
});
return row ;
}
);
TableView表=;
table.setRowFactory(私有最终BooleanBinding itemIsNewTrade=Bindings.isNotNull(itemProperty())和(Bindings.equal(itemProperty(),recentlyAddedTrade));
{
//匿名构造函数:
addListener((obs,wasNew,isNew)->pseudoClassStateChanged(newTradePseudoClass,isNew));
}
电视->{
TableRow行=新TableRow();
时间线闪光器=新时间线(
新关键帧(持续时间。秒(0.5),e->{
pseudoClassStateChanged(flashHighlight,true);
}),
新关键帧(持续时间。秒(1.0),e->{
row.pseudoClassStateChanged(flashHighlight,false);
})
);
闪光器。设置循环计数(动画。不确定);
ChangeListener cautionListener=(obs、cautionWasSet、cautionIsNowSet)->{
如果(注意事项现在已设置){
闪光器播放();
}否则{
闪光器停止();
row.pseudoClassStateChanged(flashHighlight,false);
}
};
row.itemProperty().addListener((obs、oldItem、newItem)->{
if(oldItem!=null){
oldItem.cautionProperty().RemovelListener(cautionListener);
}
if(newItem==null){
闪光器停止();
row.pseudoClassStateChanged(flashHighlight,false);
}否则{
newItem.cautionProperty().addListener(cautionListener);
if(newItem.cautionProperty().get()){
闪光器播放();
}否则{
闪光器停止();
row.pseudoClassStateChanged(flashHighlight,false);
}
}
});
返回行;
}
);
更新:
表格闪烁的代码来自,而表格高亮显示的代码来自。我试图通过上面的结构将两者结合起来
但是我犯了一个错误。我只是不知道如何将匿名内部类和lambda表达式组合在一起
如何克服这个问题?最好的方法是创建一个单独的
TableRow
类,而不是一个匿名的内部类
我在下面创建了一个示例实现
值得一提的是:
表格行
定义样式。表格行单元格:new
表格行
(s)定义样式。表格行单元格:flash
ObjectExpression
)最近添加的项存储在何处,在您的情况下可能是recentlyAddedTrade
函数
)如何提取确定闪烁状态的属性。在您的情况下,它应该是Trade::cautionProperty
public static class AnimatedTableRow<T> extends TableRow<T> {
private static final PseudoClass PS_NEW = PseudoClass.getPseudoClass("new");
private static final PseudoClass PS_FLASH = PseudoClass.getPseudoClass("flash");
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 AnimatedTableRow(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();
} else {
flashTimeline.stop();
pseudoClassStateChanged(PS_FLASH, false);
}
}
private void recentItemChanged() {
final T tmpRecentItem = recentItem.get();
pseudoClassStateChanged(PS_NEW, tmpRecentItem != null && tmpRecentItem == getItem());
}
@Override
protected void updateItem(T item, boolean empty) {
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();
}
}
公共静态类AnimatedTableRow扩展了TableRow{
私有静态最终伪类PS_NEW=PseudoClass.getPseudoClass(“新”);
私有静态最终伪类PS_FLASH=PseudoClass.getPseudoClass(“FLASH”);
私人最终目的表达最近;
私有最终失效监听器recentlyAddedListener=fObs->recentItemChanged();
专用最终函数闪光器;
私有最终ChangeListener flashListener=(fObs、fOld、fNew)->FlashrChanged(fNew);
私人最终时间表;
public AnimatedTableRow(ObjectExpression fRecentlyAddedProperty,
函数(提取程序){
recentItem=fRecentlyAddedProperty;
addListener(新的WeakInvalizationListener(recentlyAddedListener));
闪蒸萃取器=闪蒸萃取器;
flashTimeline=新的时间线(
新关键帧(持续时间.秒(0.5),e->pseudoClassStateChanged(PS_FLASH,true)),
新的关键帧(Duration.seconds(1.0),e->pseudoClassStateChanged(PS_FLASH,false));
flashTimeline.setCycleCount(Animation.unfinite);
}
私有void flashrChanged(布尔fNew){
如果(fNew){
flashTimeline.play();
}否则{
flashTimeline.stop();
pseudoClassStateChanged(PS_闪存,false);
}
}
私有void recentItemChanged(){
final T tmpRecentItem=recentItem.get();
pseudoClassStateChanged(PS_NEW,tmpRecentItem!=null&&tmpRecentItem==getItem());
}
@凌驾
受保护的void updateItem(T项,布尔值为空){
如果(getItem()!=null){
最终布尔表达式be=flashxtractor.apply(getItem());
如果(be!=null){
be.RemovelListener(flashListener);
}
}
super.updateItem(项,空);
如果(getItem()!=null){
最终布尔表达式be=flashxtractor.apply(getItem());
如果(be!=null){
be.addListener(flashListener);
flashrChanged(be.get());
}
}
recentItemChanged();
}
}
用法:
table.setRowFactory(tableView -> new AnimatedTableRow<>(recentlyAddedPerson, Person::flashProperty));
table.setRowFactory(tableView->new AnimatedTableRow(最近添加的Person,Person::flashProperty));
在setRowFactory()中如何调用这个类