primaryStage.show()
添加图形
接下来在 primaryStage.show()行之前添加 Example 3 中的代码来创建30个圆。
Example 3 30 Circles
Group circles = new Group(); for (int i = 0; i < 30; i++) {
Circle circle = new Circle(150, Color.web(\ circle.setStrokeType(StrokeType.OUTSIDE); circle.setStroke(Color.web(\ circle.setStrokeWidth(4);
circles.getChildren().add(circle); }
root.getChildren().add(circles);
这些代码创建了称为 circles 的Group,然后使用一个ofr循环向其中添加30个圆。每个圆半径到是150,并用white颜色填充,此外不透明度是5%,所以基本是透明的。
然后为这些圆创建边框,代码中包含了 StrokeType 类。 描边类型的 OUTSIDE 标明圆的边界向外扩展 StrokeWidth 的值,也就是4。描边的颜色是 white ,不透明度是16%,使得它比圆的颜色浅。
最后一行把 circles 加到根节点上。这只是临时结构,稍候将修改场景图形使得它匹配 Figure 2 展示那样。
Figure 4 展示了当前应用。由于代码没有为每个圆指定特定位置,它们都叠加在一起,并且窗口的左上角是圆心。层叠的圆的不透明度和黑色北京作用使得圆看起来是灰色的。
Figure 4 Circles
增加视觉效果
继续为圆应用盒子模糊效果使得它们看起来柔和。代码是 Example 4 。 在primaryStage.show() 之前添加这些代码。
Example 4 Box Blur Effect
circles.setEffect(new BoxBlur(10, 10, 3));
代码设置了模糊半径,宽和高都是10并且迭代3次,使它接近高斯模糊。 这样便在圆的边缘出现了平滑效果,看Figure 5 .
Figure 5 Box Blur on Circles
创建背景渐变
现在创建一个矩形并用线性渐变填充,代码见 Example 5 .
在 root.getChildren().add(circles) 之前添加这些代码,这样矩形才能在圆下面。
Example 5 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(\ new Stop(0.14, Color.web(\ new Stop(0.28, Color.web(\ new Stop(0.43, Color.web(\ new Stop(0.57, Color.web(\ new Stop(0.71, Color.web(\ new Stop(0.85, Color.web(\ new Stop(1, Color.web(\root.getChildren().add(colors);
代 码创建了称为colors的矩形。 矩形和场景同宽高,并从左下角的(0,0)点开始到右上角的(1,1)点应用线性渐变。 true 表示渐变在矩形中是成比例的,NO_CYCLE 表示颜色循环不会重复, Stop[] 序列表明了渐变颜色序列。最后一行把colors 添加到根节点。
现在边缘模糊的灰色圆出现在了彩虹色的上面,见 Figure 6 .
Figure 6 Linear Gradient
Figure 7 展示了中间的场景图。现在circles 组和colors 矩形都是根节点的孩子。
Figure 7 Intermediate Scene Graph
应用混合模式
现在通过增加混合覆盖效果给圆增加颜色并使场景变暗。这个任务需要一点家务活,你需要从场景中移除 circles组和渐变的矩形,并把它们添加到新的混合覆盖组中。
删除下面两行代码:
root.getChildren().add(colors);
root.getChildren().add(circles);
添加 Example 6 中的代码到上面删除代码的位置。
Example 6 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 添加到场景作为根节点的孩子,如Figure 2 .
混合覆盖效果是图形设计程序中的常规效果。它可以暗化图像或高亮它们,这取决于混合组中的颜色。这里,我们把线性渐变矩形用作覆盖,黑色矩形用来保持背景黑暗,而接近透明的圆从矩形中取了色不过依然变暗了。
Figure 8 展示了结果。下一步活化了圆之后将能看到完整的混合覆盖效果。
Figure 8 Overlay Blend
添加动画
最后一步是使用javaFX动画来移动圆:
如果没准备好,增加 import static java.lang.Math.random; 到导入声明。
在 primaryStage.show() 之前增加Example 7 中的活化代码。
Example 7 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秒时同样做。这样,当时间线play()后,所有圆就在40秒内从一个随机位置到另一个。
第一回 JavaFX2.0简介
javaFX2.0是JavaFX最新的主要升级发布版。它的很多新特性并不能和1.3版本兼容。如果想要用javaFX做开发,推荐使用2.0版本。
建立SDK
开始使用javafx的第一步就是在你的电脑上下载和安装javafx SDK。你可以安装完整版SDK,也可以只安装javaFX运行时环境。详见第二回。
创建应用程序框架
每个JavaFX应用都有相似的框架。程序的主类继承了Application类,main方法调用luanch方法,start方法建立并显示舞台(stage,包括了应用的UI)。
定义UI
应用接口的舞台包括了一个或多个场景(scene,依次包含了控件、形状、图形来构建接口。)
布局UI控件
决定了在UI中使用什么控件后,使用内置的布局面板来管理控件的大小和位置。 部署
JavaFX应用运行在桌面、浏览器和网络上。完成应用后,将它们做成jar、html、jnlp文件供用户使用。
第二回 安装JavaFX2.0 SDK
通过本文,你讲学会如何在windows系统中安装JavaFX2.0。你有两个选择: 安装JavaFX SDK, 包括JavaFX运行时 仅安装JavaFX运行时
同时本文还指导了如何运行样例程序和怎样搭建JavaFX的NB环境。
Mac系统也有自己的 JavaFX 2.0开发者预览版,详见 第三回.
安装JavaFX SDK
如果你想要用IDE或者命令行开发javafx应用,请安装JavaFX SDK。SDK包括了Javafx的类库和工程文件。
如何安装JavaFX SDK:
检查你的系统要求
到 http://www.oracle.com/technetwork/java/javafx/downloads/index.html找到Javafx sdk针对你系统的版本下载保存。
运行.exe文件安装。
如何卸载JavaFX SDK:
使用标准卸载程序进行卸载。
安装JavaFX Runtime
若你想在你桌面上、浏览器中或使用Java Web Start通过网络运行Javafx应用,可以只安装运行时。
注意;
如果你已经成功安装了JavaFX SDK,就无需再单独安装运行时了。
如何安装JavaFX Runtime:
检查系统要求
找到并下载你系统对应的版本。
运行.exe文件。
如何卸载JavaFX Runtime
使用标准卸载程序进行卸载
运行样例程序
下载javafx样例程序,里面有一系列用javafx构建的应用。要运行它们,必须安装好运行时。
到 http://www.oracle.com/technetwork/java/javafx/downloads/index.html.点击JavaFX 2.0 Samples的链接,保存javafx_samples-2_0.zip到本地.
从zip文件中解压样例文件到本地目录。
进入目录。
双击其中任意一个可执行文件即可运行。比如,要在桌面运行Ensemble应用,双击Ensemble.jar。要在浏览器中运行,双击html。要通过网络运行,打开Ensemble.jnlp。
每个样例的源代码都在javafx-samples-2.0\\src目录下。想要查看源代码,到javafx-samples-2.0\\src\\sample目录下,里面有你感兴趣的应用。每个样例的源代码都是NB工程。
搭建JavaFX的NetBeans环境
按照第四回搭建NB环境。
第三回 JavaFX2.0在mac系统的安装
JavaFX 2.0平台预览版包括了JavaFX SDK, 它提供了开发应用的工具和技术。
这次发布为JavaFX提供了Java API, 这为Java开发者提供了开放的功能,使得大量Java开发工具能用来开发javafx应用。此外,本次发布还提供了:
高性能图像引擎,为制作简易、平滑、快捷的富图像提供了高级支持。 媒体引擎,支持网络多媒体内容后台运行。 网络组件,是HTML能绑定在javafx应用中。
UI控件的扩展集,譬如Charts, Tables, Menus, 和 Panes.
FXML(XML-based markup language ) ,可以定义用户接口。 样例程序,快速展示了该技术的特性。
注意:
当前JavaFX应用仅能在Mac系统的桌面上运行。
系统要求
Mac OS下的JavaFX 2.0 开发者预览版需要以下软件: 操作系统 - Mac OS X 10.6 或更高 JDK - JDK 6 u 26 或更高 安装
Mac系统下的javafx文件是zip文件.
安装方法:
从http://www.oracle.com/technetwork/java/javafx/downloads/javafx2-macosx-487281.html下载JavaFX SDK zip文件。
从zip文件解压SDK文件到本地目录。 样例
JavaFX样例程序在http://www.oracle.com/technetwork/java/javafx/downloads/javafx2-macosx-487281.html. 下载该zip文件并解压到包含SDK的目录中,目录结构类似这样:
javafx-sdk2.0\\
bin\\
docs\\
javafx-samples-2.0\\ rt\\ . .
要在桌面运行应用,双击.jar文件。
每 个样例的源代码都在javafx-samples-2.0\\src目录下。想要查看源代码,到javafx-samples-2.0\\src \\sample目录下,里面有你感兴趣的应用。每个样例的源代码都是NB工程。按照 Setting Up NetBeans IDE with JavaFX 2.0在NB中创建应用。
已知BUG和事项
以下问题被发现存在。后面的数字参考JavaFX issuesdashboard中的报告。
在Dock和菜单栏中应用名称只能是\,无法更改。\关于\和\退出\中的名称是\,也不能改。[RT-12113, RT-13010]
当窗口第一次显示时,出现窗口黑屏,原因是不协调的视觉闪光。[RT-16804] 拖拉操作没有用户反馈。[RT-16307, RT-14624]
工作区:收到设置一个游标,并使用一个浮动窗口显示图像来反映拖动操作。 退出时可能异常[RT-14118, RT-15599]
工作区添加应用时悬挂或破碎不太可能。
已知渲染时有掺混。 [RT-12852]
不支持3D渲染。 [RT-13234, RT-13230] Mac OS渐变支持不好. [RT-10565]
不能向用户展示错误对话框. [RT-13739]
Caps Lock 在 TextField 和TextArea中无效. [RT-16616] 在TextField中不能剪切、复制、粘贴. [RT-16475]
第四回 在NB中创建JavaFX2.0应用
NetBeans IDE需要一个 JavaFX 2.0可用的Java平台。本部分详述了如何在NB上建立JavaFX2.0可用Java平台。
当你首次新建应用或者打开预加载向导时NetBeans IDE会尝试创建 JavaFX可用的Java平台。如果NB不能自动创建会有警告出现,这时候你必须手动创建. 你可以创建额外的Java平台,比如你想要使用不同的jdk。
这里分两步介绍自动和手动创建Java平台:
打开新建JavaFX应用向导.这是全局的起点,当打开向导时, NetBeans IDE 尝试创建一个JavaFX可用的Java平台。如果 NetBeans 成功创建,你就完成任务了.
手动创建JavaFX可用的平台.如果自动创建失败 , 或者想要添加新的JavaFX可用平台, 你必须手动创建。
打开新建JavaFX应用向导
创 建 JavaFX可用的Java平台的第一步是打开NetBeans IDE的新建JavaFX应用向导。 (或者你可以打开新建JavaFX Preloader 向导。)如果NB没有找到JavaFX可用的Java平台, 会尝试创建。如果成功了,你的新建就完成了。否则你要手动创建。
注意:Windows平台自动创建到默认目录 (C:\\Program Files\\Oracle\\).
打开新建JavaFX Application向导:
选择 JavaFX 分类. 在 Projects窗口, 选择JavaFX Application, 点击Next,打开Name and Location面板 。IDE自动寻找JavaFX SDK并尝试生成 JavaFX可用的Java平台。
NB创建环境的成功与否会出现不同的屏幕:
生 成成功:这个 JavaFX平台使用和IDE相同的 JDK,平台名称叫 Default JFX Platform。 IDE自动选择了这个平台。你成功了,除非你想用不同的jdk创建另外一个可用的平台。若你想这样,按照Creating a JavaFX-Enabled Platform Manually.
生成失败:JavaFX Platform列表没有显示任何可用平台。查看 Creating a JavaFX-Enabled Platform Manually.
手动创建JavaFX可用的平台
打开Java平台管理器NetBeans IDE Java Platform Manager: 在新建 JavaFX Application或者新建JavaFX Preloader向导中,点击Manage Platforms...;或者 点开Tools 菜单选择Java Platforms。或者
打开任意Java工程的Project Properties,切换到Libraries标签,点击Manage Platforms... 点击Add Platform... Add Java Platform向导中出现Choose Java Platform 面板。找到你想要的jdk.
选中JDK。必须选择JDK 1.6 u 26或更高 (或JDK 7)。点 NexT,打开Platform Name面板。
为你的平台命名后点Finish,返回到 Platform Manager。你创建的平台已经被加入列表了
选中你的平台,打开JavaFX标签。 现在,JavaFX 对该平台还不可用。选中Enable JavaFX框。警告出现了:“the JavaFX platform is invalid.”
点击JavaFX SDK 框旁边的Browse,找到 JavaFX 2.0 SDK文件夹。
点 击Open返回到Java Platform Manager。现在JavaFX SDK 和JavaFX Javadoc 框都填好了。如果JavaFX Runtime 2.0和JavaFX 2.0 SDK在同一目录,JavaFX Runtime 框也会填好的。若JavaFX Runtime 在其他目录,就收到找到Sources狂不用选。
点击Close。你已经完成了。
第五回 开始使用JavaFX2.0
如果想用 JavaFX快速开发富用户体验的应用,就好好读本文吧。我们将创建一个简单应用并了解到用少量代码实现复杂图形效果是多么容易。当然了,JavaFX不仅仅只是异常漂亮生动的形状而已。读完本文后去看看样例将大有好处。
Figure 1 Colorful Circles Application
如果你很熟悉JavaFX场景图形编程模型,那就很容易理解程序的代码。 舞台( stage)是应用的最高层容器,场景( scene)是应用中内容的绘图表面。内容都被组织为场景图形,是一颗节点的层次树。
Figure 2 为应用 ColorfulCircles展示了场景图形。 分支节点是 Group 类的实例化。非分支节点,即叶子节点,是 Rectangle 和Circle 类的实例化。
Figure 2 Colorful Circles Scene Graph
建立应用
你可以使用任何为开发Java设计的工具来构建javaFX应用。我们推荐使用NetBeans IDE。 开始之前,请确保你的NB版本已经支持了javaFX2.0。详见 System Requirements。
安装如下步骤用NB做开发:
从 File 菜单 , 选择New Project .
从JavaFX application 分类中, 选择JavaFX Application , 点击Next .
输入工程名 ColorfulCircles 后点 Finish .
打开 ColorfulCircles.java 文件,复制 import 声明粘贴进你的工程覆盖NB自动生成的语句。
或者你可以使用NB的代码完成功能或Fix Imports 命令导入Import语句,不过记得确保包都以javafx开头。
创建应用基础
删除 NetBeans IDE生成的ColorfulCircles 类并用 Example 1 中的代码代替。以下是运行javaFX应用所需的最少代码:
Example 1 Basic Application
public class ColorfulCircles extends Application {
public static void main(String[] args) { launch(args); }
@Override
public void start(Stage primaryStage) {
primaryStage.show(); } }
ColorfulCircles类继承了 Application 类,包含两个方法。第一个方法是 main() 方法, 用来调用 launch() 方法。作为JavaFX最佳实践,launch() 方法是被 main() 方法调用的唯一方法。
然后, ColorfulCircles 类重写了抽象的 start() 方法。start() 方法的参数是应用的初始舞台。最后一行使得舞台可见。
现在你可以编译运行ColorfulCircles了,每一步都记得查看下中间结果。如果出问题了,查看下 ColorfulCircles.java 文件。
添加场景
现在为舞台添加场景:增加三行代码,参见Example 2 。这有两个最佳实践: 代码中为场景创建了一个Group节点做根节点,并设置了场景的宽和高(这里是800和600)。
在 primaryStage.show() 这一行之前添加场景及其所有内容。这是另一个最佳实践。
Example 2 Scene @Override
public void start(Stage primarystage) { Group root = new Group();
Scene scene = new Scene(root, 800, 600, Color.BLACK);
primaryStage.setScene(scene);
Figure 9 展示了运动中的30个圆。完成后查看 ColorfulCircles.java 文件 .
Figure 9 Animated Circles
第六回 JavaFX2.0 UI 控件
JavaFX控件是通过API在场景图形中使用结点构建的,所以它们可以使用javaFX平台的富视觉特点。由于javaFX API是完全用Java语言实现的,所以可以轻松将javaFX UI 控件集成进已存在的Java应用中。 JavaFX 2.0中支持的UI控件
UI控件的构造类位于API的javafx.scene.control 包中。
控件列表包括了你可能很熟悉的用Java开发客户端应用的典型UI组件。不过,JavaFX 2.0 SDK引入了新的Java UI 控件,比如TitledPane 和TableView .
Figure 1-1 是一副屏幕截图,有三个TitledPane 元素和一个社交类型列表,并且列表可以滑入 (retract)和滑出 (extend).
Figure 1-1 Titled Panes
可以从 API文档查看全部UI控件。
UI 控件类比Control类提供了更多的变量和方法,这样就能以直观的方式支持典型的用户交互。你可以使用层叠样式表(CSS)为你的UI组件设计特殊样 式。对于某些个别任务,还可能要继承Control 类来创建定制的UI 组件,或者使用Skin 接口为已存在的控件定义一个新皮肤。
从样例中的Ensemble 应用试着了解下控件的范围、它们的行为、可以实现的样式。
特性和效果
由于javafx.scene.control包中的 UI 控件都继承了 Node 类,所以它们可以和场景图形的渲染、动画、变换及动画过度进行整合。
考虑创建一个按钮,为它添加倒影并通过时间线修改它的透明度来让它闪动。
Figure 1-2 展示了这个按钮的三个不同时间线上的状态。左边的图像是不透明度设为1.0时 ,中间的图像是不透明度 0.8 ,最右边的不透明度是0.5 .
Figure 1-2 Animated Button
通过使用JavaFX API只用少量代码就能实现这个任务。
Example 1-1 创建了一个无限的时间线并开始了它,里面有一个600毫秒的关键帧设置按钮的不透明度从默认值(1.0)向 0.0变化。setAutoReverse 使得时间线可以自动反向。
Example 1-1 Creating an Animated Button 复制代码
1. import javafx.animation.KeyFrame; 2. import javafx.animation.KeyValue; 3. import javafx.animation.Timeline; 4. import javafx.util.Duration;
5. import javafx.scene.control.Button; 6. import javafx.scene.text.Font;
7. import javafx.scene.effect.Reflection; 8. 9. ...
10.Button button = new Button(); 11. button.setText(\
12. button.setFont(new Font(\13. button.setEffect(new Reflection()); 14.
15.final Timeline timeline = new Timeline(); 16.timeline.setCycleCount(Timeline.INDEFINITE); 17.timeline.setAutoReverse(true);
18.final KeyValue kv = new KeyValue(button.opacityProperty(), 0); 19.final KeyFrame kf = new KeyFrame(Duration.millis(600), kv); 20.timeline.getKeyFrames().add(kf); 21.timeline.play(); ...
你也可以应用 javafx.scene.effect 包中的其他效果,比如shadow, lighting, 或者 motion blur.
为UI控件添加CSS装饰
通过定义自己的Cascading Style Sheets (CSS)可以定制内建的UI控件。在JavaFX 应用中使用CSS很像在HTML中使用,因为都必须遵循相同的CSS 规范。控件的视觉效果由.css文件定义,见代码Example 1-2 .
Example 1-2 Defining Styles for UI Controls in the CSS File /*controlStyle.css */
.scene{
-fx-font: 14pt \ -fx-color: #e79423;
-fx-background: #67644e; }
.button{
-fx-text-fill: #006464;
-fx-background-color: #e79423; -fx-border-radius: 20;
-fx-background-radius: 20; -fx-padding: 5; }
可以通过Scene类中的 getStylesheets 方法应用该效果,见Example 1-3 .
Example 1-3 Applying CSS Scene scene = new Scene();
scene.getStylesheets().add(\//译者注:添加外部css文件时,即使文件和类在同意目录下,也要加上css所在的包名。
另外,你可以通过使用setStyle方法直接定义控件风格。 Example 1-4 中的 -fx-base 属性为场景中新增的双态按钮定义,它重写了CSS文件中对应的属性。
Example 1-4 Defining the Style of a Toggle Button in the JavaFX Application ToggleButton tb3 = new ToggleButton (\tb3.setStyle(\
Figure 1-3 展示了双态按钮的效果。
Figure 1-3 Applying CSS Style to a Toggle Button
图表
除 了为用户接口提供典型元素外, JavaFX SDK在 javafx.scene.chart包中 提供了预置图表。以下类型图表已经可以支持了:area chart, bar chart, bubble chart, line chart, pie chart, and scatter chart。一个图表可以包含几个系类的数据。
Figure 1-4 是一个进口水果饼图。
Figure 1-4 Pie Chart
和其他Java客户端工具不同,使用JavaFX SDK 只需要在应用中添加几行代码就能构建这样的图表。你也可以定义一系列的颜色表和风格、应用视觉效果、处理鼠标事件、创建动画等。
来 Using JavaFX Charts 了解更多的图表特性和功能信息。
集成JavaFX 2.0 UI 控件和 Swing
可以将 JavaFX UI 控件集成进已存在的用Swing构建的Java客户端应用。
要集成JavaFX内容和Swing,请安装以下步骤:
将JavaFX UI 控件一个一个地添加到javafx.scene.Scene 对象中的布局容器中,比如一个group.
把Scene 对象加入Swing 应用.
即使把一个单独的JavaFX 2.0 控件加入到已存在的Swing代码中也要做上面的两个步骤。
尽管它们被集成进了Swing程序,JavaFX 2.0 UI 控件也依然被菱镜图形库(Prism graphical library)渲染 ,并具有全部的高级渲染能力。
到第七回 了解更多二者的集成信息。
第七回 JavaFX2.0和Swing的集成
JavaFX 2.0 发布版引入了JFXPanel类,它位于 javafx.embed.swing 包中,使你能够将JavaFX内容绑定进Swing 程序。
本文教你怎么将JavaFX内容加进Swing 程序中并指导你如何在一个同时具备Swing 和JavaFX 的应用中正确使用线程。
添加JavaFX到Swing组件
要达到本文的目的,你要创建一个JFrame 组件,并添加一个JFXPanel 对象,JFXPanel组件的图形场景要包含JavaFX 内容。
和 所有的Swing程序一样,你要在 Event Dispatch Thread (事件调度线程EDT)上创建图形用户接口(GUI) 。Example 1 展示了initAndShowGUI 方法,它创建了一个JFrame 组件并添加了JFXPanel 对象。创建JFXPanel 类的实例会在后台开始JavaFX 运行时。GUI 创建后,调用initFX 方法在JavaFX线程上创建JavaFX场景。
Example 1 复制代码
1. public class Test { 2.
3. private static void initAndShowGUI() {
4. // This method is invoked on the EDT thread 5. JFrame frame = new JFrame(\
6. final JFXPanel fxPanel = new JFXPanel(); 7. frame.add(fxPanel); 8. frame.setVisible(true); 9.
10. Platform.runLater(new Runnable() { 11. @Override
12. public void run() { 13. initFX(fxPanel); 14. } 15. }); 16. } 17.
18. private static void initFX(JFXPanel fxPanel) { 19. // This method is invoked on the JavaFX thread 20. Scene scene = createScene(); 21. fxPanel.setScene(scene); 22. } 23.
24. private static Scene createScene() { 25. //Code to create the JavaFX scene 26. } 27.
28. public static void main(String[] args) {
29. SwingUtilities.invokeLater(new Runnable() { 30. @Override
31. public void run() { 32. initAndShowGUI(); 33. } 34. }); 35. } 36.}
JavaFX-Swing的互操作性和线程
由于JavaFX和Swing的数据存在与一个程序中,你可能遇到以下互操作的情况:
一个JavaFX的数据改变是由Swing的数据改变引起的.
反之.
改变JavaFX的数据来回应Swing数据的改变
记住JavaFX的数据只能通过javaFX用户线程访问。不论何时要改变JavaFX 数据都要把你的代码用一个Runnable 对象包围起来并调用Platform.runLater 方法。见Example 2 .
Example 2 复制代码
1. jbutton.addActionListener(new ActionListener() { 2. public void actionPerformed(ActionEvent e) { 3. Platform.runLater(new Runnable() { 4. @Override
5. public void run() {
6. fxlabel.setText(\7. }
8. }); 9. } 10.});
改变Swing数据来回应JavaFX 数据的改变
记住Swing数据的改变要通过EDT。确保你的代码实现了EDT,把它用Runnable 对象环绕并调用SwingUtilities.invokeLater 方法。见Example 3 .
Example 3 复制代码
1. SwingUtilities.invokeLater(new Runnable() { 2. @Override
3. public void run() {
4. //Code to change Swing data. 5. } 6. });
SwingBrowser2: 一个集成了JavaFX组件的Swing应用
通 过SwingBrowser2 可以看到 Swing - JavaFX是怎么互操作的,它为浏览器提供了常用的基本功能。你可以在它的地址栏中键入一个URL 来查看应用窗口加载的页面。你可以通过点页面链接去到新页面、返回前一页、打开标签页、加入书签、全页面检索。 Figure 1是该应用的窗口。
Figure 1 The SwingBrowser2 application window
初始化Swing数据
你可以从一个NB工程中的侧边栏点链接来下载swingbrowser2.zip 文件。解压到本地并从Netbeans IDE中运行为工程。确保你的NetBeans IDE版本是支持的。
SwingBrowser2打开后,它的GUI创建就在 EDT上。通过边栏的链接查看 Main.java 文件。
应用的顶层窗口是一个 JFrame 组件,包含了很多Swing 组件,比如一个tabbed面板,一个menu,几个text field、button,还有一个要显示JavaFX内容的JFX 面板。
加载 JavaFX内容
刚开始运行,JFX面板包含一个空的WebView 对象。当在地址栏输入一个URL后, AddressBar.java中的 action listener 就开始加载页面。代码见Example 4 .
Example 4 复制代码
1. txtURL.addActionListener(new ActionListener() {
2. @Override public void actionPerformed(ActionEvent e) { 3. browser.load(txtURL.getText()); 4. } 5. });
Browser.java文件中的load 方法验证URL并调用call方法,见 Example 5 .
Example 5 复制代码
1. public void load(String str) { 2. if (str != null {
3. str = str.trim(); 4.
5. if (str.isEmpty()) return; 6.
7. String url = toURL(str); 8. if (url == null) {
9. url = toURL(\10. }
11. if (url != null) {
12. Platform.runLater (new Runnable() { 13. @Override
14. public void run () { 15.
16. call(url); 17. } 18. } 19.} 20.
21.private static String toURL(String str) { 22. try {
23. return new URL(str).toExternalForm(); 24. } catch (MalformedURLException exception) { 25. return null; 26. } 27.}
JavaFX数据应该只能在JavaFX线程上访问。call方法验证了线程并确保特点URL的页面被加载在 JavaFX线程上。Callback.java 文件中有完整代码。Example 6 是表明了实现方案的代码块。
Example 6 复制代码
1. public final void call(final String value) { 2. if (Platform.isFXApplicationThread()) { 3. callImpl(value); 4. }
5. else {
6. Platform.runLater(new Runnable() { 7. @Override public void run() { 8. callImpl(value); 9. } 10. }); 11. } 12.} 13.
14.protected void callImpl(String value) { 15. getEngine().load(value); 16.}
更新Swing数据
当 WebView 组件加载了新页面后,页面标题就从JavaFX数据中取回并传递给Swing GUI。然后页面标题就显示在标签页上并加入应用标题。
TabbedBrowser.java 中有完整代码。Example 7 是表明了实现方案的代码块。
Example 7 复制代码
1. public WebPane addNewTab(final String url, boolean selected) { 2. ...
3. final WebPane wp = new WebPane(url); 4.
5. wp.getBrowser().getEngine().titleProperty().addListener( 6. new javafx.beans.value.ChangeListener
8. public void changed(ObservableValue extends String> observable,
9. String oldValue, final String title) {
10. EventQueue.invokeLater(new Runnable() { 11. @Override public void run() {
12. setTitleAt(indexOfComponent(wp), title); 13. setToolTipTextAt(indexOfComponent(wp), title); 14.
15. if (getSelectedComponent() == wp) { 16. setWindowTitle(title); 17. } 18. } 19. )}; 20. } 21. )}; 22.}
想了解怎么部署二者的整合应用,到 Deploying JavaFX Applications查看。
第八回 JavaFX2.0 标签Label
Label 类位于 JavaFX API的 javafx.scene.control 包中,它继承了 Labeled 类。Label 类用来显示一个文本元素。你可以让一个文本换行来适应特定大小的空间,也可以加入图像。
Figure 2-1 展示了三个标签的常规用法。左边是带有图像的文本元素,中间的是转动后的文本,右边的是换行文本。
Figure 2-1 Sample Application with Labels
创建Label
JavaFX API提供了三个Label 类的构造方法来创建标签,见代码Example 2-1 .
Example 2-1 Creating Labels //空标签
Label label1 = new Label(); //有文本的标签
Label label2 = new Label(\//有文本有图像
Image image = new Image(getClass().getResourceAsStream(\Label label3 = new Label(\
创建标签后就可以用下面Labeled 类的方法向其中添加文本和图像内容。 setText(String text) – 为标签指定一个标题。
setGraphic(Node graphic) – 指定图标
setTextFill方法为标签的文本元素指定了颜色。研究下 Example 2-2:先创建了一个文本标签,又添加了一个图标,再指定文本的填充颜色。
第二个按钮被选中了,但焦点依然在第一个按钮上。使用requestFocus函数可以改变焦点位置,见Example 4-5.
Example 4-5 Requesting Focus for the Second Radio Button rb2.setSelected(true); rb2.requestFocus();
这样,代码产生的结果如Figure 4-4.
Figure 4-4 Setting Focus for the Selected Radio Button
第十一回 JavaFX2.0开关按钮ToggleButton
ToggleButton类代表了可以通过JavaFX API创建的另一类按钮。 2个或更多的这种按钮被加入一个组中,但是每次只能有一个被选中,或者一个都没有。 Figure 5-1是在一个组中有3个开关按钮的应用截图。这个应用根据哪个开关按钮别按下来决定绘制何种颜色的矩形。
Figure 5-1 Three Toggle Buttons
创建Toggle Button
可以通过ToggleButton类的3个构造方法的任意一个来创建开关按钮。见Example 5-1. 复制代码
1. //A toggle button without any caption or icon 2. ToggleButton tb1 = new ToggleButton(); 3. //A toggle button with a text caption
4. ToggleButton tb2 = new ToggleButton(\5. //A toggle button with a text caption and an icon 6. Image image = new
Image(getClass().getResourceAsStream(\7. ToggleButton tb3 = new ToggleButton (\ImageView(image));
ToggleButton类继承了Labeled类,因而你可以为其指定文本标题、图像、文本加图像。可以使用Labeled 类的setText和setGraphic方法来给开关按钮指定文本和图像。
在代码中定义了开关按钮后,就可以把它们放进组中并指定特定的行为。
把Toggle Button加入组
ToggleButton类的实现和RadioButton类实现相当类似。不过和单选框不同的是,开关按钮并不要求每次必须最少有一个按钮被选中在组中。也就是说,点击选中的开关按钮会使其取消选中,但是点击组中的单选按钮没任何反应。
t花点时间看下 Example 5-2中的代码吧. 复制代码
1. Example 5-2 Combining Toggle Buttons in a Group 2. final ToggleGroup group = new ToggleGroup(); 3.
4. ToggleButton tb1 = new ToggleButton(\5. tb1.setToggleGroup(group); 6. tb1.setSelected(true); 7.
8. ToggleButton tb2 = new ToggleButton(\9. tb2.setToggleGroup(group); 10.
11.ToggleButton tb3 = new ToggleButton(\12.tb3.setToggleGroup(group);
Example 5-2创建了3个开关按钮并把它们加入开关组中。tb1调用了
setSelected方法,所以应用打开后它会被按下。但是,你也可以按起Minor按钮使得没有任何开关按钮被按下。见 Figure 5-2.
Figure 5-2 Three Toggle Buttons in a Group
Description of \
一般使用开关按钮的组来为每个按钮分配特定行为。下一部分将解释如何使用这些开关按钮改变矩形的颜色。
设置行为
ToggleButton类从Node 类继承了setUserData方法,该方法可以让你给任意选中的选项赋特定的值。在 Example 5-3中,用户数据指明了要用什么颜色来绘制矩形。 复制代码
1. Example 5-3 Setting User Data for the Toggle Buttons 2. tb1.setUserData(Color.LIGHTGREEN); 3. tb2.setUserData(Color.LIGHTBLUE); 4. tb3.setUserData(Color.SALMON); 5.
6. final Rectangle rect = new Rectangle(145, 50); 7.
8. final ToggleGroup group = new ToggleGroup(); 9. group.selectedToggleProperty().addListener(new ChangeListener
10. public void changed(ObservableValue extends Toggle> ov, 11. Toggle toggle, Toggle new_toggle) { 12. if (new_toggle == null)
13. rect.setFill(Color.WHITE); 14. else
15. rect.setFill( 16. (Color)
group.getSelectedToggle().getUserData() 17. );
18. } 19.});
ChangeListener
比如用户按下了tb2按钮, setSelectedToggle().getUserData()的调用返回 Color.LIGHTBLUE结果如图 Figure 5-3.
Figure 5-3 Using Toggle Buttons to Paint a Rectangle
Description of \
查看 ToggleButtonSample.java文件检查应用的完整代码。
美化Toggle Button
可以通过为开关按钮应用CSS来改善应用的视效。在JavaFX 2.0应用中使用CSS和在HTML中使用几乎一样,因为它们都基于相同的CSS规范。Example 5-4使用setStyle方法改变了开关按钮的 -fx-base CSS熟悉。
Example 5-4 Applying CSS Styles to Toggle Buttons tb1.setStyle(\tb2.setStyle(\tb3.setStyle(\
程序中加入这些代码后开关按钮的变化见 Figure 5-4.
Figure 5-4 Painted Toggle Buttons