Blurred Background for Dialogs (Extreme GUI Makeover 2007)

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.

54 Responses to “Blurred Background for Dialogs (Extreme GUI Makeover 2007)”

  1. Antonis says:

    Exquisite, utterly beautiful and captivating !
    I can’t take my eyes from this screenshot !!!
    The attention to detail and the way all effects gently blend together is astonishing !

  2. Janitrix says:

    Really nice. Good work and thank you for sharing ;)

  3. lecuret cedric says:

    excellent article ! thanks a lot for these demos

  4. anoweb says:

    how did you make that nice rounded dialog??

  5. gerryg says:

    I like the look, but use this effect with caution!! I can’t tell you how many zillions of times I’ve needed to move a dialog box out of the way to see something underneath I needed in order to respond to a dialog input. But, for example, a netflix interface with movie description pop-ups, this would work great. Again, USE CAUTION and think about what you’re wanting the user to do in the dialog before you hide the data needed to make a decision.

  6. DK says:

    Just want to echo what gerryg said: this is a cool effect, but usability tests on the Business Intelligence product that I used to work on showed that users often want to see context, so they will often move the “detail” dialog to one side of the screen so they can also see the “bigger picture” at the same time. The real estate example shown here is a perfect example of a case where you probably would NOT want to use this cool effect in a real business app.

  7. Romain Guy says:

    DK, gerryg: That is up to you guys. I’m here to show you how you can achieve the effect. Use it however you want.

  8. anoweb says:

    how did you make that nice rounded dialog??

    :)

  9. Love the blurring effect. As for gerryg’s concern, instead of blurring I think gray-scaling the background might make an interesting effect..

  10. Bill says:

    Just curious, what was the source you used for the listing data?

    –Bill

  11. Romain Guy says:

    It’s just a bunch of hard-coded String arrays.

  12. Romain Guy says:

    anoweb: I will blog about this soon.

  13. gerryg says:

    Romain, I agree with you, but having a lot of experience using computer programs over the years, I know that introducing a great new effect will cause a number of copycats to go hog-wild and (mis)use the effect in lots of inappropriate ways. I’ve been beaten up by cool effects that get applied in a way that makes a terrible UI. This effect (which is definitely cool!) is potentially in that category. It’s important to suggest good usage patterns or describe antipatterns when introducing a new tool for the toolbox (if warranted – e.g. rounded corners wouldn’t trigger this), even if it’s only a couple sentences. Thanks again for your continued innovation, though — you do great work!

  14. Romain Guy says:

    I totally agree gerryg. Unfortunately, in my experience, that kind of precaution has always proven to be useless. I’ll try to focus more on this next time though. Thanks!

  15. czar says:

    This looks awsome!!! when will the full source be available for this… looking forward to it… cheers!

  16. eugene says:

    Hi Romain,

    I did a similar task a few months ago using JXLayer (but without the animation). I particularly like the trick of shrinking the blur image to increase performance.

    Do you think its possible to bring up another dialog on top of the previous one and have the previous dialog blurred as well?

  17. Hi Romain,
    Could we expect this kind of affects and techniques in FilthyRichClients Book.
    Dhilshuk Reddy.

  18. Antonis says:

    DK, geryg, The fact that usability concerns should be first priority in the design of a GUI application simply cannot be overemphasized enough. All usability issues should be resolved before one proceeds to refining looks. And, IMHO anyway, a system which forces the user to look underneath a modal dialog for information needed to complete his work on the dialog has some of these issues unresolved. May be the ‘modal dialog’ pattern should not be used in the first place ; the ‘perspective’ idea (central details viewer/editor surrounded by views of information slices) may be more appropriate and DK has a point that this could be the pattern of choice in the real-estate application. However once a modal dialog pattern is selected the blur effect beautifully conveys the overall context and links the dialog’s particular modality to it’s cause (in Windows there is still no visual clue of this information). But what is more striking than the blur in this particular example is the details dialog itself. I can count at least 5 effects used in this dialog (not to mention the particular color and font choices) that work so well together to bring out the content !
    Romain, you have the gift of being filthy with a taste !

  19. Jimbo says:

    Romain, how did you achieve the row spanning within the table.? This is something I am especially interested i.

  20. Romain Guy says:

    This was written by Hans Muller or Shannon Hickey but I remember we had a discussion about it. If I remember correctly, and this is explained in the slides, it’s a simple trick with translation and clipping in each cell.

  21. Daniel says:

    Hi Romain,
    I am very impressed with all the graphics works you have done for Extreme GUI Makeover 2005, 2006, and 2007.

    Quick question:
    To do the blur effect in this example, one of the code you showed is
    g2.setComposite(AlphaComposite.SrcOver.derive(alpha));

    This requires JDK 6.0. I am currently still using JDK 5.0. Are there any way to do the same thing using JDK 5.0?

  22. Romain Guy says:

    Sure, use AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha) instead.

  23. Rob says:

    Does anyone know when the sample will be available for download. Looks very interesting and be great to play with. Many thanks.

  24. Romain Guy says:

    Rob, when Hans, Shannon, Chris and I will have the time to go through the legal hoops :(

  25. S. Daiß says:

    With GridBagLayout as given here it did not work fpr me, so I used BorderLayout.CENTER

    Although my dialog is still empy it looks great ;-)

    I’m delighted to have found this website, hope more “howto”s of you will come here Romain!

  26. S. Daiß says:

    ah and a additional question:
    what Look and Feel did you use for the screenshot’s program?

  27. Romain Guy says:

    It’s the Windows look and feel with custom components.

  28. Pierre says:

    Hi Romain,

    how would you implement the above if you had JFrame.setDefaultLookAndFeelDecorated set to true? I ask this, because now the glass pane contains the title bar, making it not only blurred, but also un-usable, since it swallows all the mouse events.

    Regards,
    Pierre

  29. Romain Guy says:

    Just take into account the title bar rectangle.

  30. Pierre says:

    It’s easy enough to get it visible – you just set the clip shape appropriatly. Getting the mouse events through is another story – one to which I don’t know the ending :-). To let all the mouse events through is easy, just don’t add any mouse listeners, however, we only want to let mouse events through to the title bar, i.e. we want to be able to close and minimize the frame, etc.

    I think it’s a bit more complex than it may initially seem.

    Pierre

  31. Romain Guy says:

    Not really. You can simply override the contains() method.

  32. Pierre says:

    Thanks, that works perfectly

  33. sdark not says:

    alguien tiene el ejemplo me lo podrian mandar a mi correo darkx_valen666@hotmail.com

  34. Ravin says:

    So when do we get to see and use the code? Thanks.

  35. Wesley says:

    Romain, This is a very nice effect.

    But, it also has some side effects… Some controls stop working as expected. for example: a combobox doesn’t drop down the list anymore, a JXDatePicker doesn’t show the calender, etc….
    Does anyone have an idea how to resolve this issue?

  36. Antonetteet says:

    Great text.., bro

  37. xxxx says:

    hi…
    May be you can make sample application for demonstration of this cool effects? please, guys.

  38. Rogier says:

    A great effect; it looks absolutely miraculous :)

    I did find that you can’t seem to fire fadeOut and forget about it, though. When the animation has ended, it is still the GlassPlane and blocking input to the GUI. To resolve this, I’ve added a setVisible( false ); call in the setAlpha method whenever alpha is zero (or close to it anyway).

    However, this does feel kind of like a ‘quick hack’ – is there something in the example code that I overlooked? Or are there other, better methods? (apart from removing the DetailsView as the GlassPane – because I didn’t need the GlassPane for anything else anyway, so I like to keep it there)

  39. Romain Guy says:

    Hi Rogier,

    That’s the correct way to do it.

  40. Rogier says:

    Thanks for your response :) I’m happy it isn’t a quick hack and firing nice dialogs is very easy now.

    I added a first dialog with the blurred background to an irc applet – I think the result has come out quite nicely:

    http://www.digillusions.com/downloads/webchat_blurdialog.png

    Thanks again!

  41. greg says:

    hi all,
    Need some help implementing this. I have a JFrame with a JPane for holding toolbar etc, and a canvas for painitng on to. I want DetailPanel to sit over the canvas. How do I add DetailPanel to the canvas.

    Thanks
    greg

  42. Bane says:

    Hi Romain,

    How does this effect integrate with Substance look and feel? I tried couple of things but it was not working as expected. Any ideas?

    Thanks.

  43. java user says:

    Hi,

    did you made the source code public for “Extreme GUI Makeover session, at JavaOne 2007″? can you provide a link?

    Thanks.

  44. SnoopOne says:

    Hi guys,

    Great feature. I am currently using it instead of my Joptionpanes and it looks great. But I want it to be blocking. E.g. I have a button that triggers a screentransition effect – but before this happens I would like to show the dialog box and theirafter the screentransition may start. If I use a Joptionpane there is no problem – so how do I achieve the same behaviour?

    Thanks.

  45. Amar says:

    Hi,

    Is it possible to get the source code for this? I would like to use it in a project and would not mind paying for it.

    Thanks
    Amar..

  46. Overwhelming says:

    Hello Romain,

    could it be possible, to get the sourcecode for the above example ?

    I tried do get it work, but it failed…

    Tanks
    Reiner

  47. Rosena Hibbs says:

    Wow!, this was a top quality post. In idea I would like to write like this too – taking time and actual effort to make a great article… however what can I say… I procrastinate so much and never seem to get one thing carried out