前面介绍了如何通过fxml文件编排界面布局,可是光有静态界面根本没法处理业务,必须另外书写业务逻辑的代码,方能响应各按钮的单击事件,并将业务结果即使呈现到界面上。显然,fxml内部写不了Java代码,同时入口程序已经把控件都托管给了fxml文件,也无法在Application代码中干预控件的操作。既然整个界面都托付给了fxml,那么解铃还须系铃人,只能且必须由fxml指定后续的逻辑控制器。具体做法是在fxml的根节点中添加属性“fx:controller”,通过该属性设置当前界面的控制器路径。比如之前的登录布局文件login_with_flow.fxml,它的根节点是流式窗格FlowPane,所以就给FlowPane节点补充“fx:controller”的取值,详细的标签例子见下:

<FlowPane fx:controller="com.javafx.fxml.LoginController"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="5" vgap="5">

由以上的FlowPane标签可知,它指定的控制器路径为“com.javafx.fxml.LoginController”,这个LoginController类正是login_with_flow.fxml对应的控制器代码。作为FXML专属的搭档,控制器也要符合一定的格式规范,首先它必须实现了接口Initializable,并重写该接口定义的initialize方法,这个方法顾名思义会在界面初始化之时调用。其次,控制器内部需要声明FXML文件定义好的控件编号,这样才能通过控件编号操作每个控件对象。下面便是一个控制器范本的代码示例:

//界面控制器必须实现自接口Initializable
public class LoginController implements Initializable {
@FXML
private 控件类型 控件编号; // 其中控件类型为JavaFX的控件类名,控件编号取自fxml文件中的fx:id @Override
public void initialize(URL location, ResourceBundle resources) { // 界面打开后的初始化操作
// 可在此给各控件设置单击事件或者选中事件,也可设置控件上的文本字体及其大小
}
}

仍以前述的登录窗口为例,它的布局文件名叫login_with_flow.fxml,同时fxml文件设定了界面对应的控制器叫做LoginController。注意到登录窗口拥有两个单选按钮和一个登录按钮,这三个按钮都应当触发单击或者选中事件,于是在控制器的代码中分别声明几个待操作的控件对象,对象名称与fxml中的fx:id保持一致。然后重写控制器的initialize方法,在该方法中各自调用三个按钮的setOnAction方法,用以注册单击或选中按钮后的触发事件。根据以上说明编写登录窗口的控制器代码示例如下:

//登录窗口的界面控制器
public class LoginController implements Initializable {
@FXML
private RadioButton rbPassword; // 密码登录对应的单选按钮
@FXML
private RadioButton rbVerifycode; // 验证码登录对应的单选按钮
@FXML
private Label labelUser; // 用户名标签
@FXML
private TextField fieldUser; // 用户名输入框
@FXML
private Label labelPassword; // 密码标签
@FXML
private PasswordField fieldPassword; // 密码输入框
@FXML
private Button btnLogin; // 登录按钮
@FXML
private Label labelLoginResult; // 登录结果标签 @Override
public void initialize(URL location, ResourceBundle resources) { // 界面打开后的初始化操作
rbPassword.setOnAction(e -> { // 选中“密码登录”单选按钮后触发的事件
labelUser.setText("用户名:");
labelPassword.setText("密 码:");
});
rbVerifycode.setOnAction(e -> { // 选中“验证码登录”单选按钮后触发的事件
labelUser.setText("手机号:");
labelPassword.setText("验证码:");
});
//
btnLogin.setOnAction(e -> { // 单击“登录”按钮后触发的事件
String result = String.format("您输入的用户名为%s,密码为%s",
fieldUser.getText(), fieldPassword.getText());
labelLoginResult.setText(result); // 在登录结果标签上显示登录信息
});
}
}

由上面代码可见,这个控制器的处理逻辑很简单,选中按钮后仅仅给文本标签设置指定文字而已,当然这样也方便观察控件的操作结果。

回到登录窗口的入口代码LoginMain,运行测试程序弹出如下图所示的登录界面。


由图示可见登录窗口默认选中“密码登录”,接着单击右边的“验证码登录”按钮,发现下方的用户名标签变成了“手机号:”,密码标签变成了“验证码:”,说明“验证码登录”按钮的选中事件被正常触发。然后分别在用户名输入框与密码输入框中填入用户名和密码,再单击下面的登录按钮,此时登录窗口的界面效果如下图所示。


果不其然,登录按钮下方的文本标签展示了输入的用户名和密码信息,可知登录按钮的单击事件也正确响应了。


更多Java技术文章参见《Java开发笔记(序)章节目录

