Here are some Swing links that you might have missed during the last week:
- Ken Orr explores an interesting usability side of Swing buttons with popup menus. The solution involves using an unpublished “doNotCancelPopup” client property supported by the current implementation of popup handling in core Swing. This may be different in other JVM implementations, and may even break in the future Swing versions (although the later is quite unlikely). Thanks to this post i have also updated the Flamingo command buttons to dismiss popup menu / panel on the second click. The implementation does not use the above client property, since Flamingo has its own code to manage popups.
- Gregg Bolinger has kicked off a series of posts on blueprints for well-written Swing applications (part 1, part 2, part 3 so far). Project Maddie has been created to provide the collaboration grounds for interested developers, and it will be interesting to see how this pans out after the initial excitement is gone. I have talked about the lack of Swing blueprints in May 2006 (just after JavaOne 2006), and unfortunately nothing has changed as far as the proper platform documentation goes.
- Jeremy Wood delves into the intricacies of using existing alpha composites to do cross fades between two translucent images. After finding out that the existing alpha composites are not up to the job, he tries doing direct manipulations on the underlying buffer. As this turns off the hardware acceleration, the time and memory performance were disappointing.
- Gabriele Carcassi provides a solution for registering JavaScript functions to respond to Swing events on applets.
- Following his experimentations in the SwingX incubator, Matt Nathan has decided to create a separate project for scalable icons.
- Geertjan Wielenga writes about the JSyntaxPane project, mentioning the supported editor kits, find / replace dialog, code completion configuration, color styles and more.
- Gregg Bolinger vents his frustration over the opaque and very slow bug fixing process of core Swing bugs. Working on drag-and-drop between tables and lists, he has hit a bug reported in 2003 and not fixed since then. In the next post he presents (a rather poorly formatted) a solution that he found on JavaRanch came up with.
- Wolfgang Zitzelsberger has announced release 2.8 of Synthetica look-and-feel. New in this release are the SyntheticaSimple2D theme, improved translucency / border support for comboBox / spinner / text components, transparent window support for 6u10, improved RTL component orientation support.
- Jean Francois Poilpret has posted the slides to his Jazoon 08 presentation on the JSR 296 (AppFramework).
- Greg Brown shows two examples of building Pivot applications that are wired with JavaScript and Groovy.
- Jeremy Wood talks about his implementation of Aqua-like preference panel thats supports both single-row and multi-row layouts, along with cross fading between the components.
- And finally, Collin Fagan kicks off the new series on exploring layout prototyping. The first part documents his attempts to apply XML to the UI layouts. Layout managers surveyed in this part are absolute, table, grid bag and Mig. It certainly looks like the desktop heavyweights (Adobe and Microsoft) have adopted XML as the lingua franca to enable easier collaboration between designer and developer tools. And while the hardcore developers still prefer writing and tweaking those XML files by hand, both sides of the respective toolchains provide tools that are familiar to the target audience.
What, why, when and how – these are the questions that shape the communication between the product developers and their users. Different teams choose different levels of opacity regarding these four questions, and making the answers more opaque over the time leads to a building frustration among the community members. This has been one of the major reasons behind my post on the current state of core Swing, and allow me to further explore this area.
Open-sourcing Java during the JavaOne 2006 and the announcement of OpenJDK project was hailed by Sun as the new era for Java, where everybody can lend their hand in shaping the future of the Java platform. Specifically in the client area, the summer of 2006 has supplied Swing developers with such gems as Chris Campbell’s entry on soft clipping, Chet Haase talking about Java on Vista, official birth of JSR 295 and JSR 296, as well as lively discussions on the SwingX painters and layers. Those have been exciting times for me personally, as they showed a renewed and well backed interest in the Java client side development.
Unfortunately, the last eighteen months have been quite disappointing. The level of openness (or transparency, if you will) set in the summer of 2006 was not a genuine and lasting commitment to the community, which has been effectively shut not only from participating in the decision making process, but in following it as well. And this brings me back to the four questions – what, why, when and how.
The how is perhaps the easiest one, and Java has always been shipped with the matching source archives. This has allowed the users to understand not only how the specific piece works, but also how to work around the specific bugs in order to achieve the required functionality. Even if the internal technical design documents (if any are present) are not available to the community, the full source code is an excellent reference guide to a deeper understanding of the platform and becoming a better Java developer in the process.
The answer to when allows bigger projects to estimate timelines for the different technologies, both existing and emerging. In this area, Java has not been a great success over the last three years. The new 18-month release cycle for major versions (announced at JavaOne 2005) which would have Java 6 ship in summer 2006 and Java 7 to ship in early 2008 has failed, without any explanation or apology. While the main reason for “slipping” Java 7 is the great work that has gone into Java 6 update 10, we still don’t even have the umbrella JSR for Java 7.
The answer to what allows estimating the functionality for the different technologies in coming to decide which one to use. Will we have a cross-platform Swing web browser component in Java 7? Will we have a public Swing API for translucent and shaped windows in Java 7? Will we have a public Swing API for playing, manipulating and producing video streams in Java 7? Will we have binding layer for Swing applications in Java 7? Will we see modern Swing components such as pivot table or date picker in Java 7? Withholding answers to these questions has been a normal practice for the past eighteen months, and this opacity has resulted in quite a few disappointed advocates of the toolkit.
The answer to why defines the level of trust between you and your community. You can be extremely opaque, not only making your decisions behind closed doors, but also presenting them as the only right way. You can be somewhat translucent and write about the reasons behind the decisions, even when the decisions themselves are made without any input from the community. Or, you can be extremely transparent and have the community participate equally in shaping and moving the platform forward.
Different projects will differ in their level of opacity. One-man open source projects are different from commercial companies that are frequently judged by revenue stream and monetization. You have the extremely opaque Apple and somewhat translucent Microsoft. On the other hand, you have an incredibly open Mozilla that already has 61 posts on its aggregator since the beginning of this week. And in between you have projects such as Qt Labs that are engaging in early feeback cycle about emerging functionality in their toolkit.
The last two examples (Mozilla and Qt Labs) show a continuous level of commitment to the two-way communication with their users. Is this coming from the developers? Is this coming from the management? Does it matter at all to your developer users?
If you’re starting a blog about the product and then abandon it after a few weeks, why start it in the first place? If your project has the word “open” in it and then you want to suppress the discussion about the planned features, why bother pretending? Do you really want to hold all your cards close to your chest if you’re trying to compete against a formidable opponent, especially when many of your pre-announced features are already in his well established offerings? Can you afford keeping the potential developers out of the loop instead of using the power of dev-to-dev blogs to build up the excitement? Is it beneficial to your project to hide behind the “open source you can help us instead of whining” mantra, when my chances as a potential outside contributor to add significant new functionality (as opposed to fixing a bug) are almost non existant?
And lastly, can you justify being “heads down” in development / testing to create a void to be filled with rumors, conjectures, interpretations and wild guesses?
The latest addition in the Flamingo component suite is support for pluggable resizing policies on the ribbon tasks and ribbon bands. This has been one of the items on the roadmap for version 4.0 (code named Fainnear), and is now available in the latest 4.0dev drop of Flamingo core and 5.1dev drop of Substance Flamingo plugin.
The existing support has been in place for more than two years, but it was quite flaky. It would often happen that making the ribbon progressively smaller resulted in a jarring resizing behavior of individual bands, and recently a bug report was filed on inconsistent layouts that sometimes enter into an infinite re-layout loop. In addition, the resizing decisions were rigid and not configurable by the application code.
This has finally been addressed in the latest 4.0dev drop of the core Flamingo library. The entire layout / resizing layer has been completely revisited, making the code much simpler, more modular, and, more importantly, configurable by the application code. I will talk about the relevant APIs at the end of this entry, but first let me show a few screenshots that illustrate the out-of-the-box resize policies.
The first screenshot shows the progressive collapse of different ribbon bands under the core CollapseFromLast resize sequencing policy. Under this policy, the ribbon bands are being collapsed from right to left. When the currently collapsing band has reached the last step (iconified), the band to its left becomes the next one to be collapsed.

