在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属性,但这似乎是一个错误的温床。
要不然是啥?我希望可以使用某些
LightWeight
组件或ImNotReallyHereProperty
来添加此开发辅助工具。谢谢你的帮助!
最佳答案
您的方法似乎存在根本缺陷。您不应该停止JavaFX应用程序线程。
相反,您应该有一个并发过程,并在过程开始,进行和完成时适当地更新UI。
有关这种替代方法的示例,请参见此java2s sample for using the JavaFX concurrency and progress indicator facilities。
如果要暂时禁用UI的某些部分,则节点具有可以设置的Disabled属性。您可以使用CSS来设置禁用节点的样式,以便用户有一些迹象表明该事物不仅只是挂起而且是故意禁用的。
关于java - 响应度指示器的JavaFX场景图修改,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29322620/