Java 你最好的 Swing 设计模式和技巧是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/496233/
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
What are your best Swing design patterns and tips?
提问by David Grant
I'm writing a GUI for an application using Swing, and in the interests of code maintenance and readability, I want to follow a consistent pattern throughout the whole system.
我正在使用 Swing 为应用程序编写 GUI,为了代码维护和可读性,我希望在整个系统中遵循一致的模式。
Most of the articles and books (or at least book sections) that I've read appear to provide plenty of examples on how to create and arrange various components, but ignore the bigger picture of writing a full GUI.
我读过的大多数文章和书籍(或至少是书籍部分)似乎提供了大量关于如何创建和排列各种组件的示例,但忽略了编写完整 GUI 的大局。
What are your best tips for application GUI design, and what patterns do you follow when designing or refactoring a GUI application?
您在应用程序 GUI 设计方面的最佳技巧是什么?在设计或重构 GUI 应用程序时您遵循哪些模式?
采纳答案by Paul Tomblin
Use layout managers. You might think it's simpler just to position everything with hard coded positions now (especially if you use a graphical layout tool), but when it comes time to update the gui, or internationalize it, your successors will hate you. (Trust me on this, I was the guy saying to use the layout managers from the start, and the successor to the guy who ignored me.)
使用布局管理器。您可能认为现在仅使用硬编码位置来定位所有内容更简单(特别是如果您使用图形布局工具),但是当需要更新 gui 或将其国际化时,您的继任者会讨厌您。(相信我,我就是那个从一开始就说要使用布局管理器的人,也是那个无视我的人的继任者。)
回答by Marko
Avoid using GUI layout designers (builders). Later on it will make your code much cleaner and easier to maintain.
避免使用 GUI 布局设计器(构建器)。稍后它将使您的代码更清晰,更易于维护。
回答by emeraldjava
mvc is your friend.
mvc 是你的朋友。
回答by Paul Tomblin
Get into the habit of having your callbacks spawn off threads to do the actual work, and then you won't be having frozen GUIs when one of your callbacks turns into a time consuming monster.
养成让回调从线程中产生出来来完成实际工作的习惯,然后当你的一个回调变成一个耗时的怪物时,你就不会冻结 GUI。
回答by Eddie
Definitely put the GUI in one class and the logic in another class or multiple classes -- to the greatest extent possible. If you use the MVC (Model-View-Controller)pattern, this will happen automatically. If you don't do this, the GUI will quickly become unmaintainably complicated.
绝对将 GUI 放在一个类中,将逻辑放在另一个类或多个类中——尽可能地。如果您使用MVC(模型-视图-控制器)模式,这将自动发生。如果您不这样做,GUI 将很快变得难以维护的复杂。
回答by Bill K
Try not to code the text into your app. Swing guis can be pretty easily written to be data driven, consider defining your GUI in an xml file (including the component names and positions/layout attributes).
尽量不要将文本编码到您的应用程序中。Swing guis 可以很容易地编写为数据驱动,考虑在 xml 文件中定义您的 GUI(包括组件名称和位置/布局属性)。
I worked on systems that had a LOT of property sheets (which are just piles of controls, page after page of them)--without making it data driven, it's virtually impossible to maintain or internationalize.
我研究的系统有很多属性表(它们只是一堆控件,一页又一页)——如果不使其数据驱动,几乎不可能维护或国际化。
If you decide to use a GUI builder, never modify the code it outputs if you can possibly avoid it--it's better to bind to the GUI from an external class. Think about what will happen if you have to do it without the builder--will it be difficult to port? Impossible?
如果您决定使用 GUI 构建器,请不要修改它输出的代码,如果可以避免的话,最好从外部类绑定到 GUI。想一想如果没有构建器你必须这样做会发生什么——移植会不会很困难?不可能的?
Understand the gotchas in swing--only modifying GUI components from the AWT thread, returning the AWT thread as quickly as possible (spawn a new thread if you have to do anything that takes over 100ms),
了解 Swing 中的问题——仅从 AWT 线程修改 GUI 组件,尽快返回 AWT 线程(如果您必须执行任何超过 100 毫秒的操作,则生成一个新线程),
Try your best to keep your code DRY--It can be a real programming challenge with Swing GUIs--Again, data driven code is the only way I've found to not constantly repeat code like new JButton("...");
尽量保持代码干燥——使用 Swing GUI 可能是一个真正的编程挑战——同样,数据驱动的代码是我发现不会像 new JButton("...") 那样不断重复代码的唯一方法;
If your data is property-sheet based, seriously consider creating a binding mechanism to tie your controls to your data. A good goal for DRY code would be 0 (ZERO) control-specific lines of code per control to get a piece of data from your database to your GUI, have the user edit it and get it back to your DB. This means that you should be able to add a new control by doing nothing but modifying your data.
如果您的数据是基于属性表的,请认真考虑创建一个绑定机制来将您的控件与您的数据联系起来。DRY 代码的一个好的目标是每个控件有 0 (零) 行特定于控件的代码,以便将一段数据从您的数据库获取到您的 GUI,让用户对其进行编辑并将其返回到您的数据库。这意味着您应该能够通过修改数据来添加新控件。
回答by Bill K
This is a more abstract high-level answer about what your GUI represents, not the mechanics of it..
这是关于您的 GUI 代表什么的更抽象的高级答案,而不是它的机制。
Depending on your task, it may be kind of difficult to make it so your user can conceptually grasp what the GUI is doing. I've done some pretty tricky work involving GUIs, and my most successful approaches have been those that took a complex set of controls and put them into a layout that the user expected.
根据您的任务,制作它可能有点困难,因此您的用户可以从概念上掌握 GUI 正在做什么。我做过一些涉及 GUI 的非常棘手的工作,我最成功的方法是采用一组复杂的控件并将它们放入用户期望的布局中。
For instance I wrote a system to manage 2 devices one at either end of a T1 line (kinda like modems). The controls were really hard to comprehend--fields like "create loopback, test far end signal, test near end bit patterns, sending various bit patterns, ..." (this is a huge oversimplification, it was a lot worse than this)
例如,我编写了一个系统来管理 2 个设备,一个在 T1 线路的两端(有点像调制解调器)。控件真的很难理解——诸如“创建环回、测试远端信号、测试近端位模式、发送各种位模式……”(这是一个巨大的过度简化,比这更糟糕)
I had to really understand the problem, so I went to a Tech Support rep who helped customers with this problem all the time. He showed me a diagram in the manual and stepped me through what the different controls did on that diagram.
我必须真正了解这个问题,所以我去找了一位技术支持代表,他一直帮助客户解决这个问题。他向我展示了手册中的图表,并带我了解了该图表上不同控件的作用。
I took the diagram, re-created it using graphics (just a simple line-drawing for the most part, but it showed both ends and the connections between them), then used regions of the graphics to represent controls AND feedback (color changes). You could visually see that a signal was going out. When you turned on a loopback at the far end, you could see that the line looped the signal back to it's outgoing line, then you could see the color change as your near-end started getting the pattern that it was sending out it's other line.
我拿了图,用图形重新创建它(大部分只是一个简单的线条图,但它显示了两端和它们之间的连接),然后使用图形的区域来表示控件和反馈(颜色变化) . 您可以直观地看到信号正在消失。当您在远端打开环回时,您可以看到线路将信号循环回它的出线,然后您可以看到颜色发生变化,因为您的近端开始获得它正在发送的模式,它是另一条线路.
The "Controls" were significantly more convoluted than this, but the GUI reduced it to EXACTLY what the customer needed to understand the problem.
“控制”明显比这更复杂,但 GUI 将其简化为客户理解问题所需的内容。
After this we had customers coming back to us telling us that they had never been able to figure this stuff out before, but now they totally get it!
在此之后,我们有客户回来告诉我们,他们以前从未能够弄清楚这些东西,但现在他们完全明白了!
This presentation was infinitely more important than the wiring of the GUI implementation.
此演示文稿比 GUI 实现的接线重要得多。
回答by Pierre
Have a look at the application framework API ( https://appframework.dev.java.net/and http://java.sun.com/developer/technicalArticles/javase/swingappfr/. It's a great API to build your swing application. e.g. : all the styles (color, font,icons...) are defined in a simple config file.
看看应用程序框架 API(https://appframework.dev.java.net/和http://java.sun.com/developer/technicalArticles/javase/swingappfr/。这是一个很好的 API 来构建你的 Swing 应用程序. 例如:所有样式(颜色、字体、图标...)都在一个简单的配置文件中定义。
回答by jfpoilpret
Never derive from JDialog, JFrame or JInternalFrame for defining your forms, dialogs...
永远不要从 JDialog、JFrame 或 JInternalFrame 派生来定义你的表单、对话框......
Rather derive from JPanel. This will bring you the follwing advantages:
而是从 JPanel 派生。这将为您带来以下优势:
- possibility to later change from a JFrame to a JDialog for instance (because user changed his mind)
- you can reuse one panel instance from one JDialog to another (JDialog are generally not reusable because they are constructed with a reference to their "parent", a frame or another dialog)
- you can later on change replace JDialog with a more functional subclass from a 3rd-party framework.
- 例如,稍后从 JFrame 更改为 JDialog 的可能性(因为用户改变了主意)
- 您可以将一个面板实例从一个 JDialog 重用到另一个(JDialog 通常不可重用,因为它们是通过对其“父”、框架或另一个对话框的引用构建的)
- 您可以稍后更改使用来自 3rd 方框架的功能更强大的子类替换 JDialog。
回答by Peter ?tibrany
You're not supposed to extend JFrame, JDialog, JPanel, JButton, Janything classes (although certain extensions to table behaviour are only available if you extend it). You can extend JComponent if you feel like doing custom component. If are supposed to implement models (e.g. by extending abstract models), listeners (e.g. by extending adapters), but that's it. You don't need/have to extend swing components usually, and you better not do it, as it makes your code tied to implementation of superclass.
您不应该扩展 JFrame、JDialog、JPanel、JButton、Janything 类(尽管表行为的某些扩展只有在您扩展时才可用)。如果您喜欢自定义组件,可以扩展 JComponent。如果应该实现模型(例如通过扩展抽象模型)、侦听器(例如通过扩展适配器),仅此而已。您通常不需要/必须扩展 Swing 组件,并且最好不要这样做,因为它会使您的代码与超类的实现相关联。