第 6 课:排放 GUI 元素

 第 6 课:排放 GUI 元素

使用 JavaFX SDK 中的布局机制,您可以很容易地排列和对齐组件,而不必为每个 UI 对象指定绝对坐标。尽管绝对坐标可提供一定程度的灵活性,但有时您会发现布局机制更加方便。本教程中提供的示例代码使用 JavaFX Script 编程语言的数据绑定和声明性语法。有关这些概念的更多详细信息,请参阅学习 JavaFX Script 编程语言
 

目录


创建应用程序窗口
创建图形场景
定义单选按钮
创建圆
创建垂直布局
应用水平布局
 

考虑创建三个圆和一个单选按钮切换组。每个单选按钮可控制对应圆中的一种颜色。选择该单选按钮后,即会应用这种颜色,否则,圆是灰色的。此方案模拟交通信号灯,它是本教程中用来说明布局机制的示例。

 
交通信号灯
图 1:交通信号灯
 


要评估和测试您的应用程序,请创建一个扩展名为 .fx 的文件,例如 layout.fx

您可以在任意时间使用以下命令编译您的代码:

javafxc layout.fx


您可以使用以下命令运行编译的代码:

javafx layout


使用 Stage 类创建一个窗口:

  1. javafx.stage.Stage 类添加 import 语句。
  2. Stage 对象字面值添加到代码中。
  3. 指定窗口的标题、宽度和高度。

在图形场景中显示 UI 对象中,您已经了解了 UI 组件、形状、文本和图形被当作是图形场景中的对象分层结构。现在,您可以创建场景了。

  1. SceneColor 类添加 import 语句。
  2. Scene 对象字面值添加到 Stage 类的 scene 实例变量中。
  3. 使用 Scene 类的 fill 变量定义场景的颜色。

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
Stage {
title: "Lights"
width: 220
height: 130
visible: true
scene:
Scene{
fill: Color.HONEYDEW
}//Scene
}//Stage


创建一组单选按钮,在给定的时间只能选择其中一个按钮。这称为切换组。请执行以下步骤:

  1. 使用 SwingToggleGroup 类定义切换组。


    注意:在本课的示例代码中,您将为每个 UI 元素定义一个变量名称,以便可以很容易地了解布局机制是如何工作的。您还要通过引用变量名称来对 UI 元素应用绑定。
  2. 使用 SwingRadioButton 类创建三个可用来选择特定交通信号灯的单选按钮。
  3. 使用 toggleGroup 实例变量将每个单选按钮添加到组中。
  4. 使用 font 实例变量来更改单选按钮的标题样式。
  5. 将相应的 import 语句添加到代码中。

以下代码片段用来定义一个切换组,然后创建单选按钮并将它们添加到组中。

import javafx.ext.swing.SwingToggleGroup;
import javafx.ext.swing.SwingRadioButton;
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};


绘制代表交通信号灯的圆:

  1. CircleRadialGradientStop 类添加 import 语句。
  2. lightStop 变量中定义代表红灯的圆。
  3. 应用径向渐变填充以增强此示例的视觉效果。

    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。有关形状和视觉效果的更多信息,请参阅创建图形对象
  4. 再创建两个由 lightReadylightGo 定义的圆,然后将这两个圆绑定到相应的单选按钮。

在创建所有组件之后,您可以使用 HBoxVBox 类将其排放在场景中。VBox 类用于垂直排列组件,HBox 类用于水平排列组件。在本示例中,您需要使用一个 VBox 对象来排放单选按钮,使用一个 HBox 对象来排放圆,还要使用一个 HBox 来排列这两个框。

 
HBox 和 VBox 的组合
图 2:HBox 和 VBox 的组合
 

为单选按钮创建垂直布局:

  1. 将相应的 import 语句添加到代码中。VBoxHBox 都位于 javafx.scene.layout 软件包中。
  2. 使用以下代码行在垂直框中排列这些单选按钮:

    VBox{content:[choice1, choice2, choice3]}
     
  3. 使用 spacing 实例变量定义 VBox 对象的元素之间的间隔(以像素为单位)。

以下代码片段可完成这些任务。

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
} //Stop
]
} //RadialGradient
};
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
} //Stop
]
} //RadialGradient
};

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
}//Stop
]
}//RadialGradient
};
Stage {
title: "Lights"
width: 220
height: 130
visible: true
scene:
Scene{
fill: Color.HONEYDEW
content:
VBox{spacing: 10 content:[choice1, choice2, choice3]}
} //Scene
}//Stage


编译和运行之后,此修改后的代码将生成以下窗口。

 
具有单选按钮的垂直框
图 3:具有单选按钮的垂直框
 


执行以下步骤对交通信号灯圆应用水平布局:

  1. 使用以下代码行将这些圆添加到 HBox 对象的内容中。

    HBox{spacing: 15 content:[lightStop, lightReady, lightGo]}
     
  2. translateY 实例变量设置为 25 来为水平框指定垂直偏移。
  3. 使用另一个 HBox 对象来排放具有单选按钮的垂直框和具有圆的水平框。
  4. 请参见此示例的完整代码,如下所示。

    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 组件。您可以针对您的当前任务使用布局机制、绝对坐标或这两种方法的组合。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值