问题:从外部类控制Swing GUI并将逻辑与用户界面分离

时间:2011-06-05 05:26:56

标签: java swing jtextfield

更新:我正在使用Netbeans和Matise,它可能是Matise导致我在下面描述的问题。

更新2:感谢那些提出建设性意见的人。在没有Matise帮助的情况下重写代码后, ignis 提供的答案按照他的描述工作。我仍然不确定Netbeans代码生成器如何干扰代码。

虽然我已经用Java编程了一段时间,但直到现在我还没有完成任何GUI编程。我想从外部控制程序的某个部分(用外部源的输出更新jTextArea字段),而不需要任何用户操作来触发jTextArea中此输出的显示。

具体来说,我希望此输出在启动时开始显示,并根据与GUI无关的外部条件或用户正在执行的操作启动和停止。根据我的理解,到目前为止,您可以通过动作侦听器触发此类事件,但这些动作侦听器假设它们正在侦听用户活动。如果我必须使用动作侦听器,是否有办法欺骗GUI以便认为用户交互已经发生,或者是否有更直接的方式来实现我想要做的事情?

另外,我真的想了解更多关于将GUI代码与应用程序逻辑分离的最佳实践。从我遇到的文档来看,GUI开发似乎需要更多的逻辑和用户界面的混乱集成,而不是一个可以实现完全分离的Web应用程序。我对这方面的任何线索非常感兴趣。

3 个答案:

答案 0 :(得分:3)

无需使用听众。 GUI对象就像程序中的任何其他对象一样,实际上

  1. 您可以在程序的任何部分使用侦听器模式,即使它与GUI无关
  2. 您可以在程序执行期间随时调用GUI对象的方法,即使您没有将任何侦听器附加到GUI中的对象。
  3. 您必须遵循的主要“规则”是,必须在AWT事件调度线程上运行对GUI对象执行的每个方法调用(是的,对于Swing也是如此)。

    http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

    因此,您必须将访问GUI对象的代码包装到

    javax.swing.SwingUtilities.invokeLater( new Runnable() { ... } )
    

    javax.swing.SwingUtilities.invokeAndWait( new Runnable() { ... } )
    

    http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html


    关于“将GUI代码与应用程序逻辑分离”:谷歌“MVC”或“模型视图控制器”。这是分离这些东西的“标准”方式。它包括使GUI代码(“视图”)只是内容的“外观”(“模型”)。应用程序的另一部分(“控制器”)根据需要创建和调用模型和视图(它“控制”程序执行,或者它应该这样做,因此它被命名为“controller”),并将它们相互连接

    http://download.oracle.com/javase/tutorial/uiswing/components/model.html

    例如,javax.swing包中定义Swing组件的JFoo类充当javax.swing或其子包之一定义的一个或多个FooModel类或接口的视图。您的程序将是“控制器”,它正确地实例化视图和模型的实现(这可能是我提到的那些包下的默认实现之一,或者在程序中的自定义包中定义的自定义实现)。 / p>

    http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/package-summary.html

答案 1 :(得分:1)

这是一个非常好的问题,恕我直言......几年前我在Sun的Java论坛上问过这个问题(现在基本上已经不复存在了,而不是甲骨文,这是一个半死不活的财政法西斯分子)。

在为kaos带来秩序的前面,这是你典型的GUI的“第一次切割”,Google for Swing MVC。我读到的关于该主题的第一篇文章是JavaWorld's "MVC meets Swing"。我很幸运,因为它解释了问题,并提出了理智的解决方案(附例子)。仔细阅读,并自己谷歌“阅读扩展”并向我们提出任何具体问题。

在“模拟用户活动”方面你真的没什么值得担心的......你只需要观察你的外部条件,比如说你检测到本地文件已被更新(例如)并且反过来“向注册听众发出通知......唯一的区别是,在这种情况下,你实施的是“说话者”和“听众”。 Swings Listener接口可以重新用于消息传递(或者不是,在您的干扰中)。这里没什么棘手的。

“提升”一个“事件”是完全直截了当的。基本上你只需要在当前注册的每个监听器上调用“EventHappened”方法。唯一棘手的问题是处理所有非平凡的Swing应用程序中的“多线程”...否则它们会像三条腿一样运行,因为EDT(谷歌它)总是不做任何事情,而不是只是绘画和消息代理(即它的设计目的)。 (如前所述,Ignis)SwingUtilies类在EDT上为“引发事件”提供了一些方便的invoke方法。

Swing应用程序并没有什么特别之处...... Swing只是有一个非常陡峭的学习曲线,这就是全部,特别是多线程......我之前曾经避免的一个话题就像瘟疫一样,“对于一个不起眼的大脑来说太复杂了矿”。毋庸置疑,事实证明这是一种毫无根据的恐惧。甚至像我这样的老白痴也能理解它......它只需要更长的时间,就是这样。

干杯。基思。

答案 2 :(得分:0)

这并不能完全回答您的问题,但您可能对使用Netbeans进行Java GUI开发感兴趣。您可以在Netbeans中使用GUI来进行Java GUI开发。

这是一个开始的好地方 - http://netbeans.org/kb/trails/matisse.html