前面介绍了FXML的基本格式及其控制器的用法,算是打通了FXML方式的编码流程。程序界面通常保持固定尺寸,不过有时也允许用户拖曳窗口大小,不拖不打紧,一拖就可能坏事。像之前的登录窗口,没拖的时候界面如下图所示。


现在开始慢慢把窗口拖长,拖到一半停下来,此时登录界面如下图所示。


乍看过去,界面上的各控件大小保持不变,且始终居中显示,没发现什么问题。可是继续拖长窗口,突然之间这些控件乾坤大挪移,用户名区域顶到了第一行,登录按钮跟着顶到了第二行,变化后的界面效果如下图所示。


之所以出现控件排版错乱的问题,是因为该界面的根节点采用了流式窗格FlowPane。所谓流式,指的是从左到右排列,倘若没排满一行,就跟在当前行后面;只有排满了一行,才会另起一行继续排。刚刚拖拉窗口的时候,拖得太长了,导致窗口的宽度能够容纳登录类型与用户名两个区域,结果两块区域便挤到同一行了。显然这不是期望的界面布局,至少控件要老老实实呆在自己的位置,不可越雷池一步。
若想避免流式窗格排版飘忽的问题,可以使用垂直箱子VBox替换流式窗格,垂直箱子规定它的每个直接下级都占用一行,绝对不会产生两个直接下级挤在同一行的现象。于是修改原来的fxml文件,把根节点FlowPane换成VBox,对应的xml标签变为以下格式:

<VBox fx:controller="com.javafx.fxml.LoginController" xmlns:fx="http://javafx.com/fxml" alignment="center"><!-- 这是xml注释标记。中间省略登录窗口的各控件标签 -->
</VBox>

fxml文件修改完毕,重新运行测试程序,弹出的登录窗口如下图所示。


现在不管怎样拉长窗口,各区域都留在当前行,再也不会乱跑了。然而采用VBox的界面很不协调,缘由在于VBox不支持hgap与vgap属性,因此各控件之间没能自动分隔开,几乎都粘在一起了,例如:
1、登录类型、用户名、密码三块区域的左侧直接顶到了窗口边缘;
2、用户名输入框、密码输入框、登录按钮三个自上往下紧紧贴着,不留一丝空隙;
似此过于紧凑的界面,令人感觉颇为拘谨,还是留个适当的间隔比较好。虽然VBox不支持hgap与vgap属性,但它另外提供了padding属性组,允许分别指定上、下、左、右四个方向的间距。padding节点挂在哪个VBox或HBox之下,就表示哪个箱子会在内部自动留白,padding对应的xml标签具体写法如下所示:

  <padding><Insets top="10.0" bottom="10.0" left="10.0" right="10.0"/></padding>

上述的padding节点例子,定义了在上、下、左、右四个方向各留出10个像素的空白间距。考虑到VBox和HBox下面可能挂着好几个子控件,为了更好地将这些子控件跟padding区分开,fxml又给VBox和HBox引入了children子节点,凡是下级控件统统放到children节点之下,而padding节点专门放置四个方向的间隔距离。如此一来,形态完整的VBox节点结构变成了以下这般:

<VBox fx:controller="com.javafx.fxml.LoginController" xmlns:fx="http://javafx.com/fxml" alignment="center"><children><!-- 这是xml注释标记。中间省略VBox的下级控件列表 --></children><padding><Insets top="10.0" bottom="10.0" left="10.0" right="10.0"/></padding>
</VBox>

