在 JavaFX 中,如何计算文本所占像素的宽度

  • 注意事项
  • 算法
  • 代码
    • 计算单行文本的像素宽度
    • 计算文本框尺寸

  JavaFX 的恼人之处在于很多基本的操作都要自己亲力亲为。有些时候,我们希望 TextArea 能自动根据文本内容换行以及调整大小。换行是 TextArea 中已经有的功能,不过这也带来了新的问题。在 JavaFX 中,可以使用 Text 对象的方法 .getBoundsInLocal().getWidth() 测得文本的基本尺寸。不过,依然有很多要注意的问题。


【注意】

  不同的符号的尺寸是不同的,不仅是中文汉字与英文字母,就连运算符、数字、英文字母之间的尺寸也不尽相同。不要自行编写自适应各种 Unicode 符号的算法。应该使用 JavaFX 内置的 API,如 Text 类的方法 Text对象.getBoundsInLocal().getWidth()


注意事项

  主要的注意事项如下:

  • 计算后最终的行宽值不会大于 TextArea 的行宽值。另外,当文本内容超过 TextArea 的最大宽度时,会触发换行。因此,还需要计算 TextArea 自动换行后的行数。

  • 用户输入的原始内容中就有可能包含换行。对这种情况可以有不同的处理方案,但是需要考虑这个问题。如果不选择直接去除换行符,则需要先将用户输入分割成各个不含换行符的文本,然后分别统计这些文本的行数与最大行宽,最后加行数相加,并来取这些最大行宽中的最大值。

  • Windows 会将回车解释成 \n\r,但 TextArea 清除文本中所有的 \r。换句话说,当在 Windows 输入回车时,实际上输入的是 \n\r。但当向 TextArea 输入 \n\r 时,TextArea 会移除所有的 \r。从 TextArea 得到的字符串中不会包含任何 \r,TextArea 的换行符为 \n

  • 行数只能是整数。另外,如果使用整数除法,需要将结果加 1。因为不满 1 行也需要占用一行。

  • 考虑用户的特殊输入:

    • 输入为空串

    • 输入的内容全是换行符

    • 输入的内容存在连续的换行符

    • 输入的开头是换行符

算法

  实现的算法大致如下:

(假设:当用户输入内容包含换行符时,不管是否连续,也直接进行原始输出而不删除。当用户输入的内容为空时,不报错,也直接视文本长度为 0 来计算)

  1. 判断输入是否为 null 或空串,如果是,视文本行宽为 0,行数为 1。如果不是,进行下一步。

  2. 判断输入是否只有换行符,如果是,视文本行宽为 0,行数为换行符的个数。如果不是,进行下一步。

  3. 将输入按照换行符分割成各个不含换行符的文本,然后先计算单个文本尺寸,最后叠加。方法如下:

    1. 计算单个文本的尺寸。方法如下:

      1. 求文本的原始像素长度。

      2. 计算文本的行宽值:取像素长度与单行文本最大长度之间的最小值。

      3. 计算文本的行数:将像素长度除以单行文本最大长度,然后向上取整。

    2. 计算整个文本的行宽值:取各个文本行宽值的最大值。

    3. 计算整个文本的行数:将各个文本行数值累加。

  4. 计算文本框的宽度:将文本的行宽值与文本框左右内边距相加。

  5. 计算文本框的长度:将文本的行数乘以单行文本行高,然后加上文本框上下内边距。

代码

  核心代码如下。

计算单行文本的像素宽度

public static double calculateTextPixelWidth(String text, Font font) {Text theText = new Text(text);theText.setFont(font);return theText.getBoundsInLocal().getWidth();
}