Java开发笔记(一百四十四)实现FXML对应的控制器的更多相关文章

  1. Java开发笔记(三十四)字符串的赋值及类型转换

    不管是基本的char字符型,还是包装字符类型Character,它们的每个变量只能存放一个字符,无法满足对一串字符的加工.为了能够直接操作一连串的字符,Java设计了专门的字符串类型String,该类 ...

  2. Java开发笔记(八十四)文件与目录的管理

    程序除了处理内存中的数据结构,还要操作磁盘上的各类文件,这里的磁盘是个统称,泛指可以持久保留数据的存储介质,包括但不限于:插在软驱中的软盘.固定在机箱中的硬盘.插在光驱中的光盘.插在USB接口上的U盘 ...

  3. Java开发笔记(二十四)方法的组成形式

    经过前面的学习,我们发现演示的Java代码越来越复杂,而且每个例子的代码都堆在入口方法main内部,这会导致如下问题:1.一个方法内部堆砌了太多的代码行,看着费神,维护起来也吃力:2.部分代码描述的是 ...

  4. Java开发笔记(五十四)内部类和嵌套类

    通常情况下,一个Java代码文件只定义一个类,即使两个类是父类与子类的关系,也要把它们拆成两个代码文件分别定义.可是有些事物相互之间密切联系,又不同于父子类的继承关系,比如一棵树会开很多花朵,这些花儿 ...

  5. Java开发笔记(六十四)静态方法引用和实例方法引用

    前面介绍了方法引用的概念及其业务场景,虽然在所列举的案例之中方法引用确实好用,但是显而易见这些案例的适用场合非常狭窄,因为被引用的方法必须属于外层匿名方法(即Lambda表达式)的数据类型,像isEm ...

  6. Java开发笔记(七十四)内存溢出的两种错误

    前面介绍的几种异常,其实都存在这样那样的逻辑问题,属于程序员的编码手误.还有一大类系统错误,表面上看不出什么问题,但是程序仍然运行不下去,兹举二例说明.第一个例子且看下列的测试代码: // 测试内存溢 ...

  7. OpenCV开发笔记(六十四):红胖子8分钟带你深入了解SURF特征点(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  8. Java开发笔记(八十二)注解的基本单元——元注解

    Java的注解非但是一种标记,还是一种特殊的类型,并且拥有专门的类型定义.前面介绍的五种内置注解,都可以找到对应的类型定义代码,例如查看注解@Override的源码,发现它的代码定义是下面这样的: @ ...

  9. Java开发笔记(二十五)方法的输入参数

    前面通过main方法介绍了方法的定义形式,对于方法的输入参数来说,还有几个值得注意的地方,接下来分别对输入参数的几种用法进行阐述.一个方法可以有输入参数,也可以没有输入参数,倘若无需输入参数,则方法定 ...

  10. Java开发笔记(二十九)大整数BigInteger

    早期的编程语言为了节约计算机的内存,给数字变量定义了各种存储规格的数值类型,比如字节型byte只占用一个字节大小,短整型short占用两个字节大小,整型int占用四个字节大小,长整型long占用八个字 ...

随机推荐

  1. I2c理解

    1.IIc是什么: 是飞利浦公司设计的一种用于mcu与外围设备之间信息交互的一种协议.高速IIC总线一般可大400kbs 2.IIC作用: 用于mcu与外围设备间信息交互. 3.IIc由什么组成: 由 ...

  2. 使用haproxy 2.0 prometheus metrics 监控系统状态

    haproxy 2.0 已经发布一段时间了,提供内部直接暴露的prometheus metrics 很方便 ,可以快速的监控系统的状态 以下是一个简单的demo 环境准备 docker-compose ...

  3. 第08组 Alpha冲刺(3/6)

    队名:955 组长博客:https://www.cnblogs.com/cclong/p/11872693.html 作业博客:https://edu.cnblogs.com/campus/fzu/S ...

  4. tidyr

    tidyr包主要提供了数据整理和清洗的功能,包括 1. 数据框的变形 2. 处理数据框中的空值 3. 根据一个表格衍生出其他表格 4. 实现行或列的分隔和合并 该包将要用的数据处理成标准且统一的数据框 ...

  5. Java finally未被执行的情况

    一种是先执行了用于终止程序的System.exit()方法,或进程被关闭 还有一种情况是,当前线程一直在执行,在一些业务逻辑里面跳不出来,看上去就像finally一直未被执行 线程被终止的时候也会执行 ...

  6. malloc分配到一块内存,读写操作时却发生segmentation falt的奇怪问题。

    期初现象:malloc一块内存,读写操作时发生segmentation falt.一般来讲malloc倘若失败应该抛出异常,所以malloc返回一个指针后,这个指针应该都是可用的,况且是进行读操作. ...

  7. Python知乎上推荐的项目

    原文地址:https://www.zhihu.com/question/29372574/answer/88744491 作者:Wayne Shi链接:https://www.zhihu.com/qu ...

  8. 异常值检验实战3_NBA球员表现稳定性分析

     机器学习_深度学习_入门经典(博主永久免费教学视频系列) https://study.163.com/course/courseMain.htm?courseId=1006390023&sh ...

  9. paddlepaddle如何预加载embedding向量

    使用小批量数据时,模型容易过拟合,所以需要对全量数据进行处理,我是用的是word2vec训练的词向量. 那么训练好对词向量如何加载呢? #!/usr/bin/env python # -*- codi ...

  10. 大数据常见端口汇总-hadoop、hbase、hive、spark、kafka、zookeeper等(持续更新)

    常见端口汇总:Hadoop:        50070:HDFS WEB UI端口    8020 : 高可用的HDFS RPC端口    9000 : 非高可用的HDFS RPC端口    8088 ...