The Source for Java Technology Collaboration
User: Password:



Kirill Grouchnikov's Blog

Community: JavaDesktop Archives


Substance 4.3 official release

Posted by kirillcool on April 14, 2008 at 11:01 AM | Permalink | Comments (1)

It gives me great pleasure to announce the official release for version 4.3 of Substance look-and-feel (code-named Nairobi). The list of new features includes:

It was on this day in 2005 that Substance project has been created. It is now three years old and to celebrate this occasion i have redesigned the main project page to be less cluttered and a little better organized. Hope that you like it, and if you have any comments, i will be more than interested to hear your opinion.

A few screenshots of the new functionality in Substance 4.3:

New decoration painters applied to the Flamingo ribbon component:

Highlight painters on table (note a single-line border separators):

Colorized visuals of disabled selected buttons:

A button with 72 pixel font:

Click on the button below to launch a signed WebStart application that shows the available Substance features.

 The sources and binaries are available on the project site and the CVS repository.

Translucent and shaped windows in core Java

Posted by kirillcool on February 27, 2008 at 09:38 AM | Permalink | Comments (7)

The lack of support for translucent and shaped windows has been a subject of quite a few complaints about AWT and Swing. This has finally been addressed in the latest 6u10 build.

Here is how a translucent window looks like:

window-translucent.png

And here is a shaped window:

window-shaped.png

And here is a translucent and shaped window:

window-translucent-shaped.png

For more (unofficial) information on where these APIs are located and how to use them, click through to Pushing Pixels.



Flamingo 3.0 official release

Posted by kirillcool on February 19, 2008 at 09:43 AM | Permalink | Comments (9)

It gives me great pleasure to announce the official release for version 3.0 of Flamingo component suite (code-named Deirdre). The goal of this project is to provide a small and cohesive set of powerful UI components that allow creating modern applications that provide visual functionality similar to or superseding that of Vista Explorer and Office 2007. The components provide consistent visuals under the existing core and third-party look-and-feels, respect the DPI settings of the user desktop and follow the core Swing guidelines in the external APIs and the internal implementation details.The component suite includes:

The project is licensed under BSD license and requires JDK 6.0. You can see the demo applications here. The binary and source bits are available here. A few screenshots of some of the Flamingo components:

File-selector breadcrumb bar and file viewer panel with medium command buttons:

Ribbon under Windows XP look-and-feel with resizable SVG-based icons:

Ribbon under Synthetica Mauve Metallic look-and-feel:

SVN-selector breadcrumb bar and file viewer with tile command buttons and SVG based icons:

Command button with a command button panel embedded in a popup panel:

Cross-posted at "Pushing Pixels".



Flamingo component suite 3.0 - ribbon

Posted by kirillcool on February 08, 2008 at 09:50 AM | Permalink | Comments (1)

The ribbon component is one of the major parts of the Flamingo component suite. It is a Swing component that provides capabilities of Office 2007 Command Bar, and the detailed documentation has been updated to show the latest visuals, APIs and terminology of the ribbon component. Here, i will show a few screenshots that illustrate the ribbon functionality.

The following screenshot shows a sample ribbon component (under Metal look-and-feel with the default Ocean theme):

Ribbon consists of a set of ribbon tasks. Only one task is visible at a time (a-la card layout). Logically, a task also includes its toggle button (the top portion of the ribbon control):

When another task is selected (programmatically or via user interaction), the contents of the selected task replace the previously selected task:

A ribbon task consists of a number of ribbon task bands:

A ribbon task band can contain command buttons in different states, usual core Swing controls (buttons, check boxes, combo boxes) and in-ribbon galleries. The available width is distributed between the task bands based on the priority of the elements in the task. As can be seen in these screenshots, some command buttons are in ElementState.BIG (big icon and text), some are in ElementState.MEDIUM (small icon and text), and the others are in ElementState.SMALL (only small icon).

An in-ribbon gallery allows scrolling and operating a large number of command buttons in a limited space.

Clicking on the gallery expand button opens a popup panel that shows the gallery command buttons arranged in a multi-row scrollable grid:

The ribbon component uses the visuals of the current look-and-feel. Here is how ribbon looks under the Windows XP with Windows look-and-feel:

And under Windows Vista:

And under Ubuntu 7.10 with GTK look-and-feel:

And under Looks Plastic XP:

And under Synthetica Mauve Metallic:

And finally under Pagosoft:

The release candidate of Flamingo 3.0 is scheduled for February 11, with the official release scheduled for February 18. The latest binaries and source can be downloaded here.

Cross-posted at Pushing Pixels



Substance 4.2 official release

Posted by kirillcool on February 04, 2008 at 05:15 PM | Permalink | Comments (5)

It gives me great pleasure to announce the official release for version 4.2 of Substance look-and-feel (code-named Memphis). The list of new features includes:

In addition to the core release candidate, the following Substance plugins and modules have been updated as well:

A few screenshots of the new functionality in Substance 4.2:

Support for native text rasterization (viewed here with Segoe UI 12 pixel font under Windows Vista on JDK 5.0):

Component colorization with 50% factor (both background and foreground):

Respecting the KDE desktop font settings:

Better visuals for disabled controls under Raven Graphite skin:

Removing visual noise on tables and table headers in scroll panes:



Substance 4.1 official release

Posted by kirillcool on November 12, 2007 at 12:01 AM | Permalink | Comments (9)

It gives me great pleasure to announce the official release for version 4.1 of Substance look-and-feel (code-named Lima). The list of new features includes:

Applications that use or implement custom border painters and title painters should consult the instructions in the migration guide.

In addition to the core release, the following Substance plugins and modules have been updated as well:

The documentation has been updated with the latest visuals and APIs. In addition, there are new tutorials on Substance painters and skinning of custom components. Special thanks for bug reporting and testing go to Mikael Grev, Vincent Trussart, Kamil Paral, Klaus Rheinwald and Jean-Francois Poilpret.

A few screenshots of the new functionality in Substance 4.1:

The inner border painters and tab pane content borders in the Raven Graphite Glass skin:

The new Creme Coffee skin:

