The Source for Java Technology Collaboration
User: Password:



Kirill Grouchnikov's Blog

March 2007 Archives


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...



Genuitec, Hibernate and playing nice with open source

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

It all started on The Server Side where Gavin King accused Genuitec of "skirting waaay to close to an LGPL violation over bundled modifications to Hibernate Tools". Genuitec CEO hasn't addressed this issue, instead choosing to focus on other issues (which sound plausible, but are not relevant to the alleged license violation). Gavin replied by bringing the focus back to the LGPL issue, stating that "Genuitec have decided not to comply with [LGPL] restriction". The ball went back to Genuitec's court and the response is a little surprising, to say the least:

Given their history, I cannot help but fault Genuitec for assuming that providing our source code changes to the Hibernate team would motivate them to accept the enhancements and thereby make the changes public. For that poor assumption, shame on us. We provided the source to all our modification, in good faith, directly to them when they were made. However, since they chose to discard our enhancements, our changes are technically not available to others. But insinuating that we don't comply with their license, or haven't attempted to comply by providing the modified source to them, is extremely disingenuous.

Here is what i read in plain English:

  • Genuitec indeed took LGPL code and modified it.
  • Genuitec then contacted Hibernate dev team and sent them the modified code.
  • Hibernate dev team decided to not accept this code.
  • Genuitec proceeded putting this code into their own offering, without releasing the modified code as stipulated by the terms of LGPL

Now, the first three are regular business practice (doesn't matter if you're an open-source or a commercial vendor). Genuitec's business is to provide one-stop-shop for popular technologies. Obviously, Hibernate is one of the leaders in its space, so it's a good candidate for inclusion in MyEclipse offering. Genuitec obviously tries to minimize its overhead by introducing some kind of generic layer. Having made some changes to Hibernate code, they contacted Hibernate team and offered the code back. Hibernate doesn't owe Genuitec much (all those tens of thousands of calls and downloads served both sides, making MyEclipse one of the leading products in its field, so Genuitec shouldn't use these numbers to picture themselves martyrs). For whatever reasons, Hibernate team has decided to reject the code. It has all the right in the world to do so, there's nothing in the license that requires the original codebase to assimilate any outside change.

At this point, Genuitec had the following options:

  • Drop the changes they made to Hibernate codebase.
  • Change their own code to LGPL and release all of it.
  • Refactor the specific changes to a separate module, change the license of that module to LGPL and release the source to the general public as soon as the binaries were made available.

As far as i can tell, none of this happened up until today. Both parties agree that it has taken between 12 to 18 months, Genuitec acknowledges that the code was sent privately to the original developers (and not shipped with MyEclipse binaries / made available on the public website), and Hibernate even alleges that even the module that has now been released under LGPL doesn't constitute a separate body of work (but that's not for me to say).

Somehow, Genuitec tries to shift the blame on to Hibernate. So, you've sent the code and it's been rejected. It's not enough, not according to LGPL. The minute the binaries were available to MyEclipse customers (doesn't matter if they are paying or not), the code should have been made publicly available (at least circa August 2006 when MyEclipse 5.0.1 was released). You can spin it all you want, but for quite some time, the licensing terms have been knowingly violated.

I'm not sure how David and Goliath story fits here. Who's David? Who's Goliath? Wasn't David this witty cunning guy who employed a kind of shady apparatus to beat the other guy (who, on the other hand, would have tried to use his physical traits to his advantage)? But i digress.

A little disclaimer. I have nothing connecting me to any one of these two parties. I've never used Hibernate (ducks), we have an in-house tool to do that, and i've written my share of ODBC / JDBC. I've never used MyEclipse (ducks) as well. I'm also not a free software zealot, in fact almost all of my java.net projects are BSD (Substance module for NetBeans is under CDDL since it was developped on top of the NetBeans code). But i do understand the reasoning behind moving to GPL in this case.

Last thing - it may be only temporary, but at the present time, the download page is not directly accessible from the main MyEclipse page (which also doesn't seem to have a search link, but maybe i'm missing something). In addition, searching for both "Hibernate" and "Open Source" / "Open Source Resources" doesn't seem to produce a link to the above page.



When backward is really forward

Posted by kirillcool on March 19, 2007 at 06:17 PM | Permalink | Comments (8)

So, i'm reading a book and in one of the first chapters the authors try to put some reasoning behind an awkward API:

