Let's fix Swing first

This was supposed to be a post about JDIC on Mac OS. Somehow I never got past introductory remarks about what else needs fixing to make Java applications at home on the desktop before we start to worry about JDIC.

Get the LAFs pixel-perfect

It's usually pretty easy to recognize a Java application. Ever since the move to Swing from AWT, the majority of components have looked slightly wrong. Even Apple's LAF, though very strong in some areas (the buttons, checkboxes, scroll bars, split panes, and tabs all look very convincing) is weak in others (lists, menus, popped-up combo boxes, and tables are all wrong in both look and feel). Windows has similar problems, and GTK+ has worse problems (perhaps the worst of all, from my limited exposure to it).

I'm not interested in the AWT/Swing/SWT argument; I do have opinions on the right way to have done things, but that's not relevant to the situation we're in. From here, the most important thing is to fix the LAFs. That would be an easy thing for outsiders to contribute to if Sun and Apple would only let us. There are plenty of us who've come up with little improvements (poking UIManager, writing our own subclasses or renderers) who'd love to contribute them and see all applications improve.

At the moment, neither Sun nor Apple offer us the chance, and we suffer for years watching these things stay the same.

Note that this isn't an argument that Java should be open source. I have no particular opinion on that: all I care about is that Java continues to exist, and continues to improve. What I'd like is a quick-turnaround way for people to submit patches and stay up-to-date in this one particular area, because it seems that's where Sun and Apple most need help. (I don't understand why Apple isn't wall to wall with the kind of person who gets upset when a pixel's out of place, and would stay all evening to fix it, but maybe they're just too busy with other stuff.)

Some access to platform-specific component variants

Although I said I'd avoid the AWT/Swing/SWT argument, we have a problem fundamental to the philosophy underlying AWT and Swing: there's no support for platform-specific components, even when they're very similar to ones common to all platforms. As a Mac user, I'd like to have a JTextField that's more like NSSearchField, for example. (I've written the extra functionality; it's the appearance that's hard for me to duplicate without the JNI that Apple use to get their rendering right.)

Swing is unlikely to ever offer me such a choice. I'm not sure what the pragmatic answer is here, but it might be (to continue with the example of NSSearchField) for the LAF to support some property on JTextField that makes it look like an NSSearchField. But if Apple don't have the time to fix the mandatory parts of the LAF, as appears to be the case, I won't be holding my breath for such optional niceties. (I've had an Apple bug open requesting a way to ask for a sheet for years now.)

Spelling checking

Any decent application has spelling checking. On the Mac, all applications that use Cocoa text fields (or the AWT TextArea) can turn it on with one line of code. Swing applications? Don't ask.

