简体   繁体   English

Java AWT / SWT / Swing:如何规划GUI?

[英]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设计/调试的建议是:

  • Add a main method to each panel (or "top-level" component) implementation, allowing other developers to easily determine what a component looks like. 为每个面板(或“顶级”组件)实现添加一个main方法,允许其他开发人员轻松确定组件的外观。
  • Favour the use of Action s over ActionListener s and register these actions with each JComponent 's ActionMap . 支持在ActionListener使用Action ,并在每个JComponentActionMap注册这些操作。 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控制它们的状态(即松散耦合)。
  • Use assert to ensure that all UI component modifications are occurring on the Event Dispatch thread; 使用assert确保在Event Dispatch线程上发生所有UI组件修改; eg assert SwingUtilities.isEventDispatchThread() . 例如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 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分离/隐藏。
  • Do not use the Observer / Observable classes, but instead favour ChangeListener , PropertyChangeListener or your own custom listener implementation for propagating events. 不要使用Observer / Observable类,而是使用ChangeListenerPropertyChangeListener或您自己的自定义侦听器实现来传播事件。 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检查类型并执行向下转换,使代码不可读并使类之间的关系不那么清晰。
  • Favour the use of 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中有一些讨厌的功能,包括你需要为它提供一个原型值来正确计算它的大小。
  • Never use 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 除了工具讨论,还有一些想法和想法

  1. Before you touch the keyboard, draw the GUI elements on paper. 在触摸键盘之前,在纸上绘制GUI元素。 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) 如果您有客户,请使用手绘(!)设计来传达这些想法(..只是阅读,您已经计划在纸上)
  2. Plan to implement a model-view-controller (MVC) or model-view-presenter pattern 计划实现模型 - 视图 - 控制器(MVC)或模型 - 视图 - 展示器模式
  3. Databinding is 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) 它保证了模型(数据)和视图(GUI)之间的同步,并提供输入验证,动态转换和更多有用的东西(提供了JFace数据绑定的链接,但我敢肯定,还有其他框架用于Swing / AWT以及)

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 for myself use 我自己用

Pencil 铅笔

for some prototyping first, then start coding "by hand" (ie not using any GUI editor). 首先进行一些原型设计,然后“手动”开始编码(即不使用任何GUI编辑器)。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM