将展开动画添加到TreeView

时间:2013-12-23 14:48:08

标签: javafx javafx-2 javafx-8

我有TreeView的这个例子:

enter image description here

import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;

public class MainApp extends Application
{

    //private final Node rootIcon = new ImageView(new Image(getClass().getResourceAsStream("picture.png")));
    //private final Image depIcon = new Image(getClass().getResourceAsStream("picture.png"));
    List<Employee> employees = Arrays.<Employee>asList(
        new Employee("Ethan Williams", "Sales Department"),
        new Employee("Emma Jones", "Sales Department"),
        new Employee("Michael Brown", "Sales Department"),
        new Employee("Anna Black", "Sales Department"),
        new Employee("Rodger York", "Sales Department"),
        new Employee("Susan Collins", "Sales Department"),
        new Employee("Mike Graham", "IT Support"),
        new Employee("Judy Mayer", "IT Support"),
        new Employee("Gregory Smith", "IT Support"),
        new Employee("Jacob Smith", "Accounts Department"),
        new Employee("Isabella Johnson", "Accounts Department"));
    TreeItem<String> rootNode = new TreeItem<>("MyCompany Human Resources");//, rootIcon);    // Set picture

    public static void main(String[] args)
    {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage)
    {
        rootNode.setExpanded(true);
        for (Employee employee : employees)
        {
            TreeItem<String> empLeaf = new TreeItem<>(employee.getName());
            boolean found = false;
            for (TreeItem<String> depNode : rootNode.getChildren())
            {
                if (depNode.getValue().contentEquals(employee.getDepartment()))
                {
                    depNode.getChildren().add(empLeaf);
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                TreeItem<String> depNode = new TreeItem<>(
                    employee.getDepartment()//,new ImageView(depIcon)   // Set picture
                );
                rootNode.getChildren().add(depNode);
                depNode.getChildren().add(empLeaf);
            }
        }

        stage.setTitle("Tree View Sample");
        VBox box = new VBox();
        final Scene scene = new Scene(box, 400, 300);
        scene.setFill(Color.LIGHTGRAY);

        TreeView<String> treeView = new TreeView<>(rootNode);
        //treeView.setEditable(true);
        treeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>()
        {
            @Override
            public TreeCell<String> call(TreeView<String> p)
            {
                return new TextFieldTreeCellImpl();
            }
        });

        box.getChildren().add(treeView);
        stage.setScene(scene);
        stage.show();
    }

    private final class TextFieldTreeCellImpl extends TreeCell<String>
    {

        private TextField textField;

        public TextFieldTreeCellImpl()
        {
        }

        @Override
        public void startEdit()
        {
            super.startEdit();

            if (textField == null)
            {
                createTextField();
            }
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        }

        @Override
        public void cancelEdit()
        {
            super.cancelEdit();
            setText((String) getItem());
            setGraphic(getTreeItem().getGraphic());
        }

        @Override
        public void updateItem(String item, boolean empty)
        {
            super.updateItem(item, empty);

            if (empty)
            {
                setText(null);
                setGraphic(null);
            }
            else
            {
                if (isEditing())
                {
                    if (textField != null)
                    {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                }
                else
                {
                    setText(getString());
                    setGraphic(getTreeItem().getGraphic());
                }
            }
        }

        private void createTextField()
        {
            textField = new TextField(getString());
            textField.setOnKeyReleased(new EventHandler<KeyEvent>()
            {

                @Override
                public void handle(KeyEvent t)
                {
                    if (t.getCode() == KeyCode.ENTER)
                    {
                        commitEdit(textField.getText());
                    }
                    else if (t.getCode() == KeyCode.ESCAPE)
                    {
                        cancelEdit();
                    }
                }
            });
        }

        private String getString()
        {
            return getItem() == null ? "" : getItem().toString();
        }
    }

    public static class Employee
    {

        private final SimpleStringProperty name;
        private final SimpleStringProperty department;

        private Employee(String name, String department)
        {
            this.name = new SimpleStringProperty(name);
            this.department = new SimpleStringProperty(department);
        }

        public String getName()
        {
            return name.get();
        }

        public void setName(String fName)
        {
            name.set(fName);
        }

        public String getDepartment()
        {
            return department.get();
        }

        public void setDepartment(String fName)
        {
            department.set(fName);
        }
    }
}

我想在展开树时添加动画。如何做到这一点?

1 个答案:

答案 0 :(得分:0)

看看我找到的在线搜索。在谷歌搜索“javafx TreeView动画”后,我发现它here

好的,所以在花了一些时间检查代码后,我推断出代码的重要部分是:

rootItem.expandedProperty().addListener(new ChangeListener<Boolean>() {
    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
        new Timeline(
            new KeyFrame(Duration.seconds(0), new KeyValue(tree.opacityProperty(), 0)),
            new KeyFrame(Duration.seconds(1), new KeyValue(tree.opacityProperty(), 1.0))
        ).play();
    }
});

此代码添加一个侦听器,触发每次rootItem.expandedProperty()更改时执行所需动画的代码,即用户展开或折叠树。

每当某些内容导致expandedProperty发生变化时,它会构造一个新的Timeline对象,我假设该对象代表特定动画中的实际步骤。当前代码正在修改树的不透明度,导致rootItem的子树在1秒内“淡入”。

要实现关闭树的单独动画,可以在侦听器中使用changed的方法参数来区分这两种情况。

为了使每个子树都能进行这样的动画,需要将这样的监听器添加到树中具有子节点的每个节点。枚举树的所有元素是您在学习数据结构时学到的一项非常基本的操作,因此我不需要详细了解如何实现这一点。

但是,如果淡入动画对您的应用程序来说不够好,那么我建议使用嵌套手风琴,如this question does。从您提供的示例项目中,手风琴将是一种更好的方式来显示员工列表。