java - JavaFX TextArea 文本修改监听器:资源消耗困境
问题描述
我们能够处理在 JavaFX TextArea 中所做的更改,如下所示: JavaFX TextArea onChange event
本质上,这个“监听器”帮助我在对 TextArea 进行更改之前和之后检查文本。
有时,只检查一个字符就足够了,但上述方法的实现方式,它抓取整个字符串的前后。例如,我希望实现一个持久缩进,我的逻辑是:
- 我保留一个初始值为 0 的制表符计数器。
- 如果
\t
输入了一个字符,那么我每次都会增加该值。 - 在输入 a
\n
后,许多\t
字符被预先放置在下一行中。 - 如果按下一个
BACKSPACE
键(为简单起见,让我们认为这是删除文本的唯一选项),然后我检查前一个字符,如果是 a,\t
那么我每次都会递减该值,依此类推。
但是,我觉得 Java 像之前和之后一样抓取整个文本内容会占用太多资源,而不是只抓取一个字符。所以,
- 在实践中,这实际上有多大的不同?我认为这在文本文件大约只有 0.5MB 左右的级别上会占用大量资源。
- 是否有任何其他方法可以实现侦听器以使其按我想要的方式工作,当前方法将不接受除仅包含字符串的 ObservableList 对象之外的任何内容。
解决方案
ChangeListener
在文本区域上使用 atextProperty()
不是执行您想要的操作的受支持方式。它创建了不必要的复杂逻辑:通过修改 上的侦听器内的文本textProperty()
,您会在更改属性本身时触发对属性的另一次更改。简而言之,您对用户更改文本(实际属性已更改)做出反应,然后再次修改文本以表示您想要的内容。
例如,如果您注册了一个不同的侦听textProperty()
器,或者绑定到它,则该侦听器或绑定将观察到文本的两个更改:第一个(“无效”,即您希望文本看起来像) 由用户引起,第二个,恢复到您实际想要的状态,由您的侦听器中的代码引起。
目前尚不清楚您指的是什么“资源”:在最坏的情况下,我只能在文本区域中看到一个额外的、非常临时的文本副本;但即使这样似乎也不太可能 - (临时)副本可能无论如何都存在。
所以不使用监听器的理由textProperty()
与机器资源或性能无关;它与您的应用程序的逻辑和您想要textProperty()
假设的值序列有关。您希望该属性反过来采用最终用户看到的值,并且永远不要采用您想用您的代码“更正”的值。
实现它的方法是使用TextFormatter
:
textArea.setTextFormatter(new TextFormatter<String>(change -> {
// examine change and modify it if necessary...
return change ;
}));
提供给TextFormatter
构造函数的过滤器采用一个TextFormatter.Change
对象,该对象封装了文本中建议的更改(即当前文本和新文本之间的建议差异)。这是在实际文本被修改之前调用的。这意味着在您的实现中,您可以根据需要修改该更改,这正是您的用例。(您可以通过返回来完全否决更改,即不允许更改null
。)使用这种方法,文本区域的text
属性将从当前值转换为用户输入所表示的值加上您的代码所做的修改,没有中间值.
有关如何使用该TextFormatter.Change
对象的详细信息,请参阅上面链接的文档。
推荐阅读
- jhipster - 将 Jhipster 与 Prometheus/Grafana 一起使用
- node.js - MS Graph API 从 driveItem 访问工作簿
- c - 如何初始化结构值并正确输出结构
- swift - 单击按钮时如何增加和减少值?
- cron - 是否可以在几秒钟内将 crontab 格式转换为间隔格式
- java - 调用没有引用变量的方法
- r - 使用 R 从特定气象站提取数据
- angular - Angular 组件交互焦点和模糊输出事件
- .net - TextRenderer.MeasureText 似乎要四舍五入字体大小
- r - 如何使用 Shinyauthr 库在闪亮中创建登录而不在 R 中显示主面板?