由上面的xml样例可以看到,改进之后的VBox标签变得层次分明、结构清晰,大大增强了它的可读性。
除此之外,fxml还为VBox和HBox提供了自动伸展功能,也就是说,随着窗口尺寸的增大,VBox和HBox的宽高也会随之增大。其中水平方向的宽度自适应,由属性HBox.hgrow控制,其值为ALWAYS时表示当前箱子的宽度跟随上级变化;垂直方向的宽度自适应则由属性VBox.vgrow控制,其值为ALWAYS时表示当前箱子的高度跟随上级变化。尤其需要注意的是,除了VBox和HBox这两个箱子支持自动伸展以外,只有几个输入框控件支持自动伸展,其中TextField与PasswordField只支持水平方向上的自动伸展,而TextArea同时支持水平与垂直两个方向的自动伸展。
利用fxml的几个新节点和新属性改造原先的登录界面,一方面,整个登录界面在窗口四周边缘均留白,各行之间也留出一条缝隙;另一方面,令用户名输入框和密码输入框支持水平伸展,令用户名区域和密码区域支持垂直伸展。这么改造一番之后的fxml文件示例如下:

<VBox fx:controller="com.javafx.fxml.LoginController" xmlns:fx="http://javafx.com/fxml" alignment="center"><children><HBox fx:id="hbType" prefWidth="400" prefHeight="40"><children><Label fx:id="labelType" prefWidth="120" prefHeight="40" text="登录类型:" /><fx:define><ToggleGroup fx:id="tgType" /></fx:define><RadioButton fx:id="rbPassword" prefWidth="140" prefHeight="40" toggleGroup="$tgType"text="密码登录" selected="true" /><RadioButton fx:id="rbVerifycode" prefWidth="140" prefHeight="40" toggleGroup="$tgType"text="验证码登录" /></children><padding><Insets top="0.0" bottom="10.0" left="0.0" right="0.0"/></padding></HBox><HBox fx:id="hbUser" prefWidth="400" prefHeight="40" VBox.vgrow="ALWAYS"><children><Label fx:id="labelUser" prefWidth="120" prefHeight="40" text="用户名:" /><TextField fx:id="fieldUser" prefWidth="280" prefHeight="40" HBox.hgrow="ALWAYS" /></children><padding><Insets top="0.0" bottom="10.0" left="0.0" right="0.0"/></padding></HBox><HBox fx:id="hbPassword" prefWidth="400" prefHeight="40" VBox.vgrow="ALWAYS"><children><Label fx:id="labelPassword" prefWidth="120" prefHeight="40" text="密 码:" /><PasswordField fx:id="fieldPassword" prefWidth="280" prefHeight="40" HBox.hgrow="ALWAYS" /></children><padding><Insets top="0.0" bottom="10.0" left="0.0" right="0.0"/></padding></HBox><Button fx:id="btnLogin" prefWidth="400" prefHeight="40" text="登  录" /><Label fx:id="labelLoginResult" prefWidth="400" prefHeight="40" text="这里显示登录结果" /></children><padding><Insets top="10.0" bottom="10.0" left="10.0" right="10.0"/></padding>
</VBox>

再次运行测试程序,弹出的登录窗口如下图所示,果然各级控件与周边都隔了一小段距离。


接着在水平方向拉长窗口,拉长之后的窗口界面如下面左图所示。回到初始尺寸,在垂直方向拉高窗口,拉高之后的如下面右图所示。


从上面两张效果图可见,几个箱子和输入框的宽高确实跟随窗口尺寸的变化而变化。


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

转载于:https://www.cnblogs.com/pinlantu/p/11448309.html

