The Java Look-and-Feel Debate

Java Swing comes with “pluggable look-and-feel technology”, which essentially boils down to the fact that interfaces can be “skinned” (although this is simplifying a tad) and is therefore, extremely flexible. By default, Java ships with a cross-platform look-and-feel (LAF), which means your apps can look consistent across all platforms, or LAFs that mimic the look of a specific platform, say Windows, for example. However, one of the chief complaints of Java desktop applications is its “look”. It basically stems from two issues:

  1. The default cross-platform LAF is “ugly”.
  2. The platform specific LAFs lack fidelity, i.e., they’re not convincingly native.

To be honest, they have a point! That’s not to say that there aren’t many devs (and users) out there who are happy with the LAFs Java ships, but there is work to be done. However, this isn’t the end of the story. Java GUIs can be made to look great. Also, is the issue of platform fidelity really as big an issue as many developers think?

Native look and feels

There are many Java developers who program with only the Windows platform in mind. They often feel disappointed that the Windows LAF bundled with Java doesn’t do an adequate job of looking like a Windows application. However, does this really matter? Let’s look at Microsoft software for example. Take Microsoft Office, Microsoft Media Player and Microsoft Messenger. Three extremely popular pieces of software for Windows, written by Microsoft. Yet, the irony here is that MS themselves have taken great effort to deviate away from the normal Windows look (and from a intra-MS perspective, their own products also deviate from each other, where Office looks different to Media Player, which looks different to Messenger, and so on). And they aren’t the only ones.

Screenshot showing MS Office, Media Player and Messenger. All of which deviate from the Windows look and feel.

I queried Romain Guy about this issue. He’s an experienced developer and commentator on UI design, and recently started an internship at Sun working on LAFs, (NB all views expressed here are his own, and not of his employer!):

“These LAFs should have helped delivering a better desktop experience. Unfortunately they completely failed, mainly on Windows. Since Swing does not rely on any native widgets, LAF developers need to recreate them all by themselves. And it is very hard to duplicate the look and behaviour of a widget when you don’t have access to its source code. Windows LAFs have always been awkward: they almost look and feel like Windows, but not exactly. A lot of people protested against that. Funnily, they are mainly Windows developers/users. Linux and Solaris users, for instance, are used to seeing mixed toolkits on the screen. You can launch The GIMP and its GTK UI, Mozilla and its very own look and feel, KMail and its QT UI, etc. on the same desktop and nobody will ever complain about it. The Aqua look and feel for MacOS X is quite good so there aren’t so many complaints (the LAF has its quirks and there is a project, Quaqua, which addresses these issues).

“Now, Windows folks are just manic about this problem. I sure like to see the efforts of the WinLAF guys who address the Windows LAF issues, but I have a lukewarm opinion about this. See, I never liked Java’s Windows LAF precisely because it looks awkward. What’s the big deal? I used other look and feels instead. Now, a lot of people will tell you that it is a bad idea because your application would then not look like a native one. So what? I won’t use the well-debated argument of Winamp and iTunes for Windows, but I will rather use most common examples. Microsoft keeps changing the look of Office, does anyone complain? WinForms.NET widgets don’t look exactly like the widget we’re used to see, does anyone care? Delphi has brought us a lot of odd-looking components (like the ugly green-ticked Ok button) for years and nobody cares. Even Firefox and Thunderbird don’t look totally native. Oh, and what about Photoshop? The list goes on. I’m staring at my Windows taskbar right now and out of 7 launched applications, there are 6 not looking totally (or not at all) native. And Winamp isn’t even started (neither is iTunes).

“Tell me why this should be different for Java?! Worse, it is the developers who are actually complaining about that. Not the users. Don’t misunderstand, I would love having a perfect or close-to-perfect Windows look and feel, but as far as I’m concerned, it’s not that a big deal.”

Some interesting points here. Why is there so much fear from developers that Windows users won’t cope with Java LAFs, when companies like Microsoft itself disprove this? As mentioned, Linux users are less concerned by this issue because they typically use a myriad of applications which may use different UI toolkits. Some may argue that Linux users tend to be more computer savvy, and thus are less worried about differences in aesthetics. It’s the less experienced users who are thrown on seeing alternative looks (regardless if it’s an improvement or not) as unfamiliar and therefore a Bad Thing.