计算文本框尺寸

    /*** @param originText 内文本的内容* @param font 内文本的字体* @param lineSeparator 换行符的定义* @param originMaxWidth 内文本最大的行宽* @param rowExtension 对话框横向两端与内文本的边距* @param originSingleHeight 内文本一行的高度* @param columnExtension 对话框纵向向两端与内文本的边距* @return 计算出的对话框的宽度。其中,[0] 代表宽度,[1] 代表高度*/public static double[] calculateTextBoxSize(String originText, Font font, String lineSeparator,double originMaxWidth, double rowExtension,double originSingleHeight, double columnExtension) {double maxRowLength = 0;int formattedColumnNum = 0;if (originText != null && !"".equals(originText)) {var texts = originText.split(lineSeparator);if (texts.length == 0) { // 如果文本中只有换行符maxRowLength = 0;formattedColumnNum = originText.length() + 1; // 注意要加 1} else {double singleRowLength = 0;for (var text : texts) {var singleOriginWidth = calculateTextPixelWidth(text, font);singleRowLength = Math.min(singleOriginWidth, originMaxWidth); // 注意:这是求最小值maxRowLength = Math.max(maxRowLength, singleRowLength); // 注意:这里求最大值formattedColumnNum += (int) (singleOriginWidth / originMaxWidth) + 1; // 注意要加 1}}}double[] result = new double[2];result[0] = maxRowLength + rowExtension * 2;result[1] = formattedColumnNum * originSingleHeight + columnExtension * 2;return result;}

  对于 TextArea,其换行符为 \n,因此可以使用如下代码:

/*** @param originText 内文本的内容* @param font 内文本的字体* @param originMaxWidth 内文本最大的行宽* @param rowExtension 对话框横向两端与内文本的边距* @param originSingleHeight 内文本一行的高度* @param columnExtension 对话框纵向向两端与内文本的边距* @return 计算出的对话框的宽度。其中,[0] 代表宽度,[1] 代表高度*/
public static double[] calculateTextBoxSize(String originText, Font font,double originMaxWidth, double rowExtension,double originSingleHeight, double columnExtension) {String lineSeparator = "\n"; // TextArea 中的换行符为 '\n'return calculateTextBoxSize(originText, font, lineSeparator,originMaxWidth, rowExtension, originSingleHeight, columnExtension);
}

在 JavaFX 中,如何计算文本所占像素的宽度相关推荐

  1. Android布局中的空格以及占一个汉字宽度的空格的实现

    在Android布局中进行使用到空格,以便实现文字的对齐.那么在Android中如何表示一个空格呢? 空格: 窄空格:  一个汉字宽度的空格:   [用两个空格(  )占一个汉字的宽度时,两个空格比一 ...

  2. JavaFX 中的像素、分辨率与缩放比

    JavaFX 中的像素.分辨率与缩放比 总结与补充   JavaFX 中,一般需要对每个组件设置一个尺寸值,这个值实际上就是像素值(pixel,px).像素值是什么呢?在 Windows 上,一般使用 ...

  3. JavaFX官方教程(五)之在JavaFX中创建表单

    翻译自  在JavaFX中创建表单 在开发应用程序时,创建表单是一项常见活动.本教程将向您介绍屏幕布局的基础知识,如何将控件添加到布局窗格以及如何创建输入事件. 在本教程中,您将使用JavaFX构建如 ...

  4. NLP中面向文本表示的模型梳理

    引言 语言表示是将自然语言表示为计算机或者模型能够处理的数据特征,是解决例如情感分析.命名实体识别.机器翻译.文本生成等这些高级任务的基础.本文作为NLP基础知识的入门,梳理了相关文本表征的模型与方法 ...

  5. css中的单位换算_CSS像素、物理像素、逻辑像素、设备像素比、PPI、Viewport

    1.PX(CSS pixels) 1.1 定义 虚拟像素,可以理解为"直觉"像素,CSS和JS使用的抽象单位,浏览器内的一切长度都是以CSS像素为单位的,CSS像素的单位是px. ...

  6. 【NLP】竞赛中的文本相似性!

    文本相似度是指衡量两个文本的相似程度,相似程度的评价有很多角度:单纯的字面相似度(例如:我和他 v.s. 我和她),语义的相似度(例如:爸爸 v.s. 父亲)和风格的相似度(例如:我喜欢你 v.s. ...

  7. unity中单位是米还是厘米_2019-08-22Unity中的单位长度与像素之间的关系

    一:什么是像素? 像素是由很多个小方格组成,每一个小方格上都存储了位置信息和色彩信息.像素是图像的最小单位 分享一个知识点:图像分为两类,位图和矢量图 位图(点阵图):由多个像素组成,当放大时被分为多 ...

  8. JavaFX 中 FX 一词的由来

    JavaFX 中 FX 一词的由来   JavaFX 已经慢慢开始流行了,一些书籍已经开始专门介绍它.不过由于它的目前流行程度,很少人知道这个名称是怎么来的.   有人认为 JavaFX 中 FX,指 ...

  9. JavaFX官方教程(八)之JavaFX中的动画和视觉效果

    翻译自  JavaFX中的动画和视觉效果 您可以使用JavaFX快速开发具有丰富用户体验的应用程序.在本入门教程中,您将学习如何使用非常少的编码创建动画对象并获得复杂的效果. 图7-1显示了要创建的应 ...

最新文章

  1. 【转载】linux服务器下非root权限安装anaconda
  2. 在安装好python后文件显示还是应用程序_在djang中找不到已安装的应用程序
  3. java ftp 连接超时时间_ftpClient的连接超时设置(setConnectTimeout,setSoTimeout) | 学步园...
  4. 北语20春oracle数据开发2,北语20春《Oracle数据库开发》作业3题目【标准答案】
  5. pyDes vs pycrypto
  6. 【Python3网络爬虫开发实战】1.7.2-mitmproxy的安装
  7. java如何配置maven路径_如何配置Eclipse构建路径以使用Maven依赖项?
  8. 记一次:java实现excel转图片
  9. 看懂卡尔曼滤波1 g-h滤波
  10. 电脑开机后,显示屏无信号怎么处理?
  11. java8中, 格林威治时间、世界时、祖鲁时间、GMT、UTC、跨时区、夏令时需要用什么类表示呢
  12. RHEL6配置本地源
  13. ker矩阵是什么意思_矩阵光学
  14. 仿qq email界面 登陆
  15. [Unity3D] MoveTowards、Lerp、Slerp
  16. 基于网页网站在线视频点播系统 毕业设计毕设源码毕业论文开题报告参考(3)网站后台系统管理功能
  17. python计算一元二次方程a=2.b=3c=1_Python1日一练03-一元二次方程的计算
  18. 命令配置bmc管理口
  19. 算法笔记(11)逻辑回归算法及Python代码实现
  20. 谈谈现阶段4K超高清视频节目制作系统的设计思路(3-1)

热门文章

  1. AJAX(Asynchronous JavaScript And XML)
  2. 从Java面试官的角度,如何快速判断程序员的能力
  3. Effective_STL 学习笔记(八) 永不建立 auto_ptr 的容器
  4. Python自动化测试框架有哪些?
  5. Android项目实战(三十二):圆角对话框Dialog
  6. Nis服务器主从安装配置
  7. 5G技术标准制定已加速 所有炒作都将变成现实
  8. centos6.9下安装composer
  9. nancy框架安装并使用
  10. processing pushMartix