views:

132

answers:

3

Hello,

I have a custom UI drawn for my java application. Right now I draw the entire UI from scratch. I know for a fact some parts of the UI are static. I know I could save these static parts to an image, but will this yield a improvement in performance (Since even an image must be drawn every frame)?

Is it plausible to save a reference to the Graphics2D object after the UI has been drawn and assign that to the new graphics object every frame (starting from a point where all the static components are drawn)?

Thanks in advance, Alan

+1  A: 

if some parts of the screen is completely static, then never redraw that part. Don't do a full-screen/window clear, just clear the part of the screen/window that changes all the time.

This way, you don't unnecessarily redraw the static image.

Lie Ryan
A: 

You don't need to redraw everything in every frame. So if you have static parts of your UI (or even dynamic parts that you know haven't changed since last frame) then you simply don't need to repaint them.

In my code (Swing games and simulations mostly) I usually try to follow the following rules:

  1. Pre-prepare static images (e.g. BufferedImage textures for UI elements)
  2. Override the paintComponent() method for each UI element individually to do the painting
  3. Only call the repaint() method of any given UI element if I know that something has changed
  4. Call repaint() in a timer-based loop for animation, but only call it on the portion of the UI that is being animated (e.g. a nested JPanel)

This approach seems to work and perform pretty well (though I'd welcome comments if there are ways to improve it!!)

mikera
Thanks. I think this will work fine.
Alan
3a. Have the repaint method check a dirty boolean that's set to true when the component needs to be repainted.I think this is what Swing does to speed up the repaint process.
Gilbert Le Blanc
+2  A: 

There are two main optimizations you can do here. The first is to make sure that when you cause your UI to be repainted, usually done by calling repaint, make sure you call the version of repaint where you specify a rectangle that has changed. Only make the rectangle big enough to encompass the parts that actually have changed, not the static parts. For this to be effective you also have to pay attention to the clipRect in the Graphics2D object you are passed in paint(). That is used by the system to tell you exactly what needs to be repainted, in the above case usually the rectangle that you passed to repaint. Don't paint anything that lies entirely outside that rectangle.

You can also get significant performance improvements by caching the static parts of your interface in an image. Writing an image is by far the fastest way of getting things onto a screen. My measurements indicate that small images are faster than even a few simple drawing primitives. However you need to make sure the image characteristics match the screen, by using createCompatibleImage().

Of course you may be using a lot of memory to get this speedup. I would recommend testing to see if you need to do image caching before implementing it.

DJClayworth