Java AWT/SWT/Swing:如何规划 GUI?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1742001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java AWT/SWT/Swing: How to plan a GUI?
提问by Atmocreations
I've already realized some applications with a small graphical user interface. Nothing complex, but I've encountered several problems that components aren't displayed or just not behaving as expected.
我已经实现了一些带有小型图形用户界面的应用程序。没有什么复杂的,但我遇到了几个问题,即组件不显示或行为不符合预期。
Now my question:
现在我的问题:
How do you plan those user interfaces? What do you do when you need to make changes? How do you debug strange behaviours?!
你如何规划这些用户界面?当您需要进行更改时,您会怎么做?你如何调试奇怪的行为?!
This applies for nearly every type of gui-design. Sure, with Microsofts Visual Studio you have a big advantage because you nearly get what you see in the designer.
这适用于几乎所有类型的 gui 设计。当然,使用 Microsoft 的 Visual Studio,您有很大的优势,因为您几乎可以在设计器中看到您所看到的内容。
Does a goodand open-source (or freeware) designer for AWT exist? Already looked around and didn't find anything really intelligent.
是否存在优秀的 AWT 开源(或免费软件)设计师?已经环顾四周,并没有发现任何真正智能的东西。
EDIT:Until now, I've also created all of my GUIs by hand. Sure it is cleaner code but sometimes it's very hard to find the layouting bugs. If Visual Studio by MS is able to create approximately clean code, why aren't the others?
编辑:到目前为止,我还手动创建了所有 GUI。当然它是更干净的代码,但有时很难找到布局错误。如果 MS 的 Visual Studio 能够创建大致干净的代码,为什么其他人不能?
I've heard about some Eclipse Visual designer. Is that one already production-ready?
我听说过一些 Eclipse Visual 设计器。那个已经准备好生产了吗?
回答by Adamski
I'm not a big fan of GUI builders: They typically autogenerate bucket-loads of code that then locks in your whole development team to using one IDE. Also, this code is often unreadable (check the code generated when using Matisse under Netbeans).
我不是 GUI 构建器的忠实粉丝:他们通常会自动生成大量代码,然后将整个开发团队锁定为使用一个 IDE。此外,这段代码通常是不可读的(检查在 Netbeans 下使用 Matisse 时生成的代码)。
My recommendations for GUI design / debugging would be:
我对 GUI 设计/调试的建议是:
- Add a
mainmethod to each panel (or "top-level" component) implementation, allowing other developers to easily determine what a component looks like. - Favour the use of
Actions overActionListeners and register these actions with eachJComponent'sActionMap. This allows them to be "extracted" and added to other parts of the UI (e.g.JToolBar) whilst still having their state controlled by the "owning"JComponent(i.e. loose coupling). - Use assert to ensure that all UI component modifications are occurring on the Event Dispatch thread; e.g.
assert SwingUtilities.isEventDispatchThread(). - To debug strange layout behaviour consider painting a component's background in red!
- Centralise the capturing and reporting of workflow events and exceptions. For example, I typically implement a
TaskManagerclass that is registered with my UI's status bar. Any background processing (performed withinSwingWorkers) is passed a handle to aTaskcreated by theTaskManager. Interracting with the Task (by callingsetDescription(String),setThrowable(Throwable),cancel()) causes the status bar to be updated. It also causes the glass pane to be displayed for "global" tasks ... but this is all decoupled / hidden from the individual SwingWorkers. - Do not use the
Observer/Observableclasses, but instead favourChangeListener,PropertyChangeListeneror your own custom listener implementation for propagating events.Observerpasses anObjectas it's event, forcing client code to check the type using instanceof and to perform downcasts, making code unreadable and making relationships between classes less clear. - Favour the use of
JTableoverJList, even in situations where your table only has one column.JListhas some nasty features in its API including the fact that you need to provide a prototype value for it to calculate its size correctly. - Never use
DefaultTableModelas it typically results in you storing your "model" data in two places: In your actual business objects and also within the 2D array thatDefaultTableModelsits on. Instead, simply subclassAbstractTableModel- It's very easyto do this and means your implementation can simply delegate through to the data structure (e.g.List) storing your data.
main为每个面板(或“顶级”组件)实现添加一个方法,允许其他开发人员轻松确定组件的外观。- 倾向于使用
Actions 而不是ActionListeners 并将这些操作注册到 eachJComponent的ActionMap。这允许它们被“提取”并添加到 UI 的其他部分(例如JToolBar),同时它们的状态仍然由“拥有”JComponent(即松散耦合)控制。 - 使用 assert 确保所有 UI 组件修改都发生在 Event Dispatch 线程上;例如
assert SwingUtilities.isEventDispatchThread()。 - 要调试奇怪的布局行为,请考虑将组件的背景绘制为红色!
- 集中捕获和报告工作流事件和异常。例如,我通常实现一个
TaskManager注册到我的 UI 状态栏的类。任何后台处理(在SwingWorkers内执行)都会传递一个句柄到Task由TaskManager. 与任务交互(通过调用setDescription(String),setThrowable(Throwable),cancel())会导致状态栏更新。它还导致为“全局”任务显示玻璃窗格……但这与单个 SwingWorkers 完全分离/隐藏。 - 不要使用
Observer/Observable班,而是青睐ChangeListener,PropertyChangeListener或传播事件自己定制的监听器实现。Observer传递一个Objectas it's event,强制客户端代码使用 instanceof 检查类型并执行向下转换,使代码不可读并使类之间的关系不太清楚。 - 赞成使用
JTableoverJList,即使在您的表只有一列的情况下。JList它的 API 中有一些令人讨厌的功能,包括您需要为其提供原型值以正确计算其大小的事实。 - 切勿使用,
DefaultTableModel因为它通常会导致您将“模型”数据存储在两个位置:在您的实际业务对象中以及位于其上的 2D 数组中DefaultTableModel。相反,只需子类化AbstractTableModel- 这样做非常容易,这意味着您的实现可以简单地委托给List存储数据的数据结构(例如)。
回答by Carl Smotricz
I'm one of those archaic dudes who do GUI layout by hand. I'm also not afraid of the infamous GridBagLayout!
我是那些手工进行 GUI 布局的古老家伙之一。我也不怕臭名昭著GridBagLayout!
I keep things simple for myself by emulating the coding standard used by Visual Age, years ago: I use a lot of JPanels to organize parts of the GUI, and each one gets its own makeXXX()method to create it, lay it out and return it to a a parent panel or the constructor. That way, each makeXXXonly has to concentrate on a small part of the whole works.
我通过模仿 Visual Age 多年前使用的编码标准来让事情变得简单:我使用很多 JPanel 来组织 GUI 的各个部分,并且每个人都有自己的makeXXX()方法来创建它、布置它并将其返回到父面板或构造函数。这样,每个人makeXXX只需要专注于整个作品的一小部分。
Some components need to be accessible by various instance methods; I declare those as instance fields. The other stuff, that's just decoration or layout, need not be exposed outside the makeXXXmethods.
一些组件需要通过各种实例方法访问;我将它们声明为实例字段。其他的东西,只是装饰或布局,不需要暴露在makeXXX方法之外。
That's mostly it. Works for me.
主要是这样。对我来说有效。
回答by M1EK
Do it by hand. GUI builders aren't good unless you have the 'partial class' concept in C#, and even then they often cause more problems than they solve. Use the GUI builder tools to make a prototype - sure, but not for production code.
亲手做。除非您在 C# 中有“部分类”的概念,否则 GUI 构建器不会很好,即使这样,它们也会引起比解决的问题更多的问题。使用 GUI 构建器工具制作原型 - 当然,但不适用于生产代码。
Also, another little trick I've used over the years to good effect when trying to debug layout or "which panel am I really seeing here" problems is to give each 'container' panel a really garish background color (yellow, blue, etc). Something obvious enough that you'll see it even if it's only one pixel wide.
此外,多年来我在尝试调试布局或“我真正看到的面板”问题时使用的另一个小技巧是给每个“容器”面板一个非常花哨的背景颜色(黄色、蓝色等) )。一些足够明显的东西,即使它只有一个像素宽,你也会看到它。
And my favorite layout for simple dialogs is BoxLayout. It's not great, you have to write a lot of boilerplate, but at least it generally works the way you would expect it to in your head. Don't overthink layouts until you have to.
我最喜欢的简单对话框布局是 BoxLayout。这不是很好,您必须编写大量样板文件,但至少它通常以您在头脑中期望的方式工作。除非必要,否则不要过度考虑布局。
回答by helpermethod
回答by Sam Barnum
I use JFormDesignerfor gui generation. It generates nice clean java code, and I've learned a few things from reading through the generated code. Makes localization a snap.
我使用JFormDesigner生成 gui。它生成了漂亮干净的 java 代码,我从阅读生成的代码中学到了一些东西。使本地化变得轻而易举。
It's a really quick way to throw together an involved layout, especially complex menubars and grid layouts.
这是将涉及的布局(尤其是复杂的菜单栏和网格布局)组合在一起的一种非常快速的方法。
回答by Andreas Dolk
Apart from tools discussion, just some ideas and thoughts
除了工具讨论,只是一些想法和想法
- Before you touch the keyboard, draw the GUI elements on paper. Like the classic storyboard used for video production. If you have customers, use the hand-drawn (!) designs to communicate the ideas (.. just read, that you already plan on paper)
- Plan to implement a model-view-controller (MVC) or model-view-presenter pattern
- Databindingis a great technique to consider. It guarantees synchronisation between your model (data) and the view (GUI) and offers input validation, on-the-fly conversion and many more useful things (Provided the link for JFace databinding, but I'm sure, there are other frameworks for Swing/AWT as well)
回答by Joey
There has been a temporarily-dead (but now apparently at least half-alive) plugin for Eclipsefor visual GUI design and Netbeans still has support for it. The resulting code was less than stellar, though. At least for people having to work with that codebase afterwards it's quite a pain.
有一个用于 Eclipse的可视化 GUI 设计暂时失效(但现在显然至少是半死不活)插件,而 Netbeans 仍然支持它。但是,生成的代码并不出色。至少对于事后必须使用该代码库的人来说,这是相当痛苦的。
As for me I tend to plan on paper beforehand and try to get all nestings of panels with their layouts right on the first try. Java GUI code is inherently write-only in my experience.
至于我,我倾向于事先在纸上计划,并尝试在第一次尝试时就将所有面板的布局都嵌套在正确的位置。根据我的经验,Java GUI 代码本质上是只写的。
Last time I did such a thing I first created every control I needed and then pieced it together in multiple panels and layouts, etc. That way was at least manageable and worked without too much pain when changes had to be made.
上次我做这样的事情时,我首先创建了我需要的每个控件,然后将它们拼凑在多个面板和布局等中。这种方式至少是易于管理的,并且在必须进行更改时不会有太多痛苦。
I tend not to think too much about the particular layout in Winforms and WPF due to the, as you noted also, strong designer support. Also WPF is very easy to handle even in XAML. Ans partial classes make working with partly designer-generated and partly handwritten code very pleasant. Alas, no such thing in the Java world.
我倾向于不会过多考虑 Winforms 和 WPF 中的特定布局,因为正如您所指出的,强大的设计器支持。即使在 XAML 中,WPF 也很容易处理。Ans 部分类使使用部分设计者生成和部分手写的代码非常愉快。唉,在 Java 世界中没有这样的事情。
回答by Dmitry
NetBeans might the best option for building GUI in WYSIWYG manner but many java developers write their GUI by hands, as it is not that difficult. Care about the thickness of your borders and gaps between your controls and you're ok :)
NetBeans 可能是以所见即所得方式构建 GUI 的最佳选择,但许多 Java 开发人员手工编写他们的 GUI,因为这并不困难。关心你的边框的厚度和控件之间的间隙,你没问题:)
回答by Samra
I would suggest you to use netbeans for GUI development in AWT/SWING.
我建议您在 AWT/SWING 中使用 netbeans 进行 GUI 开发。
Regards, Sameer
问候, 萨米尔
回答by Joonas Pulakka
While NetBeans' Matisse editor is admittedly handy, the code it produces is fairly esoteric and the layouts are fragile. So I've been taking best of both worlds, using NetBeans for WYSIWYG prototyping and then later recoding the whole thing by hand.
虽然 NetBeans 的 Matisse 编辑器确实很方便,但它生成的代码相当深奥,而且布局也很脆弱。所以我一直在两全其美,使用 NetBeans 进行 WYSIWYG 原型设计,然后手动重新编码整个过程。