The next screenshot shows the progressive collapse of different ribbon bands under the core RoundRobin resize sequencing policy. Under this policy, the ribbon bands are being collapsed in a cyclic fashion, distributing the collapsed pixels between the different bands. Under this resize sequencing policy, when the ribbon gets shrinked it is still possible for a specific band to have more width – see the transition from step 5 to step 6 below.

When a ribbon band is fully collapsed (iconified), its contents can be shown by clicking on its collapse button. Unlike before, the display state of the popup band contents is controlled by the most permissive resize policy installed on that band. Here is a screenshot of a popup ribbon band under the core Restrictive resize policy that makes the three trailing buttons to be displayed in MEDIUM display state (unlike before where they were shown in BIG state):

As before, the popups can be multi level (a drop-down gallery shown from a collapsed ribbon band). The command button menus work as well:

Command buttons in popup ribbon bands show their rich tooltips:

Note that all screenshots are taken under Ubuntu and the native GTK look-and-feel. This illustrates how the core Flamingo components adapt the currently set look-and-feel.
If you are interested in testing the new resizing policies in your applications, here is a quick introduction (until the formal documentation is ready). All the relevant code is in the org.jvnet.flamingo.ribbon.resize package.
There are two main concepts – resize policy and resize sequencing policy. The resize policy defines a single visual state of the given ribbon band. For every control in the specific ribbon band (command button, gallery etc), the resize policy defines what is its display state. The resize sequencing policy defines which ribbon band will be chosen next when the ribbon is shrinked / expanded.
The base interface for the resize policies is defined in the RibbonBandResizePolicy interface.The new JRibbonBand.setResizePolicies API can be used to install a custom set of resize policies on the specific ribbon band. The CoreRibbonResizePolicies factory provides two core resize policies list – permissive and restrictive. The default permissive list starts with a resize policy that shows all command buttons and ribbon galleries in the BIG display state, fully utilizing the available screen space. The restrictive list starts with a resize policy that respects the associated ribbon element priority set on the specific component – this is what is used in the last three screenshots (where the popup band shows one BIG button and three MEDIUM buttons).
The base interface for the resize sequencing policies is defined in the RibbonBandResizeSequencingPolicy interface. The new RibbonTask.setResizeSequencingPolicy API can be used to install a custom resize sequencing policy on the specific ribbon task. The CoreRibbonResizeSequencingPolicies factory provides two core policies – round robin and collapse from last. Under the default round robin policy, the ribbon bands are being collapsed in a cyclic fashion, distributing the collapsed pixels between the different bands. Under the collapse from last policy, the ribbon bands are being collapsed from right to left.
If your application needs more control over the resizing of the specific ribbon task or ribbon band, you can implement one (or both) of these interfaces and install them with the APIs mentioned above. To see the default round robin resize sequencing policy and permissive resize policy in action, click the WebStart launch button below and play with the application width:

