通过javafx中的自定义单元工厂淡入淡出过渡 [英] Fade Transition via custom cell factory in javafx

查看:54
本文介绍了通过javafx中的自定义单元工厂淡入淡出过渡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在javafx中使用自定义单元格工厂来根据警报状态(当前时间和检查时间为基础)对单元格进行样式设置.

I am using a custom cell factory in javafx to style cells based on an alert status, which is based upon the time now and a check time.

一切正常,但我还想添加一个淡入淡出过渡或其他方式,这将使这些行基本闪烁,直到通过更改检查时间将其确认为止.

Everything works correctly, but I also want to add in a fade transition, or something else, that will make the rows essentially blink until it is acknowledged by changing of the checktime.

这比我想添加的代码复杂得多,所以我将发布单元工厂类

It is a little more complex than I think I could add a lot of code for, so I will post my cell factory class

public class FormattedTableCellFactory<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {
    private TableCell<S, T> cell = null;
    private FadeTransition ft;

    public FormattedTableCellFactory() {
    }

    @Override
    public TableCell<S, T> call(TableColumn<S, T> p) {
        cell = new TableCell<S, T>() {
            @Override
            protected void updateItem(Object item, boolean empty) {
                super.updateItem((T) item, empty);

                // CSS Styles
                String cssStyle;

                Person person = null;

                if(getTableRow() != null ) {
                    person = (Person) getTableRow().getItem();
                }

                ft = new FadeTransition(Duration.millis(500), cell);
                ft.setFromValue(1.0);
                ft.setToValue(0.1);
                ft.setCycleCount(Timeline.INDEFINITE);
                ft.setAutoReverse(true);
                //Remove all previously assigned CSS styles from the cell.



                //Determine how to format the cell based on the status of the container.

                if(person != null){
                    switch(PersonAlert.getAlert(person)){
                        case WARNING:
                            ft.stop();
                            cssStyle = "warning";
                            break;
                        case PAST_DUE:
                            ft.stop();
                            cssStyle = "pastdue";
                            break;
                        case ERC_PAST_DUE:
                            ft.stop();
                            cssStyle = "ercpastdue";
                            break;
                        case OVERDUE:
                            ft.playFromStart();
                            cssStyle = "overdue";
                            break;
                        case OVERNIGHT:
                            ft.stop();
                            cssStyle = "overnight";
                            break;
                        default:
                            ft.stop();
                            cssStyle = "normal";
                            break;
                    }
                }else{
                    ft.stop();
                    setText("");
                    return;
                }

                //Set the CSS style on the cell and set the cell's text.
                getStyleClass().setAll(cssStyle);
                if(item != null) {
                    setText(item.toString());
                }else{
                    setText("");
                }
            }
        };
        return cell;
    }
}

此代码正确运行,只要有人处于特定状态,单元格的颜色就会适当更改.唯一的问题是淡入淡出过渡,无论何时第一次运行,淡入淡出过渡都可以正常运行,但是当它更改为其他样式时,它不会停止并且会一直闪烁.

This code works correctly, whenever the person has a certain status, the colors of the cells will change appropriately. The only issue here is the fade transition, whenever it is first run, the fade transition runs fine, but when it changes to a different style, it does not stop and keeps blinking.

我无法使渐变过渡停止.我相信这是因为每次调用此updateItem时,它都会创建我的淡入淡出过渡的新实例,因此,当它调用stop时,它是在当前过渡而不是前一个过渡上调用它.我试图通过在顶部初始化转换来消除这种情况,但随后它甚至都不会闪烁.

I can not get the fade transition to stop. I believe this is because each time this updateItem is called, it creates a new instance of my fade transition, thus when it calls stop, it is calling it on the current transition and not a previous one. I have tried to eliminate this by initializing the transition at the top, but then it won't even blink.

所以我的问题是,当调用stop时,我该如何编辑它以使淡入淡出过渡停止,或者是否有其他方法可以使用单元格工厂使单元格/行闪烁"?

So my question is, how could I edit this to make fade transition stop when stop is called, OR is there a different way to make a cell/row "blink" using a cell factory?

推荐答案

您在错误的级别上确定范围.

You're scoping things at the wrong level.

