您可以使用JavaFX快速开发具有丰富用户体验的应用程序。在本入门教程中,您将学习如何使用很少的编码创建动画对象并获得复杂的效果。
图5-1显示了要创建的应用程序。
图5-1彩色圆圈应用
ColorfulCircles
应用程序的场景图如图5-2所示。节点分支是的实例化Group
类和无分支的节点,也被称为叶节点,是的实例Rectangle
和Circle
类。
图5-2彩色圆圈场景图
本入门教程中使用的工具是NetBeans IDE。开始之前,请确保您正在使用的NetBeans IDE版本支持JavaFX 2.有关详细信息,请参阅系统要求。
设置应用程序
在NetBeans IDE中设置您的JavaFX项目,如下所示:
-
从文件菜单中,选择新建项目。
-
在JavaFX应用程序类别中,选择JavaFX Application。单击下一步。
-
将项目命名为ColorfulCircles,然后单击完成。
-
打开ColorfulCircles.java文件,复制导入语句,并将其粘贴到项目的源文件中,覆盖NetBeans IDE生成的导入语句。
或者,您可以通过使用NetBeans IDE中“源”菜单中的代码完成功能或“修复导入”命令来完成本教程的方式生成导入语句。当有可选择的导入语句时,选择一个开头的语句
javafx
。
设立项目
ColorfulCircles
从NetBeans IDE生成的源文件中删除该类,并将其替换为示例5-1中的代码。
示例5-1基本应用
Example 5-1 Basic Application
public class ColorfulCircles extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
Group root = new Group();
Scene scene = new Scene(root, 800, 600, Color.BLACK);
primaryStage.setScene(scene);
primaryStage.show();
}
}
对于ColorfulCircles应用程序,使用组节点作为场景的根节点是适当的。组的大小由其中的节点的大小决定。然而,对于大多数应用程序,您希望节点跟踪场景的大小,并在舞台调整大小时进行更改。在这种情况下,您将使用可调整大小的布局节点作为根,如在JavaFX中创建表单中所述。
您现在可以编译并运行ColorfulCircles应用程序,并在本教程的每个步骤中查看中间结果。如果遇到问题,请查看ColorfulCircles.java文件中的代码。在这一点上,应用程序是一个简单的黑色窗口。
添加图形
接着,通过添加在代码创建30个圆圈实施例5-2的前primaryStage.show()
行。
例5-2 30圈
Example 5-2 30 Circles
Group circles = new Group();
for (int i = 0; i < 30; i++) {
Circle circle = new Circle(150, Color.web("white", 0.05));
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("white", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
}
root.getChildren().add(circles);
此代码创建一个名为的组circles
,然后使用for
循环向该组添加30个圈子。每个圆的半径150
,填充颜色white
和不透明度水平5
百分比,这意味着它大多是透明的。
要在圈子周围创建一个边框,代码包括StrokeType
该类。一种笔画类型OUTSIDE
意味着圆的边界在内部延伸到该StrokeWidth
值之外4
。笔画的颜色是white
,透明度水平是16
百分比,使其比圆圈的颜色更亮。
最后一行将该circles
组添加到根节点。这是一个临时结构。稍后,您将修改此场景图,使其与图5-2所示的场景图匹配。
应用程序如图5-3所示。因为代码还没有为每个圆圈指定一个唯一的位置,所以圆形被绘制在彼此的顶部,以窗口的左上角为圆的中心点。重叠圆圈的不透明度与黑色背景相互作用,产生圆形的灰色。
图5-3圈
添加视觉效果
继续通过对圆圈应用框模糊效果,使它们稍微偏离焦点。代码示例5-3。在该primaryStage.show()
行之前添加此代码。
示例5-3框模糊效果
circles.setEffect(new BoxBlur(10,10,3));
此代码将模糊半径到10
由宽像素10
高的像素,并且模糊迭代3,
使其近似于高斯模糊。这种模糊技术在圆形边缘产生平滑效果,如图5-4所示。
图5-4圆形框模糊
创建背景渐变
现在,创建一个矩形并用线性渐变填充,如例5-4所示。
root.getChildren().add(circles)
在行之前添加代码,使渐变矩形出现在圆圈后面。
示例5-4线性渐变
Example 5-4 Linear Gradient
Rectangle colors = new Rectangle(scene.getWidth(), scene.getHeight(),
new LinearGradient(0f, 1f, 1f, 0f, true, CycleMethod.NO_CYCLE, new
Stop[]{
new Stop(0, Color.web("#f8bd55")),
new Stop(0.14, Color.web("#c0fe56")),
new Stop(0.28, Color.web("#5dfbc1")),
new Stop(0.43, Color.web("#64c2f8")),
new Stop(0.57, Color.web("#be4af7")),
new Stop(0.71, Color.web("#ed5fc2")),
new Stop(0.85, Color.web("#ef504c")),
new Stop(1, Color.web("#f2660f")),}));
colors.widthProperty().bind(scene.widthProperty());
colors.heightProperty().bind(scene.heightProperty());
root.getChildren().add(colors);
此代码创建一个名为的矩形colors
。矩形与场景的宽度和高度相同,并且以从左下角(0,1)开始并以右上角(1,0)结束的线性渐变填充。true
表示渐变的值与矩形成比例,NO_CYCLE
表示颜色周期不会重复。该Stop[]
序列表示在特定地点的渐变颜色。
接下来的两行代码使线性渐变通过将矩形的宽度和高度绑定到场景的宽度和高度来改变场景的大小。有关绑定的更多信息,请参阅使用JavaFX属性和绑定。
代码的最后一行将colors
矩形添加到根节点。
模糊边缘的灰色圆圈现在出现在彩虹的顶部,如图5-5所示。
图5-5线性渐变
中间场景图如图5-6所示。此时,circles
组和colors
矩形是根节点的子节点。
图5-6中间场景图
应用混合模式
接下来,通过添加叠加效果,向圆圈添加颜色并使场景变暗。您将从circles
场景图中删除组和线性渐变矩形,并将它们添加到新的叠加组合组。
-
找到以下两行代码:
root.getChildren().add(colors); root.getChildren().add(circles)
-
示例5-5混合模式
Example 5-5 Blend Mode Group blendModeGroup = new Group(new Group(new Rectangle(scene.getWidth(), scene.getHeight(), Color.BLACK), circles), colors); colors.setBlendMode(BlendMode.OVERLAY); root.getChildren().add(blendModeGroup);
该组blendModeGroup
设置叠加混合的结构。该组包含两个孩子。第一个孩子是一个新的(未命名的),Group
包含一个新的(未命名的)黑矩形和以前创建的circles
组。第二个孩子是以前创建的colors
矩形。
该setBlendMode()
方法将覆盖混合应用于colors
矩形。最后一行代码将blendModeGroup
场景图添加为根节点的子节点,如图5-2所示。
叠加混合是图形设计应用中的常见效果。这种混合可以使图像变暗或添加高光或两者,这取决于混合中的颜色。在这种情况下,线性渐变矩形用作叠加。黑色矩形用于使背景变暗,而几乎透明的圆圈从渐变中拾取颜色,但也变暗。
结果如图5-7所示。当您在下一步中为圆圈动画化时,您将看到叠加混合的完整效果。
图5-7覆盖混合
添加动画
最后一步是使用JavaFX动画移动圈子:
-
如果您还没有这样做,请添加
import static java.lang.Math.random;
到导入语句列表。 -
在示例5-6之前添加动画代码
primaryStage.show()
。示例5-6动画
-
Example 5-6 Animation Timeline timeline = new Timeline(); for (Node circle: circles.getChildren()) { timeline.getKeyFrames().addAll( new KeyFrame(Duration.ZERO, // set start position at 0 new KeyValue(circle.translateXProperty(), random() * 800), new KeyValue(circle.translateYProperty(), random() * 600) ), new KeyFrame(new Duration(40000), // set end position at 40s new KeyValue(circle.translateXProperty(), random() * 800), new KeyValue(circle.translateYProperty(), random() * 600) ) ); } // play 40s of animation timeline.play();
动画由时间线驱动,因此这个代码创建一个时间轴,然后使用一个for
循环来为30个圈子中的每一个添加两个关键帧。0秒的第一个关键帧使用属性translateXProperty
并translateYProperty
设置窗口内的圆圈的随机位置。40秒的第二个关键帧也是一样的。因此,当播放时间线时,它在40秒的时间内将所有圆从一个随机位置动画到另一个位置。
图5-8显示了运动中的30个彩色圆,完成了应用。有关完整的源代码,请参阅ColorfulCircles.java文件。
图5-8动画圈