In the previous post, I showed helper class for 2D animation on Java Swing component.
If we can measure the frame rate of animation, it is very great, isn't it?
In this post, I will show you that kind of class - rendering FPS text on swing component.
Showing code is fast and snappy :p Here is the code - count frame per 1 sec.
The below is differnet version - counting 100 frame and divide it by time elapsed (In my experience, 100 frame is too much aroud 30 frame is better).
I embed the FPS text class on BezierAnim class.
After embedding, you can see the fps text on right corner...
If we can measure the frame rate of animation, it is very great, isn't it?
In this post, I will show you that kind of class - rendering FPS text on swing component.
Showing code is fast and snappy :p Here is the code - count frame per 1 sec.
package com.dukesoftware.utils.awt.graphics; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Graphics; import java.text.DecimalFormat; public class FPSText { protected static final String FPS = "FPS: "; private static final int FONT_SIZE = 24; private static final int FONT_STYLE = Font.BOLD; private static final String FONT_NAME = "SansSerif"; protected final static Color COLOR = new Color(0.55f,0.55f,0.55f); protected double frameCount; protected final DecimalFormat format = new DecimalFormat("####.00"); protected String fpsText; protected final int fpsWidth; protected long startTime; protected Font font; protected final Component comp; protected int wpos; public FPSText(Component comp){ this(comp, new Font(FONT_NAME, FONT_STYLE, FONT_SIZE)); } public FPSText(Component comp, Font font){ this.comp = comp; this.font = font; fpsText = FPS + format.format(0); fpsWidth = font.getSize()*(format.getMaximumFractionDigits()+FPS.length()) + 5; setStartTime(); wpos = comp.getWidth() - fpsWidth; } public void setStartTime(){ startTime = System.currentTimeMillis(); } public void paint(Graphics g) { ++frameCount; final long currentTimeMillis = System.currentTimeMillis(); final long span = currentTimeMillis - startTime; if (span > 1000) { fpsText = FPS + format.format(frameCount*1000 / span); frameCount = 0; startTime = currentTimeMillis; } g.setFont(font); g.setColor(COLOR); g.drawString(fpsText, comp.getWidth() - fpsWidth, 30); } }But wait! the above FPSText class is sometimes not suitable for rendering heavy animation because measuring time does not become so accurate.
The below is differnet version - counting 100 frame and divide it by time elapsed (In my experience, 100 frame is too much aroud 30 frame is better).
package com.dukesoftware.utils.awt.graphics; import java.awt.Component; import java.awt.Graphics; public class FPSText2 extends FPSText{ public FPSText2(Component comp){ super(comp); } public void paint(Graphics g) { if (++frameCount >= 100) { fpsText = FPS + format.format(100000.0f / (System.currentTimeMillis() - startTime)); frameCount = 0; startTime = System.currentTimeMillis(); } g.setFont(font); g.setColor(COLOR); g.drawString(fpsText, comp.getWidth() - fpsWidth, 30); } }
I embed the FPS text class on BezierAnim class.
After embedding, you can see the fps text on right corner...
package com.dukesoftware.utils.swing.others; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import javax.swing.JComponent; import javax.swing.Timer; import com.dukesoftware.utils.awt.graphics.FPSText; import com.dukesoftware.utils.swing.graphics2d.Model2D; public class AnimateCanvas extends JComponent implements ComponentListener, ActionListener{ private int width, height; private final Timer animator2D; private final Model2D model2D; private final FPSText text; public AnimateCanvas(Model2D model2D, int width, int height, int fps) { this.model2D = model2D; this.width = width; this.height = height; this.animator2D = new Timer(1000/fps, this); model2D.init(width, height); this.text = new FPSText(this); setPreferredSize(new Dimension(width, height)); addComponentListener(this); } public void stop() { animator2D.stop(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; model2D.step(width, height); model2D.render(width, height, g2); this.text.paint(g2); g2.dispose(); } public void start() { animator2D.start(); } public void componentHidden(ComponentEvent e) { } public void componentMoved(ComponentEvent e) { } public void componentResized(ComponentEvent e) { width = getWidth(); height = getHeight(); } public void componentShown(ComponentEvent e) { } public void actionPerformed(ActionEvent e) { repaint(); } }
コメント