每个单元格应具有一个淡入淡出过渡.当前,您每次 在单元格上创建一个新的淡入淡出过渡.您将为整个工厂保留一个参考(无论创建多少个像元,都只有一个参考),它将仅参考最近创建的淡入淡出过渡.

Each cell should have one fade transition. Currently you create a new fade transition every time updateItem() is invoked on a cell. You keep a single reference for the entire factory (just one reference, no matter how many cells are created), which will only refer to the most recently created fade transition.

尽管出于某种原因,您同样会在工厂中保留对最近创建的单元格的引用,尽管(也许感激)您从未真正使用过它.

You similarly retain a reference in the factory to the most recently created cell, for some reason, though (probably thankfully) you never actually use it.

还有两点需要注意:调用getStyleClass().setAll(...)并不是一个好主意,因为这会从单元格中删除所有默认样式类(例如.table-cell),这可能会删除所有默认样式处理.样式类由于以列表的形式实现,因此处理起来有些麻烦,但是您应该显式删除所有不需要的样式类,并确保不要添加重复的样式类(除非您确实打算这样做).另外,您假设(通过强制转换)表视图的类型为Person,因此使行类型通用没有任何意义.

A couple of other things to note: it's not a good idea to call getStyleClass().setAll(...) as this will remove all the default style classes from the cell (such as .table-cell), which may have the effect of removing all the default style handling. Style classes are a bit of a pain to deal with, as they are implemented as lists, but you should remove all occurrences of the ones you don't want explicitly, and ensure that you don't add duplicates of ones you do want (unless you really intend to do that). Also, you're assuming (by casting) that the type for the table view is Person, so there's no point in making the row type generic.

因此,虽然您没有提供任何可用来测试的代码,但由于无法进行测试,您可能需要遵循以下原则:

So, while it's impossible for me to test as you didn't provide any code to test with, you probably want something along these lines:

import java.util.Arrays;
import java.util.List;

import javafx.animation.FadeTransition;
import javafx.animation.Timeline;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.util.Callback;
import javafx.util.Duration;

public class FormattedTableCellFactory<T> implements Callback<TableColumn<Person, T>, TableCell<Person, T>> {

    private static final List<String> ALL_STYLES = Arrays.asList(
        "warning", "pastdue", "ercpastdue", "overnight", "normal"
    );

    @Override
    public TableCell<Person, T> call(TableColumn<Person, T> p) {
        TableCell<Person, T> cell = new TableCell<Person, T>() {

            private FadeTransition ft ;

            {
                ft = new FadeTransition(Duration.millis(500), this);
                ft.setFromValue(1.0);   
                ft.setToValue(0.1);   
                ft.setCycleCount(Timeline.INDEFINITE);   
                ft.setAutoReverse(true);  
            }

            @Override
            protected void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);

                // CSS Styles
                String cssStyle = "";

                Person person = null;

                if(! isEmpty() ) {
                    // avoid casting here, if you prefer:
                    person = getTableView().getItems().get(getIndex());
                }

                //Remove all previously assigned CSS styles from the cell.

                getStyleClass().removeAll(ALL_STYLES);


                //Determine how to format the cell based on the status of the container.

                if(person != null){
                    switch(PersonAlert.getAlert(person)){
                        case WARNING:
                            ft.stop();
                            setOpacity(1.0);
                            cssStyle = "warning";
                            break;
                        case PAST_DUE:
                            ft.stop();
                            setOpacity(1.0);
                            cssStyle = "pastdue";
                            break;
                        case ERC_PAST_DUE:
                            ft.stop();
                            setOpacity(1.0);
                            cssStyle = "ercpastdue";
                            break;
                        case OVERDUE:
                            ft.playFromStart();
                            cssStyle = "overdue";
                            break;
                        case OVERNIGHT:
                            ft.stop();
                            setOpacity(1.0);
                            cssStyle = "overnight";
                            break;
                        default:
                            ft.stop();
                            setOpacity(1.0);
                            cssStyle = "normal";
                            break;
                    }
                }else{
                    ft.stop();
                    setOpacity(1.0);
                    setText("");
                }

                //Set the CSS style on the cell and set the cell's text.
                if(item != null) {
                    getStyleClass().add(cssStyle);
                    setText(item.toString());
                }else{
                    setText("");
                }
            }
        };
        return cell;
    }


}

这篇关于通过javafx中的自定义单元工厂淡入淡出过渡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