Java AWT/SWT/Swing:如何规划 GUI?
Posted
技术标签:
【中文标题】Java AWT/SWT/Swing:如何规划 GUI?【英文标题】:Java AWT/SWT/Swing: How to plan a GUI? 【发布时间】:2010-12-17 01:16:53 【问题描述】:我已经实现了一些带有小型图形用户界面的应用程序。没什么复杂的,但我遇到了几个问题,即组件未显示或行为不符合预期。
现在我的问题:
您如何规划这些用户界面?当你需要做出改变时,你会怎么做?你如何调试奇怪的行为?!
这适用于几乎所有类型的 gui 设计。当然,使用 Microsoft 的 Visual Studio,您有很大的优势,因为您几乎可以得到您在设计器中看到的内容。
是否存在优秀的 AWT 的开源(或免费软件)设计器?已经环顾四周,没有发现任何真正聪明的东西。
编辑:到目前为止,我还手动创建了所有的 GUI。当然它是更干净的代码,但有时很难找到布局错误。如果 MS 的 Visual Studio 能够创建大致干净的代码,为什么其他人不能?
我听说过一些 Eclipse Visual Designer。那个已经准备好生产了吗?
【问题讨论】:
感谢您的好评,你们都提供了有用的信息。我一直在使用 Visual Editor for Eclipse 进行构建。对于原型来说,它是一个很好的工具,但不是真正用于生产。 我投票结束这个问题,因为这不是关于编程,而是关于 UI/UX。 【参考方案1】:我不是 GUI 构建器的忠实粉丝:它们通常会自动生成大量代码,然后将整个开发团队锁定为使用一个 IDE。另外,这段代码通常不可读(查看 Netbeans 下使用 Matisse 时生成的代码)。
我对 GUI 设计/调试的建议是:
为每个面板(或“***”组件)实现添加main
方法,使其他开发人员可以轻松确定组件的外观。
倾向于使用Action
s 而不是ActionListener
s,并将这些操作注册到每个JComponent
的ActionMap
。这允许它们被“提取”并添加到 UI 的其他部分(例如 JToolBar
),同时仍然由“拥有”JComponent
控制它们的状态(即松散耦合)。
使用 assert 确保所有 UI 组件修改都发生在 Event Dispatch 线程上;例如assert SwingUtilities.isEventDispatchThread()
。
要调试奇怪的布局行为,请考虑将组件的背景绘制为红色!
集中捕获和报告工作流事件和异常。例如,我通常实现一个TaskManager
类,该类注册到我的 UI 的状态栏。任何后台处理(在SwingWorker
s 内执行)都会传递一个句柄到由TaskManager
创建的Task
。与任务交互(通过调用setDescription(String)
、setThrowable(Throwable)
、cancel()
)会导致状态栏被更新。它还导致为“全局”任务显示玻璃窗格......但这一切都与单个 SwingWorker 分离/隐藏。
不要使用Observer
/ Observable
类,而是使用ChangeListener
、PropertyChangeListener
或您自己的自定义侦听器实现来传播事件。 Observer
传递一个 Object
作为它的事件,强制客户端代码使用 instanceof 检查类型并执行向下转换,使代码不可读并且使类之间的关系不太清晰。
倾向于使用JTable
而不是JList
,即使在您的表只有一列的情况下也是如此。 JList
在其 API 中有一些令人讨厌的特性,包括您需要为其提供原型值才能正确计算其大小。
永远不要使用DefaultTableModel
,因为它通常会导致您将“模型”数据存储在两个位置:在您的实际业务对象中以及在DefaultTableModel
所在的二维数组中。相反,只需将AbstractTableModel
子类化 - 这非常容易执行此操作,这意味着您的实现可以简单地委托给存储数据的数据结构(例如List
)。
【讨论】:
一切都是这个答案很棒,我只想添加一点。考虑在纸上绘制你的 GUI。使用不同颜色的钢笔/铅笔来指示隐藏的面板、布局管理器、操作等。效果很棒!你可以在白板上做同样的事情,但我更喜欢纸和笔的精确度(而且我们有各种各样的废料) +1 断言的好技巧。当您从 EDT 外部访问 UI 时发生的错误通常是微妙而奇怪的。而且很难找到。 您不需要为 JList 指定原型值。自动计算适当的大小。这是通过循环遍历模型中的所有项目并调用渲染器来确定首选大小来完成的。如果您有一个大型模型,这可能效率低下,您可能希望提供一个原型值来绕过此行为。另一方面,JTable 根本不提供对此的支持,您必须猜测行高和列宽并手动更新表和 TableColumn。 @camickr:我指的是 JList 开始为空并在应用程序生命周期内添加项目的情况。我仍然更喜欢 JTable,因为它还提供开箱即用的排序/过滤功能。要调整表格列的大小,我通常使用类似于以下的实用方法:exampledepot.com/egs/javax.swing.table/PackCol.html【参考方案2】:我是那些手工进行 GUI 布局的古人之一。我也不怕臭名昭著的GridBagLayout
!
我通过模仿多年前 Visual Age 使用的编码标准来使事情变得简单:我使用很多 JPanel 来组织 GUI 的各个部分,每个都有自己的 makeXXX()
方法来创建它,lay它出来并将其返回给父面板或构造函数。这样,每个makeXXX
只需要专注于整个作品的一小部分。
有些组件需要通过各种实例方法来访问;我将它们声明为实例字段。其他的东西,只是装饰或布局,不需要暴露在makeXXX
方法之外。
主要是这样。对我有用。
【讨论】:
我会用 MigLayout 替换 GridBagLayout(颤抖......) - miglayout.com 任何时候有人使用 GridBagLayout,天使都会失去他的翅膀。更好:确定您的布局需求,并编写您的自定义布局管理器(例如,用于键/值布局)。 如果你喜欢GridBagLayout
,你一定会喜欢MiGLayout。 ;)【参考方案3】:
手工操作。除非您在 C# 中有“部分类”概念,否则 GUI 构建器并不好,即便如此,它们通常会导致比解决的问题更多的问题。使用 GUI 构建器工具制作原型 - 当然可以,但不适用于生产代码。
此外,多年来我在尝试调试布局或“我在这里真正看到的是哪个面板”问题时使用的另一个小技巧是给每个“容器”面板一个非常花哨的背景颜色(黄色,蓝色等)。很明显的东西,即使只有一个像素宽,你也能看到。
我最喜欢的简单对话框布局是 BoxLayout。这不是很好,你必须写很多样板,但至少它通常按照你想象的方式工作。除非必要,否则不要过度考虑布局。
【讨论】:
【参考方案4】:NetBeans 可能是以 WYSIWYG 方式构建 GUI 的最佳选择,但许多 Java 开发人员手动编写他们的 GUI,因为这并不难。关心边框的厚度和控件之间的间隙就可以了:)
【讨论】:
是的,关于对齐。 UI 中有很多东西从技术角度来看是相当复杂的,并且有一些调试技巧(例如,如果您的控件经常重绘 => 使用日志记录,断点可能无济于事)但真正具有挑战性的事情发生在一张纸上和设计师的大脑。【参考方案5】:除了工具讨论,只是一些想法和想法
-
在触摸键盘之前,请在纸上绘制 GUI 元素。就像用于视频制作的经典故事板一样。如果您有客户,请使用手绘 (!) 设计来传达想法(.. 只需阅读,您已经在纸上计划好了)
计划实施模型-视图-控制器 (MVC) 或模型-视图-演示者模式
Databinding 是一个值得考虑的好技术。它保证模型(数据)和视图(GUI)之间的同步,并提供输入验证、即时转换和更多有用的东西(提供了 JFace 数据绑定的链接,但我敢肯定,还有其他框架用于Swing/AWT 也是如此)
【讨论】:
【参考方案6】:视觉 GUI 设计有一个暂时死掉的(但现在显然至少半生不死)plugin for Eclipse,Netbeans 仍然支持它。但是,生成的代码并不那么出色。至少对于之后不得不使用该代码库的人来说,这是相当痛苦的。
就我而言,我倾向于事先在纸上进行计划,并尝试在第一次尝试时将所有的面板嵌套及其布局正确。根据我的经验,Java GUI 代码本质上是只写的。
上次我做这样的事情时,我首先创建了我需要的每个控件,然后将它们拼凑到多个面板和布局等中。这种方式至少是易于管理的,并且在必须进行更改时工作起来没有太多痛苦。
我倾向于不过多考虑 Winforms 和 WPF 中的特定布局,因为正如您还提到的,强大的设计器支持。即使在 XAML 中,WPF 也很容易处理。 Ans 部分类使处理部分由设计师生成和部分手写的代码非常愉快。唉,Java 世界里没有这样的东西。
【讨论】:
如果我错了,请纠正我,但我认为 eclipse VE 再次变得活跃(几年后)。阅读有关 1.4 版的信息!? 哦,谢谢你的通知。没有注意到他们将它从死里复活,因为我大部分使用 Java 的人已经死了或几乎死了。 我喜欢生成 VE 的代码。与 Netbeans GUI builder 相比,它更简洁,易于理解和“手动”修改。 @bancer:我不得不承认,关于代码质量的评论更多是关于 Netbeans。我很高兴只修改过一次这样的代码,但这很痛苦:-)【参考方案7】:我使用JFormDesigner 生成gui。它生成了漂亮干净的 java 代码,我通过阅读生成的代码学到了一些东西。让本地化变得轻而易举。
这是一种将相关布局组合在一起的非常快速的方法,尤其是复杂的菜单栏和网格布局。
【讨论】:
【参考方案8】:我自己用
Pencil
首先进行一些原型设计,然后开始“手动”编码(即不使用任何 GUI 编辑器)。
【讨论】:
提供的链接给出了 HTTP 500 错误。这是一个更新的链接:pencil.evolus.vn【参考方案9】:我建议你在 AWT/SWING 中使用 netbeans 进行 GUI 开发。
问候, 萨米尔
【讨论】:
请看下面的链接。它会帮助你。这只是拖放的问题。 java.sun.com/docs/books/tutorial/javabeans/nb/index.html【参考方案10】:虽然 NetBeans 的 Matisse 编辑器确实很方便,但它生成的代码相当深奥,而且布局也很脆弱。所以我一直在两全其美,使用 NetBeans 进行所见即所得的原型设计,然后手动重新编码整个事情。
【讨论】:
我几乎要真正尝试编写一个从 XAML 到 Swing 代码的转换器,因为 VS 和 WPF 在原型 UI 中非常很方便。但后来我没有时间,仍然手工编码 sigh以上是关于Java AWT/SWT/Swing:如何规划 GUI?的主要内容,如果未能解决你的问题,请参考以下文章