Swing GUI Tutorial

Written by Sean R. Owens (sean at guild dot net). Share and enjoy. http://darksleep.com/player
For other fine writings on Java and other subjects, check out notablog at http://darksleep.com/notablog

Overview

This overview is very general, and the points below are probably in the wrong order I'll reorder them soon. Also, I've just started writing this, hopefully it'll still be of some use, but I've got a long way to go. (In particular, after filling out the parts of the overview, I want to also give a bunch of examples.)

Writing GUIs is not elegant

Most programmers (well, at least I feel this way and I'm guessing most other programmers feel this way too) always want to have a nice 'elegant' logically organized solution for their problems, i.e. everything logically ordered and arranged. Sadly, GUI's (and most things where humans come into the mix) are not like this. GUIs tend to have lots of edge cases, i.e. there is no "elegant" solution. It's the nature of human interfaces. If you don't accept this you're going to either end up beating your head against a brick wall, or design a GUI that only a programmer (and not even most programmers) could love. Get used to it.

The 90/10 rule

The first 90% of the work takes 90% of the time, the remaining 10% of the work takes the other 90% of the time. When you set out to write a GUI you have a model in your head of how you want the GUI to work. As you write it however, you find that your API get's you 90% of the way there pretty quickly but that last 10% doesn't really fit with how the API works, and it ends up taking the "other" 90% of the time to finish.

Unless you are starting with "draw a pixel", any API or toolkit or tool will help you get things done quickly as long as you are doing things 'their way', i.e. in ways the API designers have planned for. When you want to add something that doesn't 'fit' into their way of doing things, then your problems start. You end up fighting with the API, or doing things at very low levels, or doing too much work to design your "new" stuff to work within/the same as, the API.

The best solution is to go ahead and design your GUI, and when you discover, as you implement it, that some of the features of the GUI are nigh impossible to build within your API, just learn to be satisfied with the remaining 90% of the features done your way, and either cut the remaining feature or implement them in a way that works with the API, even it if is less than ideal.

Netbeans and other GUI design tools?

Coming soon. (Hopefully.)

GUIs are Event Based, but in Swing only sorta

(in progress)

event based vs 'normal' programs - and also worker threads and how it's not REALLY quite event based

Model/View/Controller and Swing

(in progress)

Swing kinda seems to have the model built in but really it doesn't - you can kinda skate by with using the data 'in' the swing widgets (text field, buttons, what have you) as your model but really in the end it just makes things more complicated and you're better off having a totally separate model.

The general nature of drawing in Swing (and most GUIs)

(in progress)

I.e. redraw everything every time we repaint/change, rather than 'backing store'. Also the entire notion of changing state and then calling repaint(). Also while we're at it, maybe talk about Graphics and Graphics2D and the notion of overriding paint()? This is necessary in some situations but not in others. For instance, say you're using a JButton. You specify an icon for the button, maybe change the icon when the button is pressed. All part of JButton, just use it and it works. But if you want to make a new KIND of button, say perhaps you want to do an animation of the icon when you hover the mouse over it, and switch to a different animation while the mouse key is being pressed, now you have to subclass JButton and override paint(). You also now have to use drawing stuff from Graphics/Graphics2D.

Swing and AWT and the confusion created by having both of them.

(in progress)

historically how and why it happened, and the difference between them, etc. (Generally think of AWT as the lower level "draw stuff here" vs Swing as the higher level "draw a widget/button/text field here".)

Use lots of JPanels!

One problem I had early on was, I tried to fit everything into one JPanel (and hence into one layout since a JPanel can only have one layout). Later I realized JPanels are a lot lighter weight than I'd thought and things were much much easier if I just used lots of JPanels inside other JPanels and (possibly) different layouts in each JPanel as appropriate.

Learn paint()/repaint()/paintComponent()!

(in progress)

learn/know how paint()/repaint()/paintComponent() calls work, when they're called, in what order, which ones you SHOULD be overriding and when you should be overriding them.

The Swing thread and how to avoid getting in trouble

(in progress)

Lack of understand this and the crappy programs that have resulted are the main reason the public in general thinks Java sucks and is slow.

swing repaint thread - invokeLater/invokeAndWait and worker threads, locking is usually bad; in general don't touch ANY Swing objects directly once you've made them visible, always use invokeLater/invokeAndWait to modify them and/or read from them.


Last modified: Thu Feb 3 21:21:10 EST 2011