Swing的GUI指南

10

有没有一些关于Swing GUI设计的资源,例如最佳实践等等可以解释一下?

7个回答

37

因为Swing可以在许多不同的平台上运行,所以设计指南并没有被严格遵守。Sun公司早些时候写了一些指南,但从未更改过,如果你认为这有帮助,可以阅读一下。以下是一些关于进行Swing开发的实用知识。

  • 永远不要使用GridBagLayout,使用TableLayout代替。这将大大简化Swing UI的布局。GridBagLayout很麻烦。
  • 不要过度嵌套组件来实现正确的布局(例如嵌套BoxLayout等)。请参考第1点来完成此任务。将组件放在屏幕上会影响性能。
  • 按照MVC方式分离程序,Swing有View和Model分离,但在大型程序中,View(即继承Swing组件的内容)变成伪View/Controller,使得重复使用和维护变得复杂。它会很快成为混乱的代码。打破这个习惯,创建一个不继承Swing的控制器类。Model(不包含Swing)也是如此。控制器实例化高级视图类,并将自己作为监听器连接到视图上。
  • 使用简单面板简化弹出对话框,不要子类化JDialog。创建一个可重复使用的对话框类,它包装了一个面板,可以类似于JOptionPane这样使用。您的面板将不仅限于对话框,还可以被重用。按此方式工作非常容易。
  • 避免使用actionlistener/command,这是老旧的东西,不太可重用。使用AbstractAction(匿名类是您的选择,我对它们没有问题)。AbstractAction封装了文本、图标、助记符、加速器,在按钮、弹出菜单、菜单中可重用,处理切换启用/禁用状态,可在多个组件之间共享,也是将键盘按键映射到操作的InputMap/ActionMaps基础。ActionMaps为您提供了大量的重用能力。
  • 最好将调度事件视图传递给控制器。我不是在谈论鼠标/键盘等无关紧要的东西,而是高级别的事件。例如NewUserEvent、AddUserEvent、DeleteUserEvent等。让您的控制器监听这些高级业务事件。这将通过将视图的关注点(我应该使用表格、列表、树还是其他内容?)与应用程序的流程分离来促进封装。控制器不关心用户点击了按钮、菜单还是复选框。
  • 事件不仅由控制器处理。Swing是事件编程。您的模型可能会在SwingThread或后台执行操作。将事件分派回控制器是一种非常容易的方法,使其响应模型层中正在进行工作的事情。
  • 了解Swing的线程规则!你会惊讶于有多少人实际上理解Swing是单线程的,以及对于多线程应用程序意味着什么。
  • 了解SwingUtilities.invokeLater()的功能。
  • 永远不要使用SwingUtilities.invokeAndWait()。你做错了。不要尝试在事件编程中编写同步代码。(*在某些特殊情况下,invokeAndWait()是可以接受的,但99%的情况下你不需要使用invokeAndWait())
  • 如果您从头开始启动一个新项目,请跳过Swing。它已经老旧,并且已经过时了。Sun从来没有像对待服务器那样关心客户端。Swing的维护很差,自从它第一次编写以来没有多少进展。JavaFX目前还没有到位,并且遭受了许多Swing的罪恶。我建议看看Apache Pivot。有许多新想法、更好的设计和活跃的社区。

  • 很多好的观点。感谢您的回答。Apache Pivot看起来不错。但是,我不喜欢在GUI周围有一个XML的想法。它似乎很混乱。 - Carlos Blanco
    XML仅用于布局。这是Flex和Silverlight采用的方法。想一想:在Swing中,我们将Java包装在布局周围,这使得构建所见即所得的编辑器变得困难。虽然有一些工具可用,但在获得Visual Studio十年前的资源文件之前,进展缓慢。因此,您仍然使用Java进行编码,但是您可以在XML中布置UI。由于布局在XML中,因此您可以潜在地使用可视化编辑器,因为XML比Java更容易解析。它实际上将您的代码与视图分开。 - chubbsondubs
    4
    好的观点,但我必须对一些观点表示不同意。
    1. GridBagLayout并不是魔鬼。魔鬼在于当不必要时使用它。它是复杂的布局,确实如此,但它运作良好。
    2. AbstractAction很棒 - 但是将其用于UI中的每个操作组件可能会很快导致难以维护的混乱。因此,我建议结合两种方法。对于将被重复使用的代码,请使用AbstractAction,对于本地使用,请使用ActionListener。
    - Taisin
    看待GridBagLayout的方式。为什么要使用一种工具,当有更好的工具可用?TableLayout可以用比GridBagLayout更少的代码完成所有任务。你可以把使用GridBag编写的几页代码简化成5行代码,只需尝试一下,我保证你再也不会希望任何人使用GridBagLayout了。在使用TableLayout之后,我还没有遇到过一个Swing开发者喜欢GridBagLayout胜过TableLayout的情况。 - chubbsondubs
    Flex和Silverlight使用XML并不意味着它是好的!我也不喜欢使用XML来布局GUI。有很多Swing LayoutManager可以在纯Java中提供良好的布局。请查看DesignGridLayout和MigLayout等其他选项。 - jfpoilpret
    GridBagLayout 这个布局管理器有点糟糕,但主要是因为它需要杂乱的代码,否则它可以支持许多种不同的设计,有时候却需要嵌套另一个面板。 有一个非常方便的工具“painless gridbag”,它为 GBL 包装了一组流畅的 API,确实很好用! - jfpoilpret

    5

    我在这里写了一份建议列表(链接),与Java的GUI相关。


    5
    在较大的swing项目中,我会像这样对应用程序进行分区:
    • 每个GUI元素(如JPanel、JDialog等)都有一个类。

    • 为每个屏幕使用单独的包,特别是如果您必须实现自定义的TableModels或其他复杂的数据结构。

    • 不要使用匿名和内部类,而是实现ActionListener并在其中检查ActionEvent.getActionCommand()。

    编辑:如果您更想要教程或介绍,可以从这里开始。


    +1 对于匿名内部类说不,它们和闭包会导致 GUI 代码重用的死亡。 - Bill K
    同意,但问题似乎是关于用户界面人体工程学和用户体验的。 - Pascal Thivent
    @Pascal Thivent 谢谢,那我们应该推荐 SWT 吗? - stacker
    不要看SWT,可以看看Apache Pivot。Apache Pivot作为UI工具包正在做一些非常好的事情。 - chubbsondubs

    5

    1

    您可以查看 FEST 的背后理念 - 一个 Swing 测试框架。它的主要网站在这里,项目托管在这里


    1

    1

    我也有一些指南:

    1)使用Maven将应用程序分成模块(视图,控制器,服务,持久性,实用程序,模型)。确保您仅将Swing组件和依赖项放在视图包中,因此如果您想改变视图框架,您只需重新实现视图模块,但可以保留业务逻辑,控制器等不变。

    2)使用GridBagLayout,因为它非常灵活且可配置性最高

    3)使用SwingTemplate(如果需要,我可以给您提供一个示例)

    4)创建一个SwingFactory来创建组件,以便您可以减少代码行数,因为JFrames或其他意图成为非常大的类...

    5)让视图(JFrame,JDialog等)依赖于控制器。仅在JFrames上验证输入,然后将参数传递给控制器。他们将决定触发哪些业务逻辑(服务,处理器等...)。

    6)使用大量枚举

    7)始终考虑应用程序如何更改或如何维护。因此,始终针对接口或抽象类编写代码。(思考抽象)

    8) 在您的应用程序中使用设计模式,因为它们提供了代码的舒适性和可维护性。例如,将所有控制器、服务、DAO的类设置为单例类。创建工厂(SwingFactory等),这样您就不必一遍又一遍地编写重复的代码...使用观察者,以便自动处理操作。

    9) 测试您的应用程序:在TDD(测试驱动设计)或DDT(设计驱动测试)之间做出选择。

    10) 永远不要将任何业务逻辑放在JFrames上,因为这很丑陋,也不是非常符合模型-视图-控制器设计。JFrames对数据的处理方式不感兴趣。

    希望这有所帮助。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接