添加或删除子项时动画VBox调整大小

时间:2014-06-18 18:36:34

标签: java javafx javafx-8

我最近开始玩JavaFX :)我正在开展一个小型宠物项目,我目前正在解决的一个问题是当孩子出现时调整VBox的大小。添加到VBox或从VBox中删除。

我有孩子"淡出然后从VBox中删除。一旦动画完成,我需要VBox高度调整大小,最好是动画,而不是像当前的瞬间更改。

我发现的其他主题相似,但我认为它们并不完全正是我所寻找的。
Animation upon layout changes
Adding Node's animated to a VBox

主类:

package application;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCombination;
import javafx.scene.paint.Color;
import application.notifier.*;

public class Main extends Application
{
    @Override
    public void start(Stage stage)
    {
        try
        {
            stage.setTitle("Test");
            Group root = new Group();
            Scene scene = new Scene(root, (Screen.getPrimary().getBounds().getWidth()-100), (Screen.getPrimary().getBounds().getHeight()-100), Color.WHITE);

            Notifier notice = new Notifier();

            Notifier.addNotice("Testing Add Notice");
            Notifier.addNotice("Testing Add Notice again!");

            root.getChildren().add(Notifier.container);

            stage.setFullScreen(true);
            stage.setScene(scene);
            stage.setFullScreenExitHint("");
            //stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
            stage.show();

            Button test = new Button("Remove");
            test.setLayoutX(500.0);
            test.setLayoutY(500.0);

            test.setOnAction(new EventHandler<ActionEvent>() {
                @Override public void handle(ActionEvent e) {
                Notifier.removeNotice();
            }
            });

            root.getChildren().add(test);


        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

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

通知程序类:

import java.util.ArrayList;

import javafx.animation.FadeTransition;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Screen;
import javafx.util.Duration;

public class Notifier
{
    private static int maxVisibleNotices = 5;
    private static int currentVisible = 0;

    private static ArrayList<String> msgOverflow;

    public static VBox container;

    public Notifier()
    {
        BackgroundFill bkgrndFill = new BackgroundFill(Color.rgb(0, 0, 0, .65), new CornerRadii(10.0), new Insets(0));
        Background bkgrnd = new Background(bkgrndFill);

        Notifier.container = new VBox();
        Notifier.container.backgroundProperty().set(bkgrnd);
        Notifier.container.setAlignment(Pos.TOP_CENTER);
        Notifier.container.setMinWidth(Screen.getPrimary().getBounds().getWidth() - 50);
        Notifier.container.setMaxWidth(Screen.getPrimary().getBounds().getWidth() - 50);
        Notifier.container.setLayoutX((Screen.getPrimary().getBounds().getWidth() - (Screen.getPrimary().getBounds().getWidth() - 50))/2);
        Notifier.container.setLayoutY(5.0);
        Notifier.container.setSpacing(5.0);
        Notifier.container.setPadding(new Insets(5.0));

        Notifier.msgOverflow = new ArrayList<String>();
    }

    public static void addNotice(String msg)
    {
        if(Notifier.currentVisible < Notifier.maxVisibleNotices)
        {
            Text txt = new Text(msg);
            txt.setFill(Color.rgb(255,255,255));

            Notifier.container.getChildren().add(txt);
            Notifier.currentVisible++;
        }
        else
        {
            Notifier.msgOverflow.add(msg);
        }
    }

    public static void removeNotice()
    {
        if(Notifier.currentVisible > 0)
        {
            FadeTransition ft = new FadeTransition(Duration.millis(1000), Notifier.container.getChildren().get(0));
            ft.setFromValue(1.0);
            ft.setToValue(0.0);
            ft.setCycleCount(0);
            ft.setAutoReverse(false);
            ft.play();

            ft.setOnFinished(new EventHandler<ActionEvent>() {
                @Override public void handle(ActionEvent e) {
                    Notifier.container.getChildren().remove(0);
                    Notifier.currentVisible--;
                }
            });     
        }
    }
}

我希望这很清楚。 并提前感谢您的帮助或建议。

1 个答案:

答案 0 :(得分:1)

可能不再有用了。我目前正在研究同样的事情 你只需要:
1.向VBox中的每个剩余孩子添加相同的动画(如果它们都应该相同) 2.使用ParallelAnimation使它们同时运行 3.再次使用SequentialAnimation为您&#34; kids&#34;淡出动画和平行动画。这可以确保它们不会同时发生,因为多个线程可以同时运行 4.要获得与即时更新相同的视图,请使用animation / timeline.setonFinished(EventHandler())更新屏幕