/***************************************************************************
 *   Copyright (C) 2009 by Paul Lutus                                      *
 *   lutusp@arachnoid.com                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
/*
 * FFTExplorerPanel.java
 *
 * Created on Mar 26, 2009, 11:59:23 PM
 */
package fftexplorer;

//import fftexplorerapplet.*;
import javax.swing.*;
import java.awt.*;
import java.text.*;
import javax.swing.text.html.parser.*;

/**
 *
 * @author lutusp
 */
final public class FFTExplorer extends javax.swing.JPanel {

    final public String appVersion = "3.9";
    final public String appName;
    final String programName;
    JFrame sv_mainFrame = null;
    final boolean applet;
    public InitManager initManager;
    MyHelpPane helpPane;
    NumberFormat numberFormat;
    public SignalProcessor signalProcessor;
    public GraphicPanel freqDisp;
    public GraphicPanel timeDisp;
    JComboBox sv_timeVertIndex, sv_freqVertIndex;
    JComboBox sv_timeHorizIndex, sv_freqHorizIndex;
    GraphicControl freqControl, timeControl;
    AudioCapture audioCapture;
    MP3Stream mp3Stream = null;
    String[] audioDataRates = {"768000", "384000", "192000", "96000", "48000", "44100", "22050", "16000", "11025", "8000", "4000", "2000"};
    boolean running = true;
    javax.swing.Timer graphicTimer = null;
    Thread graphicThread = null;
    int graphicLineWidth = 1;
    boolean sv_graphicTipFlag;
    double av = 0;
    protected Rectangle screenBounds = new Rectangle(0, 0, 800, 600); // default size
    int arraySize = 16384;
    double sampleRate = 8192;
    double carrier = 100;
    double modFreq = 25;
    double modLevel = 1;
    double noiseLevel = 1;
    double sv_xTimeOffset = 0;
    double sv_xFreqOffset = 0;
    ColorButton sv_backgroundColor;
    ColorButton sv_traceColor;
    String sv_soundSourceDirectory = "";
    //int sv_helpScrollPos = 0;
    protected JScrollBar sv_helpScrollBar = null;

    /** Creates new form FFTExplorerPanel */
    public FFTExplorer(Object p, boolean app, String[] args) {
        this.applet = app;
        if (applet) {
            //appletFrame = (FFTExplorerApplet) p;
        } else {
            sv_mainFrame = (JFrame) p;
        }
        // this is essential to avoid a problem with
        // HTMLEditorKit and applets
        ParserDelegator workaround = new ParserDelegator();
        // just for testing locale-immunity
        // Locale.setDefault(Locale.GERMANY);
        initComponents();
        numberFormat = NumberFormat.getInstance();
        appName = getClass().getSimpleName();
        programName = appName + " " + appVersion;
        audioCapture = new AudioCapture(this);
        sv_traceColor = new ColorButton(this, traceColorButton, new Color(0, 128, 0), "Line drawing color");
        sv_backgroundColor = new ColorButton(this, backgroundColorButton, new Color(255, 255, 255), "Graph Background color");
        //sv_mainFrame = this;
        //setBounds(screenBounds);
        //setTitle(programName);
        //setIconImage(new ImageIcon(getClass().getResource("icons/" + appName + ".png")).getImage());
        signalProcessor = new SignalProcessor(this);
        freqControl = new GraphicControl(this, true);
        timeControl = new GraphicControl(this, false);
        sv_timeVertIndex = timeControl.vertComboBox;
        sv_freqVertIndex = freqControl.vertComboBox;
        sv_timeHorizIndex = timeControl.horizComboBox;
        sv_freqHorizIndex = freqControl.horizComboBox;
        setupControls();
        resetDefaults(false);
        initManager = new InitManager(this, applet);
        helpPane = new MyHelpPane(this);
        addComponent(helpPane, helpPanel, 0, 0, 1.0, 0.01, 0);
        SwingUtilities.invokeLater(
                new Runnable() {

                    public void run() {

                        if (!applet) {
                            sv_mainFrame.setBounds(screenBounds);
                            initManager.readConfig();
                        }
                        readControls();
                        freqControl.graphicPane.setupOffset();
                        timeControl.graphicPane.setupOffset();
                        setupDisplayConfig();
                        handleTabbedPaneChange();
                    }
                });
    }

    public void p(String s) {
        System.out.println(s);
    }

    void setStatus(String s) {
        statusLabel.setText(s);
    }

    void errorMessage(String s) {
        beep();
        JOptionPane.showMessageDialog(this, s, programName + " Error", JOptionPane.WARNING_MESSAGE);
    }

    void appletError() {
        beep();
        setStatus("<html><b>Sorry, Web-based applets don't allow this. Consider downloading " + programName + ".</b></html>");
    }

