import java.awt.Toolkit; import java.awt.Graphics; import javax.swing.JPanel; import java.awt.Image; // handles the thread/update/render/paint public abstract class GamePanel extends JPanel implements Runnable { // fps protected FPSCounter fpsCounter; // double buffer protected Graphics dbg; // graphics used for gameRender() private Image dbImage = null; // image used in paintScreen() // thread private Thread thread; private boolean running = false; // child methods public abstract void gameUpdate(); public abstract void gameRender(); public abstract void onExit(); // hardcoded methods private void gamePreRender() { if (dbImage == null) { dbImage = createImage(this.getWidth(), this.getHeight()); if (dbImage == null) { System.out.println("Error creating Image Buffer"); return; } else { dbg = dbImage.getGraphics(); } } } private void paintScreen() { Graphics g; try { g = this.getGraphics(); if (g != null && dbImage != null) { g.drawImage(dbImage, 0, 0, null); } Toolkit.getDefaultToolkit().sync(); g.dispose(); } catch (Exception e) { System.out.println(e); } } protected void startThread(double desiredFPS,int count) { fpsCounter = new FPSCounter(desiredFPS,count); running = true; thread = new Thread(this); thread.start(); } protected void stopThread() { running = false; } protected boolean getRunning() { return running; } // should not be overridden by child public void run() { while (running) { fpsCounter.startFrame(); gameUpdate(); gamePreRender(); gameRender(); paintScreen(); fpsCounter.endFrame(); } onExit(); } }