Full support for desktop resolution settings:

Automatic font policy for Gnome desktops:



Why i don't care about Java 6 on Leopard

Posted by kirillcool on October 29, 2007 at 09:45 AM | Permalink | Comments (0)

It looks like anywhere you go in the Java blogosphere, people are only talking about Java 6 (or lack of thereof) on Leopard. Some say that the only reason they bought Leopard was for Java 6, some say that their honeymoon with Apple is over, and some say that Java 6 will be available shortly as a separate download. And 99% of the postings and the comments seem to agree - Java 6 should have been included in the golden master of Leopard.

I thought about it over the weekend, and time and time again i reach the same pragmatical conclusion - i don't care about Java 6 on OS X, and for that matter i don’t care about OS X as a Java development platform. While that may sound as a harsh statement, allow me just a few minutes of your time.

I’ve already written that for me, an operating system is just another layer in my development platform. I’m more interested in the tools that i’m using and the applications that i'm developing. The things that i said 30 months ago are still true - i'm perfectly OK with my Windows machines, because i rarely directly interact with the operating system. I might have switched to Linux, but pragmatically speaking, it is not a good business proposition. Between 150$ for the OEM version of Vista and spending 12 hours to download and install OS and configuring the Java environment (on my free time during the weekend away from the family), i choose Vista any given day.

Now, let’s talk some numbers. The market share for Windows is somewhere in 90-95% range, and while sales of Mac machines rise on the quarterly basis, so do sales of Windows boxes. One might say that these numbers are for all the machines, including corporate environments and home machines for non-IT people. I’m looking at the visitor stats of this blog, which is has a very specific technical orientation, and the numbers are a little surpising:

  • Windows has 75.6%
  • Linux has 14.4%
  • Mac has 9.6%

Yes, even for such a narrowly oriented site that mainly talks about Swing, Java2D and other UI topics in Java land, Mac doesn’t even cross into double digits. While you do see most of JavaOne presenters use Mac laptops, it doesn’t really extrapolate to the wider audience of JavaOne attendees, and most certainly it doesn’t extrapolate to the much wider audience of Java developers. The same applies to the blogosphere numbers - i’m sure i have seen about 20-30 rant entries on this subject over the past three days. Let’s be generous and say it’s an even hundred. Is that a lot? It is a lot of noise, but compared to the number of blogs tracked by JavaBlogs (2261)  it’s not that much.

Looking at the bug reports for my open-source projects over the past three years, i see only two Linux-specific bugs and one Mac-specific bug. Yes, about 500 bugs reported via the bug trackers, forums, mailing lists and direct mail, and only one Mac-specific bug. Of course, most of these bugs were cross-platform, but so have been the bug fixes.

Now, your numbers might be different. If you’re developing a commercial product that is targeting multiple OSes, you might not be in a position similar to mine. However, if you spend more money to provide support for Mac than what you make from product sales on Mac, that is a bad business proposition. In this case, you might as well say that your product is for Windows only (like the vast majority of all the applications out there) and don’t mention that it’s in Java (so you don’t get blog-flamed about lack of cross-platform support). Of course, in this case you might as well switch to Win32, MFC, WinForms, WPF or whatever technology is pimped that year, but that is a topic for another blog entry.

This is, of course, my personal subjective opinion. I never had a Mac, and this fact alone might severely skew my judgement. But on the other hand, i never had to have a Mac as a Java developer. And this most certainly doesn’t change now with Leopard. Windows (in its various flavors) was and remains my only Java development platform (both at work and at home), with Linux and Mac delegated to what they really are at this point in time - alternative OSes with minor penetration to be installed for platform-specific bug fixes. Will this change in the future? I’m a pragmatic person, so i don’t say "no".

Cross-posted on Pushing Pixels. If you have comments, click through.



Rainbow 1.1 - SVG browser for remote SVN repositories

Posted by kirillcool on October 08, 2007 at 08:57 AM | Permalink | Comments (0)

Those of you who came to the session (PDF link) that Alex and I have presented at JavaOne 2006 saw the application that we wrote to illustrate different animation, translucency and transition techniques. The project itself was named Rainbow and all the bits were made available immediately after the session. Unlike many other demo applications written specifically for JavaOne, Rainbow was not meant to be one-shot sow-it-all-together-over-the-pizza to be left stagnating in the dark, and over the past month i have added a few big features.

There are two main new features that you can find in the version 1.1 (nearing RC stage), code-named Nightstone:

  • Support for SVGZ format in addition to SVG
  • Ability to browse local and remote SVN repositories with the new breadcrumb bar functionality from Flamingo.

To try the latest dev version in action, click on the WebStart button below:

After the application has been downloaded (it is about 12MB large, including the bundled Batik, Substance, SVNKit and a few others) and granted permissions (as before, you can convert the SVG images to Java2D code classes and PNG images and save them to local disk), you can browse two remote SVN repositories, Oxygen and Kalzium.

Here is a screenshot that shows a few icons from the Oxygen SVN repository:

As you can see, the application is able to show compressed SVG images (in SVGZ format) after these have been downloaded from a remote SVN repository. Here is a screenshot of another Oxygen folder:

As before, when you click on an icon button, you will see another frame pop up with three tabs. The first tab will show you the SVG contents (XML), the second tab will show you the matching Java2D code that you can save as a local class, and the third tab will allow you to apply a few effects on the SVG image and save it as a local PNG file. For example, if you're interested in more details on the new Konqueror icon, here is what you'll see:

Want to see it inverted? Click on the "Invert colors" checkbox et voila:

Still convinced that web applications are the way of the future?

Also published in Pushing Pixels



Key Largo, Edelweiss and Caireann are finally released

Posted by kirillcool on September 03, 2007 at 09:36 PM | Permalink | Comments (0)

I'm very pleased to announce releases for the main three projects that i'm working on:

  • Release 4.0 of Substance look-and-feel (code-named Key Largo)
  • Release 3.1 of Laf-Widget layer for LAFs (code-named Edelweiss)
  • Release 2.0 of Flamingo component suite (code-named Caireann)
