2 Replies Latest reply: Dec 4, 2012 8:44 AM by Marcello RSS

    How would you realize a "blinking"-Effect

    Marcello
      The question narrows down to : Which is the best solution to trigger each 0,5 seconds an event (on the JavaFX thread) ?
      I could do this with a TimelineAnimation or with a Task<Void>, the problem withthe Task is that I have to update the UI with Platform.runLater() each time which is an impact on the overall perfomance. On the otherhand the TimerLineAnimation is useful to update a property and I do not think that it is the approriate method to realize a blink effect.

      How would you do this ?


      E.G. I have a circle. This shape is supposed to change its Color every 0,5 seconds (And there can be many of this circles..)
        • 1. Re: How would you realize a "blinking"-Effect
          James_D
          I would use some kind of Transition, not because of any performance consideration but merely because it will keep your code cleaner. Used properly, a Task with Platform.runLater(...) to update the UI will be as efficient as anything else, but it can be a bit tricky to get it right (and using Transitions, you delegate the job of getting the code right to the JavaFX team, who are probably better at this kind of thing than either you or I).

          The Timeline will actually animate the transition between property values. Almost anything you want to do can be expressed as a change in property; your example of changing the color of a Circle simply involves changing the value of the fillProperty. So using a Timeline will fade one color into another.

          If you want a "traditional" blink, you could two PauseTransitions with the onFinished event set to change the color.

          This compares the two approaches:
          import javafx.animation.Animation;
          import javafx.animation.KeyFrame;
          import javafx.animation.KeyValue;
          import javafx.animation.PauseTransition;
          import javafx.animation.SequentialTransition;
          import javafx.animation.Timeline;
          import javafx.application.Application;
          import javafx.beans.property.ObjectProperty;
          import javafx.beans.property.SimpleObjectProperty;
          import javafx.event.ActionEvent;
          import javafx.event.EventHandler;
          import javafx.scene.Group;
          import javafx.scene.Scene;
          import javafx.scene.layout.HBox;
          import javafx.scene.paint.Color;
          import javafx.scene.paint.Paint;
          import javafx.scene.shape.Circle;
          import javafx.stage.Stage;
          import javafx.util.Duration;
          
          public class BlinkingCircles extends Application {
          
               @Override
               public void start(Stage primaryStage) {
                 final HBox root = new HBox();
                    final Group faders = new Group();
                    final Color blue = new Color(0, 0, 1.0, 0.3);
                    final Color red = new Color(1.0, 0, 0, 0.3);
                    final ObjectProperty<Paint> colorFader = new SimpleObjectProperty<Paint>(blue);
                    for (int i=0; i<20; i++) {
                      faders.getChildren().add(createCircle(colorFader));
                    }
                    
                    KeyValue blueKV = new KeyValue(colorFader, blue);
                    KeyValue redKV = new KeyValue(colorFader, red);
                    KeyFrame blueKF = new KeyFrame(new Duration(1000), blueKV);
                    KeyFrame redKF = new KeyFrame(new Duration(500), redKV);
                    Timeline fadeTimeline = new Timeline(redKF, blueKF);
                    fadeTimeline.setCycleCount(Animation.INDEFINITE);
                    fadeTimeline.play();
                    
                    final Group blinkers = new Group();
                    final ObjectProperty<Paint> colorBlinker = new SimpleObjectProperty<Paint>(blue);
                    for (int i=0; i<20; i++) {
                      blinkers.getChildren().add(createCircle(colorBlinker));
                    }
          
                    PauseTransition changeToRed = createPauseTransition(colorBlinker, red);
                    PauseTransition changeToBlue = createPauseTransition(colorBlinker, blue);
                    SequentialTransition blinkTransition = new SequentialTransition(changeToRed, changeToBlue);
                    blinkTransition.setCycleCount(Animation.INDEFINITE);
                    blinkTransition.play();
                    
                    root.getChildren().addAll(faders, blinkers);
                    Scene scene = new Scene(root, 640, 400);
                    primaryStage.setScene(scene);
                    primaryStage.show();
               }
               
               private Circle createCircle(ObjectProperty<Paint> color) {
                 Circle c = new Circle(Math.random()*300, Math.random()*300, 20);
                 c.fillProperty().bind(color);
                 c.setStroke(Color.BLACK);
                 return c ;
               }
               
               private PauseTransition createPauseTransition(final ObjectProperty<Paint> colorBlinker, final Color color) {
                 PauseTransition changeColor = new PauseTransition(new Duration(500));
                    changeColor.setOnFinished(new EventHandler<ActionEvent>() {
                      @Override
                      public void handle(ActionEvent evt) {
                        colorBlinker.set(color);
                      }
                    });
                    return changeColor ;
               }
          
               public static void main(String[] args) {
                    launch(args);
               }
          }
          • 2. Re: How would you realize a "blinking"-Effect
            Marcello
            Thanks James,

            +"If you want a "traditional" blink, you could two PauseTransitions with the onFinished event set to change the color."+

            That's what I am looking for.

            Thanks a lot