org.bryantd.lightscameraaction.PluginInterface.java Source code

Java tutorial

Introduction

Here is the source code for org.bryantd.lightscameraaction.PluginInterface.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package org.bryantd.lightscameraaction;

import java.awt.Component;
import java.awt.Container;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.CancellationException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.joda.time.DateTime;
import javax.swing.SwingWorker;
import javax.swing.SwingWorker.StateValue;
import static javax.swing.SwingWorker.StateValue.PENDING;
import static javax.swing.SwingWorker.StateValue.STARTED;
import javax.swing.text.DefaultCaret;

public class PluginInterface extends javax.swing.JFrame {
    private Camera camera_;
    private Lights lights_;
    private LightsCameraPlugin plugin_;
    private SwingWorker worker_;

    private String lightsIPAddress_;
    private Integer lightsPort_;
    private String savePath_;
    private Integer lightsToImageDelayMS_;
    private ArrayList<DateTime> imageJobsSchedule_;

    public PluginInterface(LightsCameraPlugin plugin) {
        this.plugin_ = plugin;
        initComponents();
    }

    public void dispose() {
        super.dispose();
    }

    /**
     * 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() {

        buttonGroupTimeUnits = new javax.swing.ButtonGroup();
        buttonGroupImageDelay = new javax.swing.ButtonGroup();
        jFileChooserSaveLocation = new javax.swing.JFileChooser();
        jFileChooserLoadConfig = new javax.swing.JFileChooser();
        jPanelConfiguration = new javax.swing.JPanel();
        jButtonImageSaveLocation = new javax.swing.JButton();
        jTextFieldSaveLocation = new javax.swing.JTextField();
        jSpinnerTimeBetween = new javax.swing.JSpinner();
        jRadioButtonTimeBetweenMin = new javax.swing.JRadioButton();
        jRadioButtonTimeBetweenS = new javax.swing.JRadioButton();
        jRadioButtonTimeBetweenMS = new javax.swing.JRadioButton();
        jLabelTimeBetween = new javax.swing.JLabel();
        jSpinnerNumImages = new javax.swing.JSpinner();
        jLabelNumImages = new javax.swing.JLabel();
        jLabelConfiguration = new javax.swing.JLabel();
        jSpinnerDelay = new javax.swing.JSpinner();
        jRadioButtonDelayMin = new javax.swing.JRadioButton();
        jRadioButtonDelayS = new javax.swing.JRadioButton();
        jRadioButtonDelayMS = new javax.swing.JRadioButton();
        jLabelLightsImageDelay = new javax.swing.JLabel();
        jTextFieldLightsIPAddress = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jTextFieldPort = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jButtonLoadConfig = new javax.swing.JButton();
        jButtonSaveConfig = new javax.swing.JButton();
        jPanelTesting = new javax.swing.JPanel();
        jLabelTesting = new javax.swing.JLabel();
        jButtonTestLights = new javax.swing.JButton();
        jButtonTestImage = new javax.swing.JButton();
        jPanelRun = new javax.swing.JPanel();
        jLabelRun = new javax.swing.JLabel();
        jButtonStartJob = new javax.swing.JButton();
        jCheckBoxRequireSchedule = new javax.swing.JCheckBox();
        jPanelOutput = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextAreaStatus = new javax.swing.JTextArea();
        jPanelWavelengths = new javax.swing.JPanel();
        jLabelWavelenghts = new javax.swing.JLabel();
        jButtonGetwl = new javax.swing.JButton();
        jTextFieldWavelenghts = new javax.swing.JTextField();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTextAreaWavelengthsHelpText = new javax.swing.JTextArea();
        jMenuBarFileMenu = new javax.swing.JMenuBar();
        jMenuFile = new javax.swing.JMenu();
        Exit = new javax.swing.JMenuItem();

        jFileChooserSaveLocation.setAcceptAllFileFilterUsed(false);
        jFileChooserSaveLocation.setCurrentDirectory(null);
        jFileChooserSaveLocation.setDialogTitle("Choose images save location...");
        jFileChooserSaveLocation.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY);

        jFileChooserLoadConfig.setDialogTitle("Load Configuration File");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("LightsCameraAction");
        setMaximumSize(new java.awt.Dimension(5000, 5000));
        setMinimumSize(new java.awt.Dimension(700, 950));
        setPreferredSize(new java.awt.Dimension(700, 950));

        jPanelConfiguration
                .setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

        jButtonImageSaveLocation.setText("Specify Image Save Location");
        jButtonImageSaveLocation.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonImageSaveLocationActionPerformed(evt);
            }
        });

        jTextFieldSaveLocation.setEditable(false);
        jTextFieldSaveLocation.setBackground(new java.awt.Color(204, 204, 204));
        jTextFieldSaveLocation.setText("No location specified.");

        jSpinnerTimeBetween.setModel(new javax.swing.SpinnerNumberModel(Double.valueOf(0.0d), Double.valueOf(0.0d),
                null, Double.valueOf(0.1d)));

        buttonGroupTimeUnits.add(jRadioButtonTimeBetweenMin);
        jRadioButtonTimeBetweenMin.setSelected(true);
        jRadioButtonTimeBetweenMin.setText("Min");

        buttonGroupTimeUnits.add(jRadioButtonTimeBetweenS);
        jRadioButtonTimeBetweenS.setText("S");

        buttonGroupTimeUnits.add(jRadioButtonTimeBetweenMS);
        jRadioButtonTimeBetweenMS.setText("MS");

        jLabelTimeBetween.setText("between acquired images.");

        jSpinnerNumImages.setModel(new javax.swing.SpinnerNumberModel(Integer.valueOf(0), Integer.valueOf(0), null,
                Integer.valueOf(1)));

        jLabelNumImages.setText("Number of images to acquire.");

        jLabelConfiguration.setFont(new java.awt.Font("Lucida Grande", 0, 18)); // NOI18N
        jLabelConfiguration.setText("Configuration");

        buttonGroupImageDelay.add(jRadioButtonDelayMin);
        jRadioButtonDelayMin.setText("Min");

        buttonGroupImageDelay.add(jRadioButtonDelayS);
        jRadioButtonDelayS.setText("S");

        buttonGroupImageDelay.add(jRadioButtonDelayMS);
        jRadioButtonDelayMS.setSelected(true);
        jRadioButtonDelayMS.setText("MS");

        jLabelLightsImageDelay.setText("WL command sent to image delay.");

        jTextFieldLightsIPAddress.setHorizontalAlignment(javax.swing.JTextField.CENTER);

        jLabel1.setText("Lights IP Address : Port");

        jTextFieldPort.setHorizontalAlignment(javax.swing.JTextField.CENTER);

        jLabel2.setText(":");

        jButtonLoadConfig.setText("Load Configuration");
        jButtonLoadConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonLoadConfigActionPerformed(evt);
            }
        });

        jButtonSaveConfig.setText("Save Configuration");
        jButtonSaveConfig.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSaveConfigActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelConfigurationLayout = new javax.swing.GroupLayout(jPanelConfiguration);
        jPanelConfiguration.setLayout(jPanelConfigurationLayout);
        jPanelConfigurationLayout.setHorizontalGroup(jPanelConfigurationLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanelConfigurationLayout.createSequentialGroup().addContainerGap()
                        .addGroup(jPanelConfigurationLayout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanelConfigurationLayout.createSequentialGroup()
                                        .addGroup(jPanelConfigurationLayout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING,
                                                        false)
                                                .addComponent(jButtonLoadConfig,
                                                        javax.swing.GroupLayout.Alignment.LEADING,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                .addComponent(jButtonSaveConfig,
                                                        javax.swing.GroupLayout.Alignment.LEADING,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                .addComponent(jButtonImageSaveLocation,
                                                        javax.swing.GroupLayout.Alignment.LEADING,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(jTextFieldSaveLocation))
                                .addGroup(jPanelConfigurationLayout.createSequentialGroup()
                                        .addGroup(jPanelConfigurationLayout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addGroup(jPanelConfigurationLayout.createSequentialGroup()
                                                        .addGroup(jPanelConfigurationLayout
                                                                .createParallelGroup(
                                                                        javax.swing.GroupLayout.Alignment.TRAILING,
                                                                        false)
                                                                .addComponent(jSpinnerTimeBetween)
                                                                .addGroup(javax.swing.GroupLayout.Alignment.LEADING,
                                                                        jPanelConfigurationLayout
                                                                                .createSequentialGroup()
                                                                                .addComponent(
                                                                                        jTextFieldLightsIPAddress,
                                                                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                        137,
                                                                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                                .addPreferredGap(
                                                                                        javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                                .addComponent(jLabel2)
                                                                                .addPreferredGap(
                                                                                        javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                                .addComponent(jTextFieldPort,
                                                                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                        68,
                                                                                        javax.swing.GroupLayout.PREFERRED_SIZE)))
                                                        .addPreferredGap(
                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                        .addGroup(jPanelConfigurationLayout
                                                                .createParallelGroup(
                                                                        javax.swing.GroupLayout.Alignment.LEADING)
                                                                .addGroup(jPanelConfigurationLayout
                                                                        .createSequentialGroup()
                                                                        .addComponent(jRadioButtonTimeBetweenMin)
                                                                        .addPreferredGap(
                                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                        .addComponent(jRadioButtonTimeBetweenS)
                                                                        .addPreferredGap(
                                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                        .addComponent(jRadioButtonTimeBetweenMS)
                                                                        .addPreferredGap(
                                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                        .addComponent(jLabelTimeBetween))
                                                                .addComponent(jLabel1)))
                                                .addGroup(jPanelConfigurationLayout.createSequentialGroup()
                                                        .addComponent(jSpinnerDelay,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE, 221,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                                        .addPreferredGap(
                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(jRadioButtonDelayMin)
                                                        .addPreferredGap(
                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(jRadioButtonDelayS)
                                                        .addPreferredGap(
                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(jRadioButtonDelayMS)
                                                        .addPreferredGap(
                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(jLabelLightsImageDelay))
                                                .addGroup(jPanelConfigurationLayout.createSequentialGroup()
                                                        .addComponent(jSpinnerNumImages,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE, 221,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                                        .addPreferredGap(
                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                        .addComponent(jLabelNumImages,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE, 198,
                                                                javax.swing.GroupLayout.PREFERRED_SIZE))
                                                .addComponent(jLabelConfiguration))
                                        .addGap(0, 0, Short.MAX_VALUE)))
                        .addContainerGap()));
        jPanelConfigurationLayout.setVerticalGroup(jPanelConfigurationLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelConfigurationLayout
                        .createSequentialGroup().addContainerGap().addComponent(jLabelConfiguration)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonLoadConfig)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonSaveConfig)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelConfigurationLayout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                                .addComponent(jButtonImageSaveLocation).addComponent(jTextFieldSaveLocation,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelConfigurationLayout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jTextFieldLightsIPAddress, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel1)
                                .addComponent(jTextFieldPort, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel2))
                        .addGap(7, 7, 7)
                        .addGroup(jPanelConfigurationLayout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                                .addComponent(jSpinnerTimeBetween, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jRadioButtonTimeBetweenMin).addComponent(jRadioButtonTimeBetweenS)
                                .addComponent(jRadioButtonTimeBetweenMS).addComponent(jLabelTimeBetween,
                                        javax.swing.GroupLayout.PREFERRED_SIZE, 28,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelConfigurationLayout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                                .addComponent(jSpinnerDelay, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jRadioButtonDelayMin).addComponent(jRadioButtonDelayS)
                                .addComponent(jRadioButtonDelayMS).addComponent(jLabelLightsImageDelay))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelConfigurationLayout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                                .addComponent(jSpinnerNumImages, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabelNumImages))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

        jPanelTesting.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

        jLabelTesting.setFont(new java.awt.Font("Lucida Grande", 0, 18)); // NOI18N
        jLabelTesting.setText("Testing");

        jButtonTestLights.setText("Test Lights On/Off");
        jButtonTestLights.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonTestLightsActionPerformed(evt);
            }
        });

        jButtonTestImage.setText("Test Image Acquisition");

        javax.swing.GroupLayout jPanelTestingLayout = new javax.swing.GroupLayout(jPanelTesting);
        jPanelTesting.setLayout(jPanelTestingLayout);
        jPanelTestingLayout.setHorizontalGroup(jPanelTestingLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanelTestingLayout.createSequentialGroup().addContainerGap()
                        .addGroup(jPanelTestingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabelTesting)
                                .addGroup(jPanelTestingLayout.createSequentialGroup()
                                        .addComponent(jButtonTestLights, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                189, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addComponent(jButtonTestImage)))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
        jPanelTestingLayout
                .setVerticalGroup(jPanelTestingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanelTestingLayout.createSequentialGroup().addContainerGap()
                                .addComponent(jLabelTesting)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(jPanelTestingLayout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                        .addComponent(jButtonTestLights).addComponent(jButtonTestImage))
                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

        jPanelRun.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

        jLabelRun.setFont(new java.awt.Font("Lucida Grande", 0, 18)); // NOI18N
        jLabelRun.setText("Run");

        jButtonStartJob.setText("Start Imaging Job");
        jButtonStartJob.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonStartJobActionPerformed(evt);
            }
        });

        jCheckBoxRequireSchedule.setSelected(true);
        jCheckBoxRequireSchedule.setText("Require Lights Schedule Running");

        javax.swing.GroupLayout jPanelRunLayout = new javax.swing.GroupLayout(jPanelRun);
        jPanelRun.setLayout(jPanelRunLayout);
        jPanelRunLayout
                .setHorizontalGroup(jPanelRunLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanelRunLayout.createSequentialGroup().addContainerGap().addComponent(jLabelRun)
                                .addContainerGap(645, Short.MAX_VALUE))
                        .addGroup(jPanelRunLayout.createSequentialGroup().addComponent(jButtonStartJob)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(jCheckBoxRequireSchedule).addContainerGap()));
        jPanelRunLayout.setVerticalGroup(jPanelRunLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanelRunLayout.createSequentialGroup().addContainerGap().addComponent(jLabelRun)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanelRunLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                                .addComponent(jButtonStartJob).addComponent(jCheckBoxRequireSchedule))
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

        jPanelOutput.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

        jTextAreaStatus.setEditable(false);
        jTextAreaStatus.setBackground(new java.awt.Color(0, 0, 0));
        jTextAreaStatus.setColumns(20);
        jTextAreaStatus.setForeground(new java.awt.Color(255, 255, 255));
        jTextAreaStatus.setLineWrap(true);
        jTextAreaStatus.setRows(5);
        jTextAreaStatus.setWrapStyleWord(true);
        jScrollPane1.setViewportView(jTextAreaStatus);
        DefaultCaret caret = (DefaultCaret) jTextAreaStatus.getCaret();
        caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

        javax.swing.GroupLayout jPanelOutputLayout = new javax.swing.GroupLayout(jPanelOutput);
        jPanelOutput.setLayout(jPanelOutputLayout);
        jPanelOutputLayout.setHorizontalGroup(jPanelOutputLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(jPanelOutputLayout
                        .createSequentialGroup().addContainerGap().addComponent(jScrollPane1).addContainerGap()));
        jPanelOutputLayout.setVerticalGroup(jPanelOutputLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanelOutputLayout.createSequentialGroup().addContainerGap()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 305, Short.MAX_VALUE)
                        .addContainerGap()));

        jPanelWavelengths
                .setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));

        jLabelWavelenghts.setFont(new java.awt.Font("Lucida Grande", 0, 18)); // NOI18N
        jLabelWavelenghts.setText("Wavelengths");

        jButtonGetwl.setText("Send getwl command");
        jButtonGetwl.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonGetwlActionPerformed(evt);
            }
        });

        jTextFieldWavelenghts.setText("setall 0");

        jScrollPane2.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);

        jTextAreaWavelengthsHelpText.setEditable(false);
        jTextAreaWavelengthsHelpText.setBackground(new java.awt.Color(238, 238, 238));
        jTextAreaWavelengthsHelpText.setColumns(20);
        jTextAreaWavelengthsHelpText.setLineWrap(true);
        jTextAreaWavelengthsHelpText.setRows(3);
        jTextAreaWavelengthsHelpText.setText(
                "Lights command prior to imaging is \"setall 0\" by default. Replace with appropriate \"setwlsrelpower\" command below, if desired. Click button above to query your lights for supported wavelenghts.");
        jTextAreaWavelengthsHelpText.setToolTipText("");
        jTextAreaWavelengthsHelpText.setWrapStyleWord(true);
        jTextAreaWavelengthsHelpText.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        jTextAreaWavelengthsHelpText.setDragEnabled(false);
        jScrollPane2.setViewportView(jTextAreaWavelengthsHelpText);

        javax.swing.GroupLayout jPanelWavelengthsLayout = new javax.swing.GroupLayout(jPanelWavelengths);
        jPanelWavelengths.setLayout(jPanelWavelengthsLayout);
        jPanelWavelengthsLayout.setHorizontalGroup(
                jPanelWavelengthsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanelWavelengthsLayout.createSequentialGroup().addContainerGap()
                                .addGroup(jPanelWavelengthsLayout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(jScrollPane2)
                                        .addGroup(jPanelWavelengthsLayout.createSequentialGroup()
                                                .addComponent(jLabelWavelenghts)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(jButtonGetwl).addGap(0, 0, Short.MAX_VALUE))
                                        .addComponent(jTextFieldWavelenghts))
                                .addContainerGap()));
        jPanelWavelengthsLayout.setVerticalGroup(jPanelWavelengthsLayout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelWavelengthsLayout
                        .createSequentialGroup().addContainerGap()
                        .addGroup(jPanelWavelengthsLayout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jButtonGetwl).addComponent(jLabelWavelenghts))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextFieldWavelenghts, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

        jMenuFile.setText("File");

        Exit.setText("Exit");
        Exit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ExitActionPerformed(evt);
            }
        });
        jMenuFile.add(Exit);

        jMenuBarFileMenu.add(jMenuFile);

        setJMenuBar(jMenuBarFileMenu);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup().addContainerGap()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jPanelWavelengths, javax.swing.GroupLayout.Alignment.TRAILING,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        Short.MAX_VALUE)
                                .addComponent(jPanelOutput, javax.swing.GroupLayout.Alignment.TRAILING,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        Short.MAX_VALUE)
                                .addComponent(jPanelConfiguration, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(jPanelTesting, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(jPanelRun, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addContainerGap()));
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                javax.swing.GroupLayout.Alignment.TRAILING,
                layout.createSequentialGroup().addContainerGap()
                        .addComponent(jPanelConfiguration, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelTesting, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelWavelengths, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelRun, javax.swing.GroupLayout.PREFERRED_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelOutput, javax.swing.GroupLayout.DEFAULT_SIZE,
                                javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addContainerGap()));

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void ExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ExitActionPerformed
        System.exit(0);
    }//GEN-LAST:event_ExitActionPerformed

    private void jButtonStartJobActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonStartJobActionPerformed
        if (worker_ == null) {
            if (!sanitizeIPPort()) {
                jTextAreaStatus.append(Utilities.timeStamp("Please check your IP and Port.\n").toString());
            } else if (!userSetSavePath()) {
                jTextAreaStatus.append(Utilities.timeStamp("Please set image save path.\n").toString());
            } else if (initializeImagingJobs()) {
                if (lights_ == null) {
                    lights_ = new Lights(lightsIPAddress_, lightsPort_);
                }
                if (camera_ == null) {
                    try {
                        camera_ = new Camera(plugin_.getCore_(), savePath_);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }
                String setWLCommand = jTextFieldWavelenghts.getText();
                worker_ = new LightsCameraActionWorker(camera_, lights_, jTextAreaStatus, imageJobsSchedule_,
                        lightsToImageDelayMS_, setWLCommand, jCheckBoxRequireSchedule.isSelected());
                addPropertyChangeListenersRun(worker_);
                worker_.execute();
            }
        } else {
            worker_.cancel(true);
        }
    }//GEN-LAST:event_jButtonStartJobActionPerformed

    private Boolean initializeImagingJobs() {
        Boolean userInputOK = true;
        imageJobsSchedule_ = new ArrayList<DateTime>();

        Double timeBetweenImages = Double.parseDouble((jSpinnerTimeBetween.getValue()).toString().trim());
        Integer timeBetweenImagesMS = timeBetweenImages.intValue();
        Double lightsToImageDelay = Double.parseDouble((jSpinnerDelay.getValue()).toString().trim());
        Integer lightsToImageDelayMS = lightsToImageDelay.intValue();
        Integer numImages = (Integer) jSpinnerNumImages.getValue();

        if (jRadioButtonTimeBetweenMin.isSelected()) {
            Double tempMS = timeBetweenImages * 60.0 * 1000.0;
            timeBetweenImagesMS = tempMS.intValue();
        } else if (jRadioButtonTimeBetweenS.isSelected()) {
            Double tempMS = timeBetweenImages * 1000.0;
            timeBetweenImagesMS = tempMS.intValue();
        }
        System.out.println("Time between images MS: " + timeBetweenImagesMS);

        if (jRadioButtonDelayMin.isSelected()) {
            Double tempMS = lightsToImageDelay * 60.0 * 1000.0;
            lightsToImageDelayMS = tempMS.intValue();
        } else if (jRadioButtonDelayS.isSelected()) {
            Double tempMS = lightsToImageDelay * 1000.0;
            lightsToImageDelayMS = tempMS.intValue();
        }
        System.out.println("Lights to image delay MS: " + lightsToImageDelayMS);

        if (numImages < 1 || timeBetweenImagesMS <= 0 || lightsToImageDelayMS < 0
                || timeBetweenImagesMS < 2 * lightsToImageDelayMS) {
            userInputOK = false;
            if (timeBetweenImagesMS <= 0) {
                jTextAreaStatus.append(Utilities
                        .timeStamp("Error: " + timeBetweenImagesMS + " is not a valid time between images.\n")
                        .toString());
            }
            if (lightsToImageDelayMS < 0) {
                jTextAreaStatus
                        .append(Utilities
                                .timeStamp("Error: " + lightsToImageDelayMS
                                        + "is not a valid lights off to image acquisition time delay.\n")
                                .toString());
            }
            if (timeBetweenImagesMS < 2 * lightsToImageDelayMS) {
                jTextAreaStatus.append(Utilities
                        .timeStamp("Error: time between images (" + timeBetweenImagesMS
                                + " ms) must be at least 2x delay (" + lightsToImageDelayMS + " ms).\n")
                        .toString());
            }
            if (numImages < 1) {
                jTextAreaStatus.append(Utilities
                        .timeStamp("Error: " + numImages + " is not a valid number of images to acquire.\n")
                        .toString());
            }
        }

        if (userInputOK) {
            this.lightsToImageDelayMS_ = lightsToImageDelayMS;
            imageJobsSchedule_.clear();
            DateTime now = new DateTime();
            now = now.plusSeconds(5);
            for (Integer i = 0; i < numImages; i++) {
                DateTime scheduledJob = now.plusMillis(i * timeBetweenImagesMS);
                imageJobsSchedule_.add(scheduledJob);
                System.out.println("Added " + scheduledJob);
            }
            jTextAreaStatus.append(Utilities
                    .timeStamp("Added " + imageJobsSchedule_.size() + " image acquisition events to schedule.\n")
                    .toString());
        }
        return userInputOK;
    }

    private Boolean userSetSavePath() {
        Boolean saveLocationSpecified = !(jTextFieldSaveLocation.getText().equals("No location specified."));
        if (saveLocationSpecified) {
            savePath_ = jTextFieldSaveLocation.getText();
        }
        return saveLocationSpecified;
    }

    private Boolean sanitizeIPPort() {
        Boolean ipPortOK = true;
        String ip = jTextFieldLightsIPAddress.getText();
        Integer port = 0;
        try {
            port = Integer.parseInt(jTextFieldPort.getText());
        } catch (NumberFormatException e) {
            jTextAreaStatus.append(Utilities.timeStamp("Error: Invalid lights port.\n").toString());
            ipPortOK = false;
        }
        String validIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";
        if (!ip.matches(validIpAddressRegex)) {
            jTextAreaStatus.append(Utilities.timeStamp("Error: Invalid lights IP addess.\n").toString());
            ipPortOK = false;
        }
        if (ipPortOK) {
            this.lightsIPAddress_ = ip;
            this.lightsPort_ = port;
        }
        return ipPortOK;
    }

    private void jButtonTestLightsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonTestLightsActionPerformed
        if (worker_ == null) {
            if (sanitizeIPPort()) {
                jTextAreaStatus.append(Utilities.timeStamp("Testing lights...\n").toString());
                worker_ = new SwingWorker<Boolean, Void>() {
                    @Override
                    public Boolean doInBackground() {
                        if (lights_ == null) {
                            lights_ = new Lights(lightsIPAddress_, lightsPort_);
                        }
                        Boolean success = false;
                        try {
                            success = lights_.issueCommands(Arrays.asList(LightsTask.TEST), null, null);
                        } catch (final InterruptedException e) {
                        } catch (final Exception e) {
                            System.out.println(e.getMessage());
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("Error: " + e.getMessage() + "\n").toString());
                        }
                        return success;
                    }

                    @Override
                    public void done() {
                        Boolean success = false;
                        try {
                            success = (Boolean) worker_.get();
                        } catch (final CancellationException e) {
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("Operation cancelled by user.\n").toString());
                        } catch (final Exception ignore) {
                        }

                        if (success) {
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("Successfully connected to lights.\n").toString());
                        } else {
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("COULD NOT connect to lights.\n").toString());
                        }
                    }
                };
                addPropertyChangeListenersTest(worker_);
                worker_.execute();
            }
        } else {
            worker_.cancel(true);
        }
    }//GEN-LAST:event_jButtonTestLightsActionPerformed

    private void jButtonGetwlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonGetwlActionPerformed
        if (worker_ == null) {
            if (sanitizeIPPort()) {
                jTextAreaStatus.append(Utilities.timeStamp("Sending GETWL command...\n").toString());
                worker_ = new SwingWorker<Boolean, Void>() {
                    @Override
                    public Boolean doInBackground() {
                        if (lights_ == null) {
                            lights_ = new Lights(lightsIPAddress_, lightsPort_);
                        }
                        Boolean success = false;
                        try {
                            StringBuilder lightsReturn = new StringBuilder();
                            success = lights_.issueCommands(Arrays.asList(LightsTask.GETWL), lightsReturn, null);
                            String lightsReturnString = lightsReturn.toString();
                            jTextAreaStatus.append(Utilities.timeStamp(lightsReturnString + "\n").toString());
                            if (success) {
                                String[] lightsReturnTokens = lightsReturnString.split("\\s+");
                                int numWLs = lightsReturnTokens.length - 1;
                                if (numWLs > 0) {
                                    String wlMessage = "It looks like your lights have " + numWLs
                                            + " controllable wavelengths. Your \"setwlsrelpower\" command should have "
                                            + numWLs + " values like: setwlsrelpower ";
                                    for (Integer i = 1; i <= numWLs; i++) {
                                        wlMessage += "value" + i.toString() + " ";
                                    }
                                    wlMessage = wlMessage.trim() + "\n";
                                    jTextAreaStatus.append(Utilities.timeStamp(wlMessage).toString());
                                }
                            }
                        } catch (final InterruptedException e) {
                        } catch (final Exception e) {
                            System.out.println(e.getMessage());
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("Error: " + e.getMessage() + "\n").toString());
                        }
                        return success;
                    }

                    @Override
                    public void done() {
                        Boolean success = false;
                        try {
                            success = (Boolean) worker_.get();
                        } catch (final CancellationException e) {
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("Operation cancelled by user.\n").toString());
                        } catch (final Exception ignore) {
                        }

                        if (success) {
                            jTextAreaStatus.append(Utilities
                                    .timeStamp("Successfully queried wavelengths from lights.\n").toString());
                        } else {
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("COULD NOT connect to lights.\n").toString());
                        }
                    }
                };
                addPropertyChangeListenersTest(worker_);
                worker_.execute();
            }
        } else {
            worker_.cancel(true);
        }
    }//GEN-LAST:event_jButtonGetwlActionPerformed

    private void jButtonSaveConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSaveConfigActionPerformed
        JFileChooser jFileChooserSaveConfig = new JFileChooser() {
            @Override
            public void approveSelection() {
                File f = getSelectedFile();
                if (f.exists() && getDialogType() == SAVE_DIALOG) {
                    int result = JOptionPane.showConfirmDialog(this, "The file exists, overwrite?", "Existing file",
                            JOptionPane.YES_NO_CANCEL_OPTION);
                    switch (result) {
                    case JOptionPane.YES_OPTION:
                        super.approveSelection();
                        return;
                    case JOptionPane.NO_OPTION:
                        return;
                    case JOptionPane.CLOSED_OPTION:
                        return;
                    case JOptionPane.CANCEL_OPTION:
                        cancelSelection();
                        return;
                    }
                }
                super.approveSelection();
            }

        };
        jFileChooserSaveConfig.setSelectedFile(new File("LightsCameraAction.properties"));
        int returnVal = jFileChooserSaveConfig.showSaveDialog(this);
        if (returnVal == jFileChooserSaveConfig.APPROVE_OPTION) {
            String configFile = jFileChooserSaveConfig.getSelectedFile().toString();
            System.out.println("Saving config file to " + configFile);
            try {
                Properties props = new Properties();
                props.setProperty("ipAddress", jTextFieldLightsIPAddress.getText());
                props.setProperty("port", jTextFieldPort.getText());

                props.setProperty("numBetweenImages", jSpinnerTimeBetween.getValue().toString());
                String unitsBetweenImages = "";
                if (jRadioButtonTimeBetweenMin.isSelected()) {
                    unitsBetweenImages = "min";
                } else if (jRadioButtonTimeBetweenS.isSelected()) {
                    unitsBetweenImages = "s";
                } else if (jRadioButtonTimeBetweenMS.isSelected()) {
                    unitsBetweenImages = "ms";
                }
                props.setProperty("unitsBetweenImages", unitsBetweenImages);

                props.setProperty("numImageDelay", jSpinnerDelay.getValue().toString());
                String unitsImageDelay = "";
                if (jRadioButtonDelayMin.isSelected()) {
                    unitsImageDelay = "min";
                } else if (jRadioButtonDelayS.isSelected()) {
                    unitsImageDelay = "s";
                } else if (jRadioButtonDelayMS.isSelected()) {
                    unitsImageDelay = "ms";
                }
                props.setProperty("unitsImageDelay", unitsImageDelay);

                props.setProperty("numImagesToAcquire", jSpinnerNumImages.getValue().toString());

                File f = new File(configFile);
                OutputStream out = new FileOutputStream(f);
                props.store(out, "Properties for LightsCameraAction ImageJ Plugin.\nUnits are one of [min,s,ms]");
            } catch (Exception e) {

            }
        }
    }//GEN-LAST:event_jButtonSaveConfigActionPerformed

    private void jButtonLoadConfigActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonLoadConfigActionPerformed
        int returnVal = jFileChooserLoadConfig.showOpenDialog(this);
        if (returnVal == jFileChooserLoadConfig.APPROVE_OPTION) {
            String configFile = jFileChooserLoadConfig.getSelectedFile().toString();
            Properties prop = new Properties();
            try {
                InputStream inputStream = new FileInputStream(configFile);
                prop.load(inputStream);
            } catch (FileNotFoundException ex) {
                jTextAreaStatus.append(Utilities.timeStamp("Properties file not found.\n").toString());
            } catch (java.io.IOException ex) {
                jTextAreaStatus.append(Utilities.timeStamp("Unable to load properties file.\n").toString());
            }
            String ipAddress = prop.getProperty("ipAddress");
            if (ipAddress == null) {
                ipAddress = "";
            }

            String port = prop.getProperty("port");
            if (port == null) {
                port = "";
            }

            Double numBetweenImagesDouble;
            String numBetweenImages = prop.getProperty("numBetweenImages");
            if (numBetweenImages == null) {
                numBetweenImagesDouble = 0.0;
            } else {
                numBetweenImagesDouble = Double.parseDouble(prop.getProperty("numBetweenImages"));
            }

            String unitsBetweenImages = prop.getProperty("unitsBetweenImages");
            if (unitsBetweenImages == null) {
                unitsBetweenImages = "";
            } else {
                unitsBetweenImages = unitsBetweenImages.toLowerCase();
            }

            Double numImageDelayDouble;
            String numImageDelay = prop.getProperty("numImageDelay");
            if (numImageDelay == null) {
                numImageDelayDouble = 0.0;
            } else {
                numImageDelayDouble = Double.parseDouble(numImageDelay);
            }

            String unitsImageDelay = prop.getProperty("unitsImageDelay");
            if (unitsImageDelay == null) {
                unitsImageDelay = "";
            } else {
                unitsImageDelay = unitsImageDelay.toLowerCase();
            }

            Integer numImagesToAcquireInt = new Integer(0);
            String numImagesToAcquire = prop.getProperty("numImagesToAcquire");
            if (numImagesToAcquire != null) {
                numImagesToAcquireInt = Integer.parseInt(numImagesToAcquire);
            }

            jTextFieldLightsIPAddress.setText(ipAddress);
            jTextFieldPort.setText(port);

            jSpinnerTimeBetween.setValue(numBetweenImagesDouble);
            if (unitsBetweenImages.contentEquals("min")) {
                jRadioButtonTimeBetweenMin.setSelected(true);
            } else if (unitsBetweenImages.contentEquals("s")) {
                jRadioButtonTimeBetweenS.setSelected(true);
            } else if (unitsBetweenImages.contentEquals("ms")) {
                jRadioButtonTimeBetweenMS.setSelected(true);
            }

            jSpinnerDelay.setValue(numBetweenImagesDouble);
            if (unitsImageDelay.contentEquals("min")) {
                jRadioButtonDelayMin.setSelected(true);
            } else if (unitsImageDelay.contentEquals("s")) {
                jRadioButtonDelayS.setSelected(true);
            } else if (unitsImageDelay.contentEquals("ms")) {
                jRadioButtonDelayMS.setSelected(true);
            }
            jSpinnerNumImages.setValue(numImagesToAcquireInt);
        } else {
            System.out.println("File access cancelled by user.");
        }
    }//GEN-LAST:event_jButtonLoadConfigActionPerformed

    private void jButtonImageSaveLocationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonImageSaveLocationActionPerformed
        int returnVal = jFileChooserSaveLocation.showOpenDialog(this);
        if (returnVal == jFileChooserSaveLocation.APPROVE_OPTION) {
            String dir = jFileChooserSaveLocation.getSelectedFile().toString();
            if (dir.charAt(dir.length() - 1) != File.pathSeparatorChar) {
                dir += File.separator;
            }
            jTextFieldSaveLocation.setText(dir);
        } else {
            System.out.println("File access cancelled by user.");
        }
    }//GEN-LAST:event_jButtonImageSaveLocationActionPerformed

    private void addPropertyChangeListenersTest(SwingWorker worker) {
        worker.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(final PropertyChangeEvent event) {
                String eventName = event.getPropertyName();
                if (eventName == "state") {
                    switch ((StateValue) event.getNewValue()) {
                    case STARTED:
                    case PENDING:
                        enableComponents(jPanelConfiguration, false);
                        enableComponents(jPanelTesting, false);
                        enableComponents(jPanelRun, false);
                        jButtonTestLights.setText("Cancel");
                        jButtonTestLights.setEnabled(true);
                        break;
                    case DONE:
                        jButtonTestLights.setText("Test Lights On/Off");
                        enableComponents(jPanelConfiguration, true);
                        enableComponents(jPanelTesting, true);
                        enableComponents(jPanelRun, true);
                        worker_ = null;
                        break;

                    }
                }
            }
        });
    }

    private void addPropertyChangeListenersRun(SwingWorker worker) {
        worker.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(final PropertyChangeEvent event) {
                String eventName = event.getPropertyName();
                if (eventName == "state") {
                    switch ((StateValue) event.getNewValue()) {
                    case STARTED:
                    case PENDING:
                        enableComponents(jPanelConfiguration, false);
                        enableComponents(jPanelTesting, false);
                        enableComponents(jPanelRun, false);
                        enableComponents(jPanelWavelengths, false);
                        jButtonStartJob.setText("Cancel");
                        jButtonStartJob.setEnabled(true);
                        break;
                    case DONE:
                        try {
                            worker_.get();
                        } catch (final CancellationException e) {
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("Operation cancelled by user.\n").toString());
                        } catch (Exception e) {
                            jTextAreaStatus
                                    .append(Utilities.timeStamp("Error: " + e.getMessage() + "\n").toString());
                        }
                        jButtonStartJob.setText("Start Imaging Job");
                        enableComponents(jPanelConfiguration, true);
                        enableComponents(jPanelTesting, true);
                        enableComponents(jPanelRun, true);
                        enableComponents(jPanelWavelengths, true);
                        worker_ = null;
                        break;
                    }
                }
            }
        });
    }

    private void enableComponents(Container container, Boolean enable) {
        Component[] components = container.getComponents();
        for (Component component : components) {
            component.setEnabled(enable);
            if (component instanceof Container) {
                enableComponents((Container) component, enable);
            }
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem Exit;
    private javax.swing.ButtonGroup buttonGroupImageDelay;
    private javax.swing.ButtonGroup buttonGroupTimeUnits;
    private javax.swing.JButton jButtonGetwl;
    private javax.swing.JButton jButtonImageSaveLocation;
    private javax.swing.JButton jButtonLoadConfig;
    private javax.swing.JButton jButtonSaveConfig;
    private javax.swing.JButton jButtonStartJob;
    private javax.swing.JButton jButtonTestImage;
    private javax.swing.JButton jButtonTestLights;
    private javax.swing.JCheckBox jCheckBoxRequireSchedule;
    private javax.swing.JFileChooser jFileChooserLoadConfig;
    private javax.swing.JFileChooser jFileChooserSaveLocation;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabelConfiguration;
    private javax.swing.JLabel jLabelLightsImageDelay;
    private javax.swing.JLabel jLabelNumImages;
    private javax.swing.JLabel jLabelRun;
    private javax.swing.JLabel jLabelTesting;
    private javax.swing.JLabel jLabelTimeBetween;
    private javax.swing.JLabel jLabelWavelenghts;
    private javax.swing.JMenuBar jMenuBarFileMenu;
    private javax.swing.JMenu jMenuFile;
    private javax.swing.JPanel jPanelConfiguration;
    private javax.swing.JPanel jPanelOutput;
    private javax.swing.JPanel jPanelRun;
    private javax.swing.JPanel jPanelTesting;
    private javax.swing.JPanel jPanelWavelengths;
    private javax.swing.JRadioButton jRadioButtonDelayMS;
    private javax.swing.JRadioButton jRadioButtonDelayMin;
    private javax.swing.JRadioButton jRadioButtonDelayS;
    private javax.swing.JRadioButton jRadioButtonTimeBetweenMS;
    private javax.swing.JRadioButton jRadioButtonTimeBetweenMin;
    private javax.swing.JRadioButton jRadioButtonTimeBetweenS;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSpinner jSpinnerDelay;
    private javax.swing.JSpinner jSpinnerNumImages;
    private javax.swing.JSpinner jSpinnerTimeBetween;
    private javax.swing.JTextArea jTextAreaStatus;
    private javax.swing.JTextArea jTextAreaWavelengthsHelpText;
    private javax.swing.JTextField jTextFieldLightsIPAddress;
    private javax.swing.JTextField jTextFieldPort;
    private javax.swing.JTextField jTextFieldSaveLocation;
    private javax.swing.JTextField jTextFieldWavelenghts;
    // End of variables declaration//GEN-END:variables
}