Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何避免Swing中的无限更新循环?_Java_Swing_Refresh_Infinite Loop - Fatal编程技术网

Java 如何避免Swing中的无限更新循环?

Java 如何避免Swing中的无限更新循环?,java,swing,refresh,infinite-loop,Java,Swing,Refresh,Infinite Loop,我有一个带有一组项目(例如组合框和文本字段)的JPanel。在这些项目上实现一些操作侦听器以注册用户更新 如果用户在JComboBox中选择一个值(例如),则动作侦听器将捕获事件。调用相应的底层bean方法并刷新面板。更改可能会影响窗格中显示的其他字段 问题是当面板刷新时,所有侦听器都会被触发,并且它们会自己调用刷新。这将导致一个无限循环 我怎样才能避免这种情况?我无法摆脱监听器,因为我需要捕获用户更新,但我不希望在我仅刷新面板内容时触发这些更新。一个选项是设置一个中心布尔值或一些指示器,每个监

我有一个带有一组项目(例如组合框和文本字段)的JPanel。在这些项目上实现一些操作侦听器以注册用户更新

如果用户在JComboBox中选择一个值(例如),则动作侦听器将捕获事件。调用相应的底层bean方法并刷新面板。更改可能会影响窗格中显示的其他字段

问题是当面板刷新时,所有侦听器都会被触发,并且它们会自己调用刷新。这将导致一个无限循环


我怎样才能避免这种情况?我无法摆脱监听器,因为我需要捕获用户更新,但我不希望在我仅刷新面板内容时触发这些更新。

一个选项是设置一个中心布尔值或一些指示器,每个监听器都可以检查以防止事件链接


另一个选项是,如果值不变,则不刷新字段。这样,每个组件每次刷新最多更新一次。

我认为,如果您的问题在combobox中,那么它只是指向一个bug。实际上,如果用户更改了组合框的值,则会以某种方式触发窗格的刷新。组合框的值不应再次更改!所以,如果它是onValueChanged()(或类似的内容),则在刷新窗格时根本不应该调用它

但是,如果出于某种原因发生这种情况,您可以验证新旧值是否相同,然后退出侦听器

如果这仍然没有帮助,我建议您使用一些非标准的解决方案:尝试调查侦听器中的堆栈跟踪。您能否确定调用侦听器是作为对用户操作的直接反应还是在刷新窗格之后?在这种情况下,您可以创建实用程序方法并将其放在所有相关侦听器的开头

我无法摆脱侦听器,因为我需要捕获用户更新,但我不希望在我仅刷新窗格内容时触发这些更新


然后删除侦听器,刷新窗格内容,然后恢复侦听器。这样,监听器只有在用户进行更改时才会启动。

我的应用程序也遇到了这个问题,我应该检查每个监听器并在代码中启用/禁用该标志的解决方案对我来说不是很好。我总是忘记在必要的地方将此标志设置为true/false。 这就是我决定实施另一个解决方案的原因。
我只是对我经常使用的所有默认swing组件进行子类化,并实现了在鼠标/键盘/剪贴板/etc事件之后触发的自定义ValueChanged事件。现在我总是知道,若ValueChanged事件被触发,这意味着该值是由用户发出的,而不是由代码发出的。以这种方式处理事件更干净。这个解决方案解决了我的问题。

我也考虑了第二个选择。我目前正在实现和测试它……我也在考虑检查旧值和新值。我目前正在实施和测试…请将JPane修改为JPanel,因为从JComboBox到GUI的任何输出最好是查找ItemListener,并通知只测试指定事件,您是否能够侦听JComboBox的弹出窗口,请检查,在这个论坛中有一些关于这个问题的好话题,你建议的解决方案意味着我可能会错过一些用户操作/更新。这对我的申请是不可接受的。“比较旧值/新值”解决方案正确地涵盖了这种情况。@JVerstry,您不会错过任何用户操作/更新。所有代码都在EDT上执行,因此在处理任何用户更新之前都会将侦听器添加回来。如果未注册侦听器,EDT不会调用它们。您无法预测事件的调用顺序,因为您不知道用户何时创建事件。它可能在字段更新之间,字段更新本身会生成事件。。。。用户事件将在…@JVerstry之间调度(不发送给任何侦听器),要么您不了解事件如何工作,要么您不知道如何实现此建议。无论何时提出这类问题,都有两个标准答案。删除/添加侦听器方法和布尔方法。我更喜欢这个解决方案,因为我相信它更干净,因为所有代码都位于一个地方。使用布尔方法,您将代码分为三个位置,一个用于定义变量,另一个用于设置布尔值,最后另一个用于检查布尔值。我相信任何被分割到多个地方的代码都很难维护。