Skip navigation
ANNOUNCEMENT: community.oracle.com is currently Read only due to planned upgrade until 29-Sep-2020 9:30 AM Pacific Time. Any changes made during Read only mode will be lost and will need to be re-entered when the application is back read/write.

So, I've done the nice Java thing and deployed my applications as executable jars, with properly formatted manifests, and, um...

http://homepage.mac.com/invalidname/oreilly-blog/application-distrib/mac-jar.png http://homepage.mac.com/invalidname/oreilly-blog/application-distrib/win-jar.png

well, I'm feeling a little underwhelmed.

Let's face it, those don't look like applications. Nothing about them stands out in a folder and says hey, double-click me!

Oh sure, I could use an application to create an "installer" for my application. That would wrap my jar with an .exe on Windows, put it in a .app bundle for Mac OS X, etc. But I'm not entirely comfortable with reducing "write once, run anywhere" to "write once, run wherever the installer bothers to support".

Is a Java application just a class with a static void main (String[])? I think that fails to capture many of the behaviors we typically expect from desktop applications, such as:

  • A custom icon.
  • Document association (the ability to launch and open docs when they are double-clicked, based on metadata about the file like its filename extension, Mac TYPE/CREA, BeOS MIME type, etc.)
  • The ability to ask for the user's attention while in the background (flashing the button on Windows task bar, bouncing the Mac OS X icon, etc.)
  • Provide a real name to the rest of the OS (ever run five java apps on Windows, noticed one has hung, then gone to the Task Manager and had to guess which of the five "Java"s needed to be killed?)


 

While I'm at it, I'm going to be greedy. After all, I played with Project Builder on Mac OS X to bundle up a java app in a Mac wrapper recently, and I'm jealous of some of the things that developers over there can take for granted in native applications, including:

  • A standard for placing localization files. Sure, we have ResourceBundles in java, and a scheme for locating them based on the current Locale, but where do they go? Do you have one per class, one per package, or one per application?
  • Same thing for artwork. Yeah, both L10N files and artwork can go in the jar file and be found along the classpath with a ResourceLoader, but if that's such a great idea, why don't we standardize on some paths in the jar, instead of making new developers repeatedly re-invent the wheel? This would be great for tools too.
  • Java command-line args. Ever tried to set something like the max stack size (the old -mx command-line arg for "java") with a double-clickable jar file? Last time I checked, no amount of Manifest voodoo could do this. But Project Builder will do it for pure-java bundles on OS X.


 

To top it all off, I don't want to get any of this by going outside of standard Java... maybe I could get some of my application behavior with a mixture of a platform-specific installer and some JNI code to get outside the Java "box", but then I'm radically limiting the number of platforms, present and future, that my app can run on.

Obviously, this is a big wish-list. And I don't have all the answers. But I think I see where part of the problem is.

