Tag

, , , , , ,

Setelah sebelumnya memprogram Mikrokontroller untuk difungsikan sebagai counter. Sekarang saatnya membuat mengkomunikasikan uC tersebut dengan komputer melalui koneksi RS-232 dengan tentunya dengan tampilan GUI supaya lebih userfriendly. Untuk itu saya menggunakan software java (NETBEANS) dengan database MySQL. Dua perpaduan yang (menurut saya) sangat robust (apalagi under Linux). Mantabs..!!!

Langkah Pengerjaan :

1. Buat Project baru bernama prjProdCounter
Pilih File -> New Project.. Kemudian akan muncul wizard pembuatan project baru. Pilih Java pada kolom Categories, dan Java Application pada kolom Projects. Lanjutkan dengan meng-click tombol Next. Kemudian isi project name dengan prjProdCounter. Selesaikan wizard dengan meng-click tombol Finish.

Maka akan terdapat : Source Packages, Test Packages, Libraries, Test Libraries.

2. Tambahkan library untuk koneksi serial, mysql dan applet jam.
Click kanan pada (folder) Libraries, lalu pilih Add JAR/Folder… Pada kolom Look in, cari dimana terdapat library tambahan tersebut. Masukkan ketiga library tambahan ini : comm.jar, jPopText.jar, mysql.jar (click open).
Note : Library tambahan ini sudah saya paket-kan dalam file yang bisa Anda download di bagian akhir tulisan ini.

3. Buat class baru bernama KoneksiSerial
Pada Java Source Package yang bernama prjprodcounter, click kanan kemudian pilih New -> Java Class.. Pada kolom Class name isi nama class tersebut dengan KoneksiSerial diikuti Finish. Ketikkan script program berikut ini :

/*
 * Author        : InsanSains
 * Date Created  :
 * Date Modified : 28 Mei 2008
 *
 * # KoneksiSerial()
 *   Konstruktor untuk menginisialisasi Koneksi RS232
 *
 * # OpenConnRS232()
 *   Membuka koneksi RS232 dengan nomor port yang sudah ditentukan
 *   Default port-nya adalah : /dev/ttyS0
 *
 * # CloseConnRS232()
 *   Method untuk menutup koneksi RS232
 *
 * # resetData()
 *   Method untuk mengirimkan sinyal reset dari komputer ke RS232
 *   Sinyal reset tersebut diinisialisasi dengan : "R"
 *
 * # getData()
 *   Method untuk mendapatkan data yang terbaca pada RS232
 *
 * # isConnected()
 *   Method untuk mengetahui status koneksi komputer dengan RS232
 *
 */

package prjprodcounter;

/* Import Libraries yang dibutuhkan */
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Observable;
import java.util.TooManyListenersException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.comm.CommPortIdentifier;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;

/**
 * @author insansains
 *
 * Observable berarti objek ini mempunyai kemampuan untuk memberitahukan
 * kepada objek yang lainnya tentang perubahan yang terjadi kepadanya.
 * Hal ini diperlukan, sebab, kita ingin program utama lebih sederhana
 * hanya tinggal memanggil objek-objek yang diperlukan saja tanpa harus
 * mengetahui apa yang dilakukan oleh objek-objek tersebut.
 * Dalam hal ini, kita tidak ingin program utama selalu memeriksa keadaan Port
 * apakah mempunyai data baru ataukah tidak. Lebih baik hal ini diserahkan
 * kepada objek yang bersangkutan.
 *
 * Objek KoneksiSerial ini akan memberitahukan perubahan kondisi data yang
 * terbaca kepada objek lain yang mengimplemetnasikan sifat sebagai Observer
 * (dalam program ini, kita akan menemukan sebuah LabelObserver)
 *
 * Selain itu, objek KoneksiSerial ini mengimplementasikan Listener Serialport
 * fungsinya agar dapat membaca setiap kejadian di RS232
 */
public class KoneksiSerial extends Observable implements SerialPortEventListener {

    /* PENTING - PENTING - PENTING - PENTING - PENTING - PENTING
     * baudRate pada komputer di setting pada kecepatan 19200 bps,
     * tetapi baudRate pada program di mikrokontrollernya pada 9600 bps
     * BELUM ADA PENJELASAN TEKNIS UNTUK MASALAH INI,
     * BARU HASIL PERCOBAAN YANG TERBUKTI BERHASIL DAN SATU-SATUNYA CARA!
     */