This process means that the last transformation command called in your program is actually the first one applied [...]. Thus, one way of looking at it is to say that you have to specify the matrices in the reverse order. Like many other things, however, once you've gotten used to thinking about this correctly, backward will seem like forward.

Here, instead of acknowledging that the API implementation actually dictates the API usage, the authors try to blame the API users for being too dumb to grasp its beauty. It's not API, stupid, it's you not thinking about this correctly :)



Java on the desktop - trail behind or lead forward?

Posted by kirillcool on March 17, 2007 at 03:29 PM | Permalink | Comments (19)

Subpixel rendering has been around since 1988. Microsoft stepped on the scene circa 1998, applying for the patent on ClearType in 1999 and getting it in 2001. This technology has been integrated in Windows XP when LCD displays (both desktop and laptop) have been far outnumbered by CRT displays. However, when the time came, XP was ready. What about Java? The first implementation was available only in June 2005, with the official release a few months ago (good 8 years after it has been introduced by Microsoft).

What's the next big thing in desktop typography and general layout? High resolution displays, which also goes by the acronym DPI (dots per inch). Believe it or not, but the display makers don't stand still. While the 96 DPI holds the market majority now (like CRT monitors did in late 90s), the 120 DPI is just around the mass market corner. Is Swing ready? Unfortunately, the answer is "mostly no".

At Desktop Matters, Chet has held a mini-survey on possible additions to Swing in the next Java version. There were about 50 people in the room, and about 40 topics to vote on (one could vote on each one of them). If i remember correctly, the support for high-DPI displays raised about 10 hands, and when OS X was removed from the question, there were only 2 hands left (myself included). Even more interesting was Chet's phrasing of the question - it went something like "In a hundred years, when everybody has 9000 DPI monitors, how important is it for Java to support this?" Well, it won't be in a hundred years, it's already here and will only get bigger, and without immediate action Java once again will be left behind (providing it in another eight years circa Java SE 10).

Karsten has pioneered the support for high-DPI desktop settings in the Looks look and feel last year. He provides a layer that queries the desktop settings and tries to match the font family and the font size so that a Swing application running under this LAF doesn't make the user squint (if the texts are too small) or grunt (if the texts use inconsistent font). This is not all - as he mentions on the project dev mailing list, you have to scale everything else, including borders, separators, insets, margins etc.

In the next version of Substance i have decided to reuse Karsten's code (thanks for choosing a liberal BSD license :) and to take it one step forward - scale the entire UI. Currently, Looks doesn't scale the other UI elements, such as checkboxes, radio buttons, scroll arrows etc (see screenshots below). This may result in inconsistent user experience, especially for DPI settings higher than 120 (such as 144 or even 192). Here is the complete list of UI elements that is scaled with the DPI in the next Substance release (release candidate scheduled on April 2nd with the release scheduled on April 16th):

  • Check marks of check boxes and radio buttons (regular and as menu items), dimension and stroke width
  • Arrow icons of combo boxes, scroll bars, split pane dividers, submenus, tabbed panes (dimension and stroke width)
  • Title pane icons (for decorated mode) of frames, dialogs, internal frames and desktop icons + proper centering of the title pane buttons in Y direction
  • Scroll bar width
  • Slider icon and slider track size
  • Tab close buttons (dimension and stroke width)
  • Spinner button width
  • Password field mark size (diameter and gap)
  • Progress bar width / height
  • Double arrow icon stroke size
  • Minimum width and height of buttons with text
  • Insets of combo boxes, text field and spinners
  • Stroke width of focus ring

Now for the screenshots. Here is a screenshot of an internal frame under 96 DPI (normal settings):

Here is the same internal frame under 120 DPI (125% normal size). Note how all the UI elements (fonts, scroll icons, title pane icons, button size, check marks and radio buttons, combobox insets) scale:

Here is the same internal frame under 144 DPI (150% normal size):

For comparison, here are the screenshots of the same internal frame under Looks Plastic XP. Under 96 DPI:

Here is the same internal frame under 120 DPI. Note that the scroll bar remains with the same width, the title pane buttons (inherited from Metal) remain the same size and uncentered and the combobox button doesn't retain its proportions (and the arrow icon itself has the same size):

Here is the same internal frame under 144 DPI (with the same visual inconsistencies):

