Swing

InformIT is hosting a free sample chapter of Filthy Rich Clients, the book Chet Haase and I recently published. InformIT offers the full chapter 8 about image processing with Java 2D. Chapter 8 belongs to Part II of the book, advanced graphics rendering.

Refer to filthyrichclients.org to download the source code of the examples.

Free Sample Chapter for Filthy Rich Clients

Filthy Rich Clients is available and several readers already received their copy. To make sure you can follow all of our examples easily, Chet and I just released the demos of the final chapters: Static Effects, Dynamic Effects and Animated Transitions.

These chapters’ demos are our favorites so make sure to check them out!

The official web site and the java.net project page now host a total of 82 demos, all available under the BSD license. We hope you will enjoy those demos as much as you will enjoy the book.

82 Swing and Java 2D Demos

By the way, the source code of the demos from chapters 14 and 15 of the book Filthy Rich Clients are available. These chapters cover the Timing Framework in depth.

Demos for Chapters 14 and 15

I just received my copy of Filthy Rich Clients, the book I wrote with Chet Haase. You will probably be happy to know that you will soon stop hearing about it on this blog :)

Filthy Rich Clients

The Book is Here!

Some applications, like Eclipse, show a progress bar in their splash screen during the startup phase. This is a useful way to show the user that the application is actually working in the background. It helps the user to wait for the end of the process without kicking. Without such a progress indicator, the application could appear to be frozen.

During this year’s Extreme GUI Makeover session we demonstrated a nice replacement for common progress indicator. Rather than using a progress bar, a percentage or even a status text, we chose to use colors instead.

Download the following video to see how our splash screen conveys the progress information.

Alternatively, you can take a look at the screenshot below. The splash screen first appear as a sepia image. As the application loads, the image gradually turns to a fully colored picture.

Extreme GUI Makeover

Implementing this effect is very simple with Java SE 6 and the Timing Framework to fake the loading process. The first state of the splash screen is shown by using a new command line flag which lets you pick any PNG file to use it as your application’s splash screen. This is really nice because this command supports the alpha channel of the PNG file format, thus letting you create splash screens with drop shadows and other translucency effects.

java -splash:./lib/splash-sepia.png [...]

The biggest advantage of this flag over the use of a Java window is that the splash screen shows up as soon as the JVM is started. The user will therefore see the splash screen during your application’s startup and during the JVM’s startup.

Even though the JVM is responsible for creating and drawing the splash screen, our application can get a handle on a Graphics2D object which lets us paint over the splash screen. In this example, we will fade the colored version of the splash screen over the original sepia image. By doing so, we will mimic the effect of coloring the sepia image.

SplashScreen splash = SplashScreen.getSplashScreen();
if (splash != null) {
    // Load the sepia and colored images
    colorSplashImage = null;
    try {
        colorSplashImage = GraphicsUtilities.loadCompatibleImage(
            getClass().getResource("/reality/resources/splash-color.png"));
        sepiaSplashImage = GraphicsUtilities.loadCompatibleImage(
            new File("./lib/splash-sepia.png").toURI().toURL());
    } catch (IOException e) {
    }

    // Emulates the progress
    Animator animator = PropertySetter.createAnimator(
        6000, this, "colorSplash", 1.0f);
    animator.addTarget(new TimingTargetAdapter() {
        @Override
        public void end() {
            show(mainPanel);
        }
    });
    animator.start();
}

This piece of code grabs the SplashScreen instance to make sure we have a splash screen. The null test is mandatory in case your application is started without the -splash flag. The code then proceeds with loading the sepia and colored images and finally starts an animation to simulate a lengthy startup process. In this example, we simulate a startup sequence of 6 seconds.

The actual work is performed in the method setColorSplash(), which would be the equivalent of a progress bar’s setProgress() method. The method stores the current progress value, grabs the splash screen’s graphics surface and paints the effect:

public float getColorSplash() {
    return colorSplash;
}

