By James L. Weaver, 7/8/08 |
|
本系列的上一篇文章 使用经过编译的 JavaFX Script 技术创建富 Internet 应用程序 介绍了如何开发、编译和运行一个简单的、基于 JavaFX Script 技术的程序。文章深入剖析了该程序并讨论了一些 JavaFX Script 概念。
本文以上篇文章为基础,通过示例程序帮助您更好地理解 JavaFX Script 概念,并将重点介绍如何使用 JavaFX Script 技术提供的以下用户界面 (UI) 组件:
Box
ColorChooser
Dialog
Menu
MenuBar
MenuItem
SimpleLabel
TextField
通过阅读本文,您将掌握以下操作:
- 定义一个类
- 在说明性表达式中声明变量
- 将 UI 组件的属性绑定到变量
- 导入 Java 类并调用类中的方法
目录
- | 体验 SomeBasicWidgets.fx 程序 |
- | 定义和使用 JavaFX Script 技术提供的类 |
- | 创建类实例 |
- | 创建 TextField 组件 |
- | 创建菜单结构 |
- | 创建菜单栏 |
- | 创建菜单 |
- | 创建菜单项 |
- | 使用 JavaFX Script 技术提供的 Java 类 |
- | 创建对话框 |
- | 绑定的魔力 |
- | ColorChooser UI 组件 |
- | 结束语 |
- | 更多信息 |
- | 关于作者 |
根据 上篇文章 的步骤编译并运行 SomeBasicWidgets.fx 程序。弹出的窗口如图 1 所示。
|
请注意:Options 中的字母 O 是带下划线的,这表示它可以使用快捷键,用户可以单击 Options 或按 Ctrl-O 来选择 Options 菜单。您将看到如图 2 所示的 Options 下拉菜单。
|
与 Options 菜单相同,每个菜单项都有一个快捷键。此外,还有两个菜单项提供了 加速键,在本例中分别为 Ctrl-T 和 Ctrl-S,为用户选择这些菜单项提供了快捷方式。选择 Text 菜单项将出现图 3 所示的对话框。
|
使用此对话框编辑将在主窗口中显示的文本,然后单击 OK 或按 Enter 键确认更改。如您所见,OK 按钮是默认按钮,因此按下 Enter 键可以实现相同操作。如果要拒绝更改,单击 Cancel 按钮或按 Esc 键即可。
现在,在文本区域中输入 A horse of a different color
并单击 OK 按钮 或按 Enter 键。对话框关闭,程序的主窗口将如图 4 所示。
|
在 Options 菜单中,选择 Select Color 将出现图 5 所示的颜色选择器 (color chooser) 对话框,现在,您可以为消息选择不同的颜色。
|
选择一个与当前蓝色不同的颜色,比如红色,然后单击 OK 按钮或按下 Enter 键。窗口中的消息将显示为您选择的颜色。
以下是 SomeBasicWidgets.fx 程序的源代码清单:
/* |
现在,仔细阅读源代码,注意本文中介绍的概念。
JavaFX Script 是完全面向对象的描述性脚本语言,您可以根据以下示例程序的方法定义自己的类:
class Model { |
我将这个非常简单的示例命名为 Mode1
,它包含两个属性:
- 出现在应用程序主窗口中的消息
- 消息的颜色
各属性的类分别位于属性名称后的冒号 (:
) 后面。
类也可以包含函数,这将在本系列的后续文章中讨论。此外,class
、attribute
和 function
声明可以附带修饰符,如 public
、private
和 protected
。
以下代码摘录自定义 UI 的说明性表达式,用于创建 Model
类。它将到该实例的引用指定名称为 Model
的变量。
var model = |
Model
引用变量将使程序的 UI 能与 Model
类中的属性保持同步。
TextField
组件
以下代码摘录自创建 TextField
组件并将其引用指定给名称为 msgTF
变量的程序。
var msgTF:TextField = |
程序将在稍后使用该变量确定用户输入到文本区域中的内容。表 1 列出了 TextField
类有用的一些属性。
公共属性
|
类型
|
描述
|
---|---|---|
action
|
事件处理程序
function()
|
用户按 Enter 时被引用。
|
columns
|
Number
|
栏中文本的宽度。
|
editable
|
Boolean
|
控制是否文本是可编辑的。
|
enableDND
|
Boolean
|
控制是否允许拖放。
|
horizontalAlignment
|
HorizontalAlignment
|
区域中文本的水平对齐方式:前端、中间或后端。
|
margin
|
Insets
|
设置文本周围的空白,
Insets 有四个表达的像素属性:
top 、
bottom 、
left 和
right 。
|
onChange
|
事件处理程序
function(String)
|
当用户更改文本区域的内容时,被调用。更改的文本被传递到函数中。
|
selectOnFocus
|
Boolean
|
当区域收到焦点时,控制是否文本被选择。
|
text
|
String
|
用户正输入到文本区域中的内容。
|
value
|
String
|
焦点丢失或用户按 Enter 键后文本区域内的值。
|
TextField
是 Widget
类的一个子类,因此,TextField
类继承了表 2 列出的 Widget
属性。注意:几个其他的组件源自于 Widget
类,所以本文将再次引用表 2。
公共属性
|
类型
|
描述
|
---|---|---|
background
|
AbstractColor
|
该组件的背景颜色
|
focusTraversalKeysEnabled
|
Boolean
|
控制是否用户可以通过焦点遍历键(如 Tab 键)登录该组件。
|
font
|
Font
|
该组件中呈现的文本的字体
|
foreground
|
AbstractColor
|
该组件的前景色
|
name
|
String
|
您分配到该组件中的名称
|
toolTipText
|
String
|
当鼠标覆盖该文本时显示的 tooltip 文本。
|
visible
|
Boolean
|
控制组件的可见性
|
为了让您了解本文介绍的所有类和属性的全景视图,图 6 显示了 JavaFX Script 类的部分层次结构。
|
以下代码用于创建菜单结构:
menubar: |
让我们看一下该程序中使用的各个菜单相关类。
如前面的代码摘录所示,要在 Frame
创建菜单,必须首先创建一个 MenuBar
实例并把它分配到 Frame
的 menubar
属性。MenuBar
类扩展 Widget
类,所以 表 2 中的属性也适用于 MenuBar
。表 3 包含 MenuBar
类中最常用的属性。
公共属性
|
类型
|
描述
|
---|---|---|
menus
|
Menu[]
|
MenuBar 中的顶级菜单
|
要在 MenuBar
上创建菜单,请将它们分配给 MenuBar
的 menus
属性。为一个属性分配多个对象需要使用数组字面值表示,它包含值(在方括号中、以逗号隔开)。注意:数组在 JavaFX Script 技术中称作序列。
如您在前面的代码摘录中所见,Menu
组件有几个可用的公共属性,包括表 4 中所列。
公共属性
|
类型
|
描述
|
---|---|---|
items
|
AbstractMenuItem[]
|
持有菜单项(详见下节)。该属性也能持有
Menu 组件,因此可以定义多级菜单结构。
|
mnemonic
|
KeyStroke
|
制定一个能够与 Alt 键一同使用以调用菜单的键,本例中为 O 键,它由不变值
KeyStroke.O 表示。
|
text
|
String
|
Menu 上的标记,本例中为词 Options 上的标记。
|
此 Menu
为 Widget
类的子代,所以 表 2 中的属性也适用于 Menu
类。
如之前代码中的 Text
菜单项所示,要创建 Menu
菜单项,需要使用数组字面值将它们分配给 Menu
组件的 items
属性。MenuItem
组件中的可用属性如表 5 所示。
公共属性
|
类型
|
描述
|
---|---|---|
accelerator
|
Accelerator
|
定义一个用来调用菜单项的快捷键,可以通过
Accelerator 类中的
modifier 和
keystroke 属性定义快捷键。在本例中,快捷键组合为 Ctrl-T。
|
action
|
事件处理程序
function()
|
定义用于在行为事件发生时调用的函数(即用户选择该菜单项时)。要完成此项操作,必须对
action 属性分配一个匿名的函数。注意:由于与
action 属性相关的函数什么都不返回,所以应该使用
Void 返回类型定义。
|
icon
|
Icon
|
菜单项中显示的图标。
|
mnemonic
|
KeyStroke
|
定义一个键,能与 Alt 键结合使用以调用菜单项,本例中为字母 T 键,由不变值
KeyStroke.T 表示。
|
text
|
String
|
MenuItem 上的标记,本例中, 字符串
Text...
|
MenuItem
是 Widget
类的子类,所以表 2 中的属性也适用于 MenuItem
类。注意:MenuItem
是一个叶子或终端节点。它不包含其他菜单项部件。
JavaFX Script 技术的一个优势是能够利用 Java 技术。下面是一个小示例:当用户选择 Exit 菜单项时调用函数。
function():Void { |
java.lang.System
类的 exit()
方法被调用,这会触发程序退出。要识别该程序的 System
类,必须使用一个导入声明:
import java.lang.System; |
在以下代码示例中,事件发生时将调用 System
类的 exit()
方法:
onClose: |
帧关闭时将调用分配给 Frame
的 onClose
属性的函数,确保当用户点击帧的 Close 按钮时,程序仍然存在。
JavaFX Script 技术可以与 Java 技术实现全面交互,所以它能够实例化 Java 类、调用方法并访问静态和实例变量。
表 6 列出了 Frame 类中有用的一些属性:
公共属性
|
类型
|
描述
|
---|---|---|
background
|
AbstractColor
|
设置帧的背景颜色
|
centerOnScreen
|
Boolean
|
使帧集中在屏幕上
|
content
|
Widget
|
帧所包含的 UI 组件。组件被伸展以填满整个帧。
|
height
|
Number
|
帧的高度、像素。
|
menubar
|
MenuBar
|
帧上的可选菜单栏。
|
onClose
|
Event handler
function()
|
定义一个当发生对话
onClose 事件时(即当对话框关闭时)调用的函数。要完成此项操作,必须为
onClose 属性分配一个匿名函数。注意:由于与行为属性相关的函数不返回任何事物,所以应该使用
Void 返回类型对其定义。
|
onOpen
|
Event handler
function()
|
定义一个当发生对话
onOpen 事件时(即对话框开启时)调用的函数,要完成此项操作,必须为
onOpen 属性分配一个匿名函数。注意:由于与行为属性相关的函数不返回任何事物,所以应该使用
Void 返回类型对其定义。
|
title
|
String
|
将出现在帧的标题区域内字符串。
|
visible
|
Boolean
|
控制帧的可见性。
|
width
|
Number
|
帧的宽度、像素。
|
如前所述,JavaFX Script 技术提供了一个名为 MessageDialog
的简单对话框,用于向用户提供消息。但是,您也可以自己定义对话框,使用户能提供更复杂的输入。为此,您可以使用 Dialog
类,如下所示:
dlg = |
该说明性表达式将生成一个 Dialog
实例,并提供 图 3 中的内容和按钮。该表达式将被分配给一个变量,所以当用户点击按钮时会调用 Dialog
类的 hide()
函数。dlg
变量声明如下所示:
var dlg:Dialog |
注意:Dialog
类的属性与 Frame
类的属性非常相似。本对话框中使用了一个新的属性:modal
。如果值为 true
,必须先解除对话框,用户才能与潜在的应用程序交互。
如上述代码所示,您可以使用 Box
布局组件让 SimpleLabel
直接出现在 TextField
上方。回想一下,TextField
实例被分配给 msgTF
变量。SimpleLabel
组件正是一个包含文本和/或图标的简单的标记。
表 7 列出了 SimpleLabel
类中有用的一些属性。
公共属性
|
类型
|
描述
|
---|---|---|
icon
|
Icon
|
SimpleLabel 能够包含图标,文本或包含两者。该属性使图标显示。
|
text
|
String
|
该
SimpleLabel 中显示的文本字符串。
|
Box
布局组件使您能够垂直或水平堆叠组件。表 8 列出了 Box
类中有用的一些属性
公共属性
|
类型
|
描述
|
---|---|---|
content
|
Widget[]
|
Box 包含的 UI 组件。组件保留优选尺寸。
|
orientation
|
Orientation
|
Box 中的内容的方向,例如,是水平的还是垂直的
|
现在,将注意力转到按钮上来。如果 defaultButton
属性为 true
,则按 Enter 键将激活按钮。同样,如果 defaultCancelButton
属性是 true
,则按 Esc 将激活按钮。在本程序中,当用户在文本区域内输入文本字符并单击 OK 或按下 Enter 键时,文本区域的值将被分配给 model
对象的 messageText
属性。
表 9 列出了 Dialog
类中有用的一些属性。
公共属性
|
类型
|
描述
|
---|---|---|
buttons
|
Button[]
|
出现在对话框中的按钮。
|
content
|
Widget
|
对话框包含的 UI 组件。组件被伸展以填满整个对话框,但不包括为按钮保留的区域。
|
height
|
Number
|
对话框的高度、像素。
|
modal
|
Boolean
|
决定是否在用户与应用程序交互前必须解除对话框。
|
onClose
|
事件处理程序
function()
|
定义当发生
dialog onClose 事件时(即当对话框关闭时)调用的函数。要达到此目的,必须对
onClose 属性分配一个匿名函数。注意:由于与行为属性相关的函数不返回任何事物,所以使用
Void 返回类型定义该函数。
|
owner
|
UIElement
|
指出 UI 元件所属的对话框。尤其当
modal 为
true 时,它的意义重大,因为此时对话随它的所有者是形式上的。
|
title
|
String
|
出现在对话框标题区域的字符串。
|
visible
|
Boolean
|
控制对话框的可见性。
|
width
|
Number
|
对话框的宽度、像素。
|
开发人员常说:“一旦使用了绑定,则永远不能执行返回操作”,JavaFX Script 技术的独特设计实现了“模型-视图-控制程序(MVC)” 模式。借助 bind
运算符,您可以轻松使视图 (UI) 和模型(数据)保持同步。
在本例中,当 messageText
属性更改时,Text
图形对象的 content
属性也将随之改变,因为它与 messageText
属性是绑定在一起的,如下所示:
Text { |
同样,Text
图形对象的 stroke
和 fill
属性将与 model
对象的 messageColor
属性绑定在一起。接下来,您将了解如何使用 ColorChooser
组件实现用户对 messageColor
属性的更改。
ColorChooser
UI 组件
ColorChooser
组件是一个易于使用且功能强大的 UI 组件,用于帮助用户是实现对颜色的选择。阅读下面的代码摘录,了解如何使用该组件:
ColorChooser { |
该类的 initialColor
属性控制颜色选择器出现时选择的默认颜色。当用户单击 OK 或按 Enter 键时,所选颜色将被传递给匿名函数,然后分配给 model
实例的 messageColor
属性。这会使 Text
图形对象的 stroke
和 fill
属性保持为最新选择的颜色。例如,如果选择红色,那么主应用程序窗口将如图 6 所示。
|
表 10 列出了 ColorChooser
类有用的一些属性。
公共属性
|
类型
|
描述
|
---|---|---|
action
|
事件处理程序
function(Color)
|
定义发生行为事件时(即当用户单击 OK 或按 Enter 键时)调用的函数。要达到此目的,必须为
action 分配一个匿名函数。传给该函数的颜色为用户在
ColorChooser 中所选的颜色。
|
initialColor
|
Color
|
颜色选择器出现时默认选择的颜色。
|
selectedColor
|
Color
|
用户已经选择的颜色。
|
title
|
String
|
出现在颜色选择器标题区域的字符串。
|
通过阅读本文,您已经掌握了以下技巧:
- 使用经过编译的 JavaFX Script 技术定义简单的类并将其实例化,将实例分配给变量。
- 创建和使用
TextField
、Dialog
、SimpleLabel
和ColorChooser
UI 组件。 - 创建
MenuBar
、Menu
和MenuItem
实例,并为它们设置合适的快捷键和加速键。你还掌握了如何创建匿名函数,定义用户选择MenuItem
时的事件。 - 将 UI 组件和图形对象的属性绑定到变量。在本例中,这些变量是
Model
类的属性。 - 导入 Java 类并调用它的方法,本例调用的是
java.lang.System
类的静态exit()
方法。
- OpenJFX Compiler 项目主页
- The OpenJFX Compiler 项目维客
- The OpenJFX Compiler 项目邮件列表
- James Weaver 的JavaFX 技术博客
- 使用经过编译的 JavaFX Script 技术创建富 Internet 应用程序
- java.sun.com 上的 JavaFX 索引
James L. (Jim) Weaver 在 LAT, Inc. 担任 CTO,同时也是一名 Java 推介人。他撰写了数本书籍并经常为团队和会议演讲,还创立了 JavaFXpert BootCamp。他的最新著作是 JavaFX Script: Dynamic Java Scripting for Rich Internet/Client-Side Applications。他还定期在一家 JavaFX 技术 博客 站点上发表文章。