package org.opensourcephysics.tools; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import org.opensourcephysics.analysis.FourierSinCosAnalysis; import org.opensourcephysics.display.ColorIcon; import org.opensourcephysics.display.Data; import org.opensourcephysics.display.DataTable; import org.opensourcephysics.display.Dataset; import org.opensourcephysics.display.DatasetManager; import org.opensourcephysics.display.PlottingPanel; import org.opensourcephysics.display.TeXParser; /** * A JPanel that displays a plot and table of the Fourier spectrum of an input Dataset. * * @author Doug Brown */ public class FourierPanel extends JPanel { // instance fields protected Dataset sourceData; protected PlottingPanel plot; protected DataTable table; protected DatasetManager fourierManager; // local datasets: frequency vs power, cosine, sine protected JSplitPane splitPane; protected JCheckBox[] buttons; protected JPanel plotPanel; /** * Constructs a FourierPanel. */ public FourierPanel() { super(new BorderLayout()); createGUI(); } // _______________________ protected & private methods ______________________ /** * Creates the GUI. */ protected void createGUI() { fourierManager = new DatasetManager(); fourierManager.setXPointsLinked(true); table = new DataTable(); table.add(fourierManager); plot = new PlottingPanel("", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ plotPanel = new JPanel(new BorderLayout()); plotPanel.add(plot, BorderLayout.CENTER); splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); splitPane.setResizeWeight(1); JScrollPane scroller = new JScrollPane(table); splitPane.setRightComponent(scroller); splitPane.setLeftComponent(plotPanel); add(splitPane, BorderLayout.CENTER); } /** * Refreshes the fourier data based on a source dataset. * * @param data the source dataset * @param name a name that identifies the source */ protected void refreshFourierData(Dataset data, String name) { JDialog dialog = (JDialog)this.getTopLevelAncestor(); dialog.setTitle(ToolsRes.getString("DataToolTab.Dialog.Fourier.Title")); //$NON-NLS-1$ fourierManager.removeDatasets(); Data fourierData = createFourierData(data); if (fourierData==null) return; ArrayList<Dataset> datasets = fourierData.getDatasets(); createButtons(datasets); for (Dataset next: datasets) { fourierManager.addDataset(next); } table.refreshTable(); name = TeXParser.removeSubscripting(name); String x = TeXParser.removeSubscripting(data.getXColumnName()); String y = TeXParser.removeSubscripting(data.getYColumnName()); plot.setTitle(name+" ["+x+", "+y+"]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ refreshPlot(); } /** * Refreshes the plot to show currrently selected variables. */ protected void refreshPlot() { plot.removeDrawables(Dataset.class); String s = ""; //$NON-NLS-1$ for (int i=0; i<buttons.length; i++) { if (buttons[i].isSelected()) { Dataset data = fourierManager.getDataset(i); plot.addDrawable(data); plot.setXLabel(data.getXColumnName()); if (s.length()>0) s += ", "; //$NON-NLS-1$ s += data.getYColumnName(); } } plot.setYLabel(s); plot.repaint(); } /** * Creates the plot variable buttons. * * @param datasets the fourier datasets */ protected void createButtons(ArrayList<Dataset> datasets) { if (buttons==null) { buttons = new JCheckBox[datasets.size()]; JPanel buttonPanel = new JPanel(); plotPanel.add(buttonPanel, BorderLayout.SOUTH); for (int i=0; i<buttons.length; i++) { Dataset next = datasets.get(i); buttons[i] = new PlotCheckBox(next.getYColumnName(), next.getFillColor()); buttonPanel.add(buttons[i]); } buttons[0].setSelected(true); } } // ____________________________ static methods ______________________________ /** * Creates a Data object containing the Fourier spectrum of the input Dataset. * * @param dataset the input * @return the fourier spectrum Data */ public static Data createFourierData(Dataset dataset) { if (dataset==null) return null; double[] x = dataset.getXPoints(); double[] y = dataset.getYPoints(); if (y.length<2) return null; if (y.length%2==1) { // odd number of points double[] xnew = new double[y.length-1]; double[] ynew = new double[xnew.length]; System.arraycopy(x, 0, xnew, 0, xnew.length); System.arraycopy(y, 0, ynew, 0, ynew.length); dataset.clear(); dataset.append(xnew, ynew); x = xnew; y = ynew; } FourierSinCosAnalysis fft = new FourierSinCosAnalysis(); fft.doAnalysis(x, y, 0); return fft; } //____________________________________ inner classes _________________________________ class PlotCheckBox extends JCheckBox { ColorIcon icon; Color outlineColor, fillColor=Color.WHITE; PlotCheckBox(String text, Color color) { super(text); outlineColor = color; icon = new ColorIcon(fillColor, outlineColor, 13, 13); setIcon(icon); addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JCheckBox checkBox = (JCheckBox)e.getSource(); setSelected(checkBox.isSelected()); refreshPlot(); } }); } public void setSelected(boolean select) { icon.setColor(select? outlineColor: fillColor); super.setSelected(select); } } }