public void setColorSplash(float colorSplash) {
    this.colorSplash = colorSplash;

    SplashScreen splash = SplashScreen.getSplashScreen();
    Graphics2D g2 = splash.createGraphics();

    g2.setComposite(AlphaComposite.Clear);
    g2.fillRect(0, 0, splash.getSize().width, splash.getSize().height);

    g2.setPaintMode();
    g2.drawImage(sepiaSplashImage, 0, 0, null);

    g2.setComposite(AlphaComposite.SrcOver.derive(colorSplash));
    g2.drawImage(colorSplashImage, 0, 0, null);

    g2.dispose();
    splash.update();
}

You might be surprised by the first painting commands. The first action here is to clear the splash screen. On the contrary to Swing components, the splash screen is never updated automatically and everything you draw on the splash screen is persistent. Without the clear operation, our drawings would add up and the colorization would happen a lot faster than expected. The rest of the code is straightforward. We first draw the sepia image, then we set an alpha composite to draw a translucent copy of the colored image. Do not forget the call to update() to synchronize the splash screen with the changes you made on the graphics surface.

This is naturally only one example of what you can do with a splash screen to replace a dull progress bar. The translucency trick will work in many situations but you might want to consider SwingX’s blending modes. The BlendComposite class mimics all of Photoshop’s blending modes and lets you create beautiful lighting and coloring effects.

Progress Bars Are Boring (Extreme GUI Makeover)

I blogged a while ago about Artemis. This simple tool uses a blurry background to draw user’s attention onto a modal progress bar. Artemis is a good example of how you can use a blurry background. It emphasizes the importance of the modal dialog which doesn’t require any context.

You can watch a video of Artemis in action. Note that I did not take the time to polish the UI. Therefore, the blurry background does not appear progressively but instantly (and the indeterminate progress bar clearly needs some work.)

Artemis

The full source code of Artemis is part of chapter 16 of Filthy Rich Clients. It will be released at the same time as the book will be available in book stores.

Putting Blurry Background to Good Use

At JavaOne 2007, the Extreme GUI Makeover demo showed a semi-translucent dialog over a blurry background. This effect was explained in a previous entry on this blog. However, I received a few requests asking how the dialog itself was implemented.

This dialog is shown in the screenshot below. Not only is it translucent, but it also sports rounded corners and a subtle drop shadow. Implementing such a dialog is fairly easy and I will describe you what techniques you can use.

Extreme GUI Makeover

Before we delve into the code, remember that this “dialog” is in fact a simple JPanel (more specifically a JXPanel from SwingX) added to the frame’s glass pane. To draw the rounded corners and the translucent background we first need to make our component non-opaque:

public class DetailPanel extends JPanel {
    public DetailPanel() {
        setOpaque(false);
    }
}

The next step is simply to override the paintComponent() method:

@Override
protected void paintComponent(Graphics g) {
    int x = 34;
    int y = 34;
    int w = getWidth() - 68;
    int h = getHeight() - 68;
    int arc = 30;

    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    g2.setColor(new Color(0, 0, 0, 220));
    g2.fillRoundRect(x, y, w, h, arc, arc);

    g2.setStroke(new BasicStroke(3f));
    g2.setColor(Color.WHITE);
    g2.drawRoundRect(x, y, w, h, arc, arc); 

    g2.dispose();
}

This implementation fills a black, translucent rounded rectangle to paint the background. Then it proceeds with drawing a white, opaque rounded rectangle using the exact same dimension, location and arcs. The border effect is rendered by setting a thick stroke on the graphics surface, 3 pixels in this case. As you can see you can create good-looking custom components with just a few lines of code.

Rendering the drop shadow is a bit more complicated though. SwingX provides a DropShadowBorder that works in most situation but that fits only rectangular components. Because we are using a rounded rectangle component, we need another approach. Hopefully, SwingX contains a very handy class named ShadowRenderer. As its name suggests, it can be used to render shadows. Just pass an image and you get a shadow for it.

