Wednesday, July 24, 2013

Animated Wizard using JavaFX

I recently got to work on a Wizard Type application for one of my clients. Also I am currently playing with the JavaFX Animations. Animations were never straight forward in Swing and even if we were to develop a custom animation, performance was a big factor to consider. This made JavaFX animations a lot of fun.

In this post I'm going to share a simple wizard like application, that has two forms. Not a real world use case, but could give you some basics on how animations can be used in a wizard.

The code for this application can be downloaded as a Netbeans project from here.

I use a single Parent View and two Child Views in this demo. The Parent view has Stack Pane in place, which acts as a host for the child views. The child view is swapped when "Next" button is clicked.



The nodes are animated in the initialize method of the controller class for each view. For this purpose I have a AnimationManager, which will animate the nodes for me. The layout of each child view (the actual forms), is simple. I have got a VBox and number of HBox s' inside it, for each field.


If you are a WPF developer trying to understand JavaFX, VBox is similar to a WPF StackPane with vertical orientation and HBox is similar to a WPF StackPane with horizontal orientation. 

The AnimationManager helps me animate all the 1st level child of the VBox (which are HBoxs). Below is the method from AnimationManager that animates the nodes.

  1. private static ObservableList<Timeline> getTimelines(Parent node) {
  2. double deltaSeconds = 0;
  3. ObservableList<Timeline> timeLines = FXCollections.observableArrayList();
  4. ObservableList<Node> children = node.getChildrenUnmodifiable();
  5. for(Node child: children) {
  6. deltaSeconds += 0.5;
  7. Rotate rotate = new Rotate(-90, 0, 0, 0, Rotate.Y_AXIS);
  8. child.getTransforms().add(rotate);
  9. Timeline anim = new Timeline(
  10. new KeyFrame(Duration.seconds(deltaSeconds),
  11. new KeyValue(child.opacityProperty(), 0),
  12. new KeyValue(rotate.angleProperty(), -90)),
  13. new KeyFrame(Duration.seconds(deltaSeconds + 1.0),
  14. new KeyValue(child.opacityProperty(), 100),
  15. new KeyValue(rotate.angleProperty(), 0))
  16. );
  17. timeLines.add(anim);
  18. }
  19. return timeLines;
  20. }

This method returns a List of Timeline objects to the caller. The AnimationManager is called inside the initialize method of the controller. And hence when the views are initialized the animation is played. Download the source to experiment further.

No comments:

Post a Comment