Here are some Swing links that you might have missed during this week:

  • Bruce Eckel wonders if anyone really cares about desktop Java, and the responses are mixed. Any established technology has its shortcomings, and it would be short-sighted to assume that the same question will not be asked in five-ten years about Flex. In the meantime, those have have invested in learning Swing produce good-looking and responsive applications.
  • Karl Tauber has announced release 4.0 of the JFormDesigner tool for designing Swing user interfaces. New in this version are support for GroupLayout, FormLayout 1.2, improved conversion of IntelliJ forms and more.
  • JavaPosse has talked about multi-threading in UI toolkits, and there’s a follow-up discussion on this subject in the Google group of the show.
  • Eskil Blomfeldt reports that Qt Jambi AWT bridge has been rewritten to provide better support for window activation and whitespace around embedded components. It sounds that this project faces much the same issues as Albireo (that aims to provide the bridge between Swing and SWT). The Qt Jambi AWT bridge has still some unresolved issues with keyboard focus – something that has been addressed in Albireo.
  • Alex Ruiz has announced the first beta for release 1.0 of FEST Swing, a library that provides a fluent interface for functional Swing UI testing.
  • JavaSwing.net has a number of useful tutorials on using the JTextField and related classes, including the introduction to DocumentFilter to enforce upper limit on the number of characters, auto-conversion to upper case, number-only content and e-mail content. For more background on using regular expressions in e-mail verification see this article.
  • Clemens Eisserer has committed the first changeset for the XRender pipeline under the OpenJDK innovators’ challenge program.
  • And finally, Alexander Potochkin writes about the internal implementation of JXLayer‘s event interception on subcomponents in a non-intrusive manner using the InputContext class.

Java on the desktop

July 26th, 2008

I’ve said before that the customers don’t care about the technology. To a certain extent, this is also true about the developers, especially when it comes to choosing the “right technology” for your next big project. If your team members have considerable experience with a specific technology, you’re much better off going with that instead of trying to learn the newest shiniest framework and making all the beginners’ mistakes (on the other hand, it never hurts to keep your eyes and mind open).

The case at hand – Woopra, the real-time Web tracking and analysis application. It has been called the Chuck Norris of Site Analytics and some promise that it will make you drool, and while a few reviews briefly mention that it is written in Java, nobody seems to care. And this is one of the best compliments the underlying technology can get – it is so good that you don’t even notice it. I’m not going to talk about Woopra’s features (although they are pretty nifty compared to Google Analytics). I’m just going to show a few screenshots that highlight the attention to visual details and the level of customization made possible in Swing. The live application feels great, with subtle animations, intuitive navigation and no UI freezes. Click on the thumbnails below to view the full size slideshow.

And while some ask if anyone really cares about desktop Java, others just use it to create good-looking and responsive applications.