Shadow rendering is performed in the setBounds() methods, called whenever the component changes dimension and/or location. The idea is to create an image buffer in which we draw a rounded rectangle of the same dimension as the one we used at painting time. This image is then passed to the shadow renderer to create the shadow we want to paint behind the component:

@Override
public void setBounds(int x, int y, int width, int height) {
    super.setBounds(x, y, width, height);

    int w = getWidth() - 68;
    int h = getHeight() - 68;
    int arc = 30;
    int shadowSize = 20;

    shadow = GraphicsUtilities.createCompatibleTranslucentImage(w, h);
    Graphics2D g2 = shadow.createGraphics();
    g2.setColor(Color.WHITE);
    g2.fillRoundRect(0, 0, w, h, arc, arc);
    g2.dispose();

    ShadowRenderer renderer = new ShadowRenderer(shadowSize, 0.5f, Color.BLACK);
    shadow = renderer.createShadow(shadow);
}

Once again, very easy. Unfortunately, this technique does not work very well. Because our component uses a translucent background, we can see the shadow through. The result of the blending produces an almost opaque effect which defeats the purpose of having a semi-translucent dialog in the first place. This is why tools like Photoshop do not draw shadows behind the layers.

The solution is to get rid of the part of the shadow that lies within the area in which the component paints its background. This could be achieved at painting time but I chose to do it when generating the shadow. To the previous code snippet, just add the following:

g2 = shadow.createGraphics();
// The color does not matter, red is used for debugging
g2.setColor(Color.RED);
g2.setComposite(AlphaComposite.Clear);
g2.fillRoundRect(shadowSize, shadowSize, w, h, arc, arc);
g2.dispose();

When the “clear” alpha composite is set on the graphics surface, everything we draw erases the existing pixels. We thus cut a hole into our shadow. The final step is simply to paint the shadow in paintComponent(), just before the filling and drawing of the rounded rectangles occurs:

if (shadow != null) {
    int xOffset = (shadow.getWidth()  - w) / 2;
    int yOffset = (shadow.getHeight() - h) / 2;
    g2.drawImage(shadow, x - xOffset, y - yOffset, null);
}

This code is not the most efficient nor elegant way to achieve this effect but it is clear, easy to implement and fast enough. This technique can be used in a variety of situations too. For instance, you could add a drop shadow to an icon by generating the shadow, then “clearing” with the icon itself. Note that the “clearing” step is required only when you are or might be drawing a translucent element on top of the shadow.

Rounded Corners and Shadow for Dialogs (Extreme GUI Makeover)

JavaDesktop.org just published a new Swing Sighting. The application is called Palantir and sports a very clean, very modern-looking Swing user interface. They even emulated Office 2007 menu/toolbar. I really urge you to go take a look at the screenshots.

Palantir

Another Pretty Java Application

Shannon, Chris and I showed many cool effects during this year’s Extreme GUI Makeover session, at JavaOne 2007. Since we cannot release the source code yet, I will explain some of the effects in detail. I will start with the blurred background displayed when a modal dialog shows up.

Blurring a dialog’s or a menu’s background is often used in video games to attract user’s attention to the front most widgets. Using this effect allows you to keep the context without suffering from the visual clutter it might induce. Adobe Flex offers a similar effect when you bring up a modal dialog in a Flex application. To better understand this effect, you can take a look at one of these two videos:

You can also take a look at the screenshot below. Note that the screenshot does not show the fade in and fade out animations used to bring up and dismiss the dialog. The background gradually blurs while the dialog progressively becomes visible.

Extreme GUI Makeover

Writing this effect is surprisingly easy with the help of the Timing Framework and SwingX. The former is used to drive the animations while the latter offers support for alpha translucency and blur.

