[英]Java AWT/SWT/Swing: How to plan a GUI?
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. 这适用于几乎所有类型的gui设计。 Sure, with Microsofts Visual Studio you have a big advantage because you nearly get what you see in the designer. 当然,使用Microsofts Visual Studio,你有一个很大的优势,因为你几乎得到了你在设计师看到的东西。
Does a good and open-source (or freeware) designer for AWT exist? 是否存在针对AWT的优秀开源(或免费软件)设计器? Already looked around and didn't find anything really intelligent. 已经环顾四周,没有找到真正聪明的东西。
EDIT: Until now, I've also created all of my GUIs by hand. 编辑:到现在为止,我还手工创建了所有的GUI。 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? 如果MS的Visual Studio能够创建大致干净的代码,为什么不是其他代码?
I've heard about some Eclipse Visual designer. 我听说过一些Eclipse Visual设计师。 Is that one already production-ready? 这个已经准备就绪吗?
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. 我不是GUI构建器的忠实粉丝:它们通常会自动生成桶装代码,然后锁定整个开发团队使用一个IDE。 Also, this code is often unreadable (check the code generated when using Matisse under Netbeans). 此外,此代码通常是不可读的(检查在Netbeans下使用Matisse时生成的代码)。
My recommendations for GUI design / debugging would be: 我对GUI设计/调试的建议是:
main
method to each panel (or "top-level" component) implementation, allowing other developers to easily determine what a component looks like. 为每个面板(或“顶级”组件)实现添加一个main
方法,允许其他开发人员轻松确定组件的外观。 Action
s over ActionListener
s and register these actions with each JComponent
's ActionMap
. 支持在ActionListener
使用Action
,并在每个JComponent
的ActionMap
注册这些操作。 This allows them to be "extracted" and added to other parts of the UI (eg JToolBar
) whilst still having their state controlled by the "owning" JComponent
(ie loose coupling). 这允许它们被“提取”并添加到UI的其他部分(例如JToolBar
),同时仍然由“拥有” JComponent
控制它们的状态(即松散耦合)。 assert SwingUtilities.isEventDispatchThread()
. 例如assert SwingUtilities.isEventDispatchThread()
。 TaskManager
class that is registered with my UI's status bar. 例如,我通常实现一个在我的UI状态栏中注册的TaskManager
类。 Any background processing (performed within SwingWorker
s) is passed a handle to a Task
created by the TaskManager
. 任何后台处理(在SwingWorker
执行)都会传递给TaskManager
创建的Task
的句柄。 Interracting with the Task (by calling setDescription(String)
, setThrowable(Throwable)
, cancel()
) causes the status bar to be updated. 与Task setThrowable(Throwable)
(通过调用setDescription(String)
, setThrowable(Throwable)
, cancel()
)会导致状态栏更新。 It also causes the glass pane to be displayed for "global" tasks ... but this is all decoupled / hidden from the individual SwingWorkers. 它还会使玻璃窗格显示为“全局”任务......但这些都与各个SwingWorkers分离/隐藏。 Observer
/ Observable
classes, but instead favour ChangeListener
, PropertyChangeListener
or your own custom listener implementation for propagating events. 不要使用Observer
/ Observable
类,而是使用ChangeListener
, PropertyChangeListener
或您自己的自定义侦听器实现来传播事件。 Observer
passes an Object
as 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. Observer
传递一个Object
作为它的事件,强制客户端代码使用instanceof检查类型并执行向下转换,使代码不可读并使类之间的关系不那么清晰。 JTable
over JList
, even in situations where your table only has one column. 支持在JList
使用JTable
,即使在表只有一列的情况下也是如此。 JList
has some nasty features in its API including the fact that you need to provide a prototype value for it to calculate its size correctly. JList
在其API中有一些讨厌的功能,包括你需要为它提供一个原型值来正确计算它的大小。 DefaultTableModel
as it typically results in you storing your "model" data in two places: In your actual business objects and also within the 2D array that DefaultTableModel
sits on. 永远不要使用DefaultTableModel
因为它通常会导致您将“模型”数据存储在两个位置:在您的实际业务对象中以及DefaultTableModel
所在的2D数组中。 Instead, simply subclass AbstractTableModel
- It's very easy to do this and means your implementation can simply delegate through to the data structure (eg List
) storing your data. 相反,只需简单地继承AbstractTableModel
- 这很容易实现,这意味着您的实现可以简单地委托给存储数据的数据结构(例如List
)。 I'm one of those archaic dudes who do GUI layout by hand. 我是那些手工制作GUI布局的古老家伙之一。 I'm also not afraid of the infamous GridBagLayout
! 我也不怕臭名昭着的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 aa parent panel or the constructor. 多年前,我通过模拟Visual Age使用的编码标准为自己保持简单:我使用了大量的JPanel来组织GUI的各个部分,每个人都有自己的makeXXX()
方法来创建它,将它布局,将其返回到父面板或构造函数。 That way, each makeXXX
only has to concentrate on a small part of the whole works. 这样,每个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 makeXXX
methods. 其他东西,只是装饰或布局,不需要在makeXXX
方法之外暴露。
That's mostly it. 这主要是它。 Works for me. 适合我。
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. 除非你在C#中使用“部分类”概念,否则GUI构建器并不好,即便如此,它们通常会导致比解决更多的问题。 Use the GUI builder tools to make a prototype - sure, but not for production code. 使用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. 我最喜欢的简单对话框布局是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. 在必要之前,不要过度思考布局。
There has been a temporarily-dead (but now apparently at least half-alive) plugin for Eclipse for visual GUI design and Netbeans still has support for it. Eclipse的视觉GUI设计暂时已经死了(但现在显然至少有一半) 插件 ,Netbeans仍然支持它。 The resulting code was less than stellar, though. 但是,由此产生的代码不是很好。 At least for people having to work with that codebase afterwards it's quite a pain. 至少对于之后不得不使用该代码库的人来说,这是非常痛苦的。
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. 我倾向于不要过多考虑Winforms和WPF中的特定布局,因为正如您所指出的那样,强大的设计师支持。 Also WPF is very easy to handle even in XAML. 即使在XAML中,WPF也很容易处理。 Ans partial classes make working with partly designer-generated and partly handwritten code very pleasant. Ans部分类使用部分设计器生成的和部分手写的代码非常愉快。 Alas, no such thing in the Java world. 唉,Java世界没有这样的东西。
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. NetBeans可能是以所见即所得的方式构建GUI的最佳选择,但许多Java开发人员手工编写GUI,因为它并不困难。 Care about the thickness of your borders and gaps between your controls and you're ok :) 关心边框的厚度和控件之间的间隙,你可以:)
Apart from tools discussion, just some ideas and thoughts 除了工具讨论,还有一些想法和想法
I use JFormDesigner for gui generation. 我使用JFormDesigner进行gui生成。 It generates nice clean java code, and I've learned a few things from reading through the generated code. 它生成了很好的干净java代码,我通过阅读生成的代码学到了一些东西。 Makes localization a snap. 使本地化变得轻而易举。
It's a really quick way to throw together an involved layout, especially complex menubars and grid layouts. 这是一种非常快速的方法,可以将相关的布局,特别是复杂的菜单栏和网格布局组合在一起。
I would suggest you to use netbeans for GUI development in AWT/SWING. 我建议你在AWT / SWING中使用netbeans进行GUI开发。
Regards, Sameer 此致,Sameer
While NetBeans' Matisse editor is admittedly handy, the code it produces is fairly esoteric and the layouts are fragile. 虽然NetBeans的马蒂斯编辑器很方便,但它产生的代码相当深奥,布局很脆弱。 So I've been taking best of both worlds, using NetBeans for WYSIWYG prototyping and then later recoding the whole thing by hand. 因此,我一直在利用NetBeans进行WYSIWYG原型设计,然后手动重新编码整个事物。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.