2009-01-30 76 views
34

我正在为使用Swing的应用程序编写GUI,为了维护代码和可读性,我希望在整个系统中遵循一致的模式。什么是你最好的Swing设计模式和技巧?

我读过的大部分文章和书籍(或者至少是书本章节)似乎都提供了大量有关如何创建和安排各种组件的示例,但忽略了编写完整GUI的大图。

什么是应用程序GUI设计的最佳提示,以及在设计或重构GUI应用程序时遵循哪些模式?

+0

这里是我的四个孩子:http://blue-walrus.com/swing-design-patterns/ – 2013-07-02 07:30:31

回答

14

使用布局管理器。你可能会认为只需要用硬编码的位置来定位所有的东西就更简单了(特别是如果你使用图形化布局工具的话),但是当需要更新gui或者国际化时,你的后继者会恨你。 (请相信我,我是一开始就使用布局管理器的人,以及忽视我的人的继任者。)

14

避免使用GUI布局设计器(构建器)。稍后它会让你的代码更清洁和更容易维护。

+1

确实,如果你用一个建造者开始你的GUI,你几乎承诺整个使用这个建造者GUI的整个生命周期。这有时可以接受,有时不可以。 – Eddie 2009-01-30 17:27:01

+0

是的,这是真的。不同的构建者以不相互兼容的不同格式存储元数据。唯一的例外是Instantiations Swing Designer,它直接与代码一起工作。 所有这些代码都不会被手动编辑(无法读取),这会稍后再咬你。 – Marko 2009-01-30 17:30:23

+2

我不同意。如果您知道Swing,那么由GUI构建器生成的任何代码都将具有足够的可读性。问题在于,通过使用GUI构建器,您无法很好地了解Swing。良好的分离当然是必要的。 – willcodejavaforfood 2009-02-01 14:49:47

7

养成你的回调产生线程来完成实际工作的习惯,然后当你的回调变成一个耗时的怪物时,你不会有冻结的GUI。

4

绝对把GUI放在一个类中,而把逻辑放在另一个类或多个类中 - 尽最大可能。如果您使用MVC (Model-View-Controller)模式,则会自动发生。如果你不这样做,GUI将很快变得难以维系复杂。

5

尽量不要将文本编码到您的应用程序中。 Swing guis可以很容易地写成数据驱动,可以考虑在xml文件中定义你的GUI(包括组件名称和位置/布局属性)。

我工作的系统有很多属性表(它们只是一堆一堆的控件,一页接一页地) - 如果没有数据驱动,几乎不可能维护或国际化。

如果您决定使用GUI构建器,请不要修改它输出的代码(如果可以避免的话) - 最好从外部类绑定到GUI。想想如果你必须在没有建造者的情况下做到这一点会发生什么 - 难以移植吗?不可能?

理解挥杆的陷阱 - 只能从AWT线程修改GUI组件,尽可能迅速返回AWT线程(生成一个新的线程,如果你做任何事情,需要大于100ms),

尝试最好让代码保持干爽 - 这可能是Swing GUI的一个真正的编程挑战 - 同样,数据驱动的代码是我发现的不会重复代码的唯一方式,如 新的JButton(“...”) ;

如果您的数据基于属性表,请认真考虑创建绑定机制以将控件与数据绑定。对于DRY代码来说,一个好的目标是每个控件的控制特定的代码行,以便从数据库中获取一段数据到您的GUI,并让用户编辑它并将其返回到数据库。这意味着你应该可以通过不做任何事情来修改你的数据来添加一个新的控件。

8

这是一个更抽象的关于GUI代表什么的高层次的答案,而不是它的机制。

根据任务的不同,它可能是一种很难说这样你的用户可以在概念上把握什么GUI正在做什么。我已经做了一些非常棘手的工作,涉及GUI,我最成功的方法是将一组复杂的控件放入用户期望的布局中。

例如我写了一个系统来管理2台设备的一个在T1线路(有点像调制解调器)的任一端。这些控件真的很难理解 - 像“创建回送,测试远端信号,测试近端位模式,发送各种位模式......”(这是一个巨大的过度简化,比这更糟糕)

我必须真正理解这个问题,所以我去了一位技术支持代表,他帮助客户解决了这个问题。他向我展示了手册中的图表,并向我介绍了该图表上不同的控件。我用图形重新创建了它(大部分只是一个简单的线条图,但它显示了两端和它们之间的连接),然后使用图形区域来表示控件和反馈(颜色变化)。你可以通过视觉看到信号正在传出。当你在远端打开一个环回时,你可以看到这条线路将信号环回到它的外线,然后你可以看到颜色的变化,因为你的近端开始得到它发出它的另一条线路的模式。

“控件”比这个显著比较绕口,但是GUI也减少到需要什么客户来理解问题。

