跨多个控件实例同步转换

时间:2017-08-21 21:12:15

标签: java javafx javafx-8

我有几个自定义控件。其中一个要求是让控件能够根据其状态进行闪烁。我正在使用淡入淡出过渡,效果很好。

如何同步淡入淡出过渡,以便在屏幕上闪烁多个控件时,它们会以相同的速率淡入淡出?

我能想到的唯一能让这项工作变得轻松的就是拥有一个静态ParallelTransition,每个实例都将它添加到活动时的淡入淡出过渡,但这对我来说听起来不是一个干净的方法

1 个答案:

答案 0 :(得分:2)

您可以使用绑定链接所有内容到基于时间轴更改的键值。

下面的代码会创建一堆圆圈,然后在不同时间点亮它们,但是一旦闪烁开始,所有圆圈都会一直闪烁(如果你很容易,请不要运行它癫痫...)

您可以使用时间轴中使用的值和插值器来获得所需的效果。

import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.Random;

public class Synchronicity extends Application {
    private static final double N = 10;
    private static final double R = 10;
    private static final Duration D = Duration.seconds(2);

    private static final double MIN_VAL = 0.1;
    private static final double MAX_VAL = 1;

    private static final Random r = new Random();

    private final DoubleProperty opacity = new SimpleDoubleProperty(MAX_VAL);
    private final Timeline oscillator = new Timeline(
            new KeyFrame(Duration.ZERO, new KeyValue(opacity, MAX_VAL, Interpolator.EASE_BOTH)),
            new KeyFrame(D.divide(2), new KeyValue(opacity, MIN_VAL, Interpolator.EASE_BOTH))
    );

    @Override
    public void start(final Stage stage) {
        Pane layout = new Pane();
        for (int i = 0; i < N; i++) {
            Circle circle = new Circle(R, Color.FIREBRICK);
            circle.setCenterX(2 * R + i * R * 3);
            circle.setCenterY(R * 2);
            layout.getChildren().add(circle);

            PauseTransition pause = new PauseTransition(D.multiply(r.nextDouble() * N));
            pause.setOnFinished(e ->  blink(circle));
            pause.play();
        }
        layout.setMinSize(R + N * R * 3,R * 4);

        stage.setScene(new Scene(layout));
        stage.show();

        oscillator.setAutoReverse(true);
        oscillator.setCycleCount(Timeline.INDEFINITE);
        oscillator.play();
    }

    private void blink(Node node) {
        node.opacityProperty().bind(opacity);
    }

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