Here are some Swing links that you might have missed during this week:

  • Clemens Eisserer continues working on the XRender pipeline for Java2D, and has a few screenshots showing the progress of this project. Part 1, part 2 and part 3 show different test applications under this pipeline.
  • A message from Richard Bair on the mailing list of AppFramework (reference implementation of JSR 296) announces that Alex Potochkin has taken over the ownership of this project. The time indeed has arrived – the last source commit was in October 2007, and while Alex hasn’t posted any message on the mailing list / his blog, i would assume that he is taking his time making himself familiar with the project itself and the JCP / JSR process in general.
  • Alex himself continues writing about the JXLayer project and talks about the internal painting implementation in his latest entry. Jing Ge has a follow up entry in which he builds a complete validation module using BeansBinding, JXLayer and Hibernate Validator.
  • Xavier Young has a short introduction for using the EaSynth look-and-feel.
  • Ethan Nicholas introduces the JavaCSS project that aims to provide CSS support for styling Swing and JavaFX components. While the amount of comments on this entry indicates a significant level of interest in this project, it would be interesting to see how well will it be able to cope with the expectations implied by using the “CSS” in its name. As mentioned by Ben Galbraith in his JavaOne 2006 session, Swing and HTML are sufficiently different in that you can not take the existing “pure” CSS directives and apply them on Swing components. In addition, implementing the layout constructs of CSS may require changing the existing application layout managers. Throw the look-and-feel layer into the mix (don’t forget that the look-and-feel is responsible for computing the inner metrics of Swing components, such as margings, padding, gaps, etc), and you get quite an interesting challenge.
  • Ken Orr writes about unified toolbar buttons in his quest to emulate the appearance of native Mac applications. Surprisingly, this entry features a rather questionable advice on using the SwingUtilities2 class. Not sure about the Apple VM, but this is a strict no-no for even Sun VMs. Not only this class is in an internal sun package, it has also changed location between JDK 5.0 and JDK 6.0. What’s the alternative for SwingUtilities2.drawStringUnderlineCharAt? Call BasicGraphicsUtils.drawStringUnderlineCharAt and install the desktop rendering hints before that.
  • This is most probably will be a part of the next weekly JDK 7 build. Bug 6725214 on forward-porting the new D3D rendering pipeline from 6u10 has been marked as Fix delivered. For the brave souls wishing to venture into the implementation details, follow this Mercurial changeset. No word yet on porting the support for shaped and translucent windows and which package that might end up in.
  • Jacek Furmankiewicz continues working on the Java SwingBuilder project, and this time he writes about adding an SWT-style API for creating menus.
  • And finally, Richard Kennard adds component wiring based on Commons JEXL to his MetaWidget project, aiming at those environments that don’t have expression languages built into the language (such as Swing).

About half a year ago Christopher Deckers had a guest spot post on this blog about a non-daemon WebStart thread that prevents JVM from exiting when you’re closing your last Swing window running under the DISPOSE_ON_CLOSE mode. To illustrate the problem with the current implementation of WebStart helper threads, he posted the following excerpt from the AWT threading documentation:

Prior to 1.4, the helper threads were never terminated. Starting with 1.4, the behavior has changed as a result of the fix for 4030718. With the current implementation, AWT terminates all its helper threads allowing the application to exit cleanly when the following three conditions are true:

  • There are no displayable AWT or Swing components.
  • There are no native events in the native event queue.
  • There are no AWT events in java EventQueues.

There is an additional clarification to the last item in the same document:

Make sure that no method of AWT event listeners registered by the application with any AWT or Swing component can run into an infinite loop or hang indefinitely. For example, an AWT listener method triggered by some AWT event can post a new AWT event of the same type to the EventQueue. The argument is that methods of AWT event listeners are typically executed on helper threads.

So, as long as you don’t post another event from your event handler or hang indefinitely, you should be OK, right? That is not entirely correct, since the current implementation of the last item (at least in Sun’s VM) makes an additional restriction on shutting down the AWT queues in absence of events.

The relevant class in Sun’s VM is sun.awt.AWTAutoShutdown and it has additional logic on top of the official documentation (relevant part is highlighted by me):

The internal AWTAutoShutdown logic secures that the single non-daemon thread is running when AWT is not in ready-to-shutdown state. This blocker thread is to prevent AWT from exiting since the toolkit thread is now daemon and all the event dispatch threads are started only when needed. Once it is detected that AWT is in ready-to-shutdown state this blocker thread waits for a certain timeout and if AWT state doesn’t change during timeout this blocker thread terminates all the event dispatch threads and exits.

In the current implementation this timeout is 1000 ms (or one second). What this effectively means that AWT is not shutdown immediately after disposing the last window in your application and processing all pending events. Instead, it wakes every second, checks for any pending or processed events during the sleep and continues sleeping if there have been any such events.

How can this affect your application? In my case, i have a daemon thread that wakes up every 100ms and synchronizes the visual state of certain components. Since everything UI-related must run on the Event Dispatch Thread, i wrap each iteration loop inside the SwingUtilities.invokeLater (otherwise i run into sporadic deadlocks). As far as AWT is concerned, such an invocation is an event which effectively prevents AWT from shutting down.

Bottom line is that you should be careful with calling SwingUtilities.invokeLater from daemon threads in applications using DISPOSE_ON_CLOSE. Before calling that method you can check that the relevant component is visible and showing. If both are true it means that the window of that component is still not disposed.