The release for version 4.0 of Substance look-and-feel includes the following new features:
  • Six new skins: Nebula, Nebula Brick Wall, Autumn, Magma, Mist Silver and Mist Aqua.
  • State-aware theme transitions
  • Smart tree scroll
  • Glowing icons (buttons, option pane)
  • Support for JXPanel translucency
  • SwingX UI delegates in SwingX plugin
  • Border painters
  • New title painters: Brushed Metal, Marble Noise

Some applications may need to follow the instructions in the migration guide. The latest stable NetBeans module available here installs Substance as the look-and-feel in NetBeans 6.0 and allows playing with various skins, themes and watermarks.

Work has begun on the next releases, Lima for Substance, Foxglove for Laf-Widget and Deirdre for Flamingo.



An article on Swing EDT violations

Posted by kirillcool on August 30, 2007 at 09:03 AM | Permalink | Comments (0)

There's a new article that has been published today on java.net titled Debugging Swing. It builds on the previous work by Scott Delap and Alex Potochkin to provide even more tools for tracing the EDT violations that can lead to visual artifacts, unresponsive or frozen UIs and infinite painting cycles.

If you're interested in more articles on Swing, please post your suggestions in the comments. Specifically, i'm looking for the "everyday" problems that you're facing in the regular business Swing applications. Note that an article scope is too small to talk about architecturing a Swing application, so try to keep it to a specific topic, such as auto-completion support on comboboxes or writing a custom component.

Thanks to Eamonn McManus for his help on JMX-related code and to Chris Adamson for the editing.



OSCON 2007 - presentation slides and stray thoughts

Posted by kirillcool on July 26, 2007 at 09:33 AM | Permalink | Comments (0)

First of all, thanks to all those who came to listen to my presentation yesterday at OSCON 2007. The presentation slides are available in the PowerPoint2007 and PDF formats. I'm also planning a series of articles on my other blog to go more deeply into the various parts of the Swing painting pipeline.

And now some stray thoughts that went through my head on the plane back as i started comparing OSCON with JavaOne

  • Much better organization of connectivity and power supplies. Quite a few big tables outside the session rooms where you can plug your laptop to an outlet and connect to the internet with a hard wire. Not to mention that the session rooms had extension cords with outlets under the chairs, with a decent (15-20 KBs) WiFi access.
  • No standing in line to get in the sessions. Arguably, there are less people at the conference, but everybody is entitled to go and sit on the floor when they pay four figures to go to the conference.
  • Much more girls / women at OSCON. Perhaps Java needs to borrow some sex-appeal from other languages :)

And it was nice to see a friendly face at the conference itself and at the airport (both our flights were delayed, which gave me a chance to start reading the "Beautiful code", which is for now very disappointing).



Flurry of activity

Posted by kirillcool on July 19, 2007 at 08:39 AM | Permalink | Comments (1)

I guess it's because of all the free evenings one gets during the summer (the hit TV shows take long breaks, and not too many major DVD releases), so i've been pretty busy over at Pushing Pixels, writing about the new functionality in the Substance and its plugin for SwingX.

There are a few new skins in the latest 4.0dev drops, Magma, Autumn, Mist Silver, Mist Aqua, Nebula and Nebula Brick Wall described here.

The "Support for SwingX components" series shows screenshots and videos of SwingX components under the latest drops of 4.0dev:

  • The first part shows the support for JXTaskPaneContainer and JXTaskPane.
  • The second part shows the support for JXStatusBar.
  • The third part shows the support for JXTitledPanel.
  • The fourth part shows the support for JXTipOfTheDay.
  • The fifth part shows the support for JXLoginPanel.
  • The sixth part shows the support for JXMonthView.
  • The seventh part shows the support for JXHeader.
  • The eighth part shows the support for JXErrorPane.

The "Advanced animations on core Swing components" series takes a deeper look into the enhancements made to the built-in animation layer:

  • The first part shows rollover and selection background animations on menus, sliders, tables and table headers
  • The second part shows rollover foreground animations on menus under a skin that uses dark background fill on menubars
  • The third part shows rollover and selection background and foreground animations under a mixed dark-light theme
  • The fourth part shows rollover and selection background and foreground animations under the new Magma skin

The Advanced animations on SwingX components brings these two series together, showing the animations on the JXMonthView component.

Also, i have a brand new article on java.net on auto-completion support on Swing comboboxes using GlazedLists, JIDE, SwingX and Laf-Widget. Many thanks to James Lemieux of GlazedLists, David Qiao of JIDE and Chris Adamson of java.net for reviewing this article.

Last but not the least, next Wednesday i'm going to present a session on Swing advanced effects at the OSCON 2007 conference. If you're there, drop in to learn a thing or two about the Swing rendering pipeline and its extension points that allow you to hook the custom painting functionality.



Substance module will not be supported in NetBeans 6.0

Posted by kirillcool on June 19, 2007 at 09:17 PM | Permalink | Comments (1)

It saddens me to say this, but Substance module for NetBeans, which allows you to play with all the available themes, watermarks, skins, and even set an arbitrary image as the IDE watermark (a feature that was used extensively in the NetBeans look and feel contest about a year ago) will not be supported in NetBeans 6.0.

You can see the comments on issue 66335 and issue 103361. The first one was opened more than two years ago, and asked to clean up the code of the custom tabbed pane used for the NetBeans editor. The vast majority of the code there is either private or package-protected, and as such, i had to copy a lot of it into Substance module. This led to quite significant code bloat on my part (which was completely unnecessary), making the code base much less readable and maintainable. Nonetheless, the module was functioning as expected in 5.0 and in 5.5 (without any code changes).

However, the upcoming version 6.0 introduces binary incompatibilities in the tabbed pane component (see the second issue above), which breaks the Substance module. In order to address this, i would have to copy yet more classes into my module, since the base implementation is, once again, either private or package-protected. Unfortunately, NetBeans developers view this as internal implementation details, saying this in the comments on the first bug that i filed:

The code is not designed for extensibility to other UI delegates (which is btw complicated task, believe me) and I doubt it will ever be, currently we have no plan to support it, simply because this library was intended primarily as private use-only-in-IDE library and we can't afford to maintain it as public extensible library with nice API. Too little effect for too much work for us, sorry.