The actual “dialog” is made of two classes, DetailsView and DetailPanel. The first class, DetailsView is used as a glass pane and is responsible for managing the animations and blurring the background. The second class contains the actual dialog, the black rounded rectangle in the screenshot. While DetailPanel contains interesting pieces of code, we will not spend any time on it in this entry. Simply note, however, that DetailPanel extends the JXPane class from SwingX. This class offers a public property called alpha which can be used to change the translucency of the container and its children.

Here is what the DetailsView class looks like:

public class DetailsView extends JPanel {
    private DetailPanel detailPanel;
    private BufferedImage blurBuffer;
    private BufferedImage backBuffer;
    private float alpha = 0.0f;

    DetailsView(DetailPanel detailPanel) {
        setLayout(new GridBagLayout());

        this.detailPanel = detailPanel;
        this.detailPanel.setAlpha(0.0f);
        add(detailPanel, new GridBagConstraints());

        // Should also disable key events...
        addMouseListener(new MouseAdapter() { });
    }
}

You can notice that we use two image buffers. They are used to create the animation of a gradually blurring background. The basic idea is to capture the frame’s content into a buffer, blur this buffer and paint it in the glass pane, behind the “dialog.” Unfortunately, doing so would be impractical for an animation. Even though SwingX provides an efficient blur filter, it would be very difficult to render a smooth animation of that size with it. Instead, we keep the frame’s content into an original buffer and blur that buffer into another buffer. At drawing time, we first paint the frame’s content, then the blurred copy. By progressively changing the opacity of the blurred copy, we can simulate an increasing blur effect.

Our first step is therefore to create our buffers:

private void createBlur() {
    JRootPane root = SwingUtilities.getRootPane(this);
    blurBuffer = GraphicsUtilities.createCompatibleImage(
        getWidth(), getHeight());
    Graphics2D g2 = blurBuffer.createGraphics();
    root.paint(g2);
    g2.dispose();

    backBuffer = blurBuffer;

    blurBuffer = GraphicsUtilities.createThumbnailFast(
        blurBuffer, getWidth() / 2);
    blurBuffer = new GaussianBlurFilter(5).filter(blurBuffer, null);
}

This method relies on GraphicsUtilities and GaussianBlurFilter from SwingX to render a good-looking blur efficiently. Notice how the blurred buffer is downscaled before the filter is applied. This trick lets us reduce the blur’s radius, thus making it a lot faster. We just need to scale this image back to its original size at drawing time.

Drawing the back buffer and the blur buffer does not involve any complicated trick. We just set the bilinear rendering hint on the graphics context and rely on an alpha composite to perform the translucent drawing:

@Override
protected void paintComponent(Graphics g) {
    if (isVisible() && blurBuffer != null) {
        Graphics2D g2 = (Graphics2D) g.create();

        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2.drawImage(backBuffer, 0, 0, null);

        g2.setComposite(AlphaComposite.SrcOver.derive(alpha));
        g2.drawImage(blurBuffer, 0, 0, getWidth(), getHeight(), null);
        g2.dispose();
    }
}

The most interesting part of this piece of code is the use of the field called alpha, that you saw in the first code snippet. This field is a float which holds a value ranging from 0 (no blur, transparent dialog) to 1 (blurred background, opaque dialog.) The animated effect is generated by modifying this value over time. To do this, we will use the trusty Timing Framework:

public float getAlpha() {
    return alpha;
}

public void setAlpha(float alpha) {
    this.alpha = alpha;
    repaint();
}

public void fadeIn() {
    createBlur();

    setVisible(true);
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Animator animator = PropertySetter.createAnimator(
                400, detailPanel, "alpha", 1.0f);
            animator.setAcceleration(0.2f);
            animator.setDeceleration(0.3f);
            animator.addTarget(
                new PropertySetter(DetailsView.this, "alpha", 1.0f));
            animator.start();
        }
    });
}

For those of you who don’t know the Timing Framework, we are simply instructing it to animate two properties, both called “alpha,” on two different targets, this and the DetailPanel (remember, its alpha property is provided by its superclass JXPanel.) These properties are animated from their current value, 0.0f, to 1.0f over 400 milliseconds. The acceleration and deceleration are used to create a non-linear interpolation of the values over time and generate a more natural rendering.