Java开发笔记(一百四十五)FXML布局的伸展适配相关推荐

  1. Android开发笔记(七十四)布局文件优化

    include/merge 布局优化中常常用到include/merge标签,include的含义类似C代码中的include,意思是直接把指定布局片段包含进当前的布局文件.include适用于多个布 ...

  2. Android开发笔记(七十五)内存泄漏的处理

    内存泄漏的原因 一直以来以为只有C/C++才存在内存泄漏的问题,没想到拥有内存回收机制的Java也可能出现内存泄漏.C/C++存在指针的概念,程序中需要使用指针变量时,就从内存中开辟一块区域,并把该区 ...

  3. Android开发笔记(六十五)多样的菜单

    菜单Menu Android的菜单分为两类:选项菜单和上下文菜单,默认使用选项菜单.菜单的布局文件存放在res/menu目录下,使用ADT新建一个Android工程,首页代码MainActivity中 ...

  4. Java学习笔记(三十五)

    在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度.现在将跟着视频做的笔记进行整理.本篇博客是整理Java知识点的第三十五 ...

  5. Java开发笔记(八十六)通过缓冲区读写文件

    前面介绍了利用文件写入器和文件读取器来读写文件,因为FileWriter与FileReader读写的数据以字符为单位,所以这种读写文件的方式被称作"字符流I/O",其中字母I代表输 ...

  6. Java开发笔记(八十八)文件字节I/O流

    前面介绍了如何使用字符流读写文件,并指出字符流工具的处理局限,进而给出随机文件工具加以改进.随机文件工具除了支持访问文件内部的任意位置,更关键的一点是通过字节数组读写文件数据,采取字节方式比起字符方式 ...

  7. Android开发笔记(八十五)手机数据库Realm

    Realm应用背景 Android自带的SQLite数据库,在多数场合能够满足我们的需求,但随着app广泛使用,SQLite也暴露了几个不足之处: 1.开发者编码比较麻烦,而且还要求开发者具备SQL语 ...

  8. Android开发笔记(三十五)页面布局视图

    布局视图的类别 布局视图有五类,分别是线性布局LinearLayout.相对布局RelativeLayout.框架布局FrameLayout.绝对布局AbsoluteLayout.表格布局TableL ...

  9. Android开发笔记(二十五)assets目录下的文件读取

    AssetManager工具类 assets目录用于存放应用程序的资产文件,该目录下的文件不会被系统编译,所以无法通过R.*.*这种方式来访问.Android专门为assets目录提供了一个工具类As ...

  10. Android开发笔记(四十五)手势事件

    手势事件的流程 基本手势事件 基本的手势事件主要有如下三个方法: dispatchTouchEvent : 判断该事件是否需要下发.返回true表示需要下发给下级视图,返回false表示不需要下发(交 ...

最新文章

  1. 升维:ValueError: all the input arrays must have same number of dimensions,
  2. 深入理解PHP内核(四)概览-PHP脚本的执行
  3. Linux fork()一个进程内核态的变化
  4. poj-2891(Strange Way to Express Integers)--中国剩余定理扩展欧几里得
  5. 栈溢出利用-----jmp esp
  6. Struts2学习笔记1
  7. 百度地图gif图标_华为手机误删照片怎么找回?手机怎么快速制作GIF动图
  8. SQL Server2014 SP2新增的数据库克隆功能
  9. Linux Ubuntu 18.04安装JDK、Hadoop、Hbase以及图形界面
  10. DEVONthink Pro作为浏览器插件脚本,如何使用
  11. easyui datagrid 表格不让选中(双层嵌套)
  12. 如何解决stata数据管理器中变量变红的问题
  13. JavaScript嗅探执行神器-sniffer.js,你值得拥有!
  14. 转【iOS应用安全】游戏安全之IPA破解原理及防御
  15. GIT远程分支误删恢复
  16. Flash使用到数学、物理的公式
  17. Win11任务栏太宽了怎么办?教你一招快速修改任务栏大小
  18. effective c++ 学习笔记之 Shifting from c to c++
  19. npm安装vue,在vue/dist目录下没有产生vue.js文件
  20. 高亮显示用户键盘输入(kbd)

热门文章

  1. oracle怎么同步时间设置,【oracle数据库获取当前时间】
  2. c/c++编译的程序占用的内存分配
  3. mysql block是什么,php – MySQL PDO – try {block}里面应该是什么?
  4. HIVE 命令行操作和参数指引
  5. L3-014 周游世界 (30分)
  6. Centos / Ubuntu /linux/mac JAVA 环境变量设置
  7. linux 下 docker NGINX+PHP+MYSQL+REDIS+Elasticsearch 开发环境搭建
  8. white-space 空白处理、强制内容不换行,word-wrap 文本自动换行,text-overflow 文本溢出
  9. linux下的多线程,linux下的多线程
  10. docker安装jdk8