Java开发笔记(一百四十)JavaFX的选择框
与Swing一样,JavaFX依然提供了三种选择框,它们是复选框CheckBox、单选按钮RadioButton、下拉框ComboBox,分别说明如下:
一、复选框CheckBox
复选框允许同时勾选多个,已勾选的时候在方框内部打个勾,未勾选的时候显示空心方框。查看CheckBox的源码,发现它与Button控件都派生自抽象类ButtonBase,因而CheckBox拥有和Button同样的set***/get***方法。不同之处主要有以下两点:
1、关于勾选状态的设置与判断:调用setSelected方法可以设置复选框的勾选状态,调用isSelected方法可以判断复选框是否被勾选了。
2、关于勾选监听器的设置:先调用selectedProperty方法获得复选框的属性对象,再调用属性对象的addListener方法设置该复选框的勾选监听器。下面是给复选框设置单击监听器的代码例子:
- CheckBox ck = new CheckBox("满意"); // 创建一个复选框
- ck.selectedProperty().addListener(new ChangeListener<Boolean>() { // 设置复选框的勾选监听器
- @Override
- public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
- // 单击复选框会触发这里的changed方法
- }
- });
接下来举个具体的案例,餐厅的点餐系统要在界面上罗列各种菜肴,以便顾客勾选准备下单的菜品。简单起见先列出三道菜肴,对应三个复选框,编写完成的界面代码示例如下:
- // 获取复选框的界面
- private void getCheckBox(BorderPane borderPane) {
- VBox vbox = new VBox(); // 创建一个垂直箱子
- HBox hbox = new HBox(); // 创建一个水平箱子
- CheckBox ck1 = new CheckBox("麻婆豆腐"); // 创建一个复选框
- CheckBox ck3 = new CheckBox("清蒸桂花鱼"); // 创建一个复选框
- CheckBox ck2 = new CheckBox("香辣小龙虾"); // 创建一个复选框
- hbox.getChildren().addAll(ck1, ck2, ck3); // 把三个复选框一起加到水平箱子上
- CheckBox[] boxArray = new CheckBox[]{ck1, ck2, ck3}; // 构建复选框数组
- Label label = new Label("这里查看菜单详情"); // 创建一个标签
- label.setWrapText(true); // 设置标签文本是否支持自动换行
- vbox.getChildren().addAll(hbox, label); // 把水平箱子和标签一起加到垂直箱子上
- ck1.selectedProperty().addListener(new ChangeListener<Boolean>() { // 设置复选框的勾选监听器
- @Override
- public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
- // 拼接并显示当前的勾选结果,以及已经勾选的菜肴
- label.setText(String.format("您%s了%s。当前已点菜肴包括:%s",
- (ck1.isSelected() ? "点" : "取消"), ck1.getText(), getCheckedItem(boxArray)));
- }
- });
- ck2.selectedProperty().addListener(new ChangeListener<Boolean>() { // 设置复选框的勾选监听器
- @Override
- public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
- // 拼接并显示当前的勾选结果,以及已经勾选的菜肴
- label.setText(String.format("您%s了%s。当前已点菜肴包括:%s",
- (ck2.isSelected() ? "点" : "取消"), ck2.getText(), getCheckedItem(boxArray)));
- }
- });
- ck3.selectedProperty().addListener(new ChangeListener<Boolean>() { // 设置复选框的勾选监听器
- @Override
- public void changed(ObservableValue<? extends Boolean> arg0, Boolean old_value, Boolean new_value) {
- // 拼接并显示当前的勾选结果,以及已经勾选的菜肴
- label.setText(String.format("您%s了%s。当前已点菜肴包括:%s",
- (ck3.isSelected() ? "点" : "取消"), ck3.getText(), getCheckedItem(boxArray)));
- }
- });
- borderPane.setCenter(vbox); // 把垂直箱子放到边界窗格的中央
- }
上面代码用到了新方法getCheckedItem,该方法用来获取已经选中的所有菜肴,它的代码定义如下所示:
- // 获取已经选定的菜单
- private String getCheckedItem(CheckBox[] boxArray) {
- String itemDesc = "";
- for (CheckBox box : boxArray) { // 遍历复选框数组
- if (box.isSelected() == true) { // 复选框被选中了
- if (itemDesc.length() > 0) {
- itemDesc = itemDesc + "、";
- }
- itemDesc = itemDesc + box.getText(); // 菜单添加选定的菜肴
- }
- }
- return itemDesc;
- }
运行包含以上代码的点餐程序,弹出的窗口初始界面如下图所示。
从左往右依次单击三个复选框,界面上的点餐结果分别如下列三张图所示。
二、单选按钮RadioButton
在同一小组内的单选按钮,最多只能选择其中一个,它被选中时在圆圈内部显示一个圆点,未选中时只显示空心圆圈。RadioButton也由ButtonBase派生而来,因此拥有与Button控件同样的set***/get***方法。区别之处主要有下列两点:
1、关于加入到一个单选小组:调用单选按钮的setToggleGroup方法,即可加入到指定的按钮小组,该小组的控件类型是ToggleGroup。
2、关于单选按钮的选择监听器:JavaFX把这个监听器改到小组上面了,先调用ToggleGroup对象的selectedToggleProperty方法获得单选组的属性对象,再调用属性对象的addListener方法设置该小组的单击监听器。
仍然以点餐系统为例,这次准备让顾客享用单点的快餐,小店刚开业暂时只提供三种快餐,对应三个单选按钮,编写完成的界面代码示例如下:
- // 获取单选按钮的界面
- private void getRadioButton(BorderPane borderPane) {
- VBox vbox = new VBox(); // 创建一个垂直箱子
- HBox hbox = new HBox(); // 创建一个水平箱子
- RadioButton rb1 = new RadioButton("鱼香肉丝饭"); // 创建一个单选按钮
- rb1.setSelected(true); // 设置按钮是否选中
- RadioButton rb2 = new RadioButton("香菇滑鸡饭"); // 创建一个单选按钮
- RadioButton rb3 = new RadioButton("黑椒牛排饭"); // 创建一个单选按钮
- hbox.getChildren().addAll(rb1, rb2, rb3); // 把三个单选按钮一起加到水平箱子上
- ToggleGroup group = new ToggleGroup(); // 创建一个按钮小组
- rb1.setToggleGroup(group); // 把单选按钮1加入到按钮小组
- rb2.setToggleGroup(group); // 把单选按钮2加入到按钮小组
- rb3.setToggleGroup(group); // 把单选按钮3加入到按钮小组
- Label label = new Label("这里查看点餐结果"); // 创建一个标签
- label.setWrapText(true); // 设置标签文本是否支持自动换行
- vbox.getChildren().addAll(hbox, label); // 把水平箱子和标签一起加到垂直箱子上
- // 设置单选组合的单击监听器
- group.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
- @Override
- public void changed(ObservableValue<? extends Toggle> arg0, Toggle old_toggle, Toggle new_toggle) {
- // 在标签上显示当前选中的单选按钮文本
- label.setText("您点了" + ((RadioButton)new_toggle).getText());
- }
- });
- borderPane.setCenter(vbox); // 把垂直箱子放到边界窗格的中央
- }
运行包含以上代码的点餐程序,弹出的窗口初始界面如下图所示。
从图示可见当前默认选中了第一个快餐“鱼香肉丝饭”,此时先后单击第二个快餐和第三个快餐,界面上的点餐结果分别如下列两张图所示。
三、下拉框ComboBox
如果单选小组里面的选项有很多,全部罗列到窗口上势必占用大量界面空间,故而采用可伸缩的下拉框较为合适。平时只显示最近一次选中的文字,需要改变的话再单击弹出下拉列表,在下拉列表中选完再恢复原状。看起来JavaFX的下拉框跟Swing的功能差不多,不过JavaFX的ComboBox控件用起来颇为怪异,有下面几点需要特别注意:
1、关于选中某项以及获取选中项:得先调用下拉框的getSelectionModel方法获得模型对象,再调用模型对象的相应方法完成指定功能。例如,调用模型对象的select方法可以选中某项,调用getSelectedIndex方法可以获得选中项的序号,调用getSelectedItem方法可以获得选中项的对象。
2、关于设置下拉框的字体:ComboBox控件竟然没提供setFont方法,只能调用setStyle方法通过css样式设置文本字体及其大小。
3、关于设置下拉框的选择监听器:这个操作更复杂,要先调用下拉框的getSelectionModel方法获得模型对象,再调用模型对象的selectedItemProperty方法获得该模型的属性对象,接着调用属性对象的addListener方法给下拉框添加选择监听器。
继续以点餐系统为例,原来那家快餐店的生意日趋红火,快餐种类增加了不少,他们的点餐系统也将单选小组改造成了下拉框。改造完成的界面代码示例如下:
- // 获取下拉框的界面
- private void getComboBox(BorderPane borderPane) {
- VBox vbox = new VBox(); // 创建一个垂直箱子
- // 初始化快餐列表
- List<String> snackList = Arrays.asList("鱼香肉丝饭", "香菇滑鸡饭", "黑椒牛排饭",
- "梅菜扣肉饭", "糖醋里脊饭", "红烧排骨饭", "台式卤肉饭");
- // 把清单对象转换为JavaFX控件能够识别的数据对象
- ObservableList<String> obList = FXCollections.observableArrayList(snackList);
- ComboBox<String> comboBox = new ComboBox<String>(obList); // 依据指定数据创建下拉框
- //comboBox.setItems(obList); // 设置下拉框的数据来源
- comboBox.getSelectionModel().select(0); // 设置下拉框默认选中第1项
- Font font = Font.font("NSimSun", 16); // 创建一个字体对象
- comboBox.setStyle(String.format("-fx-font: %f \"%s\";", font.getSize(), font.getFamily())); // 设置下拉框的字体
- comboBox.setEditable(false); // 设置下拉框能否编辑。默认不允许编辑
- Label label = new Label("这里查看点餐结果"); // 创建一个标签
- label.setWrapText(true); // 设置标签文本是否支持自动换行
- vbox.getChildren().addAll(comboBox, label); // 把水平箱子和标签一起加到垂直箱子上
- // 设置下拉框的选择监听器
- comboBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
- @Override
- public void changed(ObservableValue<? extends String> arg0, String old_str, String new_str) {
- // getSelectedIndex方法可获得选中项的序号,getSelectedItem方法可获得选中项的对象
- String desc = String.format("您点了第%d项,快餐名称是%s",
- comboBox.getSelectionModel().getSelectedIndex(),
- comboBox.getSelectionModel().getSelectedItem().toString());
- label.setText(desc); // 在标签上显示当前选中的文本项
- }
- });
- borderPane.setCenter(vbox); // 把垂直箱子放到边界窗格的中央
- }
运行包含以上代码的点餐程序,弹出的窗口初始界面如下图所示。
单击下拉框控件,下方弹出一个包含所有快餐的列表框,具体界面如下图所示。
单击下拉列表中的某一项,表示换成指定的快餐,此时下拉列表隐藏,下拉框的文字变成刚点的快餐名称,点餐结果正如下图所示。
更多Java技术文章参见《Java开发笔记(序)章节目录》
Java开发笔记(一百四十)JavaFX的选择框的更多相关文章
- Java开发笔记(三十二)字符型与整型相互转化
前面提到字符类型是一种新的变量类型,然而编码实践的过程中却发现,某个具体的字符值居然可以赋值给整型变量!就像下面的例子代码那样,把字符值赋给整型变量,编译器不但没报错,而且还能正常运行! // 字符允 ...
- Java开发笔记(三十八)利用正则表达式校验字符串
前面多次提到了正则串.正则表达式,那么正则表达式究竟是符合什么定义的字符串呢?正则表达式是编程语言处理字符串格式的一种逻辑式子,它利用若干保留字符定义了形形色色的匹配规则,从而通过一个式子来覆盖满足了 ...
- Java开发笔记(三十九)日期工具Date
Date是Java最早的日期工具,编程中经常通过它来获取系统的当前时间.当然使用Date也很简单,只要一个new关键字就能创建日期实例,就像以下代码示范的那样: // 创建一个新的日期实例,默认保存的 ...
- Java开发笔记(四十)日期与字符串的互相转换
前面介绍了如何通过Date工具获取各个时间数值,但是用户更喜欢形如“2018-11-24 23:04:18”这种结构清晰.简洁明了的字符串,而非啰里八唆依次汇报每个时间单位及其数值的描述.既然日期时间 ...
- Java开发笔记(八十九)缓存字节I/O流
文件输出流FileOutputStream跟FileWriter同样有个毛病,每次调用write方法都会直接写到磁盘,使得频繁的写操作性能极其低下.正如FileWriter搭上了缓存兄弟Buffere ...
- Java开发笔记(八十八)文件字节I/O流
前面介绍了如何使用字符流读写文件,并指出字符流工具的处理局限,进而给出随机文件工具加以改进.随机文件工具除了支持访问文件内部的任意位置,更关键的一点是通过字节数组读写文件数据,采取字节方式比起字符方式 ...
- Java开发笔记(八十六)通过缓冲区读写文件
前面介绍了利用文件写入器和文件读取器来读写文件,因为FileWriter与FileReader读写的数据以字符为单位,所以这种读写文件的方式被称作“字符流I/O”,其中字母I代表输入Input,字母O ...
- Java开发笔记(八十五)通过字符流读写文件
前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...
- Java开发笔记(八十四)文件与目录的管理
程序除了处理内存中的数据结构,还要操作磁盘上的各类文件,这里的磁盘是个统称,泛指可以持久保留数据的存储介质,包括但不限于:插在软驱中的软盘.固定在机箱中的硬盘.插在光驱中的光盘.插在USB接口上的U盘 ...
- Java开发笔记(八十二)注解的基本单元——元注解
Java的注解非但是一种标记,还是一种特殊的类型,并且拥有专门的类型定义.前面介绍的五种内置注解,都可以找到对应的类型定义代码,例如查看注解@Override的源码,发现它的代码定义是下面这样的: @ ...
随机推荐
- Tips on Probability Theory
1.独立与不相关 随机变量X和Y相互独立,有:E(XY) = E(X)E(Y). 独立一定不相关,不相关不一定独立(高斯过程里二者等价) .对于均值为零的高斯随机变量,“独立”和“不相关”等价的. 独 ...
- 关于Windows系统里的事后调试
我一直在想,应用程序抛出未处理的异常和附加到进程的调试器之间会发生什么.显然这些信息就在我眼皮底下,但我是瞎子.Windows调试器关于事后调试的文档包含了您想要知道的所有详细信息. 最常见的应用程序 ...
- PDO和MySQLi区别和数度;到底用哪个?
当用PHP访问数据库时,除了PHP自带的数据库驱动,我们一般还有两种比较好的选择:PDO和MySQLi.在实际开发过程中要决定选择哪一种首先要对二者有一个比较全面的了解.本文就针对他们的不同点进行分析 ...
- 微信小程序class封装http
config.js var config = { base_api_url:"https://douban.uieee.com/v2/" } export {config} uti ...
- mysql sum()函数 , 计算总和
mysql> select * from table1; +----------+------------+-----+---------------------+ | name_new | t ...
- Linux命令及作用
uname -r :查看当前使用的Linux内核版本信息 cat /proc/cpuinfo:查看当前主机CPU型号,规格等信息 cat /proc/meminfo :查看当前主机内存信息 hostn ...
- 前后端通信—CORS(支持跨域)
根据前端跨域的那些事这篇文章中的跨域的理解这一块,我们重新创建两个服务,第一个服务使用了test.html const http = require('http') const fs = requir ...
- [BUAA软工]Alpha阶段事后分析
设想和目标 虽然我们是从零开始的一个自定义项目,但语音Coding助手从一开始的设计与目标就很明确:加入语音接口使其能在shell端实现命令语音实现以及编辑运行脚本,设计前端编辑器并将后端shell与 ...
- 团队作业-Beta版本演示
组长博客链接 https://www.cnblogs.com/cmlei/p/12063671.html 本组成员 031702431 陈明磊 组长 031702227 林镕炜 031702413 韩 ...
- 测量MySQL的表达式和函数的速度
测量MySQL的表达式和函数的速度,可以调用benchmark()函数.语法格式是benchmark(loop_count,expr).运行的返回值是0,但是mysql会打印一行显示语句大概要执行多长 ...