如何制作一个动画“近距离”的VBox?

时间:2012-12-21 12:58:13

标签: animation javafx-2

我已经构建了一个在VBox内有VBox的表单。我想让内部的VBox“从底部到顶部过渡”。

之后,外部VBox的下一个元素应该向上移动以填充空白区域,就像从VBox中删除项目一样。

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

您可以尝试下一种方法:在动画期间使用剪辑隐藏“消失”内容并控制内部VBox的高度:

public class ShrinkingVBox extends Application {

    private static class SmartVBox extends Region {

        private Rectangle clipRect = new Rectangle();
        private VBox content = new VBox();

        public SmartVBox() {
            setClip(clipRect);
            getChildren().add(content);
        }

        // we need next methods to adjust our clipping to inner vbox content
        @Override
        protected void setWidth(double value) {
            super.setWidth(value);
            clipRect.setWidth(value);
        }

        @Override
        protected void setHeight(double value) {
            super.setHeight(value);
            clipRect.setHeight(value);
        }

        // here we will do all animation
        public void closeup() {
            setMaxHeight(getHeight());
            // animation hides content by moving it out of clipped area
            // and reduces control height simultaneously
            Timeline animation = TimelineBuilder.create().cycleCount(1).keyFrames(
                new KeyFrame(Duration.seconds(1),
                    new KeyValue(content.translateYProperty(), -getHeight()),
                    new KeyValue(maxHeightProperty(), 0))).build();
            animation.play();

        }

        protected ObservableList<Node> getContent() {
            return content.getChildren();
        }
    }

    @Override
    public void start(Stage primaryStage) {
        VBox outer = new VBox();
        final SmartVBox inner = new SmartVBox();

        //some random content for inner vbox
        inner.getContent().addAll(
                CircleBuilder.create().radius(25).fill(Color.YELLOW).build(),
                CircleBuilder.create().radius(25).fill(Color.PINK).build());

        // content for outer vbox, including inner vbox and button to run animation
        outer.getChildren().addAll(
                RectangleBuilder.create().width(50).height(50).fill(Color.GRAY).build(),
                inner,
                RectangleBuilder.create().width(50).height(50).fill(Color.RED).build(),
                RectangleBuilder.create().width(50).height(50).fill(Color.BLUE).build(),
                ButtonBuilder.create().text("go").onAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent t) {
                        inner.closeup();
                    }
                }).build());

        primaryStage.setScene(new Scene(new Group(outer)));
        primaryStage.show();
    }

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