What about other core and third party look and feels? As far as i know, the other third-party look and feels do not respect the DPI settings (and i'd be very happy to learn otherwise). The default (for now) Metal / Ocean doesn't scale at all, but the Windows look and feel shows some promise. How does it do so? Well, since it uses the native APIs to paint the controls, it also respects the dimensions computed by these APIs. In most cases (see the table below), Windows look and feel does indeed match the native dimensions of the controls and UI elements. Here is the same internal frame under Windows LAF in 96 DPI:

Here is the same internal frame under 120 DPI. Pretty much everything scaled, including fonts, checkbox and radio button marks, scroll bar, tabs and combo:

Here is the same internal frame under 144 DPI. Now, while fonts, scroll bar and tabs scaled, the checkbox / radio button icons and arrow icons on scroll bar / combobox remain the same size:

The reason for the later is simple - the native implementation is still not perfect. Here is the table to illustrate this (all the screenshots and the Excel 2007 spreadsheet are available right here):

The first three columns show size of different UI elements under Vista in 96, 120 and 144 DPI. The last two columns show size of the same UI elements under Windows look and feel in Java 6.0. As you can see, while the native elements scale well from 96 to 120 (with the exception of combobox arrow size), the transition from 120 to 144 is not so smooth. The checkbox / radio button checkmarks have the same size, and the arrows on scrollbars, spinners and comboboxes are the same.

What about Windows look and feel? While it picks most of the native settings, it still has some issues. Look at the spinners, tab heights, progress bar height (not picked at all), slider thumb, menu arrow and combobox. There's still work to do here.

Which brings me to my main point. The current implementation of high DPI support in Vista (and in XP) is not perfect, especially for 144+ range. In addition, changing DPI setting requires OS restart (and once Explorer crashed under 144 DPI). Java must seize this opportunity now and provide the best implementation for the mass-market. Java shouldn't wait until the market demands this support (especially with releases coming out every 18 months and with the relatively slow adoption rate of the latest releases in production environments on the large scale). Be ahead of the curve, don't lag behind.



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.



Desktop Matters - the links and more

Posted by kirillcool on March 09, 2007 at 11:15 PM | Permalink | Comments (7)

The first Desktop Matters is officially over (although there still may be a few people still talking in the conference room as we speak...) First of all, many thanks and congratulations to Ben and Dion for organizing this (and making it take place 10 minutes away from where i live).

In addition, it was great finally seeing all the real people behind the java.net (and jroller) blogs (sometimes you get a weird feeling that perhaps some of them are not real, but maybe it's just me :) Thanks for everybody who came to chat, inquire about Substance and other projects and for listening to my presentation. The slides are available in the following formats:

  • (Recommended) PowerPoint 2007 - the original presentation with the animations and code comments.
  • PDF - the same presentation, but without animations and code comments.

Note that i didn't have enough time for all the slides, so even you listened to me live, there are additional 8-9 slides that go deeper into the implementation of the ghosting effects outside the button borders. And now that it's over, finally some time for a little entertainment.



The things that we take for granted

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

Last weekend i went and bought a new laptop (actually, this is my first laptop). So, as i plugged it in and connected to the net, Vista started downloading updates and installing them. And then i started thinking - what happens if one of these updates will simply crash the OS on the next boot?

The implicit assumption of any update to the operating system is that it at least boots (if everything is OK with the hardware). For the past 8 years that i've been using Windows (from 3.11 to NT, 98, XP, 2003 and Vista) i've seen the blue screen of death only once, and that was because of bad RAM sticks (after our IT department replaced them, it all went back to normal). So you kind of take it for granted that when you switch the power on, the OS will come alive and greet you with the full functioning desktop at your disposal. But just think about myriads of small things that can go wrong, including the boot, startup processes, login, drivers, mouse and keyboard, anti-virus, firewall etc. The operating system simply can't fail.

I don't know what's the testing process inside Microsoft for releasing the automated updates, but the end result is that it simply works. They are downloaded, installed, and on some occasions (which are far less frequent than they used to be) OS reboots. And then the magic happens - it all comes back to life. No exception stack traces to copy and send to the developer. No magic key sequence to bypass a faulted module. No praying that it won't crash. It just works.

And this is a technical feat worthy of praise. Such a gigantic multi-layered beast and zero tolerance for startup errors. Makes me think twice about asking people to send stack traces when something goes wrong...





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds