代码之家  ›  专栏  ›  技术社区  ›  Carl Smotricz

是否可以在回转工作线程之外更改模型?

  •  6
  • Carl Smotricz  · 技术社区  · 15 年前

    在一个“严肃”的Java GUI应用程序中,你将有许多GUI元素背后的模型: DocumentModel 后援A JEditorPane 例如,或 ListModel 背后 JList .

    我们总是被告知不要从Swing Worker线程的外部进行GUI更改,并给出 SwingUtilities.invoke...() 为了解决这个问题。好吧,我可以忍受!当直接更改GUI组件的属性时,这当然是必要的(并且工作得很好)。

    理想情况下,我的大多数GUI可见的更改将是模型,而不是JComponents。但是因为它们是图形用户界面可见的,它们会随着图形用户界面的变化而“计数”吗?也就是说,Do Change事件和侦听器提供了必要的分离,或者需要包装模型更改吗? invoke...() 也?

    可能是老帽子的摇摆专家,但我找不到任何参考,清楚地说明了一种或另一种方式。

    3 回复  |  直到 15 年前
        1
  •  5
  •   Laurent K    15 年前

    通常,模型更改必须包装到Invokelater(…)中。在我所研究的大多数Swing类的模型代码中没有解耦。

    由您创建一个模型,该模型可以包含调用,检查是否在事件调度程序线程上修改了GUI。

        2
  •  2
  •   Tom Hawtin - tackline    15 年前

    如果事件从EDT触发并更新Swing组件,这将是一个问题。

    在Swing文本中,事件可以是也可以不是(!)转到EDT。这使得测试变得棘手。毫不奇怪,API在多线程环境中并不有用。

    所以:最简单的保持模型在EDT上,其他线程应该传递消息(涉及 EventQueue.invokeLater )或者,你可以把所有的东西都锁起来,这更困难(你可能仍然需要把东西传给EDT)。尝试微同步是 非常 很难。

        3
  •  2
  •   Gabriel    15 年前

    是的,非常肯定。

    虽然这是真的,但您不应该在EDT之外修改Swing组件。您当然可以在EDT之外更改他们的模型。

    如果已将模型正确连接到Swing组件,则视图更新和EDT调度几乎将自动进行。

    见: http://java.sun.com/products/jfc/tsc/articles/architecture/#roots

    请参见有关JavaBeans事件模型的部分。

    这就是模型如何以EDT安全的方式将其更改后的状态传递给GUI。当创建新的GUI组件时,您应该遵循这个设计模式。

    还要注意GUI状态模型和应用程序数据模型之间的区别。

    从EDT更改模型仍然需要小心。事实上,当程序员在EDT中修改模型时,当他们应该从一个单独的线程修改模型时,大多数Swing问题都会发生。(臭名昭著的冻结图形用户界面问题)

    此外,这些都不排除完全了解典型的多线程陷阱。

    但您可以从EDT外部对JTableModel进行更改。