18

While doing my pre-research for this question, I found that there isn't much well-organized information about Java Swing best practices out there on the Internet. So I figure I'll give Stack Exchange a shot at building that One Great List.

What are the best practices of Java Swing development? What have you found to work for you, and why?

Pops
  • 4,093
  • 4
  • 28
  • 41
  • 2
    I played with Swing in school, and it was not a pleasant experience. The whole thing seemed bloated and unnecessarily complex. The best practice may be to [use something else.](http://leepoint.net/notes-java/GUI/misc/80gui-generator.html) – Robert Harvey Jan 24 '11 at 22:05
  • 2
    @RobertHarvey "playing in school" is a far cry from delivering production software. I've found that Swing can do all that was required of it in a reasonable, logical way. –  Feb 06 '12 at 08:23
  • Well, put it this way: If it was that difficult on a mere school project, it would almost be unimaginably difficult on a real one. – Robert Harvey Feb 06 '12 at 15:51
  • 1
    @RobertHarvey power comes with a price... –  May 02 '12 at 08:32
  • Just one more important thing. Swing components are serializable and have many ancestors. So they are too heavy to inherit in most cases. You should consider some wrapping technique, especially when you have an unserializable state. If you inherit from a component, just use it as a view (in MVC or a similar pattern). – Dávid Horváth Nov 28 '18 at 12:10

2 Answers2

13

I can only answer for what's worked for me. Other commentors have pointed out that Java GUIs in general fall into the 'uncanny valley' of not-quite-native look and feel, and I don't dispute this.

Make good use of the Action API. It lets you better encapsulate different actions your user will perform and allow you to wire them up to shortcuts, accelerator keys, buttons and other input objects much more easily.

Use an appropriate layout manager. GridBagLayout is extremely powerful, but I would go so far as to say it is unmaintainable without an excessive amount of comments. When I run static code analysis tools such as Sonar over an older GUI app I maintain, it always points out the massive amounts of magic numbers to make the GridBags layout just right. I've had plenty of success with GroupLayout, which avoids having to specify pixel-perfect alignment.

If you think you need a JDialog... you probably don't. Dialog boxes are horrible, in terms of user experience -- this application decided to use them for every menu and form, and to enforce always-on-top rules in bizarre ways. This turned into a maintenance nightmare when we actually did need to alert something over the menu. Cue frustrated clicking on unfocusable -- and thus undismissable -- dialogs.

Use SwingWorker instead of rolling your own multithreading, where appropriate. It's very easy to extend SwingWorker and do some longrunning task while providing regular updates back to the GUI. Think downloading a client update. It'll handle the worker thread scheduling for you and let you publish download percentages back to the view, so you can update your ProgressBar or what have you.

That's all I can suggest, in my admittedly limited experience.

Thorn G
  • 411
  • 2
  • 10
  • 2
    `JDialog` is perfectly fine - as long as you use it for dialogs. – Jonas Feb 03 '11 at 00:31
  • 1
    I agree they're fine if you're using them for information that absolutely must be seen -- and acted on -- immediately. But most information really doesn't need to disrupt the user experience that much. That was the point behind my qualifier. – Thorn G Feb 03 '11 at 00:42
  • @Jonas I think the point is that dialogs are a bad thing (irrespective of whether they are implemented with `JDialog` or not). – Tom Hawtin - tackline Mar 29 '11 at 14:13
  • I suggest that `Action` and `SwingWorker` encourage bad design, coupling things which should be coupled. Try to avoid unnecessarily coupling your code to inappropriate library code. – Tom Hawtin - tackline Mar 29 '11 at 14:15
  • @Tom Hawtin: What should we use for actions instead of `Action`? And what should we use for threading when communicating with the GUI instead of `SwingWorker`? Are there any alternatives to these libraries when using Swing? – Jonas Mar 29 '11 at 14:31
  • 1
    The coupling is a bit on the smelly side, but it's better IMO than writing your own threading code. I'd rather deal with the inelegant code than subtle thread bugs. – Thorn G Mar 29 '11 at 14:36
  • @Tom Hawtin: What should we use instead of Dialogs? I think they are good. Do you mean that we should use `CardLayout` and showing the information on the full application space instead? that sounds horrible for me. I googled and found that Modal Dialogs also are a good design for modern web-pages these days: [Modal Windows In Modern Web Design](http://www.smashingmagazine.com/2009/05/27/modal-windows-in-modern-web-design/). – Jonas Mar 29 '11 at 14:58
  • 3
    You may want to look at MigLayout - http://www.miglayout.com/ –  Feb 06 '12 at 08:25
4

I'd say one of the first things is not to work on it directly. The layout system in Swing (IMHO) is terrible, and trying to make any substantial app out of it is a nightmare.

Two of the many alternative layout managers that I've used are MigLayout and MultiSplitPane layout. MigLayout is more general purpose and makes any layout you can think of in an easy, sane way. MultiSplitPane is more specific; I used it to make some simple layouts for GUI's that didn't have much complexity.

EDIT: This does not replace swing. If you have to use Swing you can still use these Layout managers since they only manage swing, not replace it.


Of course the better alternative is to just not use Swing. Swing is heavily criticized for being horrible to work with, doesn't look native, and slow. Many alternatives exist that have learned from swing what not to do like Qt, SWT, and I think even GTK. These are great long term solutions to the headaches of Swing

EDIT: As @Lord Torgamus said, these aren't really available if your forced to use Swing. If you are going to use these its best to settle this when you create your project, not 3/4's the way through or when picking up legacy apps.

I would also like to note that most of the alternative GUI's use native libraries so to look like the operating system, then fall back to Swing or some other Pure Java GUI.

TheLQ
  • 13,478
  • 7
  • 55
  • 87
  • 5
    I appreciate your opinion, but "don't use Swing" isn't helpful for people who end up at this question because they're being forced to use Swing for one reason or another. – Pops Jan 25 '11 at 15:24
  • @Lord That's why I suggested alternative layout managers before suggesting QT and SWT. Use whichever path you can. – TheLQ Jan 25 '11 at 15:29
  • "The layout system in Swing (IMHO) is terrible, and trying to make any substantial app out of it is a nightmare." The Layout managers tend to come from AWT, not Swing. Granted, there are a few Swing specific ones, such as BoxLayout and GroupLayout. Having said that, layout managers are completely optional... you can instead specify the coordinates for each component just like you do in .NET WinForms (except .NET has a nice GUI to do it for you). – Powerlord Jan 25 '11 at 16:16
  • Maybe you're attacking the problems in the wrong way. I've had great success with the GridBagLayout for complex layouts. Also, breaking it down into various panes, you can then use different layouts in each pane as necessary. Sometimes Swing isn't as straightforward as I like, but it lets you do massively complex things when necessary. – Brian Knoblauch Jan 25 '11 at 16:34
  • @R. Bemrose I would rather do anything than manually draw each component on the screen. And now adays, most people associate AWT with Swing. @Brian GridBagLayout is a beast to work with. While its the most flexible it requires a ton of code to configure it. Things like MigLayout specify everything in only a few lines – TheLQ Jan 26 '11 at 12:31
  • 3
    Have a look at MigLayout - http://www.miglayout.com/ –  Feb 06 '12 at 08:28
  • Just put `javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());` in a try-catch statement in the begin of your main method and Swing will look perfectly native. – jobukkit Jun 14 '13 at 18:24
  • @com.BOY I had to turn that off since on linux the open file window looks absolutely stupid: http://www.ffnn.nl/media/.gallery/image396.png – TheLQ Jun 14 '13 at 18:56
  • 1
    @TheLQ Ok I agree about Swing's file manager, that one is really stupid (On Mac OS X too). Anyway, I just use AWT's file manager to fix that. Works good even if the rest of the application is made using Swing. – jobukkit Jun 14 '13 at 19:25