import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.util.Timer; import java.util.TimerTask; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class J2dFrame extends JFrame { BufferedImage bigImage; BufferedImage backBuffer; final int bigXImagesize = 1024; final int bigYImagesize = 10000; final int dbXImagesize = 1024; final int dbYImagesize = 750; protected int fpsCounter = 0; protected int workCounter = 0; protected int index = 0; protected String label = "Hello"; protected String label2 = "Hello"; public J2dFrame(String label) { super(label); this.bigImage = new BufferedImage(this.bigXImagesize, this.bigYImagesize, BufferedImage.TYPE_INT_RGB); this.backBuffer = new BufferedImage(this.dbXImagesize, this.dbYImagesize, BufferedImage.TYPE_INT_RGB); // create a big bufer to scroll from Graphics2D gfx = (Graphics2D) this.bigImage.getGraphics(); gfx.setPaint(Color.ORANGE); gfx.fill(new Rectangle2D.Float(0, 0, this.bigXImagesize, this.bigYImagesize)); gfx.setPaint(Color.BLACK); for (int y = 0; y < bigYImagesize; y = y + 100) { gfx.drawString("line" + y, 100, y); gfx.drawLine(0, y + 5, this.bigXImagesize, y + 5); } } public void paint(Graphics g) { // super.paint(g); Graphics2D g2d = (Graphics2D) g; g.drawImage(this.backBuffer, 0, 0, null); // increase the nb of fps setFps(getFps() + 1); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub final J2dFrame frame = new J2dFrame("2D display"); frame.setBounds(0, 0, frame.dbXImagesize, frame.dbYImagesize); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); Runnable mainLoop = new Runnable() { public void run() throws RuntimeException { while (true) { // update the index int newIndex = frame.getIndex() + 1; if (newIndex > (frame.bigYImagesize - frame.dbYImagesize)) newIndex = 0; frame.setIndex(newIndex); // copy a part of the big image as clipping Graphics g = frame.backBuffer.getGraphics(); // erase with background color g.setColor(Color.ORANGE); g.fillRect(0, 0, frame.dbXImagesize, frame.dbYImagesize); Image image = frame.bigImage .getSubimage(0, frame.getIndex(), frame.dbXImagesize, frame.dbYImagesize); g.drawImage(image, 0, 0, null); g.setColor(Color.WHITE); g.drawString(frame.getLabel(), 800, 200); g.drawString(frame.getLabel2(), 800, 240); // update the work count frame.setWorkCounter(frame.getWorkCounter() + 1); // update the frame by painting SwingUtilities.invokeLater(new Runnable() { public void run() { frame.repaint(); } }); try { Thread.currentThread().setPriority(Thread.MAX_PRIORITY); // Thread.currentThread().sleep(1, 0); // Thread.yield(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; Thread mainLoopThread = new Thread(mainLoop, "Main loop thread"); // go mainLoopThread.start(); Thread measurementThread = new Thread(mainLoop, "measurement thread"); Timer timer = new Timer("measurement thread"); TimerTask task = new TimerTask() { public void run() { // get the scores and set the label frame.setLabel("FPS : " + frame.getFps()); frame.setLabel2("Loop count : " + frame.getWorkCounter()); // reset them frame.setFps(0); frame.setWorkCounter(0); } }; timer.schedule(task, 1000); } public synchronized int getIndex() { return index; } public synchronized void setIndex(int index) { this.index = index; } public synchronized int getFps() { return fpsCounter; } public synchronized void setFps(int fps) { this.fpsCounter = fps; } public synchronized String getLabel() { return label; } public synchronized void setLabel(String label) { this.label = label; } public synchronized String getLabel2() { return label2; } public synchronized void setLabel2(String label2) { this.label2 = label2; } public synchronized int getWorkCounter() { return workCounter; } public synchronized void setWorkCounter(int workCounter) { this.workCounter = workCounter; } }