    void setupDisplayConfig() {
        gContentPanel.removeAll();
        boolean freqSel = sv_freqDispCheckBox.isSelected();
        boolean timeSel = sv_timeDispCheckBox.isSelected();
        if (!freqSel && !timeSel) {
            sv_freqDispCheckBox.setSelected(true);
            freqSel = true;
        }
        boolean horiz = this.sv_horizontalCheckBox.isSelected();
        if (freqSel) {
            if (horiz) {
                addComponent(freqControl, gContentPanel, 1, 0);
            } else {
                addComponent(freqControl, gContentPanel, 0, 1);
            }
        }
        if (timeSel) {
            if (horiz) {
                addComponent(timeControl, gContentPanel, 0, 0);
            } else {
                addComponent(timeControl, gContentPanel, 0, 0);
            }
        }
        gContentPanel.validate();
        repaint();
    }

    public void addComponent(JPanel source, JComponent target, int x, int y) {
        addComponent(source, target, x, y, 1.0, 1.0, 0);
    }

    public void addComponent(JPanel source, JComponent target, int x, int y, double wx, double wy, int insets) {
        GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.gridx = x;
        gridBagConstraints.gridy = y;
        gridBagConstraints.insets = new Insets(insets, insets, insets, insets);
        gridBagConstraints.weightx = wx;
        gridBagConstraints.weighty = wy;
        target.add(source, gridBagConstraints);
        target.revalidate();
    }

    void setupControls() {
        new UserActionManager(1, 0, 1e12, sv_carrierTextField, this);
        new UserActionManager(1, 0, 1e9, sv_modFreqTextField, this);
        new UserActionManager(1, 0, 1000, sv_modPercentTextField, this);
        new UserActionManager(1, 0, 10000, sv_noiseLevelTextField, this);
        new UserActionManager(1, 0, 1e12, sv_sampleRateTextField, this);
        new UserActionManager(sv_arraySizeComboBoxIndex, this);
        new UserActionManager(sv_audioDataRateComboBoxIndex, this);
        new UserActionManager(this.sv_lineWidthComboBox, this);
        sv_arraySizeComboBoxIndex.removeAllItems();
        for (int n = 4; n < 20; n++) {
            sv_arraySizeComboBoxIndex.addItem("" + (int) Math.pow(2, n));
        }
        sv_audioDataRateComboBoxIndex.removeAllItems();
        for (int n = 0; n < audioDataRates.length; n++) {
            sv_audioDataRateComboBoxIndex.addItem(audioDataRates[n]);
        }
        sv_lineWidthComboBox.removeAllItems();
        for (int n = 1; n <= 32; n++) {
            sv_lineWidthComboBox.addItem("" + n);
        }
    }

    public void readControls(boolean sampleRateEntry) {
        signalProcessor.suspend(true);
        audioCapture.suspend(true);
        mp3Stream.suspend(true);
        timeDelay(250);
        arraySize = getInt(sv_arraySizeComboBoxIndex, arraySize);
        if (sampleRateEntry) {
            sampleRate = getDouble(sv_sampleRateTextField, sampleRate);
        } else {
            setSampleRate();
        }
        sv_sampleRateTextField.setText(formatNum(sampleRate));
        adjustControls();
        signalProcessor.initialize(true);
        audioCapture.suspend(false);
        mp3Stream.suspend(false);
        signalProcessor.suspend(false);
    }

    public void adjustControls() {
        carrier = getDouble(sv_carrierTextField, carrier);
        modFreq = getDouble(sv_modFreqTextField, modFreq);
        modLevel = getDouble(sv_modPercentTextField, modLevel * 100) * 0.01;
        noiseLevel = getDouble(sv_noiseLevelTextField, noiseLevel * 100.0) * 0.01;
        freqControl.adjustControls();
        timeControl.adjustControls();
        graphicLineWidth = getInt(sv_lineWidthComboBox, graphicLineWidth);
        setSampleRate();
    }

    public void readControls() {
        readControls(false);
    }

    public void setSampleRate() {
        sampleRate = (audioCapture.capturing()) ? audioCapture.getSampleRate()
                : (streamMP3()) ? mp3Stream.sampleRate()
                : signalProcessor.getSampleRate();
        //: arraySize;
        sv_sampleRateTextField.setText(formatNum(sampleRate));
        freqControl.setup(false);
        timeControl.setup(false);
    }

    void timeDelay(int millis) {
        try {
            Thread.sleep(millis);
        } catch (Exception e) {
        }
    }

    double getDouble(String s) {
        double v = 0;
        double e;
        try {
            // deal with possibility of exponent
            // which numberformat cannot process
            s = s.toLowerCase();
            String[] array = s.split("e");
            v = numberFormat.parse(array[0]).doubleValue();
            if (array.length > 1) {
                // get signed exponent
                e = numberFormat.parse(array[1]).doubleValue();
                v *= Math.pow(10, e);
            }
        } catch (Exception ex) {
            System.out.println(getClass().getName() + ".getDouble: Error: " + ex);
        }
        return v;
    }

    double getDouble(JTextField tf, double v) {
        try {
            v = getDouble(tf.getText());
        } catch (Exception e) {
            System.out.println(getClass().getName() + ": Error: " + e);
        }
        return v;
    }

