java - Swing: 是否有方法区分导致ItemEvent的用户和导致?

  显示原文与译文双语对照的内容

我在一个swing应用程序中使用一个 combobox,并且我很难找出用户事件 vs 所生成的ItemEvent 。

例如假设我有一个 combobox,'combo',我正在监听带有我的ItemListener的itemStateChanged事件,'listener'。 当用户将所选内容更改为项目 2或者我执行行( 伪代码) 时:

combo.setSelection(2)

。it似乎我无法区分这些事件。

这就是说,我没有任何方式的摆动专家,所以我想我会问。

谢谢!

时间: 原作者:

动作和React法则相当清楚:) 。 如果你尝试改变改变,就不需要区分用户和应用程序。 我可以想象到只有一个用例你需要"区分"。 应用程序显示某些数据的情况。 在这种情况下,你可能拥有应用程序的数据模型。 在这个模型中也有一些改变监听器,并且应用程序GUI将通过设置值来响应。 而且,如果用户在GUI组件中选择了。 数据模型将通过更改值来响应。 这种情况下,在数据模型上设置某种只读状态很容易,这将通知模型忽略来自观察对象的任何事件。 这里通知集应在EDT中运行,并且标记的标记没有问题。 小示例:


class ApplicationDataModel {

 private Flag current = Flag.RW;

 public void setData(ApplicationData data) {
 current = Flag.RO;
 setDataImpl(data);
 notifyObservers();
 current = Flag.RW;
 }

 public void reaction(Event e) {
 if (flag = Flag.RO) return;
. . .
 }

}

要小心标记,不要忘记线程。 如果你从另一个线程调用 setData,那么你正遇到麻烦。 当然,ApplicationData 对象的提取必须在不同的线程中运行;) 。 一般来说,重新设计你的应用程序。

用户是否选择项目 2,或者API调用 setSelection(2), 将出现相同的事件。

解决问题的方法可以能在考虑itemStateChanged代码在选择更改时要做什么。 为什么你的应用在每一个条件下都是不同的? 也许你可以用一些相似的方法。

使用标志时要注意 on事件将发生在事件调度线程上,这是与设置标志状态的它的他线程不同的线程。 这意味着使用标志可能不是 100%可靠的。

原作者:

在设置选定内容之前,可以在代码中设置标志,然后在侦听器( 如果设置了标志,则取消该标志) 中检查这里标志。

从 Java 6开始可以能有更好的方法,但是这是我总是用来做它的方式。

如David指出:如果你需要使用 SwingUtilities.invokeLater 或者类似( 你也应该在更改UI控件时这样做),你需要在EDT中设置标记( 并更新组合) 。

原作者:

如果你需要告诉事件,那么你的设计可以能需要重新考虑。 MVC的整个点是从用户的实际点击中分离模型到模型的改变。

也许你应该 restate ,为什么你会想把这两种情况区分开来呢。 然后我们就可以为实现目标提供一些不同的指导。

所以我猜你想要用户选择来执行一些操作而不仅仅是一个简单的直接状态变化。 这是由于( 灵活性总是有限的,尤其是当你在其他方面有灵活性的时候) 灵活性有限导致的问题。

我的建议是:

首先,在Swing中始终直接使用模型。 这些小部件是复杂的,你希望不同的关注点被分割。 幸运的是Swing已经有了它的模型。

通用的Pattern 是在模型之间有委托。 因此在这种情况下,你拥有保存数据的"真实"默认模型。 在JComboBox和真正的ComboBoxModel之间插入,并委托执行状态更改指令操作的ComboBoxModel 。 应用程序代码应该忽略voiceover并直接为绕过委托模型的实际进行操作。 因此在图表中:

User -- JComboBox -- ActionComboBoxModel -- DefaultComboBoxModel -- Application code
...