That’s all there is to it! Dismissing the dialog is done with the fadeOut() method, whose code is almost exactly the same as fadeIn(). Instead of changing the properties from 0.0f to 1.0f, fadeOut() changes them from 1.0f to 0.0f. Remember to set DetailsView as the glass pane on your frame and your effect is ready to go.

Blurred Background for Dialogs (Extreme GUI Makeover 2007)

This week, Chet and I released the source code, demos and examples for chapters 12 and 13 of our upcoming book, Filthy Rich Clients. These chapters explain how to create simple animation with Java SE’s APIs and how to avoid some common rendering artifacts.

Next week, we will release demos for chapters 14 and 15 which present the Timing Framework, one of the most valuable tools to create animated effects for Swing and Java 2D.

Demos of the Week, It’s All About Animations

Groovy is a very appealing language that I really enjoy using from time to time. Unfortunately, as many other languages, Groovy lacks decent development environments. Even though this shortcoming is being addressed by the Eclipse and IntelliJ, the Groovy Console remains a valuable tool to quickly test an expression or a script.

The console works fine and achieve its purpose really well. However, its GUI is somewhat lacking and integrates badly with Mac OS X. The following screenshot shows what the ordinary Groovy Console looks like on Mac OS X:

Groovy Console on Mac OS X

Mac OS X users will easily spot the problems with this user interface. The menu bar belong to the window rather than to the screen and the shortcuts are wrong (using Ctrl instead of Cmd.) Also, not shown in the screenshot, the About and Quit menu items are not in the appropriate location. After a few tweaks, here is the new UI:

New Groovy Console on Mac OS X

There are three steps required to achieve this kind of integration with Mac OS X, two of them which you are probably already aware of. First, you need to tell Apple’s VM to move the menu bar to the top of screen, out of the application’s frame. At this stage, you also need to give your application its real name, otherwise Mac OS X will use the main class’ fully qualified name (in this case, groovy.ui.Console.) The Groovy code to achieve this is the following:

System.setProperty("apple.laf.useScreenMenuBar", "true")
System.setProperty("com.apple.mrj.application.apple.menu.about.name", "GroovyConsole")
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())

Make sure to set the properties before you initialize any frame and you will get the desired result. The second part of our “Mac OS Xification” is to use the appropriate shortcut keys in the menus. The java.awt.Toolkit class offers the getMenuShortcutKeyMask() method which returns the system’s default shortcut modifier (Ctrl on Windows and Linux, Cmd on Mac OS X.) Again, using this in your application is quite simple:

def createShortcutWithModifier = { key, modifier -> KeyStroke.getKeyStroke(key,
    Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | modifier) }
def createShortcut = { key -> createShortcutWithModifier(key, 0) }

// Uses Cmd-Shift-N/Ctrl+Shift+N
def newWindowAction = action(
    name:'New Window', closure: this.&fileNewWindow, mnemonic: 'W',
    accelerator: createShortcutWithModifier(KeyEvent.VK_N, KeyEvent.SHIFT_DOWN_MASK)
)

// Uses Cmd-O/Ctrl+O
def openAction = action(
    name:'Open', closure: this.&fileOpen, mnemonic: 'O',
    accelerator: createShortcut(KeyEvent.VK_O)
)

In this sample code, we just defined Swing actions with correct menu shortcuts. Creating a menu bar with those actions is easy with Groovy’s SwingBuilder. Building the menus is also the opportunity for us to introduce the last trick regarding Mac OS X integration: handling the About and Quit menu items correctly.

def isMac = { System.getProperty("mrj.version") != null }

menuBar {
    menu(text:'File', mnemonic: 'F') {
        menuItem() { action(newFileAction) }
        menuItem() { action(newWindowAction) }
        menuItem() { action(openAction) }
        separator()
        menuItem() { action(saveAction) }
        if (!isMac()) {
            separator()
            menuItem() { action(exitAction) }
        }
    }
    // More menus...
}