For Windows at least, there is the WinLAF project which provides the most consistent LAF to the Windows platform as a library that can be easily employed by Java applications. Then there’s always SWT, which uses native widgets of a given platform, but that’s a different kettle of fish to Swing and beyond the scope of this article.

Ugly look and feels

I think this is the crux of Java’s reputation on the desktop. I personally do not think that the lack of fidelity is that important. I simply think that people feel Swing is ugly – at least relatively speaking. Romain (candidly) sums up his feelings here:

“… Let’s be clear, Java’s default look and feels suck. Really. I never used the native ones because I always found them worse that the known-to-be-ugly-Metal one. Things have become a little better with the introduction of the Windows XP look and feel. It doesn’t suck, it is just awful :)”

But does this really matter? Don’t forget, good UI is much more than aesthetics, it’s about making the user able to perform a task efficiently. Romain elucidates,

“To be honest I’m very sensitive to GUI aesthetics. I could even prefer an application over another because it looks better, even though it is worse feature-wise. In fact, aesthetics are not that important in a GUI. Ergonomics are. A nice-looking GUI can help you appeal to potential users but it otherwise it doesn’t really matter. Now, it greatly depends on what kind of application you are referring to. Applications used 8 hours a day by people who need to input kilometres of data don’t need to be eye-candy, they need to drive the user efficiently. That means an eye-candy GUI can be as bad as an ugly one. Just imagine using a word processor with any Winamp skin, would you be able to use it all day long? I don’t think so.”

Now, I agree in many respects with Romain here because I too like a good looking application – it simply has greater appeal; it gives a good first impression and makes you feel comfortable. In today’s IT world, I think users’ expectations are higher in this respect, and so expect something easy on the eye. So, will we ever have good looking Java applications? Well, yes, we already do!

The solution here is quite simple, use a different LAF! Because of the pluggable LAF facilities in Swing, it is possible to use third-party LAFs instead. Of course, some are commercial offerings, others are free. Possibly the best known freely available LAFs are those released by Karsten Lentzsch called JGoodies Looks. Let’s look at a sample Swing application using the old Metal and the new Ocean cross-platform LAFs.

Screenshot of a Swing application using Java's old Metal look-and-feel.
Screenshot of a Swing application using Java's Ocean look-and-feel, which should be an improvement over Metal to most viewers.

Ocean is an improvement, that’s for sure. Now, let’s see what happens when we use the Plastic LAF:

Screenshot of a Swing application using Platic look-and-feel, which should be more appealing to most viewers.

Now we have a perfectly pleasing LAF for any platform. JLooks also provides a themes mechanism that allows you to specify different colour schemes. By default, it tried to match the desktop colours. Also, it doesn’t take very much effort to get your Java application to look like this. LAFs can be set in the program code directly with a couple of lines of code. Alternatively, you can actually specify as a command-line option, although it does require you having the appropriate LAF classes that you want to use (if third party).

Fonts

Truthfully, the lack of anti-aliased fonts in Swing mean that it still stands out like a sore thumb. Yet, there is support – it’s just not enabled by default! This is a funny issue because the underlying graphics framework, Java2D, which actually draws the Swing components has supported anti-aliased fonts for years, although work is in progress to enhance this for better sub-pixel support to improve text display on LCDs. As far as I can tell, the reason why it’s not enabled for Swing components by default is mainly for legacy reasons, as Romain pointed out to me:

“Anti-aliased text does not have the same size as non-AA text and that can break layouts and legacy apps.”

There are many, including Karsten and Romain, who believe that because the fonts used in GUIs are typically small, e.g., ~8-10pt, anti-aliasing can actually make text more difficult to read, and therefore only support the idea of anti-aliasing for larger sizes. There is some truth to this, but I think there is a certain amount of subjectivity too, and so I personally think it better to make it simple to enable/disable anti-aliased text as necessary.

