Core Java Books

Monday 7 March 2011

Nimbus L&F JDesktopPane Background Performance Tweak

This blog is for all the people out there using the Nimbus L&F and who find that it has a performance hit when using JDesktopPane components.

I had performance problems on a lightweight application using JDesktopPane's  and I tracked it down to the amount of processing going on when the background of the pane was repainted. Nimbus paints the background using what looks like vector type drawing routines to paint a fancy background pattern. This is all very impressive but on a client with a low(ish) spec processor this has a major impact whenever the user moved or resized JInternalFrame's.

I changed the background Painter used by the JDesktopPane to simply fill the pane with the Nimbus background color. This improved the performance significantly in my case and also left more processing available for the rest of the application to use.

Below is images of the before and after shots on the simple demo application.

Original Nimbus
Updated Background Painter




For the demo code I have simply overriden the updateUI() method on the JDesktopPane to simply provide a new Painter which does a simple fill using the default color.


package com.webbyit.swing;

import com.sun.java.swing.Painter;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.UIDefaults;
import javax.swing.UIManager;

/**
 * A <code>JDesktopPane</code> that displays a simple fill <code>Color</code> as the
 * background when the nimbus l&f is being used. This saves many process cycles over the normal
 * background painting that makes use of vector drawing.
 *
 @author webbyit
 */
public class SimpleFillDesktopPane extends JDesktopPane {

    @Override
    public void updateUI() {
        if ("Nimbus".equals(UIManager.getLookAndFeel().getName())) {
            UIDefaults map = new UIDefaults();
            Painter<JComponent> painter = new Painter<JComponent>() {

                @Override
                public void paint(Graphics2D g, JComponent c, int w, int h) {
                    // file using normal desktop color
                    g.setColor(UIManager.getDefaults().getColor("desktop"));
                    g.fillRect(00, w, h);
                }
            };
            map.put("DesktopPane[Enabled].backgroundPainter", painter);
            putClientProperty("Nimbus.Overrides", map);
        }
        super.updateUI();
    }
}



And here is a quick demo for you to try it on your box. You should find if you expand the window to be full frame and move the internal frame around it should redraw fairly quick on a low spec box.




(Java 1.6 required!)

1 comment:

  1. Thank you for your idea, I was looking on the web for people experimenting the same performance problem. It effectively improve a little bit the performances :)

    ReplyDelete