I've been openly envying Mac OS X application development above, so let's look at the layers involved with a Cocoa app:

  • Language - in which we write the behavior specific to our application - Objective-C (or, if you're gutsy, Java)
  • API's - which provide common functionality to applications - CoreFoundation, Quartz, QuickTime, etc.
  • OS - which executes the code and provides the display, sound, networking, I/O, etc - Mac OS X
Now compare that with how a Java application's layers: 
  • Language - Java
  • API's - Java core libraries
  • OS - Java Virtual Machine


 

From what I can see, we have a very nice language, a vast set of API's, and a runtime environment that's not holding up its end of the deal. When people complain to me about the inability of Swing to deliver professional applications, I tell them that I don't think that it's Swing that's lacking. Surely anyone developing AWT or SWT applications has the same problems developing apps that act like real apps.

What do I want from the JVM? I think two things need to happen:

  • There needs to be an Application class or interface that gives us some kind of abstraction of behaviors like requestUserAttention() to bounce an icon or flash the task bar. The JVM then provides a platform-appropriate implementation, if any.
  • There needs to be a standard for where we put localization files, artwork, etc. inside the jar. Maybe also files defining file-associations by filename extensions, MIME types, or other predictable and somewhat standard systems. And a file for java runtime arguments.
But now here's the kicker - when the JVM sees it's running a jar whose main class is such an Application, it does a one-time-only repackaging of the jar, with the user's permission, into something that makes sense on that platform. On Windows, it creates a folder with needed files in the right places and an .exe to invoke java, dinging the registry to set up file associations. On Mac OS X, it creates a .app bundle. If the platform isn't supported in this manner, then running from the jar still works; you can still pick up the localization files and artwork from the classpath, and any Application calls like requestUserAttention() just harmlessly no-op. That way, nothing breaks, but current and future operating systems get java applications that behave more like native applications.

 

I know, this is probably idle dreaming. But something along these lines would make it easier for developers to make "first-class" applications in Java.

Years ago, I worked at CNN Headline News as a Writer / Associate Producer, which pretty much meant I was an editor, except they paid me the Writer/AP salary (the editors, in turn, were really producers, etc., up and down the corporate ladder).

At the time, the de facto standard for newsroom computer systems was "Basys", which wired dumb terminals to a mainframe, and let users view directories, edit files in those directories, print, and roll text up a teleprompter.

The commands in Basys were cryptic, and learning the keyboard took a long time. At CNN, the numeric keypad was repurposed into a collection of cursor-movement and text selection keys. Even if you'd been touch-typing since age 10, it took a while to get the hang of it.

Then one day, they installed new Windows desktops in the newsroom, with a new GUI Basys client (I think it was from Avid, who bought Basys). Now the directories could be browsed in a familiar "tree" format, text could be managed with familiar mouse gestures, and it was in eye-pleasing colors instead of 10-year-old, burned-in dumb-terminal gray.

And we all hated it.

Despised it.

Threatened to quit if they didn't get rid of it.

To the software engineers, this must have been outrageous. I can imagine them saying Don't you see how much better this is? You can see the heirarchy of the directories! You can copy-and-paste from other applications! You can have many windows open for your source stories instead of wrangling a simple emacs-style split! You can ditch the keypad!

What they didn't understand was that the crummy terminals were crude, but once mastered, they were very, very, fast. Remember how fast Data on Star Trek could operate the flat-panel controls of the Enterprise? We were faster than that. Select-word, bangbangbang, del, typetypetype, readreadread, scrolldown, readreadread, scrollup, arewecool, yeah, save, print!

Having to manage windows and mouse around might be easier for the novice, but it absolutely strangled the expert. A top speed with the GUI was nowhere near the top speed with the dumb-terminals.

And this is is the important part: editing speed turns out to be the absolute number one priority for a newsroom system. If a GUI costs me five seconds, it might mean that I can't get a breaking story to an anchor in time to read it.

So while the GUI was fine in and of itself, it totally failed to meet the users' primary needs, and was quickly abandoned.

This is one thing I was thinking about when I read Philip Brittan's weblog on usability in Java apps. Not that I disagree with him at all; I just want to reinforce the point that good-and-bad in a GUI doesn't necessarily derive from the merits or deficiencies of the GUI API.

That newsroom GUI could have been written in Swing, MFC, or Aqua and we still would have hated it, because the underlying concept was completely wrong.

Philip makes this point when he quotes the CIO who implies that open-source apps seem to do no usability work, and I think implies that many Java GUI's are developed the same way.

But the comparison to Windows applications is a trap. Don't assume that mimicking existing apps on Windows or any other platform is a valid approach in and of itself. Here's why: I remember a few years ago, I was at a company where a product manager - and apparently this was his entire output for a month of work - did a little five-page document saying how great Microsoft Outlook's GUI was, and how that should be a model for our application.

Problem is, our application wasn't an e-mail client, it was a networked media browser/distributor. Sure, in the broad view there are some concepts that carry over, like seeing items (e-mails or media clips) in some sort of broad view and then getting a detailed view through a double-click or a paned approach. But that's after thinking in the abstract. I think he really wanted it to look and behave as much like Outlook as possible. Even though that didn't really make sense.

It reminded me of the novel The Fountainhead, in which the hero, Howard Roark, is an individualist architect who understands that form follows function, that there's a right way to build things in order to be what they're supposed to be. However, many around him insist on ruining his designs by making unrelated, even dangerous additions, trying to bring in other ideas because those ideas have worked before (and as a means of tearing down Roark's individuality). To them, you put greek columns on a log cabin, simply because many great buildings have greek columns.

You probably see where I'm going. A good GUI has given features if, and only if, that's the right thing for that application. You don't use MDI just because Office does (well, it used to), you use it if you think that's the right way to handle having multiple documents open. You don't do modal dialogs because they're easy, you do them because you absolutely cannot allow anything in the app to continue without getting a response from the user.

In one recent monitoring app, I ditched the simple JTable approach of our prototype in favor of a list with multi-line cell renderers, even though it wasn't easy to code. I got the idea from the download managers of the OmniWeb and Safari browsers, which showed me why the table approach of IE's download manager sucks so much. Like them, I didn't need table columns to vertically line-up the things I was displaying, and using custom list cells, anchored with a colored icon on the left that showed the item's "priority", allowed me to use fonts and size to make the most important fields more readable at a glance, instead of getting buried like they did in the table. Plus, the layout could ensure that the media names didn't get cut off like they did in the table. Did I do this because I like OmniWeb and Safari better than IE? No, I did it because the multi-line list approach made more sense for what I was doing than the table approach did.

Knowing the right way to do a GUI comes from knowing what the app is supposed to do and how it will be used. Without that knowledge, the GUI is doomed.

Maybe you can know it up-front, maybe you'll find out through prototyping and feedback (something that Extreme Programming does well), but you have to own the problem domain if your GUI is going to make any sense at all... or be defensible when someone tells you it has to look like Outlook, or use tabs, or have a slide-out "drawer" like all the cool Mac OS X apps do now.

So Swing isn't the answer, and neither is SWT. Or MFC. Or Aqua.

Learning what your app is supposed to do is the answer.

Filter Blog

By date: