The Source for Java Technology Collaboration
User: Password:



Kirill Grouchnikov's Blog

February 2008 Archives


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



Evolving the language

Posted by kirillcool on February 06, 2008 at 10:34 AM | Permalink | Comments (21)

I guess i wasn't very focused in yesterday's entry, paying too much attention to the details of the specific puzzle and not emphasizing my main point (or as Chris defined it the "money quote"). I'll try to rectify it here, bringing together my thoughts on the subject of evolving Java as a language.

First, let's start with the code from Neal's entry. Here is the relevant part:


    static <T,U> List<U> map(List<T> list, 
		{T=>U} transform) {
        List<U> result = new ArrayList<U>(list.size());
        for (T t : list) {
            result.add(transform.invoke(t));
        }
        return result;
    }

    public static void main(String[] args) {
        List<Color> colors = map(Arrays.asList(
		Flavor.values()), { Flavor f => f.color });
        System.out.println(colors.equals(Arrays.asList(Color.values())));
    }

Putting aside the puzzle punchline, here is how i would do the same without closures:


public class Puzzler<T, U> {

   interface Transformer<T, U> {
      U transform(T t);
   }

   List<U> transform(List<T> list, 
          Transformer<T, U> transformer) {
      List<U> result = new ArrayList<U>(list.size());
      for (T t : list) {
         result.add(transformer.transform(t));
      }
      return result;
   }

   public static void main(String[] args) {
      List<Colour> colors = new Puzzler<Flavor, Colour>().transform(Arrays
            .asList(Flavor.values()), new Transformer<Flavor, Colour>() {
         public Colour transform(Flavor f) {
            return f.color;
         }
      });
      System.out.println(colors.equals(Arrays.asList(Colour.values())));
   }
}

And now comes the million dollar question - which one is better? It's a simple question that has two straightforward answers. However, the real answer is "it depends". And based on the subjective background of each one of us, we would go for either the first version or the second version. What does it depend on? Well, quite a few things.

There was an illuminating exchange of opinions in Scala blogosphere about a month ago, ignited by Doug Pardee's post, which lead Reg Braithwaite to quote Jef Raskin's views on the definition of intuitive:

It is clear that a user interface feature is "intuitive" insofar as it resembles or is identical to something the user has already learned. In short, "intuitive" in this context is an almost exact synonym of "familiar."

Let's get back to our two code samples, and to the question which one is better. In my highly subjective opinion, the second one is better, because:

  • it is more readable
  • it is more maintainable
  • it is more verbose

Allow me to address each one of these three points. The second sample is more readable because this is how i'm accustomed to program this sort of requirement. This is what the current language structures allow me to do, and i don't find it too much of a hassle. The code is more maintainable because of the limited variety of currently available options. It ascertains that i and other people who will have to maintain this code must have seen this approach a few times in the existing code base. Getting back to the Jef Raskin quote, it feels more intuitive since it is familiar. Not necessarily optimal, but familiar nonetheless.

The last point on verbosity might be a little controversial, but i'll stand by my words. I've programmed in Ada for almost five years (professionally) and i've never seen it as an over-verbose language. Sure, it might take me an extra 20 seconds to read through the definition of that interface and its invocation, but the extra verbosity makes sure that the code guides me (as its maintainer) along its intended path.

Why would one choose the first example? There are many reasons, all of them undoubtedly valid in the subjective eye of the relevant parties. Some would enjoy the perceived expressiveness (cramming more logic in less characters), some would prefer the abstraction of a method body as first-class language citizen, some would want to know that their language is on par with the hot kid-du-jour that gets all the blogosphere love, some would view it as a refreshing exercise to expand their mind, and some would see the commercial potential that lies in books, consulting and conferences (absolutely no offense meant).

One nagging question remains unanswered - who is the intended target of the new language features? Are the creative minds behind different closures proposals at work just because they are creative, or is there an overwhelming evidence that Java programs (and programmers to a lesser extent) suffer without this language feature. Couple that with the absolute refusal to remove existing language features (like, say, poorly-implemented generics), and you get the following from Bruce Eckel:

But we need to become especially conservative when considering major, fundamental language features like closures which, while they can be very appealing in theory, may have a cost that is too great in practice when they are forced into a language that values backward compatibility over the clarity of its abstractions.

There are real-life scenarios addressed by closures. Anonymous listeners, unnecessary complex try-catch-finally blocks on closing streams and connections, blocks guarded by semaphores, you name it. But if the language is not going to remove (refuse to compile) the existing ways of addressing these scenarios, adding yet another way to do what millions (yes, millions that do not read or write blogs) Java programmers already know how to do is very harmful. Harmful to the code readability (at least in the first few years with the very slow adoption rate for the server-side JDK upgrades) and harmful to the code maintainability.

In my opinion, the language is only a tool. At the end of the day, we still have real people addressing real problems. The technical merits of new language proposals need to be weighed carefully against the potential negative disruption that they bring into the everyday cycle of software development. The puzzlers are only a tip of the iceberg. When i need to maintain and extend existing code, i already have a hard enough time to understand the business logic in it. If you're not going to remove the existing ways to address the limitations imposed by the language, don't add yet another way. It's not going to help me. Not in the everyday world.



And so it begins - the first closures puzzler

Posted by kirillcool on February 05, 2008 at 10:20 AM | Permalink | Comments (41)

Neal Gafter has posted the first closures puzzler. I guess the second edition of Java Puzzlers is in works, and closures will be a hefty addition to the book. If anything, this makes me really sad.

I was very excited to lay my hands on the first edition, but after reading through a few chapters, i skimmed the table of contents, glanced at the visual illusions and never came back to it. If i had to sum this book in one sentence, it would be "great optical illusions and irrelevant content". I know, this is a harsh statement, and i have nothing but respect to both authors (in fact, i consider "Effective Java" to be the book that i would take with me to a deserted island on a condition that it has WiFi access).

I've been using Java for the last 8 years, most of it exclusively (amounting to about 10-12 hours a day, including the work and the side projects). I've written my share of new code, and i most certainly have seen my share of old code that i had to maintain, fix and extend. But never once have i encountered anything even remotely connected to any Java puzzler presented in the book and at the conferences.

Bit-level shifts, integer overflows, overloaded methods, reflection, generics - you name it. I've looked at the examples, i've tried to match them to the real code that i see during the day, and i have found nothing. Of course, i am looking at the tiniest sliver of Java code that exists in the enterprise sector, but somehow i get an impression that i'm not alone. I would even go as far as to say that a feature implemented in a way that results in at least one puzzler is not a feature worth having in the language.

Which brings me to the quote of the day. It comes from an announcement on the end-of-life for Ruby.NET:

As a researcher, my prime interest is not in developing products, but in developing innovative new ideas and having an impact by having those ideas used in the real world.

The generics were added to the language in a very incomplete manner, mainly due to the restrictions on binary compatibility. If we let the researchers in us (even if they are the best researchers) to do the same with closures, i'll pass.



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:





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