when write once run anywhere doesn’t

April 7, 2014

Java has famously tried to sell the world of software development on the idea of Write Once Run Anywhere (WORA). Unfortunately that doesn’t work in practice, especially when you’re writing GUI applications using the stock Java release. I was reminded of this yet again when I tried for something very basic; code that would run on all platforms and return an icon resource, in this case a close button that would work across all platforms and look like it fit in with the rest of the environment.

I went looking for a close icon I could use on a button that matched the given look-and-feel. I used the following call to UIManager:

UIManager.getIcon("InternalFrame.closeIcon")

It worked beautifully on Windows 8.1, and Windows 7. I was happy until I tried to run it on three different Linux distributions, and two versions of one of the three. Instead of getting a reasonable displayable icon, I got nothing. Not a null, not an exception, nothing. Specifically, I got a transparent icon that didn’t show up on the Java UI, but never the less took up the required space. When this first happened I thought my code was at fault, until I wrote a very short routine to dump all the internal look-and-feel references and what they returned, as strings. For Windows, I got the following:

InternalFrame.closeIcon = com.sun.java.swing.plaf.windows.WindowsIconFactory$FrameButtonIcon@4f626d85

For Linux (specifically CentOS (RHEL) 6.5) I got the following:

InternalFrame.closeIcon = javax.swing.plaf.basic.BasicIconFactory$EmptyFrameIcon@492ee972

Yes, I got an EmptyFrameIcon. I went looking to see if I could find anything under all the locations that Linux likes to store icons, but found nothing I could consistently use. In the end I went back to drawing on the button face (which I’ll give an example of shortly), since all I wanted was essentially the ‘X’ that appears all over.

At this point in time (2014) it’s far too late to raise holy hell with Linux, which is where the blame essentially belongs. Instead, it goes to cement once more how painful it is to do Java UI development under Linux, unless you devote a large amount of time or use a third-party look-and-feel library like JGoodies. For the time being I’ll role my own as what I need is rather minor. But for major Java UI applications in the future I’ll more than likely wind up using JGoodies in my applications. And before you ask, there are still a lot of applications that (1) need something more substantial than JavaScript and the web, and (2) today’s Java (7 and 8) is as performant as anything else you care to develop in. Maybe more so. Take your biases and move along…