Taking SWT/Cocoa and MigLayout for a spin
It's been a while since I last had a look at SWT (the so-called "standard widget tookit"). One very good reason is probably the fact that I have switched to Mac OS X, and the Mac SWT port used to suck badly. To convince yourself, download Eclipse and play with it. I'm sure you'll feel that it does not really look like a true Mac OS X application, and you will easily spot UI glitches there and there (tip: edit a field in a table, just for fun). This is even more critical when Swing applications like IntelliJ IDEA or Netbeans look so great while relying on a non-native toolkit...
SWT is still a very capable GUI toolkit. Although the API feels a lot more low-level than Swing, you can get some satisfying rsults by using it. It is not a Filthy Rich Clients compatible toolkit (forget the slick interfaces that you can make on top of Swing), but some stuff can become way easier in the world of SWT than in the world of Swing (e.g., embedding a web browser or getting a truly native file dialog). Another good reason for keeping SWT under the radar is that it is actively developed while one can reasonably fear that Swing is... more in a kind of maintenance mode to say the least.
The SWT team recently took the Mac OS X matters seriously and decided to port it over Cocoa, the framework upon which true Mac OS X applications should be built. Indeed, the existing port used to be made over Carbon, the now deprecated Mac APIs that endanger the future of Eclipse on Mac OS X. Although this is still work in progress, SWT/Cocoa is just great (and Eclipse is probably going to look ok on a Mac, although I am not going to switch back to it any time soon).
I took it for a spin to build a very stupid application:
If you press the button, a message box shows up to repeat the informations. It also features a label with an hyperlink that pops up a web browser.
Good layouts are both critical (otherwise your application looks like a toy) and hard to realize. I used the fantastic MigLayout libary. There is a version for both Swing and SWT. It is somehow reminiscent of the JGoodies layouts, and the extra bonus is that the library weights really nothing.
My main class is fairly standard for a SWT application:
public class Main { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display, SWT.SHELL_TRIM); shell.setText("Swt/Cocoa"); new MyController(shell); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } }
My "controller" (which should have not be named like that since it is not a true controller...) is relatively simple too:
public class MyController { private final Shell shell; public MyController(Shell shell) { this.shell = shell; initialize(); } private void initialize() { final MigLayout layout = new MigLayout("fillx", "[right] rel [grow, fill]"); shell.setLayout(layout); final Label nameLabel = new Label(shell, SWT.NONE); nameLabel.setText("Name:"); final Text nameText = new Text(shell, SWT.SINGLE | SWT.BORDER); nameText.setText("Somebody"); nameText.setLayoutData("wrap, width 300px"); final Label emailLabel = new Label(shell, SWT.NONE); emailLabel.setText("Email:"); final Text emailText = new Text(shell, SWT.SINGLE | SWT.BORDER); emailText.setText("foo@bar.com"); emailText.setLayoutData("wrap"); final Button displayButton = new Button(shell, SWT.PUSH); displayButton.setText("Display"); displayButton.setLayoutData("span 2, tag ok, gapy unrelated, wrap"); final Link urlLink = new Link(shell, SWT.NONE); urlLink.setText("<a>More informations...</a>"); urlLink.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent selectionEvent) { Program.launch("http://jpz-log.info/"); } }); urlLink.setLayoutData("span 2, align left, gapy unrelated, wrap"); shell.setDefaultButton(displayButton); displayButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent selectionEvent) { String normalForm = new StringBuilder() .append(nameText.getText()) .append(" <") .append(emailText.getText()) .append(">") .toString(); MessageBox box = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK); box.setMessage(normalForm); box.open(); } }); } }
Simple isn't it?
Of course it could have been made even more compact by using Groovy, Scala or JRuby...
One last thing: SWT applications need a special -XstartOnFirstThread JVM flag on Mac OS X.
Related posts:
- Building a GEF-based Eclipse editor – part 1
- Azureus on Swing is distributed using IzPack
- Initialization blocks in Java
- Playing with Berkeley DB Java Edition and Guice
- Guice it up (or AOP can be made simple sometimes)


