Active AND Passive Rendering? JPanel

Greetings all! 8)

At the moment I have created a physics engine which I am using to produce both a game and simulation. For my simulation, I need to use quite a lot of swing, and am having to created the program using an applet rather than straight JFrame etc.

The program itself is a JPanel and I’m merely opening it through a separate class which extends applet, I’m painting by overriding the paintComponent method and calling it through repaint in actionPerformed (using a swing timer obviously). However, the issue is, even after altering freedom of the components contained by the JPanel program to repaint, and after implementing a basic buffer using BufferedImage alone, there is lots of typical applet flashing when the timer delay is low (frame rate is high)! All my painting is being done in paintComponent as well, therefore I’m not using any form of rendering/game loop that seems modern formality in Java animation that doesn’t use swing!

I wondered if there is a possible approach I can take to this using both active and passive rendering, and the most important bit, complies with the fact my main program body is a JPanel! I’ve endlessly struggle to employ BufferStrategies etc, but keep returning to what I thought would mean having to rewrite my program heavily as a JFrame.

This is the way in which I am opening the program’s JPanel body,


public class Simulation extends JApplet
{

    public static void main(String []args)
    {

        EventQueue.invokeLater(new Runnable() 
            {
                public void run() 
                {

                    JFrame window = new JFrame();
                    window.setDefaultCloseOperation(3); 
                    window.setTitle("Kinetic Theory Simulator");

                    JApplet applet = new Simulation();
                    applet.init();
                    window.getContentPane().add(applet);
                    window.pack();
                    window.setVisible(true);
                }
            }
        );

    }  

    public void init() 
    {   
        JPanel panel = new KineticSimulation();
        getContentPane().add(panel);
    }

}

class KineticSimulation  extends JPanel implements MouseListener, MouseMotionListener, KeyListener, ActionListener

This is the relevant painting code,

( this initial code snippet is in the KineticSimulation() constructor)


        _delay = 1000 / _initFrameRate;
        timer = new Timer(_delay, this);
        timer.setCoalesce(true);
        timer.start();


    public void actionPerformed(ActionEvent e) 
    {
        collisionTest();
        reCalculateAll();
        updateSimulationSpeed();
        repaint();
    }


    public void paintComponent(Graphics g) 
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;

        g2 = (Graphics2D)buffer.getGraphics();

          //this is where all the painting code is

        getGraphics().drawImage(buffer, 0, 0, null); 

    }


If I haven’t made myself clear feel free to ask me to clarify,

Thanks in advance! :slight_smile:

  1. You shouldn’t use getGraphics().drawImage, you should just use the Graphics object given to you as a parameter.
  2. JPanels are automatically double buffered so you can just draw directly to the Graphics object they give you.
  3. Could you give us an example (an applet?) where it flashes?

http://www.realapplets.com/tutorial/DoubleBuffering.html

The 3 boxes depict it well, although due to the black background they seem slightly harmless as the flashes themselves are black.

So are you suggesting I just forget about double buffering? :confused: And see what happens if I let it automatically deal with it?

First one flickers badly, second flickers sometimes, and the third one doesn’t flicker at all.

Swing automatically double buffers using BufferStrategy so when drawing on a JComponent or any of its subclasses, you shouldn’t worry about double buffering. It’s when you start drawing on any AWT Component (which is recommended for games since you are skipping Swing’s bloat), that’s when you should start double buffering.