    int getInt(JTextField tf, int v) {
        try {
            v = Integer.parseInt(tf.getText());
        } catch (Exception e) {
            System.out.println(getClass().getName() + ": Error: " + e);
        }
        return v;
    }

    double getDouble(JComboBox box, double v) {
        try {
            String s = (String) box.getSelectedItem();
            v = getDouble(s);
        } catch (Exception e) {
            System.out.println(getClass().getName() + ": Error: " + e);
        }
        return v;
    }

    int getInt(JComboBox box, int v) {
        try {
            String s = (String) box.getSelectedItem();
            v = Integer.parseInt(s);
        } catch (Exception e) {
            System.out.println(getClass().getName() + ": Error: " + e);
        }
        return v;
    }
    final String[] timeUnits = {"s", "ms", "us", "ns", "ps"};
    final String[] freqUnits = {"Hz", "kHz", "MHz", "GHz", "THz"};

    protected String getEngFormatString(double v, boolean freq) {
        String ss;

        if (freq) {
            int j = -1;
            while (++j < 4 && v >= 1000.0) {
                v = v / 1000.0;
            }
            ss = freqUnits[j];
        } else {
            int j = -1;
            while (++j < 4 && v < 1.0) {
                v = v * 1000.0;
            }
            if (j >= 4) {
                j = 0;
            }
            ss = timeUnits[j];
        }
        return formatNum(v) + " " + ss;
    }

    public double ntrp(double x, double xa, double xb, double ya, double yb) {
        return ((x - xa) / (xb - xa)) * (yb - ya) + ya;
    }

    public String formatNum(Double v) {
        String fmt = (Math.abs(v) < 1e-3) ? "%.3g" : "%.3f";
        return String.format(fmt, v);
    }

    void audioCapture(boolean start) {
        if (start) {
            if (applet) {
                appletError();
            } else {
                signalProcessor.synthDisplay(false);
                streamMP3(false);
                setSampleRate();
                audioCapture.startCapture();
            }
        } else {
            audioCapture.stopCapture();
        }
        startAudioCaptureButton.setEnabled(!audioCapture.capturing());
        stopAudioCaptureButton.setEnabled(audioCapture.capturing());
    }

    void setAudioSampleColor(boolean success) {
        this.soundCardSourceLabel.setForeground(success ? Color.black : Color.red);
    }

    void setArraySizeLabelColor(boolean success) {
        arraySizeLabel.setForeground(success ? Color.black : Color.red);
    }

    void streamMP3(boolean start) {
        if (mp3Stream == null) {
            mp3Stream = new MP3Stream(this);
        }
        if (start) {
            if (applet) {
                appletError();
            } else {
                signalProcessor.synthDisplay(false);
                audioCapture(false);
                mp3Stream.streamMP3(arraySize);
            }
        } else {
            mp3Stream.stopStream();
        }
        streamMP3ButtonControl(start);
    }

    void streamMP3ButtonControl(boolean start) {
        mp3StreamProgressBar.setValue(0);
        mp3StreamProgressBar.setStringPainted(false);
        startMP3Button.setEnabled(!start);
        stopMP3Button.setEnabled(start);
    }

    boolean streamMP3() {
        return (mp3Stream != null && mp3Stream.playing());
    }

    // this is meant to avoid a really horrible filechooser dialog
    // design that only exists in the GTK L&F
    public boolean changeLookAndFeel(Component comp) {
        boolean changed = false;
        String laf = UIManager.getLookAndFeel().getDescription();
        if (laf != null && laf.matches("GTK.*")) {
            String lf = UIManager.getCrossPlatformLookAndFeelClassName();
            try {
                UIManager.setLookAndFeel(lf);
                // just this one component
                SwingUtilities.updateComponentTreeUI(comp);
                changed = true;
            } catch (Exception e) {
                System.out.println(e);
            }
        }
        return changed;
    }

    // recover from the above indulgence
    public void restoreSystemLookAndFeel() {
        try {
            // Default to system-specific L&F
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // handle exception
        }
    }

    void handleTabbedPaneChange() {
        Component comp = sv_mainTabbedPane.getSelectedComponent();
        boolean isHelp = (comp == this.helpPanel);
        graphicHolderPanel.setVisible(!isHelp);
        helpPanel.setVisible(isHelp);
        helpPane.setVisible(isHelp);
        if (isHelp) {
            helpPane.sv_findTextField.requestFocus();
        }
        validate();
    }

