Sun produces another poorly designed API for Mustang: SystemTray

I am frustrated about the new AWT SystemTray API that was released as part of Mustang build 38. It has many problems, and even though I discussed these problems with the AWT team before it was released, they have not resolved many of the problems.

I won’t go into all of the problems right now, but I’ll mention a few. First you should look at the SystemTray class and the TrayIcon class.

  • Several methods return arrays of TrayIcons and other objects. This is Java 6, a whole release after Java 5, and Sun is still using arrays. Why did we even bother adding generics to Java, if the JDK itself isn’t going to use them?
  • This API was designed to provide the lowest common denominator that all platforms support, despite the fact that such API’s have been the subject of a great deal of criticism of Java. I don’t know why Sun is intentionally crippling Java applications. Maybe they are trying to kill Java on the desktop for good. Here are some of the problems:
    • On Mac OS X, “status items” (the equivalent to system tray icons) have a fixed height, but they can have any width. However, there’s no support for this in the SystemTray API, as all icons must have the same size.
    • The displayMessage functionality is not guaranteed to be supported. This is good because OS X status items don’t normally show messages like Windows applications do from tray icons.
      However, there’s no way for your application to know whether displaying a message is supported on the current platform. I expect a lot of if (System.getProperty("os.name").contains("Mac")) {..} in conjunction with the System Tray API, or, more probably, most developers will not think of this at all, and their program won’t display messages on OS X, and Mac users will miss important information.
    • Similarly, there’s no way to determine whether popup menus or “default actions” are supported. The API guarantees that at least one is supported (I believe this is for OSX compatibility, because double-clicking an OSX status item does nothing). This means there’s no way for a Java program to even know what it’s doing (that is, whether the user can double-click the icon, or click to show a menu), and what the user is seeing.
      Imagine if an application needs to explain to the user how to open the application from the tray icon. It will have to say something like “Try double-clicking the icon. If that doesn’t work, try right-clicking it. If that doesn’t work, try to click it once. When you do these things, if you see a menu, choose the Open item. Otherwise it will open automatically.”
      I can’t imagine why Sun doesn’t want Java programs to be able to be aware of what their program actually does. Again, I expect a lot of hacky system property checks to determine these things.
    • displayMessage takes a TrayIcon.MessageType to determine what type of message it is: ERROR, INFO, NONE, or WARNING. MessageType is an enum. Using an enum prevents extension of the API in many ways because an implementation could not return an instance of a MessageType subclass, because you can’t subclass enum types. If Apple or BeOS wanted to add their own system-specific message type, they could not do so. Even if they added their own enumeration values to MessageType, there would be no way for Java code to access them without using reflection.
      Longhorn is coming out in a year or two and it may be that it has new types of tray icon messages, like, for example, a NETWORK_ERROR message type. A future OS X version could add status item alert messages, with more than just the four types specified in MessageType. With this API it will be impossible to use these from Java code, because this API uses an enumeration instead of a non-final class.

I may post about the rest of this API’s problems later.

If you agree that this API should be improved, you should post a comment here. If enough people post, it might convince Sun that there’s a problem, like it did with the applet browser lockup problem I posted about earlier this month.

10 Responses to “Sun produces another poorly designed API for Mustang: SystemTray”

  1. Charlie Hayes Says:

    I think differently about the SystemTray class. I believe that most applications that are going to create TrayIcons should be modifying the dock icon and menu in OSX and not be adding anything to the menu bar. As for displaying popup balloons and such, I think the best way on OSX would be to make the dock icon bounce, display the icon for the type of dialogue as a badge on the dock icon then, when the user clicks the bouncing icon, display message box that has the icon and text of the message while removing the badge from the dock icon.

    Additionally, the dock menu could be used to display the JMenu.

    I agree, there should totally be a way to find out if certain API is supported on the current platform without resorting to manually checking OSs

  2. jrichard Says:

    I’m concerned about this too. I wonder if the Sun group pinged the Apple group during the development?

  3. Laird Nelson Says:

    Just an aside: the use of arrays is almost certainly due to the JavaBeans specification.

  4. Val Says:

    I have the same complaints and I had to search for another solution. I landed on the following one which works like a charm. Check it out !
    http://jeans.studentenweb.org/java/trayicon/trayicon.html

  5. Joseph Ottinger Says:

    Well, you COULD go ahead and start using Apache Harmony - surely that would fix a lot of the problems that exist in build 38 of Java 6.

  6. Anonymous Says:

    Sounds like some valid concerns. In particular, some of them seem like trivial fixes with no downside. Why not implement them?

    As far as the lowest common denominator thing goes… that’s a tougher issue. Whether it’s System.getProperty(”os.name”) or a method call, you still introduce complexity into your code if you want to take advantage of features when they are present and fallback when they aren’t. Supporting the LCD is one way to simplify WORA. However, in most cases, including this one, I’d prefer exposure of the low-level detail, with a convenience layer on top that only supports the LCD features. If you want to go hogwild with MacOS support, you can dig deep; otherwise, the convenience API is for you.

  7. Ian Says:

    I’ve used systray4j before and it wasn’t too bad. Had thought about porting that to Mac OS X menulets… interesting to see its going in mustang. hope sun makes it as good as possible.

  8. Charlie Hayes Says:

    Again, SystemTray like icons do NOT belong in the MacOS X menu bar. iTunes uses the dock for Mac and the System tray for Windows. I dont want my menu bar full of silly icons like the Windows system tray.

  9. John Says:

    Really, they dont belong in the Mac menu bar?
    Tell that to iChat. ;-)

  10. Charlie Hayes Says:

    I never said Apple did everything right. But you can always apple-drag that iChat icon off, and iChat still works fine. Most ’system tray applications’ will not work at all if you remove the system tray icon. On MacOSX, menuletts are basically accessors to other running programs, system settings, or the like. They are never entire applications (or at least should not be). If Java does go that (horrable) route, what will happen when a user apple-drags a Java menulette out? Should the app quit? Should it run in the background leaving the only way to kill it the Activity monitor or the command line? Those all sound like really bad options.

    Will Java menulettes be cool? Yes. Will they be usefull and a good UI decision? No.

Leave a Reply