ioheater.ui.IOHeaterUI.java Source code

Java tutorial

Introduction

Here is the source code for ioheater.ui.IOHeaterUI.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 ioheater.ui;

import ioheater.manager.IOHeaterManager;
import ioheater.manager.IHeaterStateEventHandler;
import ioheater.manager.ISpectrometerEventHandler;
import ioheater.manager.IOHeaterException;
import ioheater.manager.ITemperatureChangeEventHandler;
import java.awt.Color;
import java.awt.FlowLayout;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.time.Second;

import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleInsets;

/**
 *
 * @author md1xsar
 */
public class IOHeaterUI extends javax.swing.JFrame
        implements IHeaterStateEventHandler, ITemperatureChangeEventHandler, ISpectrometerEventHandler {

    private static final Logger logger = Logger.getLogger("ioheater.ui.ioheaterui");
    private final SimpleDateFormat sdf;

    private final IOHeaterManager ioHeaterManager;

    private TimeSeriesCollection dataSet;

    /**
     * Creates new form IOheater
     */
    public IOHeaterUI() {
        logger.info("Entering IOheater");
        initComponents();

        jPanel3.removeAll();
        jPanel3.setLayout(new FlowLayout(FlowLayout.LEFT));
        jPanel3.add(chart());
        this.setLocationRelativeTo(null);
        this.sdf = new SimpleDateFormat("dd/MM/yy h:mm:ss");

        setTitle("IO heater");
        addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }

            @Override
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });

        this.ioHeaterManager = new IOHeaterManager(this, this, this);

        logger.info("Exiting IOheater");
    }

    /**
     * This method is called from within the constructor to initialise 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() {

        jFrame1 = new javax.swing.JFrame();
        xYPlot1 = new org.jfree.chart.plot.XYPlot();
        thermometerPlot1 = new org.jfree.chart.plot.ThermometerPlot();
        jToggleButton1 = new javax.swing.JToggleButton();
        xYPlot2 = new org.jfree.chart.plot.XYPlot();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jCheckHeater = new javax.swing.JCheckBox();
        heaterState = new javax.swing.JTextField();
        currentTemperature = new javax.swing.JFormattedTextField();
        targetTemperature = new javax.swing.JFormattedTextField();
        jLabel1 = new javax.swing.JLabel();
        pumpStateLabel = new javax.swing.JLabel();
        spectrometerProximity = new javax.swing.JTextField();
        pumpState = new javax.swing.JTextField();
        jPanel2 = new javax.swing.JPanel();
        tempTolLabel = new javax.swing.JLabel();
        temperatureTrigger = new javax.swing.JTextField();
        jPanel3 = new javax.swing.JPanel();

        javax.swing.GroupLayout jFrame1Layout = new javax.swing.GroupLayout(jFrame1.getContentPane());
        jFrame1.getContentPane().setLayout(jFrame1Layout);
        jFrame1Layout.setHorizontalGroup(jFrame1Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 400, Short.MAX_VALUE));
        jFrame1Layout.setVerticalGroup(jFrame1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 300, Short.MAX_VALUE));

        jToggleButton1.setText("jToggleButton1");

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel4.setText("Target Temperature");
        jLabel4.setToolTipText("");
        jLabel4.setMaximumSize(new java.awt.Dimension(81, 40));
        jLabel4.setMinimumSize(new java.awt.Dimension(81, 20));
        jLabel4.setPreferredSize(new java.awt.Dimension(81, 25));

        jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel5.setText("Current Temperature");
        jLabel5.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        jLabel5.setMaximumSize(new java.awt.Dimension(81, 20));
        jLabel5.setMinimumSize(new java.awt.Dimension(81, 20));
        jLabel5.setPreferredSize(new java.awt.Dimension(81, 20));

        jCheckHeater.setText("Heater");
        jCheckHeater.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jCheckHeater.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckHeaterActionPerformed(evt);
            }
        });

        heaterState.setEditable(false);
        heaterState.setBackground(new java.awt.Color(0, 0, 0));
        heaterState.setForeground(new java.awt.Color(0, 255, 255));
        heaterState.setText("Off");
        heaterState.setPreferredSize(new java.awt.Dimension(35, 25));

        currentTemperature.setEditable(false);
        currentTemperature.setBackground(new java.awt.Color(0, 0, 0));
        currentTemperature.setForeground(new java.awt.Color(0, 255, 255));
        currentTemperature.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
                new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0.00"))));
        currentTemperature.setMaximumSize(new java.awt.Dimension(35, 20));
        currentTemperature.setMinimumSize(new java.awt.Dimension(35, 40));
        currentTemperature.setPreferredSize(new java.awt.Dimension(35, 25));

        targetTemperature.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
                new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0.00"))));
        targetTemperature.setMaximumSize(new java.awt.Dimension(35, 40));
        targetTemperature.setMinimumSize(new java.awt.Dimension(35, 20));
        targetTemperature.setPreferredSize(new java.awt.Dimension(35, 25));

        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        jLabel1.setText("Spectrometer Proximity");
        jLabel1.setToolTipText("");

        pumpStateLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
        pumpStateLabel.setText("Pump State");
        pumpStateLabel.setToolTipText("");

        spectrometerProximity.setBackground(new java.awt.Color(0, 0, 0));
        spectrometerProximity.setForeground(new java.awt.Color(0, 255, 255));
        spectrometerProximity.setText("Off");
        spectrometerProximity.setMinimumSize(new java.awt.Dimension(6, 25));
        spectrometerProximity.setName(""); // NOI18N
        spectrometerProximity.setPreferredSize(new java.awt.Dimension(35, 35));
        spectrometerProximity.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                spectrometerProximityActionPerformed(evt);
            }
        });

        pumpState.setBackground(new java.awt.Color(0, 0, 0));
        pumpState.setForeground(new java.awt.Color(0, 255, 255));
        pumpState.setText("Off");
        pumpState.setToolTipText("");
        pumpState.setPreferredSize(new java.awt.Dimension(35, 25));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(jPanel1Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING,
                                javax.swing.GroupLayout.DEFAULT_SIZE, 692, Short.MAX_VALUE)
                        .addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addGroup(jPanel1Layout
                                .createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                        .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 116,
                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
                                                javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(currentTemperature, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addGroup(jPanel1Layout.createSequentialGroup()
                                        .addGroup(jPanel1Layout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                                .addComponent(jCheckHeater)
                                                .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                        .addGroup(jPanel1Layout
                                                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addComponent(heaterState, javax.swing.GroupLayout.PREFERRED_SIZE,
                                                        35, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addComponent(targetTemperature,
                                                        javax.swing.GroupLayout.Alignment.TRAILING,
                                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                                        javax.swing.GroupLayout.PREFERRED_SIZE))))
                                .addGap(61, 61, 61)
                                .addGroup(jPanel1Layout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(pumpStateLabel, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(jPanel1Layout
                                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(spectrometerProximity, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                39, Short.MAX_VALUE)
                                        .addComponent(pumpState, javax.swing.GroupLayout.DEFAULT_SIZE,
                                                javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                .addGap(0, 0, Short.MAX_VALUE)))
                        .addContainerGap()));
        jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(spectrometerProximity, javax.swing.GroupLayout.PREFERRED_SIZE, 0,
                                Short.MAX_VALUE)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(currentTemperature, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel1)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(targetTemperature, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(pumpStateLabel).addComponent(pumpState,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jCheckHeater).addComponent(heaterState,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18).addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 312,
                                javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap()));

        jTabbedPane1.addTab("Main", jPanel1);

        tempTolLabel.setText("Temperature tolerance");

        temperatureTrigger.setText("10");
        temperatureTrigger.setToolTipText("");
        temperatureTrigger.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                temperatureTriggerActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout
                .setHorizontalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jPanel2Layout.createSequentialGroup().addContainerGap().addComponent(tempTolLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(temperatureTrigger, javax.swing.GroupLayout.PREFERRED_SIZE, 24,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addContainerGap(554, Short.MAX_VALUE)));
        jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup().addContainerGap()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(temperatureTrigger, javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(tempTolLabel))
                        .addContainerGap(397, Short.MAX_VALUE)));

        jTabbedPane1.addTab("Settings", jPanel2);

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(jPanel3Layout
                .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 702, Short.MAX_VALUE));
        jPanel3Layout.setVerticalGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGap(0, 428, Short.MAX_VALUE));

        jTabbedPane1.addTab("Graph", jPanel3);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup().addComponent(jTabbedPane1).addContainerGap()));
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
                        layout.createSequentialGroup().addComponent(jTabbedPane1,
                                javax.swing.GroupLayout.PREFERRED_SIZE, 456, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(0, 0, Short.MAX_VALUE)));

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

    private void jCheckHeaterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckHeaterActionPerformed
        checkThreads();
        if (jCheckHeater.isSelected()) {
            runHeater();
        } else {
            try {
                ioHeaterManager.stopTemperatureManagement();
                heaterState.setText("Off");
            } catch (IOHeaterException e) {
                if (!e.isLogged()) {
                    logger.log(Level.SEVERE, e.getMessage(), e);
                }
            }
        }
    }//GEN-LAST:event_jCheckHeaterActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        logger.info("closing...");

        try {
            this.ioHeaterManager.stopTemperatureManagement();
            heaterState.setText("Off");
        } catch (IOHeaterException e) {
            if (!e.isLogged()) {
                logger.log(Level.SEVERE, e.getMessage(), e);
            }
        }
        this.ioHeaterManager.close();
        logger.info(" ok");
    }//GEN-LAST:event_formWindowClosing

    private void temperatureTriggerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_temperatureTriggerActionPerformed
        try {
            ioHeaterManager.setSensorChangeTrigger(Integer.parseInt(this.temperatureTrigger.getText()));
        } catch (IOHeaterException e) {
            if (!e.isLogged()) {
                logger.log(Level.SEVERE, e.getMessage(), e);
            }
        }
    }//GEN-LAST:event_temperatureTriggerActionPerformed

    private void spectrometerProximityActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_spectrometerProximityActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_spectrometerProximityActionPerformed

    private void formWindowOpened(java.awt.event.WindowEvent evt) {
        logger.info("Entering formWindowOpened");
        runPhidget();
        jCheckHeater.setSelected(false);
        targetTemperature.setText("37");
        jTextArea1.setText("");
        this.currentTemperature.setText(String.format("%.1f", ioHeaterManager.getTemperature()));

        logger.info("Exiting formWindowOpened");
    }

    /**
     * Run the interface kit manager.
     */
    public void runPhidget() {
        logger.info("EnteringrunPhidget");

        this.ioHeaterManager.runPhidget();
        try {
            this.ioHeaterManager.setSensorChangeTrigger(Integer.parseInt(this.temperatureTrigger.getText()));
        } catch (IOHeaterException e) {
            if (!e.isLogged()) {
                logger.log(Level.SEVERE, e.getMessage(), e);
            }
        }

        logger.info("Exiting runPhidget");
    }

    private void runHeater() {
        logger.info(String.format("Entering runHeater. Thread %s", getMethodName(0)));
        try {
            ioHeaterManager.startTemperatureManagement(Float.parseFloat(this.targetTemperature.getText()));
        } catch (NumberFormatException nfe) {
            logger.log(Level.WARNING, "Number format exception", nfe);
        } catch (IOHeaterException e) {
            if (!e.isLogged()) {
                logger.log(Level.SEVERE, e.getMessage(), e);
            }
        }

        logger.info("Exiting runHeater");
    }

    @Override
    public void spectrometerProximityOn() {
        this.spectrometerProximity.setText("On");
    }

    @Override
    public void spectrometerProximityOff() {
        this.spectrometerProximity.setText("Off");
    }

    @Override
    public void pumpStateOff() {
        this.pumpState.setText("Off");
    }

    @Override
    public void pumpStateOn() {
        this.pumpState.setText("On");
    }

    /**
     *
     * @param temperature
     */
    @Override
    public void temperatureChanged(float temperature) {
        this.currentTemperature.setText(String.format("%.1f", temperature));

        jTextArea1.append(String.format("%s: temperature changed to %.1f%n", sdf.format(new Date()), temperature));

        //Make sure the new text is visible, even if there
        //was a selection in the text area.
        jTextArea1.setCaretPosition(jTextArea1.getDocument().getLength());

        this.plotOnChart(temperature);

        this.revalidate();
        this.repaint();
    }

    @Override
    public void heaterManagerStopped() {
        this.jCheckHeater.setSelected(false);
    }

    @Override
    public void heaterStarted() {
        heaterState.setText("On");

        jTextArea1.append(String.format("%s: heater started%n", sdf.format(new Date())));

        //Make sure the new text is visible, even if there
        //was a selection in the text area.
        jTextArea1.setCaretPosition(jTextArea1.getDocument().getLength());

        this.revalidate();
        this.repaint();
    }

    @Override
    public void heaterStopped() {
        heaterState.setText("Off");

        jTextArea1.append(String.format("%s: heater stopped%n", sdf.format(new Date())));

        //Make sure the new text is visible, even if there
        //was a selection in the text area.
        jTextArea1.setCaretPosition(jTextArea1.getDocument().getLength());

        this.revalidate();
        this.repaint();
    }

    /**
     *
     * @return
     */
    public final ChartPanel chart() {
        this.createDataset();
        JFreeChart chart = createChart(this.dataSet);
        ChartPanel panel = new ChartPanel(chart);
        panel.setFillZoomRectangle(true);
        panel.setMouseWheelEnabled(true);
        return panel;
    }

    /**
     * Creates a chart.
     *
     * @param dataset  a dataset.
     *
     * @return A chart.
     */
    private static JFreeChart createChart(XYDataset dataset) {

        JFreeChart chart = ChartFactory.createTimeSeriesChart("Temperature Trend", // title
                "Time (m:s)", // x-axis label
                "Temperature (C)", // y-axis label
                dataset, // data
                true, // create legend?
                true, // generate tooltips?
                false // generate URLs?
        );

        chart.setBackgroundPaint(Color.white);

        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);
        plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);

        XYItemRenderer r = plot.getRenderer();
        if (r instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
            renderer.setBaseShapesVisible(true);
            renderer.setBaseShapesFilled(true);
            renderer.setDrawSeriesLineAsPath(true);
        }

        DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setDateFormatOverride(new SimpleDateFormat("H:mm:ss"));

        return chart;
    }

    private void createDataset() {

        TimeSeries timeSeries = new TimeSeries("Time");
        this.dataSet = new TimeSeriesCollection();
        dataSet.addSeries(timeSeries);
    }

    private void plotOnChart(float temperature) {
        this.dataSet.getSeries(0).addOrUpdate(new Second(), temperature);
    }

    /**
     * Utility method for checking active threads.
     */
    public static void checkThreads() {
        ThreadGroup mainThreadGroup = Thread.currentThread().getThreadGroup();
        ThreadGroup systemThreadGroup = mainThreadGroup.getParent();

        logger.log(Level.INFO, "Current thread: {0}", Thread.currentThread());
        systemThreadGroup.list();
    }

    /**
     *
     * @param depth
     * @return
     */
    public static String getMethodName(final int depth) {
        final StackTraceElement[] ste = Thread.currentThread().getStackTrace();

        //System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
        // return ste[ste.length - depth].getMethodName();  //Wrong, fails for depth = 0
        return ste[ste.length - 1 - depth].getMethodName(); //Thank you Tom Tresansky
    }
    //end Thread checks

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        logger.info("Run main");
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
                | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(IOHeaterUI.class.getName()).log(java.util.logging.Level.SEVERE, null,
                    ex);
        }
        //</editor-fold>
        checkThreads();
        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new IOHeaterUI().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JFormattedTextField currentTemperature;
    private javax.swing.JTextField heaterState;
    private javax.swing.JCheckBox jCheckHeater;
    private javax.swing.JFrame jFrame1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JToggleButton jToggleButton1;
    private javax.swing.JTextField pumpState;
    private javax.swing.JLabel pumpStateLabel;
    private javax.swing.JTextField spectrometerProximity;
    private javax.swing.JFormattedTextField targetTemperature;
    private javax.swing.JLabel tempTolLabel;
    private javax.swing.JTextField temperatureTrigger;
    private org.jfree.chart.plot.ThermometerPlot thermometerPlot1;
    private org.jfree.chart.plot.XYPlot xYPlot1;
    private org.jfree.chart.plot.XYPlot xYPlot2;
    // End of variables declaration//GEN-END:variables
}