    void resetDefaults(boolean activate) {
        signalProcessor.synthDisplay(false);
        streamMP3(false);
        audioCapture(false);
        sv_arraySizeComboBoxIndex.setSelectedItem("8192");
        sv_audioDataRateComboBoxIndex.setSelectedItem("192000");
        sv_graphicTipFlag = true;
        sv_carrierTextField.setText(formatNum(256.02));
        sv_modFreqTextField.setText("12");
        sv_modPercentTextField.setText(formatNum(100.000));
        sv_noiseLevelTextField.setText(formatNum(20.000));
        sv_xTimeOffset = 0;
        sv_xFreqOffset = 0;
        freqControl.graphicPane.setupOffset();
        timeControl.graphicPane.setupOffset();
        sv_traceColor.setColor(new Color(0, 128, 0));
        sv_backgroundColor.setColor(new Color(255, 255, 255));
        sv_timeVertIndex.setSelectedItem(formatNum(0.200));
        sv_freqVertIndex.setSelectedItem(formatNum(1.000));
        sv_timeHorizIndex.setSelectedIndex(2);
        sv_freqHorizIndex.setSelectedIndex(3);
        sv_mainTabbedPane.setSelectedIndex(0);
        if (applet) {
            sv_soundCheckBox.setSelected(true);
        } else {
            sv_soundCheckBox.setSelected(false);
        }
        sv_horizontalCheckBox.setSelected(false);
        sv_antialiasCheckBox.setSelected(false);
        sv_lineWidthComboBox.setSelectedItem("2");
        this.sv_amRadioButton.setSelected(true);
        setupDisplayConfig();
        readControls();
        if (activate) {
            signalProcessor.synthDisplay(true);
        }
    }

    void beep() {
        Toolkit.getDefaultToolkit().beep();
    }

    // applet interfaces
    public String getConfig() {
        if (initManager != null) {
            return initManager.getConfig();
        } else {
            return null;
        }
    }

    public void setConfig(String data) {
        initManager.setConfig(data);
        readControls();
        setupDisplayConfig();
        handleTabbedPaneChange();
        revalidate();
        repaint();
        signalProcessor.synthDisplay(true);
    }

    public void mouse_entered() {
        requestFocus();
    }