    /* Inisialisasi variable yang digunakan */
    private static CommPortIdentifier portId;
    private static Enumeration portList;
    private SerialPort serialPort;
    private InputStream inputStream;
    private OutputStream outputStream;
    private byte[] bufferData = new byte[7];
    private String portUsed = "/dev/ttyS0";
    private Boolean portFound = false;
    private Boolean statConn = false;
    private int baudRate = 19200;
    private String dataReset = "R";
    private String dataPort = "0";

    /* Constructor */
    public KoneksiSerial(){
    }

    public void openConnRS232() throws UnsupportedCommOperationException {
        try {
            /* masih belum ngerti kenapa harus open (nama file)
             * Mungkin adalah parameter yang memang diharuskan begitu
             * yang diminta oleh objek yang bersangkutan
             */
            portId = CommPortIdentifier.getPortIdentifier(portUsed);
            serialPort = (SerialPort) portId.open("KoneksiSerial", 3000);

            /*set parameter port */
            serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);

            serialPort.notifyOnDataAvailable(true);
            serialPort.notifyOnOutputEmpty(true);
            serialPort.setOutputBufferSize(SerialPort.DATABITS_8);
            serialPort.addEventListener(this);

            portList = CommPortIdentifier.getPortIdentifiers();
            while (portList.hasMoreElements()) {
                portId = (CommPortIdentifier) portList.nextElement();
                if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                    if (portId.getName().equals(portUsed)) {
                        System.out.println("Found port: " + portUsed);
                        portFound = true;
                        statConn = true;
                    }
                }
            }