This piece of code does not add the exit menu item when the application is running on Mac OS X. Every Mac OS X application shows this menu item in the system controlled menu named after the application itself. This menu appears in bold on the second screenshot. The main problem is to figure out to hook our code to this menu. In my modified version of the Groovy console, here is how I did it:

if (isMac()) {
    ConsoleMacOsSupport.handleMacOs(this.&exit, this.&showAbout)
}

The isMac() could be avoided if ConsoleMacOsSupport was cleverer, but I decided to go with a simple yet effective implementation. As you can see, this class exposes a static method to which you can pass two method references. The methods bound that way will be invoked by the system when the user clicks either the About or Quit menu item in the application’s menu. The support class is also written in Groovy:

package groovy.ui

import com.apple.mrj.*

class ConsoleMacOsSupport implements MRJQuitHandler, MRJAboutHandler {
    static initialized = false
	
    def quitHandler
    def aboutHandler

    public void handleAbout() {
        aboutHandler()
    }

    public void handleQuit() {
        quitHandler()
    }

    public static void handleMacOs(quit, about) {
        if (!initialized) {
            initialized = true
            def handler = new ConsoleMacOsSupport(quitHandler:quit, aboutHandler:about)
            MRJApplicationUtils.registerAboutHandler(handler)
            MRJApplicationUtils.registerQuitHandler(handler)
        }
    }
}

ConsoleMacOsSupport simply delegates two Apple VM’s specific handlers to our Groovy methods. Since Groovy won’t even bother with this class at runtime if it’s not required, it is safe to keep it in the Windows and Linux distribution. This kind of work would usually be achieved through reflection in Java to avoid compile-time headaches.

Groovy makes the use of those handles even sweeter thanks to optional method parameters. For instance, Mac OS X’s quit handler does not expect any argument when invoked. However, we would like to bind the same method to a regular JMenuItem when the application is executed on Linux or Windows. In this case we are actually writing an ActionListener, and a parameter of type EventObject is therefore expected. Groovy is here to make it simple:

// The action's closure (action listener) is bound to the exit(EventObject) method
def exitAction = action(
    name:'Quit', closure: this.&exit, mnemonic: 'Q',
    accelerator: createShortcut(KeyEvent.VK_Q)
)

// The MRJQuitHandler is bound to the exit() method
ConsoleMacOsSupport.handleMacOs(this.&exit, this.&showAbout)

// Optional evt argument
void exit(EventObject evt = null) {
    // Cleanup, etc.
}

Even though I did not used this feature in the Groovy Console, you can also install a handler to hook into Mac OS X’s Preferences menu items. If your application offers some sort of options panel or configuration dialog, make sure to bind it to this menu item because that’s where users expect to find this feature. Last but not least, all those examples work also in pure Java and should not required much work to transpose.

Improving Groovy Console’s GUI

The source code, demos and examples for the chapter 11 of Filthy Rich Clients are available online. This chapter presents the repaint manager.

Chapter 11 presents two demos, TranslucentPanel and ReflectionPanel The first one is an exercise for the reader showing why and when the user of a RepaintManager is necessary. The second one presents a component that can render real-time reflections of its children. The demo requires QuickTime for Java to add a reflection effect to a QuickTime movie streamed from the web. When QuickTime is not available, the demo reverts to regular Swing components.

Update: The final PDF of the book is available for purchase online \o/

Both screenshots below show what the demo looks like. As you can see, the reflection panel can be used with any component you fancy. All you have to do is add() your component inside the panel and you’re done.

Real-time reflection on a movie

Real-time reflection on Swing components

Repaint Manager Demos (Chapter 11)

The source code, demos and examples for the chapter 10 of Filthy Rich Clients are available online. This chapter presents layered panes.