    public void close() {
        if (!applet) {
            initManager.writeConfig();
        }
        setVisible(false);
        //dispose();
        System.exit(0);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        synthModeButtonGroup = new javax.swing.ButtonGroup();
        graphicHolderPanel = new javax.swing.JPanel();
        gControlPanel = new javax.swing.JPanel();
        sv_timeDispCheckBox = new javax.swing.JCheckBox();
        sv_freqDispCheckBox = new javax.swing.JCheckBox();
        sv_horizontalCheckBox = new javax.swing.JCheckBox();
        sv_antialiasCheckBox = new javax.swing.JCheckBox();
        sv_lineWidthComboBox = new javax.swing.JComboBox();
        jLabel2 = new javax.swing.JLabel();
        gContentPanel = new javax.swing.JPanel();
        southPanel = new javax.swing.JPanel();
        sv_mainTabbedPane = new javax.swing.JTabbedPane();
        internalSourcePanel = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        sv_carrierTextField = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        sv_modFreqTextField = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        sv_modPercentTextField = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        sv_noiseLevelTextField = new javax.swing.JTextField();
        modePanel = new javax.swing.JPanel();
        sv_amRadioButton = new javax.swing.JRadioButton();
        sv_sqwRadioButton = new javax.swing.JRadioButton();
        sv_fmRadioButton = new javax.swing.JRadioButton();
        sv_twRadioButton = new javax.swing.JRadioButton();
        sv_stRadioButton = new javax.swing.JRadioButton();
        sv_soundCheckBox = new javax.swing.JCheckBox();
        startSynthButton = new javax.swing.JButton();
        stopSynthButton = new javax.swing.JButton();
        soundCapturePanel = new javax.swing.JPanel();
        soundCardPanel = new javax.swing.JPanel();
        startAudioCaptureButton = new javax.swing.JButton();
        stopAudioCaptureButton = new javax.swing.JButton();
        soundCardSourceLabel = new javax.swing.JLabel();
        sv_audioDataRateComboBoxIndex = new javax.swing.JComboBox();
        audioDataRateLabel = new javax.swing.JLabel();
        mp3Panel = new javax.swing.JPanel();
        startMP3Button = new javax.swing.JButton();
        mp3StreamProgressBar = new javax.swing.JProgressBar();
        jLabel11 = new javax.swing.JLabel();
        stopMP3Button = new javax.swing.JButton();
        configPanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        sv_sampleRateTextField = new javax.swing.JTextField();
        arraySizeLabel = new javax.swing.JLabel();
        sv_arraySizeComboBoxIndex = new javax.swing.JComboBox();
        configSubPanel = new javax.swing.JPanel();
        jLabel7 = new javax.swing.JLabel();
        traceColorButton = new javax.swing.JButton();
        jLabel8 = new javax.swing.JLabel();
        backgroundColorButton = new javax.swing.JButton();
        defaultsButton = new javax.swing.JButton();
        helpPanel = new javax.swing.JPanel();
        statusPanel = new javax.swing.JPanel();
        statusLabel = new javax.swing.JLabel();

        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                formMouseEntered(evt);
            }
        });
        setLayout(new java.awt.GridBagLayout());

        graphicHolderPanel.setLayout(new java.awt.GridBagLayout());

        gControlPanel.setBackground(new java.awt.Color(213, 242, 254));
        gControlPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        gControlPanel.setLayout(new java.awt.GridBagLayout());

        sv_timeDispCheckBox.setBackground(new java.awt.Color(213, 242, 254));
        sv_timeDispCheckBox.setSelected(true);
        sv_timeDispCheckBox.setText("Time");
        sv_timeDispCheckBox.setToolTipText("Show time scope");
        sv_timeDispCheckBox.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_timeDispCheckBox.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_timeDispCheckBoxMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4);
        gControlPanel.add(sv_timeDispCheckBox, gridBagConstraints);

        sv_freqDispCheckBox.setBackground(new java.awt.Color(213, 242, 254));
        sv_freqDispCheckBox.setSelected(true);
        sv_freqDispCheckBox.setText("Frequency");
        sv_freqDispCheckBox.setToolTipText("Show frequency scope");
        sv_freqDispCheckBox.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_freqDispCheckBox.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_freqDispCheckBoxMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4);
        gControlPanel.add(sv_freqDispCheckBox, gridBagConstraints);

        sv_horizontalCheckBox.setBackground(new java.awt.Color(213, 242, 254));
        sv_horizontalCheckBox.setText("Horizontal");
        sv_horizontalCheckBox.setToolTipText("Arrange scopes horizontally");
        sv_horizontalCheckBox.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_horizontalCheckBox.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_horizontalCheckBoxMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4);
        gControlPanel.add(sv_horizontalCheckBox, gridBagConstraints);

        sv_antialiasCheckBox.setBackground(new java.awt.Color(213, 242, 254));
        sv_antialiasCheckBox.setText("Antialias");
        sv_antialiasCheckBox.setToolTipText("Better-looking, but slower drawing");
        sv_antialiasCheckBox.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_antialiasCheckBox.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_antialiasCheckBoxMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4);
        gControlPanel.add(sv_antialiasCheckBox, gridBagConstraints);

        sv_lineWidthComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        sv_lineWidthComboBox.setToolTipText("Slows drawing down");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4);
        gControlPanel.add(sv_lineWidthComboBox, gridBagConstraints);

        jLabel2.setText("Line Width:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4);
        gControlPanel.add(jLabel2, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.01;
        gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 2);
        graphicHolderPanel.add(gControlPanel, gridBagConstraints);

        gContentPanel.setLayout(new java.awt.GridBagLayout());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        graphicHolderPanel.add(gContentPanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 10.0;
        add(graphicHolderPanel, gridBagConstraints);

        southPanel.setLayout(new java.awt.GridBagLayout());

        sv_mainTabbedPane.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
        sv_mainTabbedPane.setTabPlacement(javax.swing.JTabbedPane.BOTTOM);
        sv_mainTabbedPane.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_mainTabbedPaneMouseClicked(evt);
            }
        });

        internalSourcePanel.setBackground(new java.awt.Color(254, 254, 205));
        internalSourcePanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        internalSourcePanel.setLayout(new java.awt.GridBagLayout());

        jLabel3.setText("Carrier Freq. Hz");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        internalSourcePanel.add(jLabel3, gridBagConstraints);

        sv_carrierTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        sv_carrierTextField.setText("100.0");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        internalSourcePanel.add(sv_carrierTextField, gridBagConstraints);

        jLabel4.setText("Mod. Freq. Hz");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        internalSourcePanel.add(jLabel4, gridBagConstraints);

        sv_modFreqTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        sv_modFreqTextField.setText("25.0");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        internalSourcePanel.add(sv_modFreqTextField, gridBagConstraints);

        jLabel5.setText("Mod. Level %");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        internalSourcePanel.add(jLabel5, gridBagConstraints);

        sv_modPercentTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        sv_modPercentTextField.setText("100.0");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        internalSourcePanel.add(sv_modPercentTextField, gridBagConstraints);

        jLabel6.setText("Noise Level %");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        internalSourcePanel.add(jLabel6, gridBagConstraints);

        sv_noiseLevelTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        sv_noiseLevelTextField.setText("100.0");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        internalSourcePanel.add(sv_noiseLevelTextField, gridBagConstraints);

        modePanel.setBackground(new java.awt.Color(254, 254, 205));
        modePanel.setLayout(new java.awt.GridBagLayout());

        sv_amRadioButton.setBackground(new java.awt.Color(254, 254, 205));
        synthModeButtonGroup.add(sv_amRadioButton);
        sv_amRadioButton.setSelected(true);
        sv_amRadioButton.setText("AM");
        sv_amRadioButton.setToolTipText("Amplitude-modulation waveform");
        sv_amRadioButton.setAlignmentX(0.5F);
        sv_amRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_amRadioButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_amRadioButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        modePanel.add(sv_amRadioButton, gridBagConstraints);

        sv_sqwRadioButton.setBackground(new java.awt.Color(254, 254, 205));
        synthModeButtonGroup.add(sv_sqwRadioButton);
        sv_sqwRadioButton.setText("Square");
        sv_sqwRadioButton.setToolTipText("Square wave");
        sv_sqwRadioButton.setAlignmentX(0.5F);
        sv_sqwRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_sqwRadioButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_sqwRadioButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        modePanel.add(sv_sqwRadioButton, gridBagConstraints);

        sv_fmRadioButton.setBackground(new java.awt.Color(254, 254, 205));
        synthModeButtonGroup.add(sv_fmRadioButton);
        sv_fmRadioButton.setText("FM");
        sv_fmRadioButton.setToolTipText("Frequency-modulation waveform");
        sv_fmRadioButton.setAlignmentX(0.5F);
        sv_fmRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_fmRadioButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_fmRadioButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        modePanel.add(sv_fmRadioButton, gridBagConstraints);

        sv_twRadioButton.setBackground(new java.awt.Color(254, 254, 205));
        synthModeButtonGroup.add(sv_twRadioButton);
        sv_twRadioButton.setText("Triangle");
        sv_twRadioButton.setToolTipText("Triangle wave");
        sv_twRadioButton.setAlignmentX(0.5F);
        sv_twRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_twRadioButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_twRadioButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        modePanel.add(sv_twRadioButton, gridBagConstraints);

        sv_stRadioButton.setBackground(new java.awt.Color(254, 254, 205));
        synthModeButtonGroup.add(sv_stRadioButton);
        sv_stRadioButton.setText("Sawtooth");
        sv_stRadioButton.setToolTipText("Sawtooth wave");
        sv_stRadioButton.setAlignmentX(0.5F);
        sv_stRadioButton.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_stRadioButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_stRadioButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        modePanel.add(sv_stRadioButton, gridBagConstraints);

        sv_soundCheckBox.setBackground(new java.awt.Color(254, 254, 205));
        sv_soundCheckBox.setSelected(true);
        sv_soundCheckBox.setText("Sound");
        sv_soundCheckBox.setToolTipText("<html>Create sound of synthesized waveform<br/>(limits program to 1 frame/sec)");
        sv_soundCheckBox.setAlignmentX(0.5F);
        sv_soundCheckBox.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        sv_soundCheckBox.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                sv_soundCheckBoxMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        modePanel.add(sv_soundCheckBox, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 5;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        internalSourcePanel.add(modePanel, gridBagConstraints);

        startSynthButton.setText("Start");
        startSynthButton.setToolTipText("Press to start the synthesizer");
        startSynthButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                startSynthButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        internalSourcePanel.add(startSynthButton, gridBagConstraints);

        stopSynthButton.setText("Stop");
        stopSynthButton.setToolTipText("Press to stop the synthesizer");
        stopSynthButton.setEnabled(false);
        stopSynthButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                stopSynthButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        internalSourcePanel.add(stopSynthButton, gridBagConstraints);

        sv_mainTabbedPane.addTab("Synthesizer", new javax.swing.ImageIcon(getClass().getResource("/fftexplorer/icons/applications-multimedia.png")), internalSourcePanel); // NOI18N

        soundCapturePanel.setLayout(new java.awt.GridBagLayout());

        soundCardPanel.setBackground(new java.awt.Color(223, 255, 221));
        soundCardPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        soundCardPanel.setLayout(new java.awt.GridBagLayout());

        startAudioCaptureButton.setText("Start");
        startAudioCaptureButton.setToolTipText("Start sound card capture");
        startAudioCaptureButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                startAudioCaptureButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        soundCardPanel.add(startAudioCaptureButton, gridBagConstraints);

        stopAudioCaptureButton.setText("Stop");
        stopAudioCaptureButton.setEnabled(false);
        stopAudioCaptureButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                stopAudioCaptureButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        soundCardPanel.add(stopAudioCaptureButton, gridBagConstraints);

        soundCardSourceLabel.setFont(new java.awt.Font("DejaVu Sans", 1, 14));
        soundCardSourceLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        soundCardSourceLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fftexplorer/icons/audio-card.png"))); // NOI18N
        soundCardSourceLabel.setText("Sound Card Source");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        soundCardPanel.add(soundCardSourceLabel, gridBagConstraints);

        sv_audioDataRateComboBoxIndex.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        sv_audioDataRateComboBoxIndex.setToolTipText("Highest data rate is preferred");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 4, 4);
        soundCardPanel.add(sv_audioDataRateComboBoxIndex, gridBagConstraints);

        audioDataRateLabel.setText("Data Rate:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        soundCardPanel.add(audioDataRateLabel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.01;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 2);
        soundCapturePanel.add(soundCardPanel, gridBagConstraints);

        mp3Panel.setBackground(new java.awt.Color(205, 223, 255));
        mp3Panel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        mp3Panel.setLayout(new java.awt.GridBagLayout());

        startMP3Button.setText("Start");
        startMP3Button.setToolTipText("Choose a sound file and play it");
        startMP3Button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                startMP3ButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        mp3Panel.add(startMP3Button, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        mp3Panel.add(mp3StreamProgressBar, gridBagConstraints);

        jLabel11.setFont(new java.awt.Font("DejaVu Sans", 1, 14));
        jLabel11.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel11.setIcon(new javax.swing.ImageIcon(getClass().getResource("/fftexplorer/icons/audio-x-monkey.png"))); // NOI18N
        jLabel11.setText("Audio File Source");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        mp3Panel.add(jLabel11, gridBagConstraints);

        stopMP3Button.setText("Stop");
        stopMP3Button.setEnabled(false);
        stopMP3Button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                stopMP3ButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        mp3Panel.add(stopMP3Button, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.01;
        soundCapturePanel.add(mp3Panel, gridBagConstraints);

        sv_mainTabbedPane.addTab("External Sources", new javax.swing.ImageIcon(getClass().getResource("/fftexplorer/icons/audio-input-microphone.png")), soundCapturePanel); // NOI18N

        configPanel.setBackground(new java.awt.Color(234, 235, 254));
        configPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        configPanel.setLayout(new java.awt.GridBagLayout());

        jLabel1.setFont(new java.awt.Font("DejaVu Sans", 1, 14));
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Sample Rate:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        configPanel.add(jLabel1, gridBagConstraints);

        sv_sampleRateTextField.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        sv_sampleRateTextField.setText("8192.0");
        sv_sampleRateTextField.setToolTipText("See help for setting this field");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        configPanel.add(sv_sampleRateTextField, gridBagConstraints);

        arraySizeLabel.setFont(new java.awt.Font("DejaVu Sans", 1, 14));
        arraySizeLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        arraySizeLabel.setText("FFT Array Size:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 4);
        configPanel.add(arraySizeLabel, gridBagConstraints);

        sv_arraySizeComboBoxIndex.setBackground(new java.awt.Color(234, 235, 254));
        sv_arraySizeComboBoxIndex.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        sv_arraySizeComboBoxIndex.setToolTipText("Large values give more detail but take longer");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        configPanel.add(sv_arraySizeComboBoxIndex, gridBagConstraints);

        configSubPanel.setBackground(new java.awt.Color(234, 235, 254));
        configSubPanel.setLayout(new java.awt.GridBagLayout());

        jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel7.setText("Line color:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        configSubPanel.add(jLabel7, gridBagConstraints);

        traceColorButton.setText("jButton1");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 0.1;
        configSubPanel.add(traceColorButton, gridBagConstraints);

        jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel8.setText("Background color:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4);
        configSubPanel.add(jLabel8, gridBagConstraints);

        backgroundColorButton.setText("jButton1");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 0.1;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 4);
        configSubPanel.add(backgroundColorButton, gridBagConstraints);

        defaultsButton.setText("Reset All Defaults");
        defaultsButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                defaultsButtonMouseClicked(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
        configSubPanel.add(defaultsButton, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        configPanel.add(configSubPanel, gridBagConstraints);

        sv_mainTabbedPane.addTab("Configure", new javax.swing.ImageIcon(getClass().getResource("/fftexplorer/icons/applications-accessories.png")), configPanel); // NOI18N

        helpPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        helpPanel.setLayout(new java.awt.GridBagLayout());
        sv_mainTabbedPane.addTab("Help", new javax.swing.ImageIcon(getClass().getResource("/fftexplorer/icons/system-help.png")), helpPanel); // NOI18N

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.0010;
        southPanel.add(sv_mainTabbedPane, gridBagConstraints);

        statusPanel.setLayout(new java.awt.GridBagLayout());

        statusLabel.setText("Status/Position");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4);
        statusPanel.add(statusLabel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        southPanel.add(statusPanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.01;
        add(southPanel, gridBagConstraints);
    }// </editor-fold>//GEN-END:initComponents

    private void sv_timeDispCheckBoxMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_timeDispCheckBoxMouseClicked
        // TODO add your handling code here:
        setupDisplayConfig();
}//GEN-LAST:event_sv_timeDispCheckBoxMouseClicked

    private void sv_freqDispCheckBoxMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_freqDispCheckBoxMouseClicked
        // TODO add your handling code here:
        setupDisplayConfig();
}//GEN-LAST:event_sv_freqDispCheckBoxMouseClicked

    private void sv_horizontalCheckBoxMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_horizontalCheckBoxMouseClicked
        // TODO add your handling code here:
        setupDisplayConfig();
}//GEN-LAST:event_sv_horizontalCheckBoxMouseClicked

    private void sv_antialiasCheckBoxMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_antialiasCheckBoxMouseClicked
        // TODO add your handling code here:
        adjustControls();
}//GEN-LAST:event_sv_antialiasCheckBoxMouseClicked

    private void sv_amRadioButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_amRadioButtonMouseClicked
        // TODO add your handling code here:
        signalProcessor.setMode();
}//GEN-LAST:event_sv_amRadioButtonMouseClicked

    private void sv_sqwRadioButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_sqwRadioButtonMouseClicked
        // TODO add your handling code here:
        signalProcessor.setMode();
}//GEN-LAST:event_sv_sqwRadioButtonMouseClicked

    private void sv_fmRadioButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_fmRadioButtonMouseClicked
        // TODO add your handling code here:
        signalProcessor.setMode();
}//GEN-LAST:event_sv_fmRadioButtonMouseClicked

    private void sv_twRadioButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_twRadioButtonMouseClicked
        // TODO add your handling code here:
        signalProcessor.setMode();
}//GEN-LAST:event_sv_twRadioButtonMouseClicked

    private void sv_stRadioButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_stRadioButtonMouseClicked
        // TODO add your handling code here:
        readControls();
}//GEN-LAST:event_sv_stRadioButtonMouseClicked

    private void sv_soundCheckBoxMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_soundCheckBoxMouseClicked
        // TODO add your handling code here:
        readControls();
}//GEN-LAST:event_sv_soundCheckBoxMouseClicked

    private void startSynthButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_startSynthButtonMouseClicked
        // TODO add your handling code here:
        signalProcessor.synthDisplay(true);
}//GEN-LAST:event_startSynthButtonMouseClicked

    private void stopSynthButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_stopSynthButtonMouseClicked
        // TODO add your handling code here:
        signalProcessor.synthDisplay(false);
}//GEN-LAST:event_stopSynthButtonMouseClicked

    private void startAudioCaptureButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_startAudioCaptureButtonMouseClicked
        // TODO add your handling code here:
        audioCapture(true);
}//GEN-LAST:event_startAudioCaptureButtonMouseClicked

    private void stopAudioCaptureButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_stopAudioCaptureButtonMouseClicked
        // TODO add your handling code here:
        audioCapture(false);
}//GEN-LAST:event_stopAudioCaptureButtonMouseClicked

    private void startMP3ButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_startMP3ButtonMouseClicked
        // TODO add your handling code here:
        streamMP3(true);
}//GEN-LAST:event_startMP3ButtonMouseClicked

    private void stopMP3ButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_stopMP3ButtonMouseClicked
        // TODO add your handling code here:
        streamMP3(false);
}//GEN-LAST:event_stopMP3ButtonMouseClicked

    private void defaultsButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_defaultsButtonMouseClicked
        // TODO add your handling code here:
        resetDefaults(applet);
}//GEN-LAST:event_defaultsButtonMouseClicked

    private void sv_mainTabbedPaneMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_sv_mainTabbedPaneMouseClicked
        // TODO add your handling code here:
        handleTabbedPaneChange();
}//GEN-LAST:event_sv_mainTabbedPaneMouseClicked

    private void formMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseEntered
        mouse_entered();
    }//GEN-LAST:event_formMouseEntered

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel arraySizeLabel;
    private javax.swing.JLabel audioDataRateLabel;
    private javax.swing.JButton backgroundColorButton;
    private javax.swing.JPanel configPanel;
    private javax.swing.JPanel configSubPanel;
    private javax.swing.JButton defaultsButton;
    private javax.swing.JPanel gContentPanel;
    private javax.swing.JPanel gControlPanel;
    private javax.swing.JPanel graphicHolderPanel;
    private javax.swing.JPanel helpPanel;
    private javax.swing.JPanel internalSourcePanel;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JPanel modePanel;
    private javax.swing.JPanel mp3Panel;
    protected javax.swing.JProgressBar mp3StreamProgressBar;
    private javax.swing.JPanel soundCapturePanel;
    private javax.swing.JPanel soundCardPanel;
    private javax.swing.JLabel soundCardSourceLabel;
    private javax.swing.JPanel southPanel;
    private javax.swing.JButton startAudioCaptureButton;
    protected javax.swing.JButton startMP3Button;
    protected javax.swing.JButton startSynthButton;
    private javax.swing.JLabel statusLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JButton stopAudioCaptureButton;
    protected javax.swing.JButton stopMP3Button;
    protected javax.swing.JButton stopSynthButton;
    protected javax.swing.JRadioButton sv_amRadioButton;
    protected javax.swing.JCheckBox sv_antialiasCheckBox;
    protected javax.swing.JComboBox sv_arraySizeComboBoxIndex;
    protected javax.swing.JComboBox sv_audioDataRateComboBoxIndex;
    protected javax.swing.JTextField sv_carrierTextField;
    protected javax.swing.JRadioButton sv_fmRadioButton;
    protected javax.swing.JCheckBox sv_freqDispCheckBox;
    protected javax.swing.JCheckBox sv_horizontalCheckBox;
    protected javax.swing.JComboBox sv_lineWidthComboBox;
    protected javax.swing.JTabbedPane sv_mainTabbedPane;
    protected javax.swing.JTextField sv_modFreqTextField;
    protected javax.swing.JTextField sv_modPercentTextField;
    protected javax.swing.JTextField sv_noiseLevelTextField;
    protected javax.swing.JTextField sv_sampleRateTextField;
    protected javax.swing.JCheckBox sv_soundCheckBox;
    protected javax.swing.JRadioButton sv_sqwRadioButton;
    protected javax.swing.JRadioButton sv_stRadioButton;
    protected javax.swing.JCheckBox sv_timeDispCheckBox;
    protected javax.swing.JRadioButton sv_twRadioButton;
    private javax.swing.ButtonGroup synthModeButtonGroup;
    private javax.swing.JButton traceColorButton;
    // End of variables declaration//GEN-END:variables
}