            /* Variable untuk baca dan kirim data dari/ke RS232 */
            inputStream = serialPort.getInputStream();
            outputStream = serialPort.getOutputStream();

        } catch (TooManyListenersException ex) {
            Logger.getLogger(KoneksiSerial.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(KoneksiSerial.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchPortException ex) {
            System.out.println("No such port!");
            Logger.getLogger(KoneksiSerial.class.getName()).log(Level.SEVERE, null, ex);
        } catch (PortInUseException ex) {
            System.out.println("Port is in use by another application!!");
            Logger.getLogger(KoneksiSerial.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void serialEvent(SerialPortEvent event) {

        /* Kondisi-kondisi yang bisa terbaca pada komunikasi serial */
        switch (event.getEventType()) {
            case SerialPortEvent.BI:
                System.out.println("Interrupted");
                break;
            case SerialPortEvent.OE:

            case SerialPortEvent.FE:

            case SerialPortEvent.PE:

            case SerialPortEvent.CD:

            case SerialPortEvent.CTS:

            case SerialPortEvent.DSR:

            case SerialPortEvent.RI:

            /* Tidak ada data yang masuk */
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                System.out.println("Output buffer empty");
                break;

            /* Ini yang paling penting
             * Disini ada pemberitahuan bahwa ada data yang terbaca di RS232
             * Maka dapatkan data tersebut
             * Tampilkan di layar (cukup beritahu Observer, biar si Observer
             * itu sendiri yang menanganinya)
             */
            case SerialPortEvent.DATA_AVAILABLE:
                /* Dapatkan data yang terbaca di RS232 */
                setData();

                /* Update objek-objek observer */
                setChanged();
                notifyObservers();
        }
    }

    void setData() {
        /* Saat ini data mentah tersebut ada di inputStream
         * Agar bisa dibaca oleh objek yang lainnya, harus di pindahkan
         * ke variable lain (dalam hal ini bufferData bertype array of byte
         * yang kemudian di convert ke String agar bisa ditampilkan di layar)
         */
        bufferData = new byte[7];
        try {
            while (inputStream.available() > 0) {
                inputStream.read(bufferData);
            }
            dataPort = new String(bufferData).trim();
            System.out.println(dataPort);
        } catch (IOException e) {
        }
    }

    void closeConnRS232() {
        /* Method tutup koneksi
         * Kirim data Reset, supaya si mikrokontroler me reset counternya
         */
        resetData();
        serialPort.close();
    }

    void resetData() {
        try {
            outputStream.write(dataReset.getBytes());
            dataPort = "0";
        } catch (IOException ex) {
            Logger.getLogger(GUIProdCounter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public String getData() {
        return dataPort;
    }

    public Boolean isConnected() {
        return statConn;
    }

}

4. Buat class baru bernama labelObserver
Pada Java Source Package yang bernama prjprodcounter, click kanan kemudian pilih New -> Java Class.. Pada kolom Class name isi nama class tersebut dengan labelObserver diikuti Finish. Ketikkan script program untuk label observer seperti berikut ini :

/*
 * Author        : InsanSains
 * Date Created  :
 * Date Modified : 28 Mei 2008
 *
 */

package prjprodcounter;

import java.util.Observer;
import java.util.Observable;
import javax.swing.JLabel;

/**
 *
 * @author insansains
 *
 * Objek ini mengimplementasikan Observer berarti :
 * Setiap perubahan yang terjadi pada objek yang Observable
 * dapat diketahui oleh objek ini
 */
public class labelObserver implements Observer {
    Observable observable;
    private String thisValue = "0";
    private JLabel myLabel = new javax.swing.JLabel();

    public JLabel getLabel() {
        return myLabel;
    }

    public labelObserver(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);
        initLabel();
    }

    private void initLabel() {
        myLabel.setFont(new java.awt.Font("Dialog",1,48));
        myLabel.setText(thisValue);
        myLabel.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
    }

/* Ini ada syarat yang harus dimiliki oleh objek yang mengimplementasikan
 * sifat Observer. Method ini digunakan ketika ada perubahan yang terjadi
 * pada objek Observable maka objek ini (observer) harus melakukan apa?
 */
public void update(Observable obs, Object obj) {
        if (obs instanceof KoneksiSerial) {
            KoneksiSerial koneksiSerial = (KoneksiSerial) obs;
            this.thisValue = koneksiSerial.getData();
            myLabel.setText(thisValue);
        }
    }
}

5. Buat class baru bernama KoneksiMysql
Pada Java Source Package yang bernama prjprodcounter, click kanan kemudian pilih New -> Java Class.. Pada kolom Class name isi nama class tersebut dengan KoneksiMysql diikuti Finish. Ketikkan script program untuk koneksi Mysql seperti berikut ini :

/*
 * Author        : InsanSains
 * Date Created  :
 * Date Modified : 28 Mei 2008
 *
 * # getMysqlConn
 *   Method untuk me-return nilai (variable) xConn
 *
 * # openConnMysql (String xNamaDatabase)
 *   Method untuk membuka koneksi dengan database MySQL
 *   Paramater yang harus diisi adalah nama database MySQL
 *
 * # closeConnMysql
 *   Method untuk menutup koneksi dengan database MySQL
 *
 * # addData2Table
 *   Method untuk menyimpan/menambahkan data ke table MySQL
 *
 */

package prjprodcounter;

/* import libraries yang dibutuhkan */
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author insansains
 */
public class KoneksiMysql {

    /* Inisialisasi variable yang dibutuhkan */
    private static Connection xConn = null;

    public Connection getMysqlConn() {
        return xConn;
    }

    public void openConnMysql(String xNamaDatabase) {
        String xUrl = "jdbc:mysql://localhost:3306/"+xNamaDatabase;
        String xDriver = "com.mysql.jdbc.Driver";
        String xUsername = "insansains";
        String xPassword = "insansains";
        try {
            Class.forName(xDriver).newInstance();
            xConn = DriverManager.getConnection(xUrl, xUsername, xPassword);
            System.out.println("Koneksi ke database "+xNamaDatabase+" [ ok ]");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void closeConnMysql() {
       try {
            xConn.close();
        } catch (SQLException ex) {
            Logger.getLogger(KoneksiMysql.class.getName()).log(Level.SEVERE, null, ex);
        }
       System.out.println("Menutup koneksi database [ ok ]");
    }

    public void addData2Table(String xNamaMesin, String xTanggal, Time xWaktuMulai, int xJumlah) {
       try {
            String Query = "insert into prodcounter (nama_mesin, tanggal, waktu_mulai, waktu_selesai, jumlah)"
                    + " values ('" + xNamaMesin + "','" + xTanggal + "',time('"+xWaktuMulai+ "'), time(now())," + xJumlah + ");";
            System.out.println(Query);
            Statement stmt = KoneksiMysql.xConn.createStatement();

            /* Catatan
             * Pernah menggunakan ResultSet rs = stmt.executeQuery(Query);
             * tapi tidak bisa menambah data yang dimaksud ke table.
             * Ketika menggunakan executeUpdate baru bisa
             */
            int execute = stmt.executeUpdate(Query);
            if(execute>0){
                System.out.println("Data berhasil disimpan");
            }else
                System.out.println("Data gagal disimpan...!");
        } catch (SQLException ex) {
            Logger.getLogger(KoneksiMysql.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

6. Buat class baru bernama ViewDatabase
Pada Java Source Package yang bernama prjprodcounter, click kanan kemudian pilih New -> JFrame Form.. Pada kolom Class name isi nama class tersebut dengan ViewDatabase diikuti Finish. Atur design sehingga kurang lebih berbentuk seperti berikut ini:

Kemudian pada mode Source, ketikkan script program berikut ini :

/*
 * Object Name   : ViewDatabase.java
 * Author        : InsanSains
 * Date Created  : 12 Mei 2008
 * Date Modified : 28 Mei 2008
 *
 * # ViewDatabase(KoneksiMysql xConn, String xNamaDatabase)
 *   Construktor untuk mengaktifkan object ini
 */

package prjprodcounter;

/* Import Libraries yang dibutuhkan */
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author  insansains
 */
public class ViewDatabase extends javax.swing.JFrame {

    /** Creates new form ViewDatabase */
    public ViewDatabase(KoneksiMysql xConn, String xNamaDatabase) {
       initComponents();

       try{
            /* Karena koneksi ke database itu sangat "mahal"
             * maka untuk prosedur membukanya dilakukan di luar objek ini
             * (jadi harus dipastikan sudah dibuka databasenya)
             * xConn.openConnMysql(xNamaDatabase); */
            String[] xheader = {"Nama Mesin", "Tanggal", "Waktu Mulai", "Waktu Selesai", "Qty"};
            String query = "select * from prodcounter";
            System.out.println(xConn.getMysqlConn());
            Statement stmt = xConn.getMysqlConn().createStatement();

            ResultSet rs = stmt.executeQuery(query);

            /* Dapatkan jumlah seluruh datanya
             * kemudian buat object dalam bentuk aray sebanyak jmlh data
             * untuk dimasukkan ke TableModel
             */
            rs.last();
            int jmldata = rs.getRow();
            Object[][] dataTable = new Object[jmldata][5];

            /* Kembali ke data teratas */
            rs.beforeFirst();
            int x = 0;

            /* Masukkan data data kedalam object array */
            while (rs.next()) {
                System.out.println(rs.getString(1));
                dataTable[x][0] = rs.getString("nama_mesin");
                dataTable[x][1] = rs.getDate("tanggal");
                dataTable[x][2] = rs.getTime("waktu_mulai");
                dataTable[x][3] = rs.getTime("waktu_selesai");
                dataTable[x][4] = rs.getInt("jumlah");
                x++;
            }

            /* Masukkan data ke dalam table */
            jTable1.setModel(new DefaultTableModel(dataTable, xheader));

            /* Tidak perlu ditutup koneksinya
             * sebab kita menghindari buka-tutup koneksi
             * xConn.tutupKoneksiMysql();
             */

        } catch (SQLException ex) {
            Logger.getLogger(ViewDatabase.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("View Database");

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

            },
            new String [] {
                "Nama_Mesin"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane1.setViewportView(jTable1);

        jLabel1.setFont(new java.awt.Font("Nimbus Sans L", 1, 18));
        jLabel1.setText("Database : Production Counter");

        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(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
                    .addComponent(jLabel1))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>
    /**
     * @param args the command line arguments
     */

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                /* Jika ingin menguji coba, komentar dibawah ini hilangkan saja! */
                //new ViewDatabase("otomatisasi").setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    // End of variables declaration                   

}

7. Gabungkan semuanya dalam satu class GUI bernama GUIProdCounter
Langkah selanjutnya adalah menggabungkan semua objek tersebut dalam satu aplikasi GUI. Untuk merealisasikan hal tersebut, click kanan pada Java Source Package yang bernama prjprodcounter. Pilih New -> JFrame Form.. Pada kolom Class name isi nama class tersebut dengan GUIProdCounter diikuti Finish. Kemudian buatlah tampilan GUI (Graphical User Interface) seperti terlihat dibawah ini :

Lalu pada mode Source, ketikkan program berikut ini :

/*
 * Program Name  : GUIProdCounter.java
 * Author        : InsanSains
 * Date Created  : 15 Mei 2008, 8:15
 * Date Modified : 28 Mei 2008
 *
 */

package prjprodcounter;

/* Import Libraries yang dibutuhkan */
import java.sql.Time;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import javax.comm.UnsupportedCommOperationException;
import javax.swing.JFrame;

/**
 *
 * @author  insansains
 */
public class GUIProdCounter extends javax.swing.JFrame {

    /* Note :
     * formatDate1 = Untuk tampilan tanggal di layar
     * formatDate2 = Untuk format tanggal saat menyimpan data ke table MySQL
     */

    String formatDate1 = "dd MMMM yyyy";
    String formatDate2 = "yyyy-MM-dd";
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat(formatDate1);
    SimpleDateFormat sdf2 = new SimpleDateFormat(formatDate2);

    private String Tanggal = sdf.format(cal.getTime());
    private String Tanggal2 = sdf2.format(cal.getTime());
    private Time startingTime;
    private KoneksiSerial KSerial;
    private KoneksiMysql KMySQL;
    private JFrame frameViewData;
    private labelObserver LObs;

    /** Creates new form GUIProdCounter */
    /* Inisialisasi dan load object yang akan dimunculkan */
    public GUIProdCounter() {
        initMyObject();
        initComponents();
    }

    private void initMyObject() {
        KSerial = new KoneksiSerial();
        LObs = new labelObserver(KSerial);
        KMySQL = new KoneksiMysql();
        KMySQL.openConnMysql("otomatisasi");
    }

    /** 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.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        panel_windows = new javax.swing.JPanel();
        panel_angka = new javax.swing.JPanel();
        label_counter = LObs.getLabel();
        button_view_data = new javax.swing.JButton();
        button_stop = new javax.swing.JButton();
        button_start = new javax.swing.JButton();
        label_date_u2d = new javax.swing.JLabel();
        combo_machine_name = new javax.swing.JComboBox();
        label_time_u2d = new com.pticosmetics.penta.client.gui.jam();
        jPanel1 = new javax.swing.JPanel();
        label_date = new javax.swing.JLabel();
        label_time = new javax.swing.JLabel();
        label_machine_name = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Production Counter");
        setName("frame_utama"); // NOI18N
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });

        panel_windows.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        panel_windows.setForeground(new java.awt.Color(153, 153, 153));

        panel_angka.setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED));

        label_counter.setFont(new java.awt.Font("Dialog", 1, 48));
        label_counter.setText("0");
        label_counter.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        label_counter.setInheritsPopupMenu(false);
        label_counter.setName("Text_Nilai"); // NOI18N

        javax.swing.GroupLayout panel_angkaLayout = new javax.swing.GroupLayout(panel_angka);
        panel_angka.setLayout(panel_angkaLayout);
        panel_angkaLayout.setHorizontalGroup(
            panel_angkaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panel_angkaLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(label_counter, javax.swing.GroupLayout.DEFAULT_SIZE, 142, Short.MAX_VALUE)
                .addContainerGap())
        );
        panel_angkaLayout.setVerticalGroup(
            panel_angkaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panel_angkaLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(label_counter)
                .addContainerGap(14, Short.MAX_VALUE))
        );

        button_view_data.setFont(new java.awt.Font("Nimbus Sans L", 0, 14));
        button_view_data.setText("View Data");
        button_view_data.setName("texname"); // NOI18N
        button_view_data.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_view_dataActionPerformed(evt);
            }
        });

        button_stop.setFont(new java.awt.Font("Nimbus Sans L", 0, 14));
        button_stop.setText("Stop");
        button_stop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_stopActionPerformed(evt);
            }
        });

        button_start.setFont(new java.awt.Font("Nimbus Sans L", 0, 14));
        button_start.setText("Start");
        button_start.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                button_startActionPerformed(evt);
            }
        });

        label_date_u2d.setText("01-01-2008");
        label_date_u2d.setAlignmentX(0.5F);

        combo_machine_name.setFont(new java.awt.Font("Nimbus Sans L", 0, 14));
        combo_machine_name.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Machine 1", "Machine 2", "Machine 3", "Machine 4" }));

        label_time_u2d.setFont(new java.awt.Font("Nimbus Sans L", 0, 12));

        jPanel1.setBackground(new java.awt.Color(51, 51, 51));
        jPanel1.setForeground(new java.awt.Color(204, 204, 204));

        label_date.setFont(new java.awt.Font("Nimbus Sans L", 1, 14));
        label_date.setForeground(new java.awt.Color(255, 255, 255));
        label_date.setText("DATE");

        label_time.setFont(new java.awt.Font("Nimbus Sans L", 1, 14));
        label_time.setForeground(new java.awt.Color(255, 255, 255));
        label_time.setText("TIME");

        label_machine_name.setFont(new java.awt.Font("Nimbus Sans L", 1, 14));
        label_machine_name.setForeground(new java.awt.Color(255, 255, 255));
        label_machine_name.setText("MACHINE NAME");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(label_date)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 85, Short.MAX_VALUE)
                .addComponent(label_time)
                .addGap(36, 36, 36)
                .addComponent(label_machine_name)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(label_machine_name)
                        .addComponent(label_time))
                    .addComponent(label_date))
                .addContainerGap())
        );

        javax.swing.GroupLayout panel_windowsLayout = new javax.swing.GroupLayout(panel_windows);
        panel_windows.setLayout(panel_windowsLayout);
        panel_windowsLayout.setHorizontalGroup(
            panel_windowsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panel_windowsLayout.createSequentialGroup()
                .addGroup(panel_windowsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panel_windowsLayout.createSequentialGroup()
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(label_date_u2d, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(12, 12, 12)
                        .addComponent(label_time_u2d, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(combo_machine_name, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panel_windowsLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(panel_angka, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(panel_windowsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(button_view_data, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(button_stop, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(button_start, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );
        panel_windowsLayout.setVerticalGroup(
            panel_windowsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(panel_windowsLayout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(panel_windowsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, panel_windowsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(label_time_u2d, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(label_date_u2d))
                    .addComponent(combo_machine_name, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(panel_windowsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(panel_windowsLayout.createSequentialGroup()
                        .addComponent(button_start)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(button_stop)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(button_view_data))
                    .addComponent(panel_angka, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        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()
                .addComponent(panel_windows, javax.swing.GroupLayout.PREFERRED_SIZE, 307, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(panel_windows, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void button_view_dataActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:

        /* Database tidak dibuka tutup lagi kecuali saat load aplikasi
         * dan nanti saat akan meng-close aplikasi
         */
        System.out.println("Memperlihatkan data....!");

        /* Tampilkan data hasil */
        new ViewDatabase(KMySQL, "otomatisasi").setVisible(true);

}                                                

    private void button_stopActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        KSerial.closeConnRS232();

        // Save data ke database
        KMySQL.addData2Table(String.valueOf(combo_machine_name.getSelectedItem()), Tanggal2, startingTime, Integer.parseInt(label_counter.getText()));

        // Atur tampilan tombol
        button_stop.setEnabled(false);
        button_start.setEnabled(true);
        combo_machine_name.setEnabled(true);
        button_view_data.setEnabled(true);
    }
/*
*/                                           

    private void button_startActionPerformed(java.awt.event.ActionEvent evt) {
/* Buka Koneksi Serial - Lakukan Reset Data
*/
        try {
            KSerial.openConnRS232();
            KSerial.resetData();

        } catch (UnsupportedCommOperationException ex) {
            Logger.getLogger(GUIProdCounter.class.getName()).log(Level.SEVERE, null, ex);
        }

        /* Catat waktu mulai proses counting ini */
        startingTime = Time.valueOf(label_time_u2d.getNow());

        button_stop.setEnabled(true);
        button_start.setEnabled(false);
        combo_machine_name.setEnabled(false);
        button_view_data.setEnabled(false);
    }

    @SuppressWarnings("static-access")
    private void formWindowOpened(java.awt.event.WindowEvent evt) {
        // TODO add your handling code here:
        button_stop.setEnabled(false);
        label_date_u2d.setText(Tanggal);
    }                                 

    @SuppressWarnings("static-access")
    private void formWindowClosing(java.awt.event.WindowEvent evt) {
        // TODO add your handling code here:
        KMySQL.closeConnMysql();
    }                                  

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUIProdCounter().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    private javax.swing.JButton button_start;
    private javax.swing.JButton button_stop;
    private javax.swing.JButton button_view_data;
    private javax.swing.JComboBox combo_machine_name;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLabel label_counter;
    private javax.swing.JLabel label_date;
    private javax.swing.JLabel label_date_u2d;
    private javax.swing.JLabel label_machine_name;
    private javax.swing.JLabel label_time;
    private com.pticosmetics.penta.client.gui.jam label_time_u2d;
    private javax.swing.JPanel panel_angka;
    private javax.swing.JPanel panel_windows;
    // End of variables declaration                   

}

8. Ujicoba program

Selesai…!!! ^_^