Hopefully this decision will be reconsidered, since this plugin is quite a popular one (featuring in the top ten most popular NetBeans plugins). If not, you will have to uninstall it if you're planning to upgrade to NetBeans 6.0.

Cross-posted at Pushing Pixels.

Update: NetBeans developers have unrolled the changes the broke Substance module. Use the latest drop of Substance 4.0dev module and NetBeans 6.0 daily builds after July 26th.



Java 6, Mac OS and Substance

Posted by kirillcool on June 07, 2007 at 06:37 PM | Permalink | Comments (4)

The topic of Apple being late to release the final JDK 6.0 for Mac is being discussed on the web in the past few months (see here, here, here, here and here for a small sample). One question that is always asked in return is what exactly is missing in the latest dev build (b88) that Apple has provided?

Dean Iverson has been kind enough to work with me to provide a AHIG-compliant implementation of Mac-specific font policy (based on the excellent initial work done by Karsten in Looks). After a few iterations, we made sure that the font family (Lucida Grande) and the font sizes match the AHIG guidelines (except the list and tree fonts which are still one point larger than they should be). And so, the latest development drop of version 4.0 of Substance (code-named Key Largo) should provide platform-consistent fonts for Mac as well.

However, one thing was still missing - proper support for desktop antialias settings. There are two new features in JDK 6.0 for the AA settings (more on this in Chet's blog), the new Toolkit property to query the desktop settings, and the VM flag to override the desktop settings. Unfortunately, it appears that the latest dev build of Apple VM supports neither (and ignores the 5.0-specific undocumented swing.aatext VM flag).

And so, the latest Substance 4.0dev drop provides a temporary workaround until Apple makes the final JDK 6.0 release that supports the features mentioned above. When you're running under Mac and JVM version is 6.0, all components will have anti-aliased texts. Here is a screenshot to illustrate this. On the left hand side, the Aqua look and feel, in the middle, the previous Substance version (note that it's not antialiased) and on the right the latest Substance version. A sidenote - the AA quality in Aqua is visibly better than in Substance (which delegates to the basic implementation). This is most probably due to the fact that i can only set VALUE_TEXT_ANTIALIAS_ON value, since i don't know the actual one (which should be returned from the new Toolkit property).

Once again, thanks to Dean Iverson for taking the time to work with me on these two issues.



Removing functionality from a stable API

Posted by kirillcool on June 01, 2007 at 08:51 PM | Permalink | Comments (5)

For the past year, Substance has been a fairly popular and stable project, making the top ten java.net lists in hits and accesses for most of the months (even given the presence of the such heavy hitters as JDK, Looking Glass and AppFuse). I get about 70 mails a month (most of them private, as people feel more comfortable without going through the hassle of public mailing lists and forums), and most of them are about bugs and problems. This is completely understandable - i almost never write a "thank you" mail when something works as advertised myself :)

And so, this steady stream of user feedback provides an interesting tool to measure the relative success of the features that i'm adding. Now, I have three main reasons to add a feature:

  • Explicit user request - about fifty percent
  • Interesting feature seen elsewhere (OS, browsers, other applications, other LAFs) - about forty five percent
  • Interesting feature that i thought about myself - about five percent (maybe even less)

As mentioned earlier, pretty much the only time that i have a feedback about some feature, it's either a bug or request for enhancement (which is, once again, totally acceptable). So, what happens when i don't hear anything (and i mean anything) about a feature. As far as i can tell, there are only two reasons:

  1. People want to use it, it works perfectly, with nothing to add and no bugs
  2. People don't need it

I'm way too old to believe in the first :) There are always bugs. In fact, as of today, the issue tracker has 221 reported issues, with many more reported privately via e-mail or found by myself and fixed without reporting them (i know, bad dog). And i do believe that if people want to use a feature and find a bug or a limitation, they'll at least shoot me an e-mail. So, this leaves the only option - people don't need the specific feature.

And so, the code lays around, gathering virtual dust, making the testing harder, complicating other code paths, requiring extra time to synchronize the documentation and adding to the total size of the runtime libraries. Which eventually has lead me to the decision of pruning the features that nobody commented upon since their inception (some more than a year ago).

Now, before you start accusing me of breaking the existing applications and alienating my users, i do have an explanation about the development process of Substance. Up until now, the release cycle was pretty tight, with releases every ten weeks. This doesn't leave too much time to polish and completely finish every new feature, so most new features mature during two or sometimes even three releases. During this time, i wait for the user feedback to see if the API is adequate, the feature itself is stable and, most important, the feature is used (if there is a bug report, it means that the feature is used or at least tested to see if it's useful). Some of the new features don't get that much attention if there is no feedback - i do tend to spend more time on user requests (since my time is limited).

So, there are some features that have been added experimentally (a request from a single user, a posting on a forum that has asked how to do something, or a stray thought during a boring movie). I know that they are not complete, and yet there hasn't been a single request for enhancement. I know that there are always bugs, and yet there hasn't been a single bug report. I feel that the time is right to start removing such features. Here is the list of first four features scheduled to be removed in the next major release of Substance (code-named Key Largo).

While some of these may sound an interesting problem to solve (all of them were such to me), i do have very good reasons to remove each one of them. If you use one of these and have a strong case against removing it, i'm open to talk (comments, project mailing lists, project forums or private e-mail).

Note that the usual release schedule has been relaxed from 10 weeks to about 20 weeks (due to the big change to the theming mechanism and the proposed removal of the features mentioned above), with the release scheduled late September. Hopefully this gives enough time for the discussion and will make the codebase a little cleaner and clearer.



Listening to the users part III - theme transitions

Posted by kirillcool on May 31, 2007 at 09:31 PM | Permalink | Comments (6)

It all started with a simple request - have Substance not paint rollover state on buttons. I could have dismissed it by simply saying that this goes against the library design, and having one request in 2+ years that the library exists hardly justifies additional setting (making the implementation more complex, the documentation more verbose and in general going further down the wrong side of the user happiness curve). However, going into further dialog about why exactly is this feature needed, uncovered much more serious problem that needed to be addressed.