Unfortunately, this hasn’t been simple. The old way required you to sub-class each component you wished to be anti-aliased and override the paint() method. This is clearly an inconvenient approach, although, the SmoothMetal project did just this and extended Java’s Metal LAF. There is another approach used by the Wrap LAF project that allows you to achieve global anti-aliased text by adding a wrapper around the bundled LAFs. As of Java 1.5, an undocumented class contained a way of setting each component to enable anti-aliased text. Better, but still required doing for each component you used, i.e., not global. The only global way (without external libraries) is also in Java 1.5 and that is an undocumented Swing property called “swing.aatext”. Set this to equal ‘true’ (and this can be done from the command-line when you launch an app) and all Swing components will be anti-aliased. It’s worth noting that Swing lead Scott Violet has said, “swing.aatext is not a documented or supported property. It’s meant for internal testing and may go away at any point.” Of course, he said in another post, “While it may go away it’ll be
replaced by something better :)”

In the meantime, it’ll do just fine! Here’s our sample app again, with anti-aliased fonts enabled.

Screenshot of a Swing application using Platic look-and-feel and with anti-aliased text.

Synth: the future of LAFs?

Creating your own LAFs requires a lot of knowledge about Swing, and is very programming intensive. Synth is a new look-and-feel that shipped with Java 1.5. It’s still pretty new and documentation is not comprehensive on this yet. Here’s Romain on Synth:

“The Synth look and feel is a generic look and feel, a kind of skins-engine. Its purpose is to let you create a whole look and feel only with an XML files and pictures. It is much simpler than creating a “real” look and feel which is a very complex and tedious task. And it actually allows you to create real look and feels. In Java 1.5, the GTK look and feel is Synth based. Unfortunately, Synth lacks documentation and examples but this issue will eventually be addressed in the future. Also, Synth might unfortunately require some programming work. Due to the nature of the Synth resources, XML files, you’re not free to do everything you want. When something’s missing, you have to crank out some code.”

This approach does look interesting, as it reduces considerably the burden required to get a LAF up-and-running, and is more analogous to skinnable applications like Winamp. There are of course performance issues to think about: a GUI consisting of images could well require additional resources, memory wise, although, with the improved graphics pipeline in the forthcoming Java release, this may not be an issue. A good example of a Synth-based LAF is Synthetica.

Screenshot of the Synthetica look-and-feel demonstrating Synth.

Summary

In conclusion, I think it’s fair to say that the bundled LAFs in Java are getting better, but still not pleasing to the majority. I have no doubt that the Java team is working hard on this. However, whilst there is room for improvement, I think this is a good time for many developers to reflect think about whether they really need true platform fidelity, when there are other perfectly decent third-party LAFs available. They will look different, but, so do many applications!

The “ugly” Java is something of a myth nowadays. Whilst Swing doesn’t exactly shine aesthetically by default, there’s not a lot of effort required to plug in a good looking LAF, and with Synth we can expect more LAFs to appear (and hopefully some will be decent!) There are plenty of Java applications that demonstrate how great Swing can look, Xerto’s Imagery is possibly my favourite example at the moment, although the JIDE products are pretty impressive. Also, Javootoo maintains a list of free and commercial LAFs.

About the author:
Andrew Roberts is a computer science graduate from the University of Leeds, UK. He remained at Leeds to study further towards a PhD in Natural Language Processing. He has been using Linux for almost 8 years, and Java has been his language of choice for advanced language processing and machine learning during the last three years.


If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.

