/** * File: FFTSpectrum.java * Author: Brian Borowski * Date created: October 2000 * Date last modified: July 1, 2011 */ import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.Rectangle2D; import javax.swing.JPanel; public class FFTSpectrum extends JPanel { public static final int MAX_HARMONICS = 64; private static final long serialVersionUID = 1L; private double[] data = null; private double min, max; private String errStr = null; private final Color maroon = new Color(113, 0, 17); private final Font font = new Font("Monospaced", Font.PLAIN, 16); public FFTSpectrum() { setBackground(Color.black); } public Dimension getPreferredSize() { return new Dimension(250, 100); } public void plot(final double[] ar, final double[] ai, final int numOfPoints) { errStr = null; if (numOfPoints > MAX_HARMONICS) { errStr = "Too many harmonics to display."; } else if (numOfPoints == 0) { errStr = "All harmonics are filtered out."; } else { data = new double[numOfPoints]; double realVal = ar[1], imagVal = ai[1]; max = min = data[0] = Math.sqrt(realVal * realVal + imagVal * imagVal); for (int i = 1; i < numOfPoints; ++i) { realVal = ar[i + 1]; imagVal = ai[i + 1]; data[i] = Math.sqrt(realVal * realVal + imagVal * imagVal); if (data[i] > max) { max = data[i]; } if (data[i] < min) { min = data[i]; } } } repaint(); } private int scalePoint(final double point) { final int heightOfMax = (int)(0.99 * this.getSize().height); return (int)(point / max * heightOfMax); } protected void paintComponent(final Graphics g) { final Graphics2D g2d = (Graphics2D)g; g2d.setColor(Color.black); final int width = this.getSize().width, height = this.getSize().height; g2d.fillRect(0, 0, width, height); if (errStr != null) { final int length = getFontMetrics(font).stringWidth(errStr); g2d.setColor(Color.white); g2d.setFont(font); g2d.drawString(errStr, (width - length) / 2, height / 2); } else if (data != null) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); final int barWidth = width / data.length; final int offset = (width - barWidth * data.length) / 2; for (int i = 0; i < data.length; ++i) { final int barHeight = scalePoint(data[i]), x = i * barWidth + 1 + offset, y = height - barHeight; final GradientPaint redToMaroon = new GradientPaint(x, y, Color.red, x, height, maroon); g2d.setPaint(redToMaroon); g2d.fill(new Rectangle2D.Double(x, y, barWidth - 1, height)); } } } }