【发布时间】:2015-03-28 21:05:57
【问题描述】:
在 UI 线程上执行大型作业是一种不好的做法,就好像您这样做一样,这些大型作业会导致程序挂起(不接受用户输入或呈现任何新数据),直到该作业完成。
我希望在我们的代码库中添加一个小部件,该小部件将在开发人员犯下此禁忌时向他们显示。我的想法,以及我在许多其他应用程序中看到的想法,是让一些组件以恒定的速度不断移动,例如在屏幕上不断旋转的条。使用这样的工具,如果开发人员正在工作并且不小心在 UI 线程上做了比他预期的计算更困难的事情,这个旋转条会变得不稳定,向他表明,当他进行功能测试时,他需要实现机制这将导致该作业在其他地方执行。
对此代码的一个奇怪要求是,它应该完全不存在于生产构建中,并且只存在于开发构建中,因为它不是为用户提供的小部件,而是为开发人员提供的。
我跳入 Canvas 对象并编写了一个快速组件,它可以简单地旋转一个蓝绿色条。这个想法是,如果在 UI 线程上转储了一个大作业,栏将停止旋转(因为 FX 作业队列不会继续调度)并且栏将向前跳跃,而不是平滑旋转(就像程序在休息)。
下面是第一个实现的屏幕截图:
(请注意蓝绿色条,如果您看到我们的应用程序正在运行,它们会缓慢而稳定地旋转——希望无论如何)
这里的问题(您可能会注意到)是我们的布局被搞砸了。这是因为我正在修改场景图:
Scene
RootComponent
Content
到
Scene
obnoxiousPane
Canvas
Spinner(s)
RootComponent
Content
以这种方式修改场景图有诸如首选高度、鼠标事件和(可能)任何数量的其他事件被分派到微调器而不是内容组件。
当然,当我们投入生产时,我希望在我们提供给用户的版本中拥有原始场景图。
所以我的问题是:我应该如何纠正这些问题?
当它们出现时,我可以单独追踪它们,编写大量自定义代码来做类似的事情
obnoxiousPane.prefHeightProperty().bind(content.prefHeightProperty)
obnoxiousPane.prefWidthProperty()//...
spinner.setMouseTransparent(true)
spinner.setOtherEventsIProbablyCantEnumerateWithoutSeriousResearchTransparent(true)
或者我可以尝试通过反射解决这个问题,尝试将内容窗格中的 每个 属性绑定到相应的 obnoxiousPane 属性,但这似乎是一个 bug 滋生地。
或者……什么?我希望有一些 LightWeight 组件或 ImNotReallyHereProperty 可以用来添加此开发辅助工具。
感谢您的帮助!
【问题讨论】:
-
当你说
big job is dumped on the UI thread时,你的意思是你在UI线程上做所有的数据处理吗? -
我的意思是有人可能犯了这样的错误,是的。
标签: java multithreading data-binding properties javafx