提问者:小点点

动画布局JavaFX


我只是想知道在JavaFx中是否有任何简单的动画布局方法,例如VBox和HBox。我希望我的应用程序在指定时间后更改我的VBox的背景颜色。但是我意识到没有什么类似于FillTranpse的东西可以让我使用VBox或HBox来做到这一点。关于如何做到这一点,有什么建议吗?


共1个答案

匿名用户

使用ReactFX的2.0-SNAPSHOT版本,颜色过渡非常容易:

ObjectProperty<Color> color = new SimpleObjectProperty<>(Color.WHITE);
Val<Background> animBgr = Val.animate(color, Duration.ofMillis(500))
        .map(c -> new Background(new BackgroundFill(c, null, null)));
vbox.backgroundProperty().bind(animBgr);

现在,每当您更新颜色时,vbox的背景颜色将在500毫秒内平滑过渡到新颜色。

如果您想每5秒更改一次颜色,您可以创建一个每5秒发出一次颜色的EventStream,并使用该颜色设置颜色的值:

private static final Color[] COLORS = new Color[] {
    Color.WHITE, Color.AQUA, Color.web("#FFDA8F"), Color.CORAL, Color.CYAN
};

private EventStream<Color> colorStream() {
    return EventStreams.ticks(Duration.ofSeconds(5))
            .accumulate(0, (n, t) -> (n + 1) % COLORS.length)
            .map(i -> COLORS[i]);
}

colorStream().feedTo(color);

一个完整的可运行演示如下所示:

import java.time.Duration;

import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import org.reactfx.EventStream;
import org.reactfx.EventStreams;
import org.reactfx.value.Val;


public class ChangingBackgroundColor extends Application {

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

    private static final Color[] COLORS = new Color[] {
        Color.WHITE, Color.AQUA, Color.web("#FFDA8F"), Color.CORAL, Color.CYAN
    };

    @Override
    public void start(Stage stage) throws Exception {
        VBox vbox = new VBox();

        ObjectProperty<Color> color = new SimpleObjectProperty<>(COLORS[0]);
        Val<Background> animBgr = Val.animate(color, Duration.ofMillis(500))
                .map(c -> new Background(new BackgroundFill(c, null, null)));
        vbox.backgroundProperty().bind(animBgr);

        colorStream().feedTo(color);

        stage.setScene(new Scene(vbox, 400, 400));
        stage.show();
    }

    private EventStream<Color> colorStream() {
        return EventStreams.ticks(Duration.ofSeconds(5))
                .accumulate(0, (n, t) -> (n + 1) % COLORS.length)
                .map(i -> COLORS[i]);
    }
}

停止动画。如果在应用程序退出之前将VBox从场景中删除,则应停止动画,以防止内存和CPU泄漏。上面的feed To方法返回一个Subcription,我在上面的示例代码中忽略了它。为了停止动画,您将执行以下操作:

Subscription subscription = colorStream().feedTo(color);

// later
subscription.unsubscribe();