第 6 课:排放 GUI 元素
使用 JavaFX SDK 中的布局机制,您可以很容易地排列和对齐组件,而不必为每个 UI 对象指定绝对坐标。尽管绝对坐标可提供一定程度的灵活性,但有时您会发现布局机制更加方便。本教程中提供的示例代码使用 JavaFX Script 编程语言的数据绑定和声明性语法。有关这些概念的更多详细信息,请参阅学习 JavaFX Script 编程语言。 |
- | 创建应用程序窗口 |
- | 创建图形场景 |
- | 定义单选按钮 |
- | 创建圆 |
- | 创建垂直布局 |
- | 应用水平布局 |
考虑创建三个圆和一个单选按钮切换组。每个单选按钮可控制对应圆中的一种颜色。选择该单选按钮后,即会应用这种颜色,否则,圆是灰色的。此方案模拟交通信号灯,它是本教程中用来说明布局机制的示例。
要评估和测试您的应用程序,请创建一个扩展名为 .fx
的文件,例如 layout.fx
。
您可以在任意时间使用以下命令编译您的代码:
javafxc layout.fx |
您可以使用以下命令运行编译的代码:
javafx layout |
使用 Stage
类创建一个窗口:
- 为
javafx.stage.Stage
类添加import
语句。 - 将
Stage
对象字面值添加到代码中。 - 指定窗口的标题、宽度和高度。
在在图形场景中显示 UI 对象中,您已经了解了 UI 组件、形状、文本和图形被当作是图形场景中的对象分层结构。现在,您可以创建场景了。
- 为
Scene
和Color
类添加import
语句。 - 将
Scene
对象字面值添加到Stage
类的scene
实例变量中。 - 使用
Scene
类的fill
变量定义场景的颜色。
|
创建一组单选按钮,在给定的时间只能选择其中一个按钮。这称为切换组。请执行以下步骤:
- 使用
SwingToggleGroup
类定义切换组。
注意:在本课的示例代码中,您将为每个 UI 元素定义一个变量名称,以便可以很容易地了解布局机制是如何工作的。您还要通过引用变量名称来对 UI 元素应用绑定。
- 使用
SwingRadioButton
类创建三个可用来选择特定交通信号灯的单选按钮。 - 使用
toggleGroup
实例变量将每个单选按钮添加到组中。 - 使用
font
实例变量来更改单选按钮的标题样式。 - 将相应的
import
语句添加到代码中。
以下代码片段用来定义一个切换组,然后创建单选按钮并将它们添加到组中。
import javafx.ext.swing.SwingToggleGroup; |
绘制代表交通信号灯的圆:
- 为
Circle
、RadialGradient
和Stop
类添加import
语句。 - 在
lightStop
变量中定义代表红灯的圆。 - 应用径向渐变填充以增强此示例的视觉效果。
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
var lightStop = Circle {
centerX: 12
centerY: 12
radius: 12
stroke: Color.BLACK
fill: bind RadialGradient {
centerX: 8, centerY: 8, radius: 12, proportional: false
stops: [
Stop {offset: 0.0 color: Color.WHITE},
Stop {offset: 1.0 color: if (choice1.selected)
then Color.RED
else Color.GREY
}//Stop
]//stops
}//RadialGradient
};//Circle
上面的代码样例使用数据绑定机制来更改圆的颜色。如果choice1
变量的selected
实例变量值为true
,则color
实例变量将变成Color.RED
,否则,它将是Color.GREY
。有关形状和视觉效果的更多信息,请参阅创建图形对象。 - 再创建两个由
lightReady
和lightGo
定义的圆,然后将这两个圆绑定到相应的单选按钮。
在创建所有组件之后,您可以使用 HBox
和 VBox
类将其排放在场景中。VBox
类用于垂直排列组件,HBox
类用于水平排列组件。在本示例中,您需要使用一个 VBox
对象来排放单选按钮,使用一个 HBox
对象来排放圆,还要使用一个 HBox
来排列这两个框。
为单选按钮创建垂直布局:
- 将相应的 import 语句添加到代码中。
VBox
和HBox
都位于javafx.scene.layout
软件包中。 - 使用以下代码行在垂直框中排列这些单选按钮:
VBox{content:[choice1, choice2, choice3]}
- 使用
spacing
实例变量定义VBox
对象的元素之间的间隔(以像素为单位)。
以下代码片段可完成这些任务。
import javafx.stage.Stage; |
编译和运行之后,此修改后的代码将生成以下窗口。
执行以下步骤对交通信号灯圆应用水平布局:
- 使用以下代码行将这些圆添加到
HBox
对象的内容中。
HBox{spacing: 15 content:[lightStop, lightReady, lightGo]}
- 将
translateY
实例变量设置为25
来为水平框指定垂直偏移。 - 使用另一个
HBox
对象来排放具有单选按钮的垂直框和具有圆的水平框。 - 请参见此示例的完整代码,如下所示。
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.ext.swing.SwingToggleGroup;
import javafx.ext.swing.SwingRadioButton;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
var group = SwingToggleGroup{};
var choice1 = SwingRadioButton{
text: "STOP"
foreground: Color.GRAY
font: Font{name:"Tahoma" size: 15}
toggleGroup: group};
var choice2 = SwingRadioButton{
text: "READY"
foreground: Color.GRAY
font: Font{name:"Tahoma" size: 15}
toggleGroup: group};
var choice3 = SwingRadioButton{
text: "GO"
foreground: Color.GRAY
font: Font{name:"Tahoma" size: 15}
toggleGroup: group};
var lightStop = Circle {
centerX: 12
centerY: 12
radius: 12
stroke: Color.GRAY
fill: bind RadialGradient {
centerX: 8,
centerY: 8,
radius: 12,
proportional: false
stops: [
Stop {offset: 0.0 color: Color.WHITE},
Stop {offset: 1.0 color: if (choice1.selected)
then Color.RED
else Color.GREY
}
]
}
};
var lightReady = Circle {
centerX: 12
centerY: 12
radius: 12
stroke: Color.GRAY
fill: bind RadialGradient {
centerX: 8,
centerY: 8,
radius: 12,
proportional: false
stops: [
Stop {offset: 0.0 color: Color.WHITE},
Stop {offset: 1.0 color: if (choice2.selected)
then Color.GOLD
else Color.GRAY
}
]
}
};
var lightGo = Circle {
centerX: 12
centerY: 12
radius: 12
stroke: Color.GRAY
fill: bind RadialGradient {
centerX: 8,
centerY: 8,
radius: 12,
proportional: false
stops: [
Stop {offset: 0.0 color: Color.WHITE},
Stop {offset: 1.0 color: if (choice3.selected)
then Color.GREEN
else Color.GREY
}
]
}
};
Stage {
title: "Lights"
width: 220
height: 130
visible: true
scene:
Scene{
fill: Color.HONEYDEW
content:
HBox{
spacing: 10
content:[
VBox{spacing: 10 content:[choice1, choice2, choice3]},
HBox{spacing: 15 content:[lightStop, lightReady, lightGo] translateY: 25}
]
}//HBox
} //Scene
}//Stage
编译和运行之后,此代码将生成以下窗口。
图 4:具有单选按钮的垂直框和具有圆的水平框
在本课中,您学习了如何在场景中排放 UI 组件。您可以针对您的当前任务使用布局机制、绝对坐标或这两种方法的组合。