Java dynamic image on static background...

Discussion in 'Mac Programming' started by NewbieNerd, Jan 19, 2007.

  1. macrumors 6502a

    NewbieNerd

    Joined:
    Sep 22, 2005
    Location:
    Chicago, IL
    #1
    Anybody know anything about efficiently doing this? Namely, creating a Speedometer, so there is a needle that moves on top of a static background image of a dial. Right now, every time the needle moves, I have to do a full clear and redraw of the background (it's slightly transparent, but it fills in completely if I don't clear). I know that there is this clear(x,y,width,height) method, but that's not terribly useful unless you want to clear a rectangle.

    Any wisdom to share?
     
  2. macrumors 603

    jeremy.king

    Joined:
    Jul 23, 2002
    Location:
    Fuquay Varina, NC
    #2
    Are you using Swing to do this?
     
  3. thread starter macrumors 6502a

    NewbieNerd

    Joined:
    Sep 22, 2005
    Location:
    Chicago, IL
    #3
    Yes, I am extending JPanel. Should I be doing AWT?
     
  4. macrumors 603

    jeremy.king

    Joined:
    Jul 23, 2002
    Location:
    Fuquay Varina, NC
    #4
    Have you considered using JLayeredPane and just repainting the needle component when you need to?
     
  5. thread starter macrumors 6502a

    NewbieNerd

    Joined:
    Sep 22, 2005
    Location:
    Chicago, IL
    #5
    Hmm, I've never noticed this JLayeredPane before, but it looks like it might be worth a try. Thanks man!
     
  6. thread starter macrumors 6502a

    NewbieNerd

    Joined:
    Sep 22, 2005
    Location:
    Chicago, IL
    #6
    So I'm using a JLayeredPane now, with both the background and needle as JPanel subclasses. Each just overrides paintComponent(Graphics g) to paint their corresponding stuff (no clearing). I also set needle.setOpaque(false), and whenever the needle needs to change, I just call needle.repaint(), but when I do this, the background's paintComponent method gets called everytime, and if I don't actually redraw the background, it gets cleared, never to be seen again.

    Anymore help for a GUI newb? :)
     
  7. macrumors 603

    jeremy.king

    Joined:
    Jul 23, 2002
    Location:
    Fuquay Varina, NC
    #7
    http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics)

    "Further, if you do not invoker super's implementation you must honor the opaque property, that is if this component is opaque, you must completely fill in the background in a non-opaque color. If you do not honor the opaque property you will likely see visual artifacts."

    Edit - after reading up on this a little more - from the JFC/Swing tutorial

    "You can improve painting performance by making components opaque when possible, so that the Swing painting system doesn't waste time trying to paint behind these components. To make a Swing component opaque, invoke setOpaque(true) on the component."

    So you may want to try it with the opaque property set to true.

    Good Luck!
     
  8. macrumors 65816

    MarkCollette

    Joined:
    Mar 6, 2003
    Location:
    Calgary, Canada
    #8
    Sorry, is it just the clock hand foreground image that uses transparency, or does the background image use transparency as well? And if so, what's behind that?
     
  9. thread starter macrumors 6502a

    NewbieNerd

    Joined:
    Sep 22, 2005
    Location:
    Chicago, IL
    #9
    Just the clock hand...the background image does use a transparent color (via alpha setting), but there is nothing else behind them, though perhaps this entire image may be placed on top of something else that has a background.
     
  10. macrumors newbie

    Joined:
    Dec 5, 2006
    #10
    You can make sure the animation looks good by using double buffering by drawing the background and needle to an offscreen Graphics object and then paint the entire image once. Google up some applet double buffering examples
     
  11. macrumors 65816

    MarkCollette

    Joined:
    Mar 6, 2003
    Location:
    Calgary, Canada
    #11
    Umm, what? In the first 4 words of your post you say that only the clock hands, and then immediately after you say that the background image does in fact use transparency? So, if you set the background color of the component that you're drawing on to vivid pink, will that pink show through or not?

    Have you tried overriding the JComponent's paintComponent method, and making it do a Graphics.clearRect(), then drawing the background image, then drawing the foreground clock hand image? Does it flicker for you? An alternative it to create an offscreen image, do a Graphics.fillRect() on it, draw the two images to it, and then just blit that one image to the component, which should eliminate the artifacting. There's a couple classes that can help with this, including BufferedImage, VolatileImage, and BufferStrategy.

    You could optimise it slightly by only clearing and blitting over the quadrants that the clock hand was in and now is in.
     

Share This Page