I decided to have a simple JavaFX 2 animated sample running as attendees entered the room for my RMOUG Training Days 2012 presentation. The desired result was achieved as attendees asked if how the running application was implemented. More than one person was surprised that it was implemented in "pure Java" without Flash or HTML5. I provide the source code for this simple example along with some screen snapshots in this post. Along the way, the example demonstrates animating multiple instances of Text along a path simultaneously.
I have previously blogged about animating along a predefined path using PathTransition. I have adapted that example into this new example by changing the moving Shape from a Circle to a Text "shape" and by having three of these "shapes" move along the path simultaneously via ParallelTransition.
To add a little extra to the demonstration, I have also made use of JavaFX effects, font sizing and specification, and character coloring in this example. The code listing for the entire simple demonstrative sample is shown next.
RmougTd2012Animation.java
package dustin.examples;
import javafx.animation.ParallelTransition;
import javafx.animation.PathTransition;
import javafx.animation.PathTransition.OrientationType;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.Glow;
import javafx.scene.effect.Reflection;
import javafx.scene.paint.Color;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Shape;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextBuilder;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
* Simple animation of labels related to RMOUG Training Days 2012 using JavaFX.
*
* @author Dustin
*/
public class RmougTd2012Animation extends Application
{
/**
* Generate Path upon which animation will occur.
*
* @return Generated path.
*/
private Path generateCurvyPath()
{
final Path path = new Path();
path.getElements().add(new MoveTo(70,20));
path.getElements().add(new CubicCurveTo(430, 0, 430, 120, 250, 120));
path.getElements().add(new CubicCurveTo(50, 120, 50, 240, 430, 240));
path.setOpacity(0.0);
return path;
}
/**
* Generate the path transition.
*
* @param shape Shape to travel along path.
* @param path Path to be traveled upon.
* @param duration Duration of single animation.
* @param delay Delay before beginning first animation.
* @param orientation Orientation of shape during animation.
* @return PathTransition.
*/
private PathTransition generatePathTransition(
final Shape shape, final Path path,
final Duration duration, final Duration delay,
final OrientationType orientation)
{
final PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(duration);
pathTransition.setDelay(delay);
pathTransition.setPath(path);
pathTransition.setNode(shape);
pathTransition.setOrientation(orientation);
pathTransition.setCycleCount(Timeline.INDEFINITE);
pathTransition.setAutoReverse(true);
return pathTransition;
}
/**
* Generate RMOUG text string with appropriate fill, font, and effect.
*
* @return "RMOUG" text string with fill, font, and effect.
*/
private Text generateRmougText()
{
return TextBuilder.create().text("RMOUG").x(20).y(20).fill(Color.DARKGRAY)
.font(Font.font(java.awt.Font.SERIF, 75))
.effect(new Glow(0.25)).build();
}
/**
* Generate "Training Days 2012" text string with appropriate position, fill,
* and font.
*
* @return "Training Days 2012" with specified font, fill, and position.
*/
private Text generateTrainingDaysText()
{
return TextBuilder.create().text("Training Days 2012")
.x(380).y(240).fill(Color.DARKOLIVEGREEN)
.font(Font.font(java.awt.Font.SERIF, 50)).build();
}
/**
* Location String with specifed effect, font, and position.
*
* @return Location String with specified effect, font, and position.
*/
private Text generateDenverText()
{
final Reflection reflection = new Reflection();
reflection.setFraction(1.0);
return TextBuilder.create()
.text("Denver, Colorado").x(20).y(20)
.font(Font.font(java.awt.Font.SANS_SERIF, 25))
.effect(reflection)
.build();
}
/**
* Apply animation.
*
* @param group Group to which animation is to be applied.
*/
private void applyAnimation(final Group group)
{
final Path path = generateCurvyPath();
group.getChildren().add(path);
final Shape rmoug = generateRmougText();
group.getChildren().add(rmoug);
final Shape td = generateTrainingDaysText();
group.getChildren().add(td);
final Shape denver = generateDenverText();
group.getChildren().add(denver);
final PathTransition rmougTransition =
generatePathTransition(
rmoug, path, Duration.seconds(8.0), Duration.seconds(0.5),
OrientationType.NONE);
final PathTransition tdTransition =
generatePathTransition(
td, path, Duration.seconds(5.5), Duration.seconds(0.1),
OrientationType.NONE);
final PathTransition denverTransition =
generatePathTransition(
denver, path, Duration.seconds(30), Duration.seconds(3),
OrientationType.ORTHOGONAL_TO_TANGENT);
final ParallelTransition parallelTransition =
new ParallelTransition(rmougTransition, tdTransition, denverTransition);
parallelTransition.play();
}
/**
* JavaFX Application starting method.
*
* @param stage Primary stage.
* @throws Exception Potential JavaFX application exception.
*/
@Override
public void start(Stage stage) throws Exception
{
final Group rootGroup = new Group();
final Scene scene = new Scene(rootGroup, 500, 400, Color.GHOSTWHITE);
stage.setScene(scene);
stage.setTitle("JavaFX 2 RMOUG Training Days 2012 Animations");
stage.show();
applyAnimation(rootGroup);
}
/**
* Main function for running JavaFX animation demo.
*
* @param arguments Command-line arguments; none expected.
*/
public static void main(final String[] arguments)
{
Application.launch(arguments);
}
}
The next series of screen snapshots attempt to provide an idea of how this appears when it is executed.
This example demonstrates that text can be animated along a path and it also demonstrates the difference between OrientationType types NONE and ORTHOGONAL_TO_TANGENT. The former orientation specification has the text facing upwards from an absolutist point of view while the latter shifts the text's direction according to the twists and turns of the path. The Javadoc for each type provides more precise explanation where NONE is defined as "The targeted node's rotation matrix stays unchange along the geometric path" while ORTHOGONAL_TO_TANGENT is defined as "The targeted node's rotation matrix is set to keep node perpendicular to the path's tangent along the geometric path."
For me, the more interesting part of this example is how easy it is to specify multiple animations be run in parallel. As the applyAnimation method of the sample code shows, three text Strings are associated with three distinct PathTransition instances. Although each of these three instances of PathTransition uses the same Path, the start time and duration time of each transition differs. None of the PathTransition instances have their individual play() methods called. Rather, each is associated with a single ParallelTransition instance and it is that ParallelTransition instance's play() method that is invoked. Because the three instances of PathTransition were associated with the instance of ParallelTransition, invoking play() on it invokes play() on all three individual PathTransition instances in parallel.
Conclusion
JavaFX 2 makes it easy to perform multiple transitions in parallel. One simply sets up each individual transition in a preferred manner and then associates each of these transitions with an instance of ParallelTransition and invokes the play() method on that instance of ParallelTransition. Animation is not limited to shapes, but can be used on text as well.
Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)
分享到:
相关推荐
Javafx 2.0: Introduction by Example
JavaFX实战:模拟电子琴弹奏效果音效资源
Use the JavaFX platform to create rich-client Java applications and discover how you can use this powerful Java-based UI platform, which is capable of handling large-scale data-driven business ...
《Netty+JavaFx实战:仿桌面版微信聊天》| 本项目是作-chat.itstack.github.io
NULL 博文链接:https://c-zhiwu.iteye.com/blog/1407930
使用JavaFX开发关于2010世界杯的C-S应用(NetBeans项目)
JavaFx2:创建一个表单
JavaFX 官方教程:RIA 应用开发
In Pro JavaFX 2: A Definitive Guide to Rich Clients with Java Technology, Jim Weaver, Weiqi Gao, Stephen Chin, Dean Iverson, and Johan Vos show you how you can use the JavaFX platform to create rich-...
Javafx1:测试阶段需要大量升级
JavaFX 2.0 Introduction by Example.zip是javafx2.0的最新书籍《[JavaFX.2.0:Introduction.by.Example].Carl.Dea》上的源码!大家可以下载本书和源码一起看!我都上传了!
资源名称:JavaFX 官方教程:RIA 应用开发内容简介:《JavaFX官方教程:RIA应用开发》通过使用JavaFX,开发人员和平面设计师可以协同工作来构建健壮的、拟真的应用程序,并能够将它部署到任何地方:桌面、Web、数...
Chapter 2, Building Blocks – Shapes, Text, and Controls, fills the window we created in the previous chapter with various building blocks provided by the JavaFX API. Chapter 3, Connecting Pieces – ...
书-javafx2 从javafx2书籍中收集的示例汇编就像它读的一样,我找到了一本精妙的javafx2书籍,以加深我对该Java框架的理解,顺便说一句。
资源名称:JAVA FX官方教程:RIA应用开发内容简介:《JavaFX官方教程:RIA应用开发》通过使用JavaFX,开发人员和平面设计师可以协同工作来构建健壮的、拟真的应用程序,并能够将它部署到任何地方:桌面、Web、数百万...
JavaFX高级教程:JavaFX2.0的FXML语言.docx 官方中文文档
In Pro JavaFX 2: A Definitive Guide to Rich Clients with Java Technology, Jim Weaver, Weiqi Gao, Stephen Chin, Dean Iverson, and Johan Vos show you how you can use the JavaFX platform to create rich-...
JavaFX高级教程:部署JavaFX2.0应用 官方中午文档
JavaFX 2.0 Introduction by Example – PDF Books
一本关于JavaFX的书,希望对你有所帮助!