As always, you are more than welcome to leave comments and report bugs on the project issue tracker, mailing lists or forums.
The previous entry has talked about the implementation details of the Eclipse Help view, and how it is using an embedded HTTP server powered by Jetty to serve dynamic content from a number of sources. Once you have such a custom server in place, you can embed a Browser control in any view / editor and call its setUrl method to show the required content. The links in the browser control will be handled in the same way as in the usual browser control – relative links will be served by the same HTTP server, and absolute links can point to content on the intranet or even external internet pages. But what about the live help actions?
The org.eclipse.help.ILiveHelpAction interface defines an entry point from Eclipse Help view “back” into Eclipse itself. If you include the PLUGINS_ROOT/org.eclipse.help/livehelp.js in your HTML document, you can attach a javascript:liveAction handler on the links in your document. This handler gets three parameters:
- ID of the plugin that contains the class defined by the second parameter
- Fully qualified class name that must implement the ILiveHelpAction interface
- Possibly empty parameter passed to the setInitializationString of the live help action instance
When such a link is clicked, the setInitializationString() and run() methods of the specified class are called. How does this work, and how can this be extended to work outside the Help view in any embedded browser control?
Here is the flow of execution in Eclipse 3.4 (all of these details are internal and subject to change in the future versions).
- The Help view is a collection of HTML pages. These are served from the org.eclipse.help.webapp plugin.
- One of the pages has an IFrame with 0*0 dimension named liveHelpFrame.
- The implementation of liveAction JavaScript method in the livehelp.js locates that frame and sets its location to the URL that encodes the three parameters (plugin ID, class name and argument string)
- A special livehelp servlet registered on the Jetty server gets this request. This servlet is implemented in org.eclipse.help.internal.webapp.servlet.LiveHelpServlet class.
- The doGet method checks that the embedded web server is running, and that the first two parameters are not null.
- The helper BaseHelpSystem.runLiveHelp locates the plugin bundle and loads the specified class. An instance of this class is created (the implicit assumption is that there is a public no-arg constructor).
- If specified, the argument string is passed to the setInitializationString of the created instance.
- A daemon thread based on this instance is created and started. Note that if your live help action needs access to the UI layer (to display a dialog, for example), the logic in the run method needs to be wrapped in Display.runAsync call.
rent a car bulgaria
Note that the above flow does not mention the actual contents of the 0*0 IFrame being used in the process. The whole reason for this frame’s existence is to make a call to the live help servlet. The LiveHelpServlet.doGet does not make anything with the resp object.
As can be seen from this flow, including the livehelp.js and putting a javascript:liveAction on the HTML anchor is not enough. The implementation of the JavaScript liveAction method makes certain checks to ensure that the browser is the one from the Help view. As such, if you click on this link in a browser control placed in another view, it will not result in invoking the specified action.
Until this functionality is supported by Eclipse in a published way, we can mimic this flow in a custom view / editor. Here are the basic steps – assuming that you have a browser control and a Jetty server / servlet already configured.
- Add two more servlets. The first will serve the “core” content, such as a custom livehelp.js, the initial blank content of the invisible IFrame and possibly a custom CSS. The second will handle the live help requests.
- Modify your existing servlet (that serves the usual HTML pages) to inject two pieces into every HTML file that it serves.
- The first piece is a HEAD tag to include the livehelp.js from the new core servlet. This piece can also include a link to the custom global CSS file.
- The second piece is a 0*0 IFrame named liveHelpFrame with initial content set to a blank page served by the core servlet. It is very important to obey the cross-scripting limitations placed by the browsers to make sure that a javascript handler on the main content can change the location of this IFrame.
- Implement the livehelp.js based on the core Eclipse script. You can simplify the implementation since you know exactly where to look for that IFrame. Get the URL of the window, strip away the trailing parts and replace them to point to your live help servlet. Add plugin ID, class name and the argument to the resulting URL to make sure that these are passed to the servlet. Finally, set the complete URL to be the location of the invisible IFrame. This will result in a call to the servlet, but leave the visible browser content unchanged.
- The implementation of the core servlet is very simple, fetching the required content from the bundled files (just like the servlet that is serving the rest of your files).
- The implementation of the live help servlet is the same as the core Eclipse one. Parse the parameters, make sure that the plugin ID and class name are present, load the class, create an instance of that class and then run its run method on a new daemon thread.
Congratulations – you have your own browser that is able to display a rich collection of interlinked documents and invoke actions defined in your plugin classes, interacting with other parts of your plugins / application.