我有一个带有模型和视图的 Swing 应用程序。在视图(GUI)中有很多组件,每个组件都映射到模型对象的某些属性并显示它的值。
现在有一些 UI 组件,当 UI 中某些模型属性的值发生变化时,会自动触发某些模型属性的更新。这需要我在 UI 中重新加载完整的模型。这样我就进入了无限更新循环,因为 UI 中的每个模型重新加载都会触发另一个模型重新加载。
我有一个指示加载过程的标志,我想用它来暂时抑制侦听器通知,同时从模型设置 UI 字段。所以我的问题是:
有没有办法在 Swing 中全局暂时禁用某些组件的侦听器,而无需删除并重新附加它们?
I've got a Swing application with a model and a view. In the view (GUI) there are a lot of components, each of them mapping to some property of a model object and displaying it's value.
Now there are some UI components that automatically trigger the updating of some model properties when their value changes in the UI. This requires me to reload the complete model in the UI. This way I'm entering an infinite update loop, as every model reload in the UI triggers another model reload.
I have a flag indicating the load process, which I'd like to use to temporarily suppress the listener notifications, while the UI fields are being set from the model. So my question is:
Is there a way to globally temporarily disable some component's listeners in Swing without removing and reattaching them?
发布评论
评论(6)
您可以为您的侦听器使用一个公共基类,并在其中使用一个静态方法来打开或关闭侦听器:
您的侦听器必须实现
doPerformAction()
而不是actionPerformed()
。(这在企业场景中会很糟糕,但在像 Swing 这样的单 VM 模型中,它应该可以正常工作)
You could use a common base class for your listeners and in it, have a static method to turn the listeners on or off:
Your listeners would have to implement
doPerformAction()
instead ofactionPerformed()
.(This would be awful in an enterprise scenario, but in a single-VM model like in Swing, it should work just fine)
通常我使用一个标志来指示 API 更改或用户更改。对于每个侦听器,我都会检查该标志,如果是 API 更改,则返回。
Normally I use a flag indicating API changes or user changes. For each of the listeners I would check the flag and if it's API changes just return.
在搜索 stackoverflow 时,我发现了这个问题。我想添加我的意见/答案。
在 Swing 中暂时禁用事件监听器确实是个坏主意。如果您的代码被破坏(或出现其他问题),您可能无法使您的应用程序恢复生机 - 响应用户和其他事件。
如果您想丢弃(响应但不执行任何操作)用户事件,您可以使用玻璃窗格,它可以忽略事件。
如果您的 EDT 很忙(您必须尽可能避免这种情况)并且您想放弃该时间段内的用户操作,您仍然可以使用 glasspane 并使用 invokeLater 删除它,以在所有事件响应后删除该窗格(被玻璃板忽略)。
可以在此问题中找到包括 SSCE 在内的完整详细信息。
java等待光标显示问题
While searching stackoverflow, I found this question. I thought to add my opinion/answer.
It is really^inf bad idea to temporarily disable event listeners in Swing. If your code is broken (or something else goes wrong), you may not be able to bring your application back to life - respond to user and other events.
If you want to discard (respond but do nothing) to user events, you may use glass pane which can just ignore the events.
If your EDT is busy (which again you must avoid as much as possible) and you wanted to discard user action for that period, you may still use a glasspane and remove it using invokeLater to remove the pane after all the events have been responded (ignored by the glasspane) to.
Full details including an SSCE can be found in this question.
java wait cursor display problem
可能对您有用的一种选择是在加载时放置一块玻璃板,以阻止在此期间发生事件:
http://download.oracle.com/javase/tutorial/uiswing /components/rootpane.html#glasspane
One option that might work for you is just to put a glass pane up while loading in order to block events during that time:
http://download.oracle.com/javase/tutorial/uiswing/components/rootpane.html#glasspane
如上所述,GlassPane 在这方面很有帮助。
这是一个简单的例子:
}
As mentioned above, the GlassPane is helpful in this regard.
Here is a simple example:
}
我发现这篇文章有助于批判性地检查我自己的设计。
每个
JComponent
都维护一个EventListenerList
,您的子类可以访问它。如有必要,您始终可以直接对列表进行操作,或者将所需的行为构建到事件监听器
I found this article helpful in critically examining my own designs.
Every
JComponent
maintains anEventListenerList
, which is accessible to your subclass. If necessary, you can always operate on the list directly or build the desired behavior into your custom implementation ofEventListener