88 Comments

  1. DoctorPepper 2005-05-19 8:02 pm EST
  2. Darius 2005-05-19 8:07 pm EST
  3. Myrd 2005-05-19 8:09 pm EST
  4. Abraham 2005-05-19 8:11 pm EST
  5. Myrd 2005-05-19 8:12 pm EST
  6. Andrewg 2005-05-19 8:13 pm EST
  7. Juan C Nuno 2005-05-19 8:24 pm EST
  8. Dracula's dead star attorney 2005-05-19 8:24 pm EST
  9. CaptainN 2005-05-19 8:30 pm EST
  10. Anonymous 2005-05-19 8:33 pm EST
  11. Anonymous 2005-05-19 8:35 pm EST
  12. CaptainN 2005-05-19 8:36 pm EST
  13. Romain Guy 2005-05-19 8:40 pm EST
  14. Romain Guy 2005-05-19 8:44 pm EST
  15. Davy Mitchell 2005-05-19 8:57 pm EST
  16. SpookyET 2005-05-19 8:59 pm EST
  17. Romain Guy 2005-05-19 9:00 pm EST
  18. Rayiner Hashem 2005-05-19 9:12 pm EST
  19. fedetxf 2005-05-19 9:16 pm EST
  20. ralphy 2005-05-19 9:18 pm EST
  21. fedetxf 2005-05-19 9:23 pm EST
  22. Mike 2005-05-19 9:30 pm EST
  23. betamike 2005-05-19 9:33 pm EST
  24. Romain Guy 2005-05-19 9:38 pm EST
  25. theorz 2005-05-19 9:39 pm EST
  26. BlueCoder 2005-05-19 9:42 pm EST
  27. Romain Guy 2005-05-19 9:44 pm EST
  28. Carlos Rodrigues 2005-05-19 10:13 pm EST
  29. Anonymous 2005-05-19 10:37 pm EST
  30. Daniel 2005-05-19 10:52 pm EST
  31. noisy 2005-05-19 11:00 pm EST
  32. Eike Hein 2005-05-19 11:51 pm EST
  33. Lumbergh 2005-05-19 11:51 pm EST
  34. Michelle of the Resistance 2005-05-20 12:02 am EST
  35. Anonymous 2005-05-20 1:03 am EST
  36. Anonymous 2005-05-20 1:45 am EST
  37. Darius 2005-05-20 2:12 am EST
  38. Anonymous 2005-05-20 2:50 am EST
  39. konkat 2005-05-20 4:24 am EST
  40. fedetxf 2005-05-20 4:27 am EST
  41. jm 2005-05-20 4:30 am EST
  42. renoX 2005-05-20 5:18 am EST
  43. Romain Guy 2005-05-20 5:40 am EST
  44. Chris Lord 2005-05-20 5:47 am EST
  45. Anonymous 2005-05-20 5:58 am EST
  46. karl 2005-05-20 9:23 am EST
  47. Anonymous 2005-05-20 9:23 am EST
  48. Andy Roberts 2005-05-20 9:33 am EST
  49. deepspace 2005-05-20 10:12 am EST
  50. Anonymous 2005-05-20 10:51 am EST
  51. Archangel 2005-05-20 11:08 am EST
  52. BlueStreak 2005-05-20 11:14 am EST
  53. Tim 2005-05-20 11:21 am EST
  54. chemicalscum 2005-05-20 11:41 am EST
  55. deepspace 2005-05-20 12:16 pm EST
  56. deepspace 2005-05-20 12:19 pm EST
  57. Victor 2005-05-20 12:41 pm EST
  58. Darius 2005-05-20 1:02 pm EST
  59. mattb 2005-05-20 1:08 pm EST
  60. Bryan Feeney 2005-05-20 1:34 pm EST
  61. Anonymous 2005-05-20 2:26 pm EST
  62. Andy Roberts 2005-05-20 2:32 pm EST
  63. Herbert Meyer 2005-05-20 2:32 pm EST
  64. David 2005-05-20 2:36 pm EST
  65. Francois Stiglitz 2005-05-20 2:48 pm EST
  66. mattb 2005-05-20 4:49 pm EST
  67. helf 2005-05-20 10:53 pm EST
  68. Archangel 2005-05-20 11:11 pm EST
  69. Iain 2005-05-20 11:25 pm EST
  70. Mike Reid 2005-05-20 11:50 pm EST
  71. Anonymous 2005-05-20 11:52 pm EST
  72. Bryan Feeney 2005-05-21 12:10 am EST
  73. Mike Reid 2005-05-21 12:17 am EST
  74. GeWizz 2005-05-21 2:04 am EST
  75. Angry Java Guy 2005-05-21 7:21 am EST
  76. Andy Roberts 2005-05-21 8:55 am EST
  77. someone 2005-05-21 3:07 pm EST
  78. Anonymous 2005-05-21 4:31 pm EST
  79. Anonymous 2005-05-21 4:34 pm EST
  80. Uno Engborg 2005-05-21 6:03 pm EST
  81. chemicalscum 2005-05-21 8:32 pm EST
  82. chemicalscum 2005-05-21 9:03 pm EST
  83. jm 2005-05-22 7:05 am EST
  84. Anonymous 2005-05-22 8:05 am EST
  85. Uno Engborg 2005-05-22 8:21 am EST
  86. Slobodan Celenkovic 2005-05-22 8:35 am EST
  87. Patrick Schriner 2005-05-22 11:02 am EST
  88. jm 2005-05-22 2:54 pm EST