For most applications, people prefer subdued colors, and there's only so many variations of saturation and brightness that you can play with to distinguish between possible states of controls. In general, there are four different flags on a button model for "active" state - rollover, select, press and arm (the last one is relevant for the menus). And now, you find yourself with much more states that you can reliably handle with only one color scheme (rollover selected, rollover unselected, pressed selected, pressed unselected, selected, and you can even go further into pressed selected rollover and pressed selected non rollover). And this is really what has been bothering my user - being unable to distinguish between a selected and rolled over toggle button, especially on such a low-saturated theme as orange of Office Silver.

The Office itself solves this problem by using more than one color scheme for active (rollover / selected / pressed) states. A selected toggle button is painted orange, a rolled over toggle button is painted yellow and a selected and rolled over toggle button is painted dark orange. Starting from this, i spent the last five weeks completely rewriting the entire background painting, including support for custom themes for every component state and proper animations between the states. Here is an example of state transitions under the new implementation of Office Silver skin. The right column shows the model state at each moment, and you can follow the color transitions from selected (light orange) to selected rollover (dark orange) to pressed selected (reddish orange) and back to rollover unselected (orangish yellow). Note that on the checkboxes and radio buttons, the transitions also involve animating the color of the checkmark:

But why stop at animating the background color only? What if you want to have black text on light background in a regular state, but light text on dark background in an active state? You should animate the foreground color as well to provide the smooth and pleasing visual transition - and this is what is done in the brand new Nebula skin which uses the colors of the Nimbus LAF (except the brown colors of the progress bars). Watch what happens when the buttons are pressed:

Note that the transitions apply not only to the "traditional" button controls such as push buttons, toggle buttons, check boxes and radio buttons, but to much wider range of controls - tabs, sliders, scroll bars, menus, menu elements etc. In addition, the same settings apply for rollover and selection effects on lists, tables and trees. Looking back, it has been a great feature request from the user. Thanks, Greg.



Bringing life to Swing desktop applications - all you need to know

Posted by kirillcool on May 13, 2007 at 08:43 PM | Permalink | Comments (7)

You might have seen the teasers (first and second), and now it's the time for all the links.

  • The slides are right here (PDF format, so you can right-click on it and save instead of viewing directly in the browser).
  • The full sources for the main demo are in the CVS repository of Rainbow project (along with the WebStart link).
  • For more information about bytecode injection read this page.
  • The source code for demoes is available here (ghost effects) and here (transition effects).

Many thanks to Alex for having me as a co-presenter. Thanks to all who came to see our presentation, and for those who asked questions.

And one last thing. One of the comments on the previous blog entry requested animating the search mask (on dynamic search result updating). The implementation of the matching JXLayer painter can be found here. Here is how it looks like in action - note how the search mask is animated according to the current search string (in the top-right portion of the frame) and to the current icon scale (last few seconds of the video clip):



Borrowing from Vista - part II

Posted by kirillcool on April 28, 2007 at 02:07 PM | Permalink | Comments (14)

The first part of this series described the fade effects on tree decorations (lines and expand / collapse icons) that happen under Vista and were added to the latest stable release of Substance. In this part, i'm going to show another nice feature that is present in Vista trees. I call this feature "smart scroll", and it is a real time saver for scrolling multi-level trees with limited horizontal space.

I first noticed this in Eclipse. Usually, i leave something like 200-250 pixels for the package / navigator view, and when i start scrolling up and down, in most cases i have to scroll horizontally as well, especially if i'm looking at classes that are 4-6 levels deep. This is rather time consuming, since you can easily wind up looking at a completely blank view of the tree, and then you have to scroll the tree either to the left or to the right to get your bearings. At that point, you're back again to the vertical scrollbar. Rinse and repeat. However, under Vista this process no longer exists - once you scroll the tree to an (almost) blank view, it automatically scrolls horizontally (as needed to the left or to the right) to bring you in sync with the visible (informational) part of the tree. Needless to say, this is a real time saver, since you're only operating the vertical scroll bar and never get lost in blank areas.

And so, the latest drop of 4.0dev version of Substance (code-named Key Largo) provides this functionality to the applications. As with the tree decorations fade, it is disabled by default and can be enabled by using the relevant FadeConfigurationManager APIs. The matching fade kind constant is SubstanceLookAndFeel.TREE_SMART_SCROLL_ANIMATION_KIND. Here is a video demonstrating it in action - note how the viewport is adjusted to scroll to the relevant tree section. In addition, note that the horizontal scroll doesn't kick in immediately (same as in Vista) - if you continue scrolling on vertically, it will wait until you stop.

If you want to see it in action, you're welcome to install the latest NetBeans module and play with the different tree views.



Bringing life to Swing desktop applications - teaser 1

Posted by kirillcool on April 24, 2007 at 08:39 PM | Permalink | Comments (6)

If you happen to be at this year's JavaOne, you're more than welcome to hear me and Alex presenting the Bringing Life to Swing Desktop Applications technical session (TS-3414). We will be talking about different techniques to bring your Swing application into the 21st century. The application that we've written to illustrate all of the techniques will be available immediately after our session, and here's a sneak peek at two of the effects combined in it (ghost effects and transition layout). Note that during the transitions (when the icons are zoomed in / out), the sliding icons are made translucent to make the transition look better. How many lines of code were added to the application to enable these effects? Three.

See you at JavaOne.



Substance LAF 3.3 official release

Posted by kirillcool on April 16, 2007 at 12:15 AM | Permalink | Comments (8)

Yet another year has passed and Substance has celebrated its second birthday. As scheduled, the release for version 3.3 (Iowa) is available. The list of new features includes:

  • Support for high DPI
  • New skins: Business Blue Steel, Business Black Steel, Raven Graphite and Raven Graphite Glass
  • Arc header painter
  • Streamlined slider painting
  • Animation on slider thumb proximity
  • Flat title painter
  • Themed button icons
  • New watermark
  • Tree decorations animation

