Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javafx:setRowFactory中的多个事件,并结合匿名内部类和lambda表达式_Java_Javafx - Fatal编程技术网

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
    类,而不是一个匿名的内部类

    我在下面创建了一个示例实现

    值得一提的是:

  • 您需要在CSS文件中为新添加的
    表格行
    定义样式
    。表格行单元格:new
  • 您需要在CSS文件中为当前正在闪烁的
    表格行
    (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()中如何调用这个类