[If you want spelling checking in your JTextComponents on Unix machines, I've written the code for you. Download the salma-hayek library used by SCM and take advantage of spelling checking with only one extra line of code in your application.]

On the one hand, I'd push for no more API than a method setSpellingCheckingAsYouType in JTextComponent, thinking that the more latitude we give implementors the better, because that's how we'll get to be most like the native system. But on the other I know that I've done a better job than Apple, for example: I'm editing this now in a Cocoa text component and "JTextComponent" and "setSpellingCheckingAsYouType" are both marked as errors. The Java spelling checking I wrote recognizes them as camel-cased words and checks the constituent words individually.

For the good of Java applications and their users everywhere, though, I'd settle for being no worse than a native application. (And, to be fair, there are notable examples of native applications that can't do this. Mac OS X stands out as being significantly better than anything else in this regard, but even there iCal doesn't think to enable this very useful functionality. Mozilla Thunderbird on Linux is the application that causes me the most grief personally through lack of check-as-you-type. Plus just about anything I've ever used on MS Windows. Either MS Office won't share its spelling checker, or no-one else knows how to use it.)

Basic functionality should be free

There's a more general point here about functionality an end-user should be able to take for granted, too. Why can't a Swing programmer say "the user should be able to search this JTextComponent/JTable"? A GTK+ programmer can. A Cocoa programmer can (although they had to wait until 10.3, amazingly). [Again, if you want this in your software, check out my salma-hayek library, which offers you one-line addition of find to any JTextComponent. Not as convenient as it just being there, but better than nothing.]

Why can't I give a JTextField (or Document) to a JList or JTable and have the latter automatically filtered based on what's been typed? Just like in the iTunes interface. [Again, if you want this in your software, check out my salma-hayek library. But if it's not in the JDK, it won't be in 9 out of 10 applications.]

Why can't a Swing programmer say "the user should be able to sort on this column"? Hell, why don't we have default column Comparators the same way we have default renderers? MS Windows 95's tables had this: just add function pointer for instant sorting. That's a decade-old version of a C library on a platform known for cruftiness we're talking about, and we're not competing. That's embarrassing.

There are so many little things that a user can reasonably expect of a quality application that Java isn't making easy enough. Yes, for any default implementation/UI supplied, someone will be able to think of something better, but you can always override the default. The point is, you should be able to get something for nothing.

Common usage should be easy: forms

Simple dialogs need to be a lot easier to write. By "simple" I mean more complicated than JOptionPane; something more like a preferences dialog. Again, if you want this in your software, check out my salma-hayek library. It's not hard to automatically do a pretty good job, and it's trivial to do a better job than most of the chimps let loose with JBuilder or other devices for churning out terrible code.

There's no reason for it to take much more code to fully implement a form in an application than it would to simply add the required fields to a Collection. People have been writing such systems for years, and it's about time a major toolkit offered it.

Even if, overnight, the visual GUI builders stopped churning out the worst code known to man, there are other reasons to favor something like this. [Note that since I wrote that, I've added proper support for status information in dialogs, and both the source and the resulting dialog look better for it.]

(As an aside, we need to do something about the poor quality of example code. The tutorial, the almanac, and the demos are all poor examples of best practices. They're fine as quickly knocked-together demos of the available functionality, but we have to realize that this code turns in to shipping applications. We can't go round encouraging people to write code that looks like it came out of JBuilder without facing the fact that it's going to make Java look bad.)

We need a new JTextComponent for multi-line editing

Swing offers two basic choices if you want a multi-line text component. There's JTextArea and there's JTextPane. The former has important deficiencies in terms of features, and the latter has terrible performance (both space and time).

Yes, you can write your own editor kit, but that's a huge effort, and pretty difficult too.

(If nothing else, the API should be made more regular between these two classes. JTextArea has a load of useful line-based functionality missing from JTextPane; if you subclass JTextPane you can just paste in the methods from JTextArea and they all work fine. I think there's a missing JMultiLineTextComponent somewhere. Or maybe the mistake's in Document, and the functionality should never have been in JTextArea. I haven't thought about it.)

Cocoa manages to have a text component, NSTextView, that takes a good stab at being all things to all men. So should Java. I want to be able to have colors in text without rendering and editing being sluggish and my application taking four times as long to read in a text file, and only being able to cope with much smaller documents. I want to be able to implement coloring that has good enough performance that I'm not so embarrassed I feel the need to take it back out. (There's no reason for JTextArea to insist on a single color, even if it does insist on a single font. The latter is often a perfectly acceptable restriction; the former much less so.)

High-performance coloring and easy-to-use hyperlinks are must-have features for serious text components in 2004. So is check-as-you-type spelling checking.

I can see that anyone who's used Xcode might argue that NSTextView isn't perfect either; there was some sluggishness there, and it's plausible that at least some of that was something to do with NSTextView. But I challenge to you do anything like as well using Swing, and I bet if you do, you'll have had to write significant chunks of code, including your own views.

This is too important to be left to individuals

It's easy to say "if you think these things are so important, do them". I have, at some time or another, done all of the things I mention here. With varying degrees of success, and varying degrees of availability to the general public (or, indeed, to me).

For Java to hold its ground, and for Java to gain new ground, we need these things to be available for everybody writing Java. Maybe the answer is something like CPAN or RubyGems, so a program can declare its dependency on some library, and the VM will go and download it. But I don't think so. I think this stuff needs to be addressed in the JDK.

And whatever else we do, let's not have another AWT to Swing transition. Let's fix one or other of the systems we have.