在此之后,我们有客户回来给我们告诉我们,他们从未能够前算出这个东西出来,但现在他们完全得到它!

此演示文稿比GUI实现的布线更为重要。

18

切勿的JDialog,JFrame的或派生的JInternalFrame定义你的表格,对话框...

从JPanel的派生而这将带给您follwing优点:

  • 可能性从后面的变化(因为用户改变了主意)
  • 您可以将一个面板实例从一个JDialog重用到另一个面板(JDialog通常不可重用,因为它们是通过引用其“父”,框架或另一个对话框)
  • 你以后可以改变与第三方框架,功能更强大的 子取代 的JDialog。
4

您不应该扩展JFrame,JDialog,JPanel,JButton,Janything类(尽管表行为的某些扩展只在扩展时才可用)。如果您想做自定义组件,可以扩展JComponent。如果应该实现模型(例如通过扩展抽象模型),听众(例如通过扩展适配器),但就是这样。通常不需要/不得不扩展摆动组件,而且最好不要这样做,因为它使您的代码与超类的实现相关联。

6

构图更容易时避免继承。

比如我见过像这样的很多:

public class CustomerSupportApp extends JFrame { 
    JList<Customer> customers; 
    OtherBusinessComponent importantComponent; 

    etc. etc 

} 

这是混合业务逻辑与表现。它只是使变化从困难变为不可能。

更好的是:

public class CustomerSupportApp { 
    JList<Customer> customers; 
    OtherBusinessComponent importantComponent; 
    // The app HAS-A frame but not IS-A frame 
    JFrame frame; 
    etc. etc 
} 
8

避免生成当用户点击操作按钮多次线程太多。在第一次点击时禁用按钮,在后台线程中产生动作,完成后再次启用按钮。这对短期运行任务可能不是问题。

1

我认为你将面临的主要问题是你的GUI应用程序的可测试性。

因此,关于单元测试的可维护性和易用性,我倾向于使用“演示者优先”成语而不是模型视图控制器(MVC)和其他衍生指令来指示您了解实际应用程序逻辑(模型)。最好的资源是将它作为思想引入的组织的web site

由于使用这种方法将需要大量样板代码来初始化应用程序的各种元素,我还建议使用依赖注入框架。我已与Guice解决。

9

我认为并行的一个良好的工作知识往往是低估。您确实需要熟悉Swing的线程策略和常规同步技术,才能构建响应式GUI和高效的后端。

6

大量使用MVC模式。这里有一个简单的例子,我的意思是:

class Person 
{ 
    String firstName; 
    String lastName; 
    // and getters and setters... 
} 

class PersonSwingModel 
{ 
    private Person person; 
    private javax.swing.text.PlainDocument firstName; 
    private javax.swing.text.PlainDocument lastName; 
    // and getters and setters... 
    // Create some method like init() that initializes PlainDocument values 
    // to attributes in model. 
} 

class SavePersonAction extends AbstractAction 
{ 
    private PersonSwingModel model; 
    // and getters and setters... 
} 

class PersonSwingView extends JFrame 
{ 
    private PersonSwingModel model; 
    private javax.swing.JTextField firstName; 
    private javax.swing.JTextField lastName; 
    private SavePersonAction savePersonAction; // hook up to JButton/JMenuItem 
    // and getters and setters... 
    // Create some method like init() which binds PlainDocument to JTextField 
    // and Actions to JButtons or JMenuItems 
} 

我看到一些人不同意扩展JFrame或JPanel。我不。适用于我。

另外,使用LayoutManagers。 GridBagLayout功能非常强大。如果使用它,则定义一些GridBagConstraints常量(如LABEL_GBC和FIELD_GBC)并继续重用它们。

6
  • Karsten Lentzsch的JGoodies对我的建筑设计非常有帮助,尤其是关于Presentation Model模式,绑定和验证。看看他的articleslibraries
  • 使用类似MVC的模式。我说“像”,因为目标实际上是将视图从模型中分离出来,而不是遵循MVC的特定风格。我更喜欢自己使用Presentation Model
  • MiGLayout - 除非基本的布局管理员会这么做,否则我会使用它。
  • 尽你所能进行模块化和重用。
  • WindowBuilder Pro对于Eclipse - 最好的视觉设计师,因为它与现有/编辑的代码一起工作,并且不锁定你。现在它是免费的!我没有使用设计师的问题,因为视图应该与其他代码分开。
  • Netbeans Platform(RCP) - 唯一真正的Swing框架。我希望在有空的时候学习和使用它,因为框架的一部分工作就是解决像你这样的问题。
  • JavaBuilders - 酷项目,允许声明性用户界面,但我不确定它是足够成熟的风险,尤其是对于现有的项目。不过,阅读PDF书籍只是为了理解他们试图解决的问题,这很有趣。
相关问题