开发者

How to avoid infinite update loops in Swing?

I have a JPanel with a set of items (for example combo boxes and text fields). Some action listeners are implemented on those items to register user updates.

If the 开发者_开发问答user selects a value in a JComboBox (for example), the action listener captures the event. The corresponding underlying bean method is called and the panel is refreshed. Changing can have an impact on other fields displayed in the pane.

The problem is that when the panel is refreshed, all listeners are triggered, and they call for a refresh themselves. This leads to an infinite loop.

How can I avoid this? I can't get rid of the listeners, because I need to capture user updates, but I don't want these to fire when I am only refreshing the panel content.


One option is to have a central boolean value or some indicator that each listener can check to prevent the chaining of events.

Another option is to not refresh the field if the value does not change. That way each component is updated at most once per refresh.


I can't get rid of the listeners, because I need to capture user updates, but I don't want these to fire when I am only refreshing the pane content

Then remove the listeners, refresh the pane content and then restore the listeners. This way the listeners only fire when a user change is made.


I think that if your problem is in combobox it just points to a bug. Really, if user changes the value of the combobox, that somehow triggers refresh of the pane the value of the combo box should not be changed second time! So if it is onValueChanged() (or something like this) it should not be called at all when pane is being refreshed.

But if for some reason it happens you can verify whether the old and new values are the same and exit the listener.

If this still does not help I'd suggest you some non-standard solution: try to investigate the stack trace into the listener. Can you identify whether the listener was called as a direct reaction to user's action or after the pane refresh? In this case you can create utility method and put it in the beginning of all relevant listeners.


My applications also suffered from this problem, and solution with the flag, that I should check in every listener and enable/disable in code, feels not very good for me. I always forgot to set this flag to true/false in necessary places. That is why I decide to implement another solution. I just subclass all default swing components that I am using often, and implemented custom ValueChanged event that I fire after mouse/keyboard/clipboard/etc events. Now I am always know, that if ValueChanged event is fired, it means, that value was issued by user, not by code. Event handling in this way much more cleaner. This solution solves my problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