The next batch of demos, focusing on Repaint Manager, will contain my favorite demo, a real-time reflection applied on a QuickTime movie.

Demos for Layered Panes

Joshua Marinacci, whom I worked with when I was at Sun, is in the Bay area this week and we had dinner together tonight. He told me more about Flying Saucer, a project he’s been working on for a few years now.

Flying Saucer is an XHTML/CSS renderer written in pure Java that can be easily embedded in Swing applications. The latest version, R7, is quite impressive. The support for XHTML and CSS 2.1 is great and the rendering very fast. I was particularly surprised by the quality of the rendering of filthyrichclients.org, which caused many troubles to IE, Firefox and Safari:

Filthy Rich Clients in Flying Saucer

Flying Saucer can do much more, like PDF and SVG rendering. While it would be foolish to write a full-fledged web browser upon this library, this project is extremely interesting and useful for regular desktop applications. Writing help screens or even complicated layouts becomes so much easier with Flying Saucer. The ability to embed any Swing component within a web page leads to countless wonderful user interfaces.

XHTML/CSS Rendering In Swing

Our editor told us a couple of days ago that our book has been sent to the printers. Printing should be over in about a month so you can expect the book to hit the shelves early/mid-August.

I’ll post more demos on the book’s web site on Monday :)

Book Sent To Print

The source code, demos and examples for the chapters 8 and 9 of Filthy Rich Clients are available online. These chapter present image processing and glass panes.

Demos for Chapter 8 and 9 available

The source code, demos and examples for the 7th chapter of Filthy Rich Clients are available online. This chapter presents Java 2D gradients, including the new gradients included in Java SE 6. Some performance tricks are also covered.

Note: FTP fixed, you can download the zip files.

Update: The web site has now been tested, fixed and tested again with Internet Explorer 6. You should now be able to view the web site in good conditions.

Demos for Chapter on Gradients Available

Chet just uploaded www.filthyrichclients.org, the web site I designed for our upcoming book, Filthy Rich Clients.

Filthy Rich Clients Web Site

We will try to make the demos and their source code available on this web site as zip archives. For the time being, the web site offers a link to the project page where you can find the CVS repository. This web site is still very much a work in progress and has been tested only with a few web browsers so please forgive me would you encounter any problem.

Update: The web site has now been tested, fixed and tested again with Internet Explorer 6. You should now be able to view the web site in good conditions.

New Web Site

The JavaOne 2007 website now offers the slides and the audio track of the Filthy Rich Clients presentation that Chet and I gave this year in San Francisco.

Slides and Audio Track for Filthy Rich Clients Available

The source code for the demos of chapters 5 (Performance) and 6 (Composites) from our book is available in the CVS repository.

Demos for Chapters on Performance and Composites

Developpez.com recently released a series of videos they captured during the Sun Tech Day 2007 in Paris. Among these videos, you will find a one hour session about Extreme GUI Makeover 2006 and yet another demo of Aerith. Both sessions are in French.

Extreme GUI Makeover Session Video

I just uploaded the source code for the demos of the fourth chapter of our book. The source code of the demos are available in the CVS repository. Chapter 4 focuses on images and contains explanations on how to resize images efficiently.

Source Code and Demos for Chapter 4 (Images)

I just uploaded the source code for the demos of the third chapter of our book. The demos are currently available only on the CVS repository. We’ll try to offer zip archives by the time the book is published. In the meantime, you’ll have to deal with CVS, which will help you get new demos as we publish them.

Demos for Chapter 3 Available

Chet and I just started uploading the source code of the demos shown in our book. The source code is available at filthyrichclients.dev.java.net. We will release the source code incrementally until the printed version of the book comes out early August. Right now, you can download the demos of Chapter 2, Swing Rendering Fundamentals. Unless specified otherwise, all the demos are released under the BSD license.

If you were at JavaOne and attended our various Filthy Rich Clients sessions, then you’ll want to look at those demos too.

Demos for Filthy Rich Clients (Book + Talk)