package de.re.easymodbus.modbusserver.gui;

import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Random;


/**
 * @author Stefan Roßmann
 */
public class NewJFrame extends javax.swing.JFrame implements de.re.easymodbus.modbusserver.ICoilsChangedDelegator, de.re.easymodbus.modbusserver.IHoldingRegistersChangedDelegator, de.re.easymodbus.modbusserver.INumberOfConnectedClientsChangedDelegator, de.re.easymodbus.modbusserver.ILogDataChangedDelegator {

    public de.re.easymodbus.modbusserver.ModbusServer modbusServer = new de.re.easymodbus.modbusserver.ModbusServer();

    /**
     * Creates new form NewJFrame
     */
    public NewJFrame() {

        super("EasyModbusTCP Server Simulator");
        initComponents();
        modbusServer.setNotifyCoilsChanged(this);
        modbusServer.setNotifyHoldingRegistersChanged(this);
        modbusServer.setNotifyNumberOfConnectedClientsChanged(this);
        modbusServer.setNotifyLogDataChanged(this);
        modbusServer.setClientConnectionTimeout(10000);
        try {
            modbusServer.Listen();
        } catch (Exception e) {
        }
        jList1.setModel(model);


    }

    private void initTables() {
        javax.swing.table.DefaultTableModel model1 = (javax.swing.table.DefaultTableModel) jTable1.getModel();
        javax.swing.table.DefaultTableModel model2 = (javax.swing.table.DefaultTableModel) jTable2.getModel();
        javax.swing.table.DefaultTableModel model3 = (javax.swing.table.DefaultTableModel) jTable3.getModel();
        javax.swing.table.DefaultTableModel model4 = (javax.swing.table.DefaultTableModel) jTable4.getModel();
        for (int i = 0; i < 25; i++) {
            model1.addRow(new Object[]{String.valueOf(i + 1), String.valueOf(false)});
        }
        for (int i = 0; i < 25; i++) {
            model2.addRow(new Object[]{String.valueOf(i + 1), String.valueOf(false)});
        }
        for (int i = 0; i < 25; i++) {
            model3.addRow(new Object[]{String.valueOf(i + 1), String.valueOf(0)});
        }
        for (int i = 0; i < 25; i++) {
            model4.addRow(new Object[]{String.valueOf(i + 1), String.valueOf(0)});
        }
    }

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

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new JScrollPane();
        jTable1 = new javax.swing.JTable();
        jScrollBar1 = new JScrollBar();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new JScrollPane();
        jTable2 = new javax.swing.JTable();
        jScrollBar2 = new JScrollBar();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane3 = new JScrollPane();
        jTable3 = new javax.swing.JTable();
        jScrollBar3 = new JScrollBar();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane4 = new JScrollPane();
        jTable4 = new javax.swing.JTable();
        jScrollBar4 = new JScrollBar();
        jLabel1 = new JLabel();
        jLabel2 = new JLabel();
        jLabel3 = new JLabel();
        jPanel5 = new javax.swing.JPanel();
        jPanel5.setAlignmentX(Component.LEFT_ALIGNMENT);
        jPanel5.setAlignmentY(Component.TOP_ALIGNMENT);
        jLabel4 = new JLabel();
        jCheckBox1 = new JCheckBox();
        jCheckBox2 = new JCheckBox();
        jCheckBox3 = new JCheckBox();
        jCheckBox4 = new JCheckBox();
        jCheckBox5 = new JCheckBox();
        jCheckBox6 = new JCheckBox();
        jCheckBox7 = new JCheckBox();
        jCheckBox8 = new JCheckBox();
        jLabel5 = new JLabel();
        jLabel6 = new JLabel();
        jLabel7 = new JLabel();
        jCheckBox9 = new JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);
        setSize(new Dimension(888, 640));
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        jTabbedPane1.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                jTabbedPane1MouseClicked(evt);
            }
        });

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
                new Object[][]{

                },
                new String[]{
                        "Address", "Value"
                }
        ));
        jTable1.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                jTable1MouseClicked(evt);
            }
        });
        jTable1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jTable1PropertyChange(evt);
            }
        });
        jScrollPane1.setViewportView(jTable1);

        jScrollBar1.setBlockIncrement(1);
        jScrollBar1.setMaximum(65534);
        jScrollBar1.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jScrollBar1AdjustmentValueChanged(evt);
            }
        });

        GroupLayout jPanel1Layout = new GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(Alignment.LEADING)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                                .addContainerGap()
                                .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jScrollBar1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(Alignment.LEADING)
                        .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
                        .addComponent(jScrollBar1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Discrete Inputs", jPanel1);

        jTable2.setModel(new javax.swing.table.DefaultTableModel(
                new Object[][]{

                },
                new String[]{
                        "Address", "Value"
                }
        ));
        jTable2.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                jTable2MouseClicked(evt);
            }
        });
        jTable2.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jTable2PropertyChange(evt);
            }
        });
        jScrollPane2.setViewportView(jTable2);

        jScrollBar2.setBlockIncrement(1);
        jScrollBar2.setMaximum(65534);
        jScrollBar2.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jScrollBar2AdjustmentValueChanged(evt);
            }
        });

        GroupLayout jPanel2Layout = new GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
                jPanel2Layout.createParallelGroup(Alignment.LEADING)
                        .addGroup(jPanel2Layout.createSequentialGroup()
                                .addContainerGap()
                                .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 228, GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jScrollBar2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
                jPanel2Layout.createParallelGroup(Alignment.LEADING)
                        .addComponent(jScrollPane2, GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
                        .addComponent(jScrollBar2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Coils", jPanel2);

        jTable3.setModel(new javax.swing.table.DefaultTableModel(
                new Object[][]{

                },
                new String[]{
                        "Address", "Value"
                }
        ));
        jTable3.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jTable3PropertyChange(evt);
            }
        });
        jScrollPane3.setViewportView(jTable3);

        jScrollBar3.setBlockIncrement(1);
        jScrollBar3.setMaximum(65534);
        jScrollBar3.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jScrollBar3AdjustmentValueChanged(evt);
            }
        });

        GroupLayout jPanel3Layout = new GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
                jPanel3Layout.createParallelGroup(Alignment.LEADING)
                        .addGroup(jPanel3Layout.createSequentialGroup()
                                .addContainerGap()
                                .addComponent(jScrollPane3, GroupLayout.PREFERRED_SIZE, 227, GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jScrollBar3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
                jPanel3Layout.createParallelGroup(Alignment.LEADING)
                        .addComponent(jScrollPane3, GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
                        .addComponent(jScrollBar3, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Input Registers", jPanel3);

        jPanel4.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jPanel4PropertyChange(evt);
            }
        });

        jTable4.setModel(new javax.swing.table.DefaultTableModel(
                new Object[][]{

                },
                new String[]{
                        "Address", "Value"
                }
        ));
        jTable4.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                jTable4PropertyChange(evt);
            }
        });
        jScrollPane4.setViewportView(jTable4);

        jScrollBar4.setBlockIncrement(1);
        jScrollBar4.setMaximum(65534);
        jScrollBar4.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jScrollBar4AdjustmentValueChanged(evt);
            }
        });

        GroupLayout jPanel4Layout = new GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
                jPanel4Layout.createParallelGroup(Alignment.LEADING)
                        .addGroup(jPanel4Layout.createSequentialGroup()
                                .addContainerGap()
                                .addComponent(jScrollPane4, GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jScrollBar4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                .addContainerGap())
        );
        jPanel4Layout.setVerticalGroup(
                jPanel4Layout.createParallelGroup(Alignment.LEADING)
                        .addComponent(jScrollPane4, GroupLayout.DEFAULT_SIZE, 456, Short.MAX_VALUE)
                        .addComponent(jScrollBar4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Holding Registers", jPanel4);

        jLabel1.setFont(new Font("Microsoft Sans Serif", 1, 18)); // NOI18N
        jLabel1.setForeground(new java.awt.Color(102, 204, 0));
        jLabel1.setText("...Modbus-TCP Server Listening (Port 502)...");


        jLabel3.setText("Version 2.5");
        jLabel3.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        jPanel5.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jLabel4.setText("Supported Function codes:");

        jCheckBox1.setSelected(true);
        jCheckBox1.setText("FC 01 (Read Coils)");
        jCheckBox1.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                jCheckBox1StateChanged(evt);
            }
        });

        jCheckBox2.setSelected(true);
        jCheckBox2.setText("FC 02 (Read Discrete Inputs)");
        jCheckBox2.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                jCheckBox2StateChanged(evt);
            }
        });

        jCheckBox3.setSelected(true);
        jCheckBox3.setText("FC 03 (Read Holding Registers)");
        jCheckBox3.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                jCheckBox3StateChanged(evt);
            }
        });

        jCheckBox4.setSelected(true);
        jCheckBox4.setText("FC 04 (Read Input Registers)");
        jCheckBox4.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                jCheckBox4StateChanged(evt);
            }
        });

        jCheckBox5.setSelected(true);
        jCheckBox5.setText("FC 05 (Write Single Coil)");
        jCheckBox5.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                jCheckBox5StateChanged(evt);
            }
        });

        jCheckBox6.setSelected(true);
        jCheckBox6.setText("FC 06 (Write Single Register)");
        jCheckBox6.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                jCheckBox6StateChanged(evt);
            }
        });

        jCheckBox7.setSelected(true);
        jCheckBox7.setText("FC 15 (Write Multiple Coils)");
        jCheckBox7.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                jCheckBox7StateChanged(evt);
            }
        });

        jCheckBox8.setSelected(true);
        jCheckBox8.setText("FC 16 (Write Multiple Registers)");
        jCheckBox8.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                jCheckBox8StateChanged(evt);
            }
        });

        GroupLayout jPanel5Layout = new GroupLayout(jPanel5);
        jPanel5Layout.setHorizontalGroup(
                jPanel5Layout.createParallelGroup(Alignment.LEADING)
                        .addGroup(Alignment.TRAILING, jPanel5Layout.createSequentialGroup()
                                .addContainerGap(29, Short.MAX_VALUE)
                                .addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING)
                                        .addGroup(jPanel5Layout.createSequentialGroup()
                                                .addGap(21)
                                                .addComponent(jLabel4))
                                        .addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING)
                                                .addComponent(jCheckBox2)
                                                .addComponent(jCheckBox1)
                                                .addComponent(jCheckBox3)
                                                .addComponent(jCheckBox4)
                                                .addComponent(jCheckBox5)
                                                .addComponent(jCheckBox6)
                                                .addComponent(jCheckBox7)
                                                .addComponent(jCheckBox8)))
                                .addGap(22))
        );
        jPanel5Layout.setVerticalGroup(
                jPanel5Layout.createParallelGroup(Alignment.LEADING)
                        .addGroup(jPanel5Layout.createSequentialGroup()
                                .addComponent(jLabel4)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jCheckBox1)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jCheckBox2)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jCheckBox3)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jCheckBox4)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jCheckBox5)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jCheckBox6)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jCheckBox7)
                                .addPreferredGap(ComponentPlacement.RELATED)
                                .addComponent(jCheckBox8)
                                .addContainerGap(11, Short.MAX_VALUE))
        );
        jPanel5.setLayout(jPanel5Layout);

        jLabel5.setText("<html><font color=blue><u>http://www.EasyModbusTCP.net</u></font></html>");
        jLabel5.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent evt) {
                jLabel5MousePressed(evt);
            }
        });

        jLabel6.setText("Number of connected clients: ");

        jLabel7.setText("0");

        jCheckBox9.setSelected(true);
        jCheckBox9.setText("Show Protocol Informations");
        jList1 = new javax.swing.JList();
        jList1.setAutoscrolls(false);
        jList1.setAlignmentY(Component.BOTTOM_ALIGNMENT);
        jList1.setAlignmentX(Component.LEFT_ALIGNMENT);
        jList1.setFont(new Font("Tahoma", Font.PLAIN, 9));

        chckbxEnableWebview = new JCheckBox("Enable Web View");
        chckbxEnableWebview.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                WebViewStateChanged(e);

            }
        });

        lblWebViewAddress = new JLabel("Webview-address:");
        lblWebViewAddress.setVisible(false);

        lblLink = new JLabel("link");
        lblLink.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                linkClicked();
            }
        });
        lblLink.setVisible(false);

        GroupLayout layout = new GroupLayout(getContentPane());
        layout.setHorizontalGroup(
                layout.createParallelGroup(Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(Alignment.LEADING)
                                        .addGroup(layout.createSequentialGroup()
                                                .addContainerGap()
                                                .addComponent(jLabel2)
                                                .addGap(6)
                                                .addGroup(layout.createParallelGroup(Alignment.TRAILING, false)
                                                        .addGroup(layout.createSequentialGroup()
                                                                .addComponent(jLabel5)
                                                                .addGap(624))
                                                        .addGroup(layout.createSequentialGroup()
                                                                .addGroup(layout.createParallelGroup(Alignment.LEADING)
                                                                        .addGroup(layout.createSequentialGroup()
                                                                                .addComponent(jLabel6)
                                                                                .addPreferredGap(ComponentPlacement.RELATED)
                                                                                .addComponent(jLabel7)
                                                                                .addGap(59)
                                                                                .addComponent(jLabel3))
                                                                        .addGroup(layout.createSequentialGroup()
                                                                                .addComponent(jPanel5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                                                                .addGap(6)
                                                                                .addComponent(chckbxEnableWebview))
                                                                        .addGroup(layout.createSequentialGroup()
                                                                                .addGap(430)
                                                                                .addComponent(jCheckBox9))
                                                                        .addComponent(jList1, GroupLayout.PREFERRED_SIZE, 583, GroupLayout.PREFERRED_SIZE)
                                                                        .addGroup(layout.createSequentialGroup()
                                                                                .addComponent(lblWebViewAddress)
                                                                                .addPreferredGap(ComponentPlacement.RELATED)
                                                                                .addComponent(lblLink)))
                                                                .addPreferredGap(ComponentPlacement.RELATED)
                                                                .addComponent(jTabbedPane1, GroupLayout.PREFERRED_SIZE, 279, GroupLayout.PREFERRED_SIZE))))
                                        .addGroup(layout.createSequentialGroup()
                                                .addGap(293)
                                                .addComponent(jLabel1)))
                                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(Alignment.TRAILING)
                        .addGroup(layout.createSequentialGroup()
                                .addComponent(jLabel1)
                                .addPreferredGap(ComponentPlacement.RELATED, 6, Short.MAX_VALUE)
                                .addGroup(layout.createParallelGroup(Alignment.TRAILING)
                                        .addGroup(layout.createSequentialGroup()
                                                .addComponent(jCheckBox9)
                                                .addPreferredGap(ComponentPlacement.UNRELATED))
                                        .addGroup(layout.createParallelGroup(Alignment.LEADING)
                                                .addGroup(layout.createSequentialGroup()
                                                        .addGap(16)
                                                        .addComponent(jLabel2))
                                                .addGroup(layout.createSequentialGroup()
                                                        .addPreferredGap(ComponentPlacement.RELATED)
                                                        .addComponent(jLabel5)
                                                        .addPreferredGap(ComponentPlacement.RELATED)
                                                        .addGroup(layout.createParallelGroup(Alignment.BASELINE)
                                                                .addComponent(jLabel6)
                                                                .addComponent(jLabel7)
                                                                .addComponent(jLabel3)))))
                                .addGap(8)
                                .addGroup(layout.createParallelGroup(Alignment.TRAILING)
                                        .addGroup(layout.createSequentialGroup()
                                                .addComponent(jList1, GroupLayout.PREFERRED_SIZE, 259, GroupLayout.PREFERRED_SIZE)
                                                .addPreferredGap(ComponentPlacement.RELATED)
                                                .addGroup(layout.createParallelGroup(Alignment.LEADING)
                                                        .addComponent(chckbxEnableWebview)
                                                        .addComponent(jPanel5, GroupLayout.PREFERRED_SIZE, 207, GroupLayout.PREFERRED_SIZE))
                                                .addPreferredGap(ComponentPlacement.RELATED)
                                                .addGroup(layout.createParallelGroup(Alignment.BASELINE)
                                                        .addComponent(lblWebViewAddress)
                                                        .addComponent(lblLink))
                                                .addGap(19))
                                        .addGroup(layout.createSequentialGroup()
                                                .addComponent(jTabbedPane1, GroupLayout.PREFERRED_SIZE, 502, GroupLayout.PREFERRED_SIZE)
                                                .addPreferredGap(ComponentPlacement.RELATED)))
                                .addGap(2))
        );
        getContentPane().setLayout(layout);

        jLabel5.getAccessibleContext().setAccessibleName("<html><font color=blue><u>http://www.EasyModbusTCP.net</u></font></html>");
        jLabel5.getAccessibleContext().setAccessibleDescription("");

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

    private void jLabel5MousePressed(MouseEvent evt) {//GEN-FIRST:event_jLabel5MousePressed
        try {
            Desktop.getDesktop().browse(new URI("http://www.EasyModbusTCP.net"));
        } catch (Exception ex) {
        }
    }//GEN-LAST:event_jLabel5MousePressed

    private void jCheckBox1StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jCheckBox1StateChanged
        if (modbusServer.getFunctionCode1Disabled())
            modbusServer.setFunctionCode1Disabled(false);
        else
            modbusServer.setFunctionCode1Disabled(true);
    }//GEN-LAST:event_jCheckBox1StateChanged

    private void jCheckBox2StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jCheckBox2StateChanged
        if (modbusServer.getFunctionCode2Disabled())
            modbusServer.setFunctionCode2Disabled(false);
        else
            modbusServer.setFunctionCode2Disabled(true);
    }//GEN-LAST:event_jCheckBox2StateChanged

    private void jCheckBox3StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jCheckBox3StateChanged
        if (modbusServer.getFunctionCode3Disabled())
            modbusServer.setFunctionCode3Disabled(false);
        else
            modbusServer.setFunctionCode3Disabled(true);
    }//GEN-LAST:event_jCheckBox3StateChanged

    private void jCheckBox4StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jCheckBox4StateChanged
        if (modbusServer.getFunctionCode4Disabled())
            modbusServer.setFunctionCode4Disabled(false);
        else
            modbusServer.setFunctionCode4Disabled(true);
    }//GEN-LAST:event_jCheckBox4StateChanged

    private void jCheckBox5StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jCheckBox5StateChanged
        if (modbusServer.getFunctionCode5Disabled())
            modbusServer.setFunctionCode5Disabled(false);
        else
            modbusServer.setFunctionCode5Disabled(true);
    }//GEN-LAST:event_jCheckBox5StateChanged

    private void jCheckBox6StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jCheckBox6StateChanged
        if (modbusServer.getFunctionCode6Disabled())
            modbusServer.setFunctionCode6Disabled(false);
        else
            modbusServer.setFunctionCode6Disabled(true);
    }//GEN-LAST:event_jCheckBox6StateChanged

    private void jCheckBox7StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jCheckBox7StateChanged
        if (modbusServer.getFunctionCode15Disabled())
            modbusServer.setFunctionCode15Disabled(false);
        else
            modbusServer.setFunctionCode15Disabled(true);
    }//GEN-LAST:event_jCheckBox7StateChanged

    private void jCheckBox8StateChanged(ChangeEvent evt) {//GEN-FIRST:event_jCheckBox8StateChanged
        if (modbusServer.getFunctionCode16Disabled())
            modbusServer.setFunctionCode16Disabled(false);
        else
            modbusServer.setFunctionCode16Disabled(true);
    }//GEN-LAST:event_jCheckBox8StateChanged

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        this.modbusServer.StopListening();
    }//GEN-LAST:event_formWindowClosing

    private void jScrollBar2AdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jScrollBar2AdjustmentValueChanged
        javax.swing.table.DefaultTableModel model2 = (javax.swing.table.DefaultTableModel) jTable2.getModel();
        model2.setNumRows(0);
        for (int i = 0; i < 25; i++) {
            if ((i + this.jScrollBar2.getValue() + 1) < 65535)
                model2.addRow(new Object[]{String.valueOf(i + this.jScrollBar2.getValue() + 1), String.valueOf(modbusServer.coils[i + this.jScrollBar2.getValue() + 1])});
        }
    }//GEN-LAST:event_jScrollBar2AdjustmentValueChanged

    private void jScrollBar3AdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jScrollBar3AdjustmentValueChanged
        javax.swing.table.DefaultTableModel model3 = (javax.swing.table.DefaultTableModel) jTable3.getModel();
        model3.setNumRows(0);
        for (int i = 0; i < 25; i++) {
            if ((i + this.jScrollBar3.getValue() + 1) < 65535)
                model3.addRow(new Object[]{String.valueOf(i + this.jScrollBar3.getValue() + 1), String.valueOf(modbusServer.inputRegisters[i + this.jScrollBar3.getValue() + 1])});
        }
    }//GEN-LAST:event_jScrollBar3AdjustmentValueChanged

    private void jScrollBar4AdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jScrollBar4AdjustmentValueChanged
        this.holdingRegistersChangedEvent();
    }//GEN-LAST:event_jScrollBar4AdjustmentValueChanged

    private void jScrollBar1AdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jScrollBar1AdjustmentValueChanged
        javax.swing.table.DefaultTableModel model1 = (javax.swing.table.DefaultTableModel) jTable1.getModel();
        model1.setNumRows(0);
        for (int i = 0; i < 25; i++) {
            if ((i + this.jScrollBar1.getValue() + 1) < 65535)
                model1.addRow(new Object[]{String.valueOf(i + this.jScrollBar1.getValue() + 1), String.valueOf(modbusServer.discreteInputs[i + this.jScrollBar1.getValue() + 1])});

        }
    }//GEN-LAST:event_jScrollBar1AdjustmentValueChanged

    private void jTable1PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTable1PropertyChange
        for (int i = 0; i < jTable1.getRowCount(); i++) {
            this.modbusServer.setDiscreteInput(Boolean.valueOf((String) this.jTable1.getValueAt(i, 1)), i + this.jScrollBar1.getValue() + 1);
        }
        jScrollBar1AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable1PropertyChange

    private void jTable2PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTable2PropertyChange
        for (int i = 0; i < jTable2.getRowCount(); i++) {
            this.modbusServer.setCoil(Boolean.valueOf((String) this.jTable2.getValueAt(i, 1)), i + this.jScrollBar2.getValue() + 1);

        }
        jScrollBar2AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable2PropertyChange

    private void jTable3PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTable3PropertyChange
        for (int i = 0; i < jTable3.getRowCount(); i++) {
            this.modbusServer.setInputRegister(Integer.valueOf((String) this.jTable3.getValueAt(i, 1)), i + this.jScrollBar3.getValue() + 1);

        }
        jScrollBar3AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable3PropertyChange

    private void jPanel4PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jPanel4PropertyChange

    }//GEN-LAST:event_jPanel4PropertyChange

    private void jTable4PropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_jTable4PropertyChange
        for (int i = 0; i < jTable4.getRowCount(); i++) {
            this.modbusServer.setHoldingRegister(Integer.valueOf((String) this.jTable4.getValueAt(i, 1)), i + this.jScrollBar4.getValue() + 1);

        }
        jScrollBar4AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable4PropertyChange

    private void jTable1MouseClicked(MouseEvent evt) {//GEN-FIRST:event_jTable1MouseClicked

        this.modbusServer.setDiscreteInput((!this.modbusServer.getDiscreteInput(jTable1.getSelectedRow() + this.jScrollBar1.getValue() + 1)), (jTable1.getSelectedRow() + this.jScrollBar1.getValue() + 1));

        jScrollBar1AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable1MouseClicked

    private void jTabbedPane1MouseClicked(MouseEvent evt) {//GEN-FIRST:event_jTabbedPane1MouseClicked

    }//GEN-LAST:event_jTabbedPane1MouseClicked

    private void jTable2MouseClicked(MouseEvent evt) {//GEN-FIRST:event_jTable2MouseClicked
        this.modbusServer.setCoil((!this.modbusServer.getCoil(jTable2.getSelectedRow() + this.jScrollBar2.getValue() + 1)), (jTable2.getSelectedRow() + this.jScrollBar2.getValue() + 1));
        jScrollBar2AdjustmentValueChanged(null);
    }//GEN-LAST:event_jTable2MouseClicked

    public void coilsChangedEvent() {
        javax.swing.table.DefaultTableModel model2 = (javax.swing.table.DefaultTableModel) jTable2.getModel();
        model2.setNumRows(0);
        for (int i = 0; i < 25; i++) {
            if ((i + this.jScrollBar2.getValue() + 1) < 65535)
                model2.addRow(new Object[]{String.valueOf(i + this.jScrollBar2.getValue() + 1), String.valueOf(modbusServer.coils[i + this.jScrollBar2.getValue() + 1])});
        }
    }

    public void holdingRegistersChangedEvent() {
        javax.swing.table.DefaultTableModel model4 = (javax.swing.table.DefaultTableModel) jTable4.getModel();
        model4.setNumRows(0);
        for (int i = 0; i < 25; i++) {
            if ((i + this.jScrollBar4.getValue() + 1) < 65535)
                model4.addRow(new Object[]{String.valueOf(i + this.jScrollBar4.getValue() + 1), String.valueOf(modbusServer.holdingRegisters[i + this.jScrollBar4.getValue() + 1])});
        }
    }

    public void NumberOfConnectedClientsChanged() {
        this.jLabel7.setText(String.valueOf(modbusServer.getNumberOfConnectedClients()));
    }

    javax.swing.DefaultListModel model = new javax.swing.DefaultListModel();

    public void logDataChangedEvent() {
        if (jCheckBox9.getSelectedObjects() == null)
            return;


        //model.removeAllElements();

        String listBoxData;
        for (int i = 0; i < 2; i++) {

            if (modbusServer.getLogData()[i] == null)
                break;
            if (modbusServer.getLogData()[i].request) {
                listBoxData = modbusServer.getLogData()[i].timeStamp.getTime() + " Request from Client - Functioncode: " + String.valueOf(modbusServer.getLogData()[i].functionCode);
                if (modbusServer.getLogData()[i].functionCode <= 4) {
                    listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity);
                }
                if (modbusServer.getLogData()[i].functionCode == 5) {
                    listBoxData = listBoxData + " Output Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Output Value: ";
                    if (modbusServer.getLogData()[i].receiveCoilValues[0] == 0)
                        listBoxData = listBoxData + "False";
                    if (modbusServer.getLogData()[i].receiveCoilValues[0] == 0xFF00)
                        listBoxData = listBoxData + "True";
                }
                if (modbusServer.getLogData()[i].functionCode == 6) {
                    listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Register Value: " + String.valueOf(modbusServer.getLogData()[i].receiveRegisterValues[0]);
                }
                if (modbusServer.getLogData()[i].functionCode == 15) {
                    listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity) + " Byte Count: " + String.valueOf(modbusServer.getLogData()[i].byteCount) + " Values Received: ";
                    for (int j = 0; j < modbusServer.getLogData()[i].quantity; j++) {
                        int shift = j % 16;
                        if ((i == modbusServer.getLogData()[i].quantity - 1) & (modbusServer.getLogData()[i].quantity % 2 != 0)) {
                            if (shift < 8)
                                shift = shift + 8;
                            else
                                shift = shift - 8;
                        }
                        int mask = 0x1;
                        mask = mask << (shift);
                        if ((modbusServer.getLogData()[i].receiveCoilValues[j / 16] & mask) == 0)
                            listBoxData = listBoxData + " False";
                        else
                            listBoxData = listBoxData + " True";
                    }
                }
                if (modbusServer.getLogData()[i].functionCode == 16) {
                    listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity) + " Byte Count: " + String.valueOf(modbusServer.getLogData()[i].byteCount) + " Values Received: ";
                    for (int j = 0; j < modbusServer.getLogData()[i].quantity; j++) {
                        listBoxData = listBoxData + " " + modbusServer.getLogData()[i].receiveRegisterValues[j];
                    }
                }
                model.add(0, listBoxData);


            }
            if (modbusServer.getLogData()[i].response) {
                if (modbusServer.getLogData()[i].exceptionCode > 0) {
                    listBoxData = ("Response To Client - Error code: " + String.valueOf(modbusServer.getLogData()[i].errorCode));
                    listBoxData = listBoxData + " Exception Code: " + String.valueOf(modbusServer.getLogData()[i].exceptionCode);
                    model.add(0, listBoxData);


                } else {
                    listBoxData = (modbusServer.getLogData()[i].timeStamp.getTime() + " Response To Client - Functioncode: " + String.valueOf(modbusServer.getLogData()[i].functionCode));

                    if (modbusServer.getLogData()[i].functionCode <= 4) {

                        listBoxData = listBoxData + " Bytecount: " + String.valueOf((int) modbusServer.getLogData()[i].byteCount) + " Values sent: ";
                    }
                    if (modbusServer.getLogData()[i].functionCode == 5) {
                        listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Output Value: ";
                        if (modbusServer.getLogData()[i].receiveCoilValues[0] == 0)
                            listBoxData = listBoxData + "False";
                        if (modbusServer.getLogData()[i].receiveCoilValues[0] == 0xFF00)
                            listBoxData = listBoxData + "True";
                    }
                    if (modbusServer.getLogData()[i].functionCode == 6) {
                        listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Register Value: " + String.valueOf(modbusServer.getLogData()[i].receiveRegisterValues[0]);
                    }
                    if (modbusServer.getLogData()[i].functionCode == 15) {
                        listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity);
                    }
                    if (modbusServer.getLogData()[i].functionCode == 16) {
                        listBoxData = listBoxData + " Starting Address: " + String.valueOf(modbusServer.getLogData()[i].startingAdress) + " Quantity: " + String.valueOf(modbusServer.getLogData()[i].quantity);
                    }
                    if (modbusServer.getLogData()[i].sendCoilValues != null) {
                        for (int j = 0; j < modbusServer.getLogData()[i].sendCoilValues.length; j++) {
                            listBoxData = listBoxData + String.valueOf(modbusServer.getLogData()[i].sendCoilValues[j]) + " ";
                        }
                    }
                    if (modbusServer.getLogData()[i].sendRegisterValues != null) {
                        for (int j = 0; j < modbusServer.getLogData()[i].sendRegisterValues.length; j++) {
                            listBoxData = listBoxData + String.valueOf(modbusServer.getLogData()[i].sendRegisterValues[j]) + " ";
                        }
                    }
                    model.add(0, listBoxData);
                }
            }
        }
    }

    int topic;
    String link;

    private void WebViewStateChanged(ChangeEvent evt) {
        topic = new Random().nextInt(99999);
        if (chckbxEnableWebview.isSelected()) {

            link = "http://www.easymodbustcp.net/webview/easymodbuswebview.html?topic=" + topic;
            lblLink.setText("<html><a href =\"" + link + "\">" + link + "</a></html>");
            lblWebViewAddress.setVisible(true);
            lblLink.setVisible(true);


        } else {

            lblWebViewAddress.setVisible(false);
            lblLink.setVisible(false);

        }

    }

    private void linkClicked() {
        if (Desktop.isDesktopSupported()) {
            Desktop desktop = Desktop.getDesktop();
            try {
                desktop.browse(new URI(link));
            } catch (IOException | URISyntaxException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        } else {
            Runtime runtime = Runtime.getRuntime();
            try {
                runtime.exec("xdg-open " + link);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* 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 ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private JCheckBox jCheckBox1;
    private JCheckBox jCheckBox2;
    private JCheckBox jCheckBox3;
    private JCheckBox jCheckBox4;
    private JCheckBox jCheckBox5;
    private JCheckBox jCheckBox6;
    private JCheckBox jCheckBox7;
    private JCheckBox jCheckBox8;
    private JCheckBox jCheckBox9;
    private JLabel jLabel1;
    private JLabel jLabel2;
    private JLabel jLabel3;
    private JLabel jLabel4;
    private JLabel jLabel5;
    private JLabel jLabel6;
    private JLabel jLabel7;
    private javax.swing.JList jList1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private JScrollBar jScrollBar1;
    private JScrollBar jScrollBar2;
    private JScrollBar jScrollBar3;
    private JScrollBar jScrollBar4;
    private JScrollPane jScrollPane1;
    private JScrollPane jScrollPane2;
    private JScrollPane jScrollPane3;
    private JScrollPane jScrollPane4;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTable jTable2;
    private javax.swing.JTable jTable3;
    private javax.swing.JTable jTable4;
    private JCheckBox chckbxEnableWebview;
    private JLabel lblWebViewAddress;
    private JLabel lblLink;
}