In addition, the following new features from release 3.0 of laf-widget project are available:

  • New modes for tab overview dialog
  • Improving grid tab overview mode
  • Support for ghost effects under other LAFs
  • Focus looping animation

Thanks to all the bug submitters (especially Jan Erik) and the users for making this happen. The next release is planned for September. If you happen to be at this year's JavaOne, come and visit the java.net community corner on Thursday at 12:30 to learn more about Substance. The Substance plugin for NetBeans has been updated as well. You can also get it at the new NetBeans plugin portal - type the word "Substance" in the search box.



Non photorealistic rendering in Java - edge detection

Posted by kirillcool on April 07, 2007 at 11:17 PM | Permalink | Comments (1)

The image structure information is one of the most important inputs to the non-photorealistic rendering algorithms. In traditional mosaics (gzipped PDF), the mosaic tiles are placed following the structure edges to convey the structural features, in watercolor simulation the artistic effect is achieved by simulating translucent glazes initialized over structure segments, while in particle-based engines (PDF), the structure features are used as particle generators.

John F. Canny's seminal paper from 1986 titled " A computational approach to edge detection" describes a fast and efficient algorithm for extracting edge information from a 2D image. A high-level description can be found at this page, and the algorithm consists of the following main steps:

  • Filter out the noise
  • Compute image gradient, resulting in gradient strength and gradient direction for each pixel
  • Non-maxima supression, resulting in thin edges
  • Thresholding / hysteresis, resulting in significant edges

At any step, you can tweak the settings according to your needs. For example, at the second step, you can either convert the original image to grayscale and apply the gradient computation, or perform the gradient computation on each one of the color channels (red, green and blue), taking the maximum value from each one. At the last step, you usually provide two values, high threshold and low threshold. Then, you start iterating over all pixels with values above the high threshold, trying to trace a "significant" edge (with either depth-first or breadth-first search). When you can't find a neighbour with value above the low threshold, the edge ends. In addition, you can decide to remove only gradient values below the low threshold, which will result in many more edges (some of which may be "false", attributed to either image noise, subtle lighting changes or small changes in texture).

The org.jvnet.ixent.algorithms.graphics.edgedetection.EdgeDetector defines an interface for edge detection implementations. It defines two enums, one for edge fuzzyness and another for edge strength. The later defines the values for low and high thresholds, while the former defines the thresholding implementation (low only, or low and high together). The existing implementation is in org.jvnet.ixent.algorithms.graphics.edgedetection.CannyEdgeDetector . To initialize the edge detector with input image, call

  /**
   * Initialize with Java image object
   
   @param image
   *            input image
   */
  public void init(BufferedImage image);

To get the edge map, call

  /**
   * Return edge map.
   
   @param fuzzyness
   *            edge fuzzyness (soft or exact)
   @param strength
   *            edge strength (soft - many edges, very string - few edges)
   @return 2-D array of values. The value at each pixel specifies the
   *         probability of an edge passing through this point
   */
  public IndexBitmapObject getValueMap2D(EdgeFuzzyness fuzzyness,
      EdgeStrength strength);

Here are a few screenshots (click on each one to see the full-size version). The original full-color image:

The same image in grayscale (which is created internally before running the edge detection itself):

The following four images show the results of applying Canny edge detection with the full thresholding step. From left to right, the the threshold values go from low to high - note that the number of edges decreases as the threshold values increase:

The last four images show the results of applying Canny edge detection the low thresholding step only - note that the number of edges is significantly higher than before, especially on low threshold value. From left to right, the the threshold values go from low to high - note that the number of edges decreases as the threshold values increase:

Note that it's always a tradeoff between the edge quality and the edge quantity, especially with the lower threshold values. Choose the edge softness and the edge fuzzyness settings according to the specific technique you're trying to simulate. For example, for traditional mosaic, it's better to use medium thresholds to highlight the major structural features without putting too many tiles in the resulting image (preserving the overall mosaic "feel").



Spring effects and widgets - now in Windows look and feel

Posted by kirillcool on March 31, 2007 at 10:11 PM | Permalink | Comments (10)

In the comments on the entry on spring effects under third-party LAFs, Chris has asked if it would be possible to make this functionality available under the platform's system look and feel. My first response mentioned one possible way to do this - download the sources for JDK, create a custom Ant build script to inject this functionality into core LAFs (such as Windows or Ocean), take the resulting jar and use the boot classpath switch to have JVM load this jar before the classes in rt.jar.

Now, this approach has a few disadvantages:

  • You inherit all the bugs in the specific com.sun.java.swing.plaf.windows package that you're taking. Any code changes to the core implementation will need to be incorporated into the widgetized binaries.
  • The size of the resulting jar file will be unnecessarily big, since it will contain the same functionality as the core classes + the injected behaviour.
  • Application startup scripts will have to be modified to point to the new jar (as boot classpath option).

One big advantage of this approach is that the existing application code (call to UIManager.setLookAndFeel) doesn't need to be changed, since the class name of the main LAF class remains the same.

Well, it so happens that the above approach is not the only way to tackle the request (and no, it's not an April Fools joke). The new laf-widget-windows subproject provides another way to inject widgets, transition layout and image ghosting effects into the core look and feels.

First, here are two screenshots of a sample application under a widgetized Windows look and feel, one under Windows Vista and another under Windows XP. Note the menu search widget, tab overview widget, password strength checker widget and lock widget on uneditable text components:

Here are two Flash movies showing the widgets and the transition layout in action (under Windows Vista and Windows XP):

Here are two Flash movies showing the ghost effects (rollover icon ghosting and button press ghosting) under Windows Vista and Windows XP:

Here is the code for the only class in this project:

package org.jvnet.lafwidget.windows;


public class WindowsLookAndFeel extends
    com.sun.java.swing.plaf.windows.WindowsLookAndFeel {
}

All the rest is taken care of by the custom Ant tasks. This way, all the disadvantages of the first approach are addressed - the code is not tied to a particular implementation of the core LAF, the binaries size is kept to the minimum, and you don't need to change the boot classpath. On the other hand, you now have to use the org.jvnet.lafwidget.windows.WindowsLookAndFeel class as the parameter to pass to UIManager.setLookAndFeel.

Feel free to download the binaries and leave comments.



Non photorealistic rendering in Java - introduction

Posted by kirillcool on March 25, 2007 at 12:27 AM | Permalink | Comments (6)

Non photorealistic rendering (or NPR for short) employs a variety of artistic techniques, such as stippling, watercoloring, stylizing, mosaicizing etc. to render digital images. Unlike photorealistic rendering which can use modeling of physical phenomena (lighting, shading, 3D modeling etc), NPR tries to mimic certain artistic styles, which are more difficult to quantify and express in mathematical domain. However, we can still employ a variety of techniques to facilitate implementation of a wide selection of NPR effects. As my proposal on this subject was rejected by this year's JavaOne committee (no worries, i still have a technical session with Alex and a BoF with Richard and David), i have decided to publish a series of entries on this subject.

The code is hosted at ixent.dev.java.net, and the subsequent entries in this series will provide much more information on each one of the project building blocks. Here is a short introduction (click on the thumbnails to view full screenshots).

The application has one main screen that allows selecting the original image and changing the default parameters:

Use the breadcrumb bar to select the original image:

After changing the various parameters that affect the image processing (more in the next entries), click Start button and the process starts (note that the UI is made "disabled" during this process using JXLayer which allows disabling some portions of UI and installing custom painting). One of the first steps is edge detection:

One of the next stages is the tesselation of the original image based on the automatically extracted structure information (edges, segments). Note how the tesselation polygons are smaller around the structure edges. In addition, note how the tesselation polygons scale up away from the edges, providing semi-random homogeneous coverage of the image area:

The final result is computed based on the color information of each one of the tesselation polygons (all mosaic cells falling into the specific polygon have the same color) and the structure edge orientation (mosaic cell orientation follows the orientation of the nearby edges):

See you in the next installments.



New to Swings

Posted by kirillcool on March 21, 2007 at 08:41 PM | Permalink | Comments (2)

What is it with people on Swing forums? Need help with Swings, help required in Swings, i am new to Swings... Searching for the "new to swings" on Google produces 14 results. Searching for the "new to delphis" produces zero. "New to cocoas" - zero. "New to MFCS" produces this, but apparently that's how it's spelled. Even "new to javas" produces this which is just a part of "new to javas cript". Sighs...



Spring effects on buttons - now at your nearest look and feel

Posted by kirillcool on March 15, 2007 at 12:07 AM | Permalink | Comments (8)

This is the third part in series about ghosting image (aka spring) effects on Swing buttons.

  • The first part introduced the "ghosting image" effects (aka "spring" in Romain presentations). When you rollover the mouse over a button, its icon has an outward decaying "ghost" image painted (starts from 50% opacity and decays linearly to zero).
  • The second part incorporated feedback from the readers, adding "spilling" the effects outside the button borders and adding the press animation.

Since then (last November) the implementation has been improved to provide the following:

  • The spilling effect is painted globally across the entire frame, including panels, toolbars, menubars, tabbed panes, desktop panes and title panes. It can also be easily extended to custom controls such as task pane container and status bar from SwingX.
  • The effects are available on JButtons and JToggleButton. They can also be easily extended to custom controls that have icons.

Last, but most certainly not the least, the implementation itself is no longer tied to Substance. It has been moved to the laf-widget project and has been successfully integrated with six other third-party look and feels. There are two ways to "inject" this functionality into the look and feel delegates (as promised in my presentation at Desktop Matters):

  • Java classes with main() methods that change existing binary UI delegates.
  • Ant tasks that change existing binary UI delegates.

The batch scripts in this CVS folder (look for augment-*.bat) show how an existing third-party LAF can be augmented with ghosting image effects. There are two separate classes, one injecting the functionality in icon-painting method in a specific UI delegate, and another injecting the spilling functionality in the update() method in a specific UI delegate.

The Ant tasks allow injecting this functionality at build time. Here is the relevant snippet from Substance build script:



   <taskdef name="icon-ghosting-augment" 
         classname="org.jvnet.lafwidget.ant.AugmentIconGhostingTask" 
         classpath="${substance.lib.dir}/laf-widget.jar;${substance.lib.dir}/asm-all-2.2.2.jar" />
   <taskdef name="container-ghosting-augment" 
         classname="org.jvnet.lafwidget.ant.AugmentContainerGhostingTask" 
         classpath="${substance.lib.dir}/laf-widget.jar;${substance.lib.dir}/asm-all-2.2.2.jar" />

      <!-- Icon ghosting augmentation -->
      <icon-ghosting-augment verbose="true">
         <classpathset dir="${substance.output.dir}" />
         <iconghosting className="org.jvnet.substance.SubstanceButtonUI" methodName="paintIcon" />
         <iconghosting className="org.jvnet.substance.SubstanceToggleButtonUI" methodName="paintIcon" />
      </icon-ghosting-augment>

      <!-- Container ghosting augmentation -->
      <container-ghosting-augment verbose="true">
         <classpathset dir="${substance.output.dir}" />
         <containerghosting className="org.jvnet.substance.SubstanceDesktopPaneUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstanceMenuBarUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstanceMenuUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstancePanelUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstanceScrollBarUI" toInjectAfterOriginal="true" />
         <containerghosting className="org.jvnet.substance.SubstanceToolBarUI" toInjectAfterOriginal="true" />
      </container-ghosting-augment>

And now for some demonstrations. The following short videos show icon ghosting (rollover) and press ghosting effects on the same application under different look and feels. Note that for demo purposes i use larger icons and high-contrast implementation (high initial values for the fade out).

Here is how it looks under the InfoNode:

Here is how it looks under the Liquid:

Here is how it looks under the Looks PlasticXP:

Here is how it looks under the Napkin:

Here is how it looks under the Pagosoft:

Here is how it looks under the Squareness:

This technique will be presented at this year JavaOne conference at the "Bringing Life to Swing Applications" technical session that i have the honor to present with Alex Potochkin. Stay tuned for more and don't hesitate to leave comments.



Spicing up your JTabbedPane - part VI

Posted by kirillcool on February 14, 2007 at 12:22 AM | Permalink | Comments (11)

This is the sixth part of the series that describes the additional capabilities that you can get on your tabbed panes.

  • The first part described close buttons and animation on modified tabs
  • The second part described vetoable close buttons and vertical tabs.
  • The third part described single-click close of multiple tabs and custom alignment of tab texts on left and right placement.
  • The fourth part described hover preview popup and tab overview dialog.
  • The fifth part described tab pager (enhanced since first described).

This entry describes the new feature available in the next version of Substance look-and-feel (code-named Japan) and any other third-party LAF using laf-widget layer.

The vast majority of code was written by Nigel Hughes and contributed to the laf-widget under Apache license. Nigel first introduced the carousel component back in December, and later in January followed up with carousel menu (inspired by Apple TV interface). I spent the last weekend integrating this functionality in the tab overview dialog that provided a grid overview up until now. The time was spent well on both sides, with Nigel graciously making numerous changes that i requested to both carousel and carousel menu (thanks for bearing with all my requests), and me enhancing the TabPreviewPainter class that defines the tabbed overview dialog functionality.

By default, the tab overview button will show the regular grid overview dialog. To show the new carousel functionality, override the public TabOverviewKind getOverviewKind(JTabbedPane tabPane) method of TabPreviewPainter or DefaultTabPreviewPainter and return either TabOverviewKind.ROUND_CAROUSEL or TabOverviewKind.MENU_CAROUSEL.

Here is an example of the TabOverviewKind.ROUND_CAROUSEL tab overview (the WebStart link is at the end):

Here is an example of the TabOverviewKind.MENU_CAROUSEL tab overview (the WebStart link is at the end):

In order to see this functionality in a WebStart demo, click the button below, wait for the application to load and:

  • Click the "General settings" task pane on the left hand side.
  • Select either "round carousel" or "menu carousel" in the "Overview kind" combo box (under "Miscellaneous" section).
  • Click the small button to the left of the tabs (the one with the magnifying glass

To view dynamically updating overview dialog (updating painting, automatic tracking of added and removed tabs) go to the "Tabbed Pane", configure its tab overview kind in the "Tabbed Pane" task pane and follow the instructions above.



Bringing life to your (j)sliders

Posted by kirillcool on February 11, 2007 at 08:26 PM | Permalink | Comments (16)

One of the more interesting suggestions on the entries about translucent scroll bars came from Mikael Grev: an interesting addition would be if the scroll bars would be very thin or in some other way very subtle and only when the mouse is close/over they would animate to their full size. While this hasn't been implemented yet on the scroll bars, this functionality is now available on the sliders in the latest development drop of the next version of Substance (code-named Japan).

First, here's a screenshot of how sliders look like under the latest release:

Now, here's a screenshot of how sliders look like in the latest development drop:

Question 3 of the project FAQ states that while the binary backwards compatibility is of topmost importance (in fact, it was broken only in one release), the visual compatibility is less strictly enforced. As a matter of fact, one of the main reasons for the slider overhaul was the amount of vertical space that the horizontal sliders take, and after seeing a video demonstration of Yahoo Messenger for Vista, it was time to make some changes. In fact, a horizontal slider with no ticks and no labels is now 18 pixels high instead of 24, a horizontal slider with ticks and no labels is 21 pixels high instead of 32 and a full blown slider with ticks and labels is 38 pixels high instead of 49.

Another, and more interesting addition comes in the form of slider thumb animation on mouse pointer proximity. This can be seen in both the demonstration of Yahoo Messenger and in the following short clips (click the play button). Here are the new sliders under the Business Black Steel skin:

Here are the new sliders under the Raven Graphite skin:

Note how the slider thumb grows when the mouse is directly over it or in its vicinity and shrinks back (the essence of this functionality is apparently lost on some). The slider ticks are less obtrusive (translucent near the end). The focus ring properly fades in on focus acquiring and fades out on focus lost. In addition, the first and the last ticks are not painted since they're pretty much redundant.

To see the new sliders in action, click on the image below and go to the "Sliders" tab.

dmsmall.jpg Last but not least, i will be presenting a small session at Desktop Matters conference which will take place on March 9th in San Jose. If you're interested in one long all-desktop day, you're welcome to register and participate.



Substance LAF 3.2 official release

Posted by kirillcool on February 05, 2007 at 12:15 AM | Permalink | Comments (2)

Substance LAF is pleased to announce the release of version 3.2 (code-named Iowa). The list of new features includes:

  • Two new dark skins, Challenger Deep and Emerald Dusk
  • New SubstanceDefaultLookAndFeel - can be set to restore the default Substance settins
  • Overlay effects on scroll bars
  • Customizable grip handles on scroll bars
  • Aligned menu opacity on rollovers / selection with tree/table/list
  • Slider respecting current shaper
  • Rollover effects on table editors
  • New version of Xoetrope color wheel panel
  • Customizable menu gutter fill kind
  • Support for removing the pin button from internal frame title pane
  • Support for image watermark from input stream

In addition, the following new features from release 2.1 of laf-widget project (code-named Camellia) are available:

Note that the support for image ghosting effects on buttons has been moved to laf-widget 2.1 release (bundled with the 3.2 release of Substance).

In addition, complete documentation for Substance API, Substance client properties and Laf-Widget client properties is available.

The Flamingo component collection project has also officially released version 1.1 (code-named Brianna).



Playing with Color

Posted by kirillcool on January 17, 2007 at 09:40 AM | Permalink | Comments (12)

Seeing that this subject has popped up twice over the last two days (here and here), i decided to share a little trick to make a Color object mutable.

In general, the Color class doesn't allow changing the existing object. However, since it's not final, we can use the Delegate pattern and direct all methods to a single "master" color that is computed dynamically. The master color computation can depend, for example, on rollover state (illustrated below) which will allow creating rollover effects without triggering the property change events (on the "foregroundColor" property).

Here is how it's done.

public class RolloverForeground extends JFrame {

  public RolloverForeground() {
    this.setLayout(new FlowLayout());

    final JButton button = new JButton("sample");
    button.setForeground(new