Membuat Menu Login Di Java Swing dengan Animasi Progress Bar

Setelah kita mengerti tentang Thread-thread dasar yang terdapat pada Java Swing dan mengetahui bagaimana cara menggunakan Background Thread dengan SwingWorker (pembahasan tentang SwingWorker bisa dilihat pada tulisan Lebih Dekat Dengan Class SwingWorker), sekarang mari kita coba membuat sebuah Project yang menggunakan Menu Login yang proses otentikasinya kita lakukan langsung ke database :)

Sebelum memulai latihan kali ini, ada beberapa hal yang harus dipersiapkan terlebih dahulu yaitu :
- Inisialisasi Master Data Pada DataBase
- Pembuatan Project Menu Login
- Hasil Akhir

Pada tulisan kali ini saya tidak akan memberikan penjelasan source code dari baris ke baris seperti pada tulisan-tulisan sebelumnya, tetapi sebagai gantinya penjelasan dapat dilihat pada komentar yang terdapat pada source code yang bersangkutan supaya lebih mudah di ingat-ingat nantinya :)

Inisialisasi Master Data Pada DataBase

Sebelum mulai membuat sebuah Project buatlah dahulu database dan tabel yang akan kita akses dari aplikasi Java, untuk membuat sebuah database dan tabel yang akan kita gunakan secara otomatis simpanlah schema database dibawah ini dengan nama MenuLoginSchema.sql :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- DataBase Schema Untuk Contoh MenuLogin
 
CREATE DATABASE `menulogin`;
 
USE `menulogin`;
 
--
-- Table structure for table `T_USER`
--
DROP TABLE IF EXISTS `T_USER`;
CREATE TABLE `T_USER` (
  `id` int AUTO_INCREMENT NOT NULL,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
--
-- Dumping data for table `T_USER`
--
INSERT INTO `T_USER` (`username`,`password`) VALUES
('martin', 'menulogin'), ('ahmad','ganteng'),('slackware','linux');

Note: DataBase yang digunakan pada tulisan ini yaitu MySQL

Setelah file MenuLoginSchema.sql tersimpan pada komputer, sekarang bukalah terminal atau command prompt kemudian masuklah kedalam direktori tempat dimana kita menyimpan file MenuLoginSchema.sql tersebut kemudian jalankanlah perintah seperti dibawah ini :

martinus@martinusadyh:~/Downloads$ mysql -u root -padmin < MenuLoginSchema.sql

Jika tidak ada pesan error, maka seharusnya kita akan mempunyai 1 database dengan nama menulogin dan 1 tabel dengan nama T_USER beserta isinya seperti dibawah ini :

mysql> show tables;
+---------------------+
| Tables_in_menulogin |
+---------------------+
| T_USER              |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from T_USER;
+----+-----------+-----------+
| id | username  | password  |
+----+-----------+-----------+
|  1 | martin    | menulogin |
|  2 | ahmad     | ganteng   |
|  3 | slackware | linux     |
+----+-----------+-----------+
3 rows in set (0.00 sec)

mysql>

Jika tampilan pada terminal atau command prompt kita sudah seperti diatas, maka proses Inisialisasi bisa dikatan sudah selesai dan kita siap untuk membuat sebuah Project :)

Pembuatan Project Menu Login

Sekarang buatlah sebuah Project dengan nama MenuLogin dari NetBeans IDE, kemudian buatlah Domain classnya terlebih dahulu pada packages domain dengan nama UserApp yang isinya adalah sebagai berikut :

40
41
42
43
44
45
46
public class UserApp {
    private Integer id;
    private String userName;
    private String password;
 
    // Generate Getter n Setter
}

Note: Klik UserApp.java untuk melihat source code lengkap

Urusan dengan Domain Class sudah selesai, sekarang mari kita buatkan Service layer-nya dengan membuat sebuah packages service kemudian buatlah sebuah java interface dengan nama LoginService seperti dibawah ini :

37
38
39
40
41
42
43
44
45
public interface LoginService {
    /** Method ini akan mengecek apakah <code>username</code> dengan <code>password</code>
     * ada atau tidak di database
     * @param username user yang ingin di cek di database
     * @param password password untuk user
     * @return UserApp null jika tidak ditemukan
     */
    public UserApp login(String username, String password);
}

Note: Klik LoginService.java untuk melihat source code lengkap

Sebelum membuat implementasi dari LoginService diatas, tambahkanlah dahulu library MySQL JDBC Driver kedalam Project hingga tampilan Node Libraries kita menjadi seperti gambar dibawah ini :
AddJDBCDriver
Adding JDBC Dirver

Tetap pada packages service sekarang buatlah implementasi dari LoginService diatas dengan nama LoginServiceImpl yang isinya kurang lebih seperti dibawah ini :

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class LoginServiceImpl implements LoginService {
 
    private Connection connection;
    private PreparedStatement findUserByUserAndPassword;
    private final String QRY_LOGIN = "select * from T_USER where" +
            " T_USER.username = ? and T_USER.password = ?";
 
    public LoginServiceImpl(Connection connection) {
        try {
            this.connection = connection;
            findUserByUserAndPassword = this.connection.prepareStatement(QRY_LOGIN);
        } catch (SQLException ex) {
            Logger.getLogger(LoginServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
    public UserApp login(String username, String password) {
        try {
            /* Lakukan pencarian berdasarkan username dan password */
            findUserByUserAndPassword.setString(1, username);
            findUserByUserAndPassword.setString(2, password);
 
            /* Ambil resultset-nya */
            ResultSet rs = findUserByUserAndPassword.executeQuery();
            while (rs.next()) {
                UserApp userApp = new UserApp();
                userApp.setId(rs.getInt("id"));
                userApp.setUserName(rs.getString("username"));
                userApp.setPassword(rs.getString("password"));
 
                return userApp;
            }
        } catch (SQLException ex) {
            Logger.getLogger(LoginServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
 
        return null;
    }
}

Note: Klik LoginServiceImpl.java untuk melihat source code lengkap

Hmm.. urusan domain dan service layer sudah beres, sekarang waktu yang paling menyenangkan yaitu membuat UI layer-nya :) Ok, sekarang mari kita buat sebuah Login Dialog dengan menggunakan class JDialog dan simpanlah pada packages ui. Setelah itu, design-lah Login Dialog tersebut hingga seperti gambar dibawah ini :
DesignLoginDialog
Design Login Dialog

Sekarang tambahkan sebuah label untuk pesan error dengan cara masuk ke menu Inspector dan pada node Other Components tambahkanlah sebuah JLabel seperti gambar dibawah ini:
AddErrorLabel
Menambahkan Error Label

Setelah selesai men-design Login Dialog, sekarang masuklah ke mode Source dan tambahkan 1 buah variabel bertipe boolean dan 1 buah method yaitu showDialog() tidak lupa hilangkan juga method main. Dan hasil akhir yang kita dapatkan kurang lebih isinya seperti dibawah ini :

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
public class LoginDialog extends javax.swing.JDialog {
 
    private boolean notLogin = true;
    private GroupLayout gl;
 
    /** Creates new form LoginDialog */
    public LoginDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
 
        /* Mendeteksi penekanan icon close, jika di close keluar dari aplikasi */
        addWindowListener(new java.awt.event.WindowAdapter() {
 
            @Override
            public void windowClosing(java.awt.event.WindowEvent e) {
                System.exit(0);
            }
        });
 
        jProgressBar1.setVisible(false);
 
        /* Membuat space progress bar tidak di *wrap* oleh button */
        gl = (GroupLayout) getContentPane().getLayout();
        gl.setHonorsVisibility(jProgressBar1, false);
 
        /* Beri fokus ke txtUsername ketika dialog tampil */
        txtUserName.requestFocusInWindow();
 
        /* Posisikan dialog seakan-akan berada di tengah-2x layar */
        setLocationRelativeTo(null);
    }
 
    /** 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 ">
    private void initComponents() {
         ....
    }
    // </editor-fold>
 
    public boolean showDialog() {
        setVisible(true);
        return notLogin;
    }
 
    // Variables declaration - do not modify
    ...
    // End of variables declaration
}

Tetap pada packages yang sama yaitu packages ui sekarang buatlah sebuah Menu Utama dengan menggunakan class JFrame dan simpanlah dengan nama MainForm. Sedangkan pada MainForm ini, tambahkanlah sebuah JMenuBar dan tambahkanlah 3 JMenuItem pada File atau jMenu1 hingga tampilannya seperti gambar dibawah ini :
DesignMainForm
Design Main Form Dengan Menu Login dan Logout

Setelah semua selesai, sekarang editlah file Main.java menjadi seperti dibawah ini :

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
public class Main {
 
    private static MainForm mainForm;
    private static LoginService loginService;
 
    public static MainForm getMainForm() {
        return mainForm;
    }
 
    public static LoginService getLoginService() {
        return loginService;
    }
 
    /** Method ini akan menginisialisassi Form Utama kemudian akan melakukan
     * proses <code>loop</code> untuk menampilkan login dialog sampai nilai
     * notLogin = FALSE baru menampilkan Menu Utama */
    public static void initLogin() {
        if (mainForm == null) mainForm = new MainForm();
        boolean notLogin = Boolean.TRUE;
        while (notLogin) {
            notLogin = new LoginDialog().showDialog();
        }
        mainForm = new MainForm();
        mainForm.setVisible(true);
    }
 
    /** Method ini akan menginisialisasi object koneksi ke database yang akan
     * digunakan di seluruh aplikasi. */
    private static void initDataBaseConnection() {
        try {
            MysqlDataSource dataSource = new MysqlDataSource();
            /* Setting koneksi ke database */
            dataSource.setUser("root");
            dataSource.setPassword("admin");
            dataSource.setDatabaseName("menulogin");
            dataSource.setServerName("localhost");
            dataSource.setPortNumber(3306);
 
            loginService = new LoginServiceImpl(dataSource.getConnection());
        } catch (SQLException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        initDataBaseConnection();
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InstantiationException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                } catch (UnsupportedLookAndFeelException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
                initLogin();
            }
        });
    }
}

Dengan kode yang sudah kita tulis, aplikasi harusnya sudah bisa berjalan tanpa mengalami kesalahan sama sekali. Tapi sayangnya kita belum mengimplementasikan proses login yang sebenarnya, untuk mengimplementasikan proses login yang sebenarnya sekarang tambahkanlah sebuah private class dengan nama WorkerLogin pada LoginDialog yang isinya kurang lebih seperti dibawah ini :

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    private class WorkerLogin extends SwingWorker<userApp, Void> {
 
        @Override
        protected void done() {
            try {
                if (get() != null) {
                    notLogin = false;
                    closeLoginDialog();
                } else {
                    gl.replace(jProgressBar1, lblError);
                    txtUserName.requestFocusInWindow();
                    txtUserName.selectAll();
                }
                btnLogin.setEnabled(true);
                jProgressBar1.setIndeterminate(false);
                jProgressBar1.setVisible(false);
            } catch (InterruptedException ex) {
                Logger.getLogger(LoginDialog.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ExecutionException ex) {
                Logger.getLogger(LoginDialog.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
 
        @Override
        protected UserApp doInBackground() throws Exception {
            /* Hilangkan ini jika digunakan pada production */
            Thread.sleep(1000);
            return Main.getLoginService().login(txtUserName.getText(),
                    String.valueOf(txtPassword.getPassword()));
        }
    }

Dan tambahkan method closeLoginDialog() dibawah method showDialog() seperti dibawah ini :

87
88
89
    private void closeLoginDialog() {
        this.dispose();
    }

Setelah selesai membuat sebuah WorkerLogin sekarang deklarasikanlah class WorkerLogin agar menjadi class variabel dan modifikasilah konstruktor dari LoginDialog hingga menjadi seperti dibawah ini :

53
54
55
56
57
58
59
60
61
	...
    private WorkerLogin workerLogin;
 
    /** Creates new form LoginDialog */
    public LoginDialog() {
        super(Main.getMainForm(), Boolean.TRUE);
        initComponents();
        ...
    }

Agar proses login berjalan ketika kita menekan tombol Login, sekarang berilah Action Listener pada tombol Login dengan cara klik kanan kemudian pilihlah menu Event > Action > actionPerformed[btnLoginActionPerformed] dan pastekan kode seperti dibawah ini :

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
    private void btnLoginActionPerformed(java.awt.event.ActionEvent evt) {
        /* Cek dahulu apakah workerLogin masih berjalan, kalau masih jalan
         * cancel dan set ke null */
        if (workerLogin != null && !workerLogin.isDone()) {
            workerLogin.cancel(true);
            workerLogin = null;
        }
 
        //TODO: cek untuk mengembalikan state lblError ke Progress Bar,
        // bagaimana cara mengecek apakah lblError sudah ditambahkan atau belum ?
        try {
            gl.replace(lblError, jProgressBar1);
        } catch (java.lang.IllegalArgumentException ae) {
            // Do nothing here
        }
 
        workerLogin = new WorkerLogin();
        workerLogin.execute();
 
        /* Disable tombol LOGIN, tampilkan dan jalankan PROGRESS BAR */
        btnLogin.setEnabled(false);
        jProgressBar1.setVisible(true);
        jProgressBar1.setIndeterminate(true);
    }

Sedangkan untuk tombol Cancel-nya, berikan Action Listener seperti kode dibawah ini :

240
241
242
    private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {
        System.exit(0);
    }

Konfigurasi pada Login Dialog sepenuhnya sudah selesai, sekarang mari kita modifikasi file MainForm agar ketika menu Logout ditekan, maka akan menampilkan Login Dialog. Sekarang berilah Action Event pada menu Logout dengan cara klik kanan pada menu Logout kemudian pilihlah menu Event > Action > actionPerformed[jMenuItem2ActionPerformed] dan pastekan kode seperti dibawah ini :

121
122
123
124
125
126
127
    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {
        /* Tutup form utama */
        this.dispose();
 
        /* Tampilkan LoginDialog-nya */
        Main.initLogin();
    }

Sampai disini semua proses pembuatan Project Menu Login telah selesai, dan tampilan struktur Project kita kurang lebih seperti gambar dibawah ini :

Hasil Akhir

Jika sudah selesai, sekarang mari kita jalankan Project Menu Login tersebut dengan menekan tombol F6 dan jika tidak ada kesalahan maka kita akan mendapatkan tampilan dari Login Dialog seperti gambar-gambar dibawah ini :

LoginDialog
1. Tampilan Awal Login Dialog
ProsesLogin
2. Tampilan Ketika Proses Login Gagal
LoginSalah
3. Proses Pengecekan Username dan Password ke DataBase
LoginSukses
4. Menu Utama DiTampilkan Ketika Login Sukses

Akhirnya selesai juga latihannya, bagaimana menurut teman-teman ?? Kalau ada yang bingung dengan penjelasan diatas, jangan sungkan-sungkan untuk tanya yah. Mari kita bahas bareng-bareng, sapa tau ada cara yang lebih baik dan elegan dari cara yang saya jelaskan disini :) :D

Akhir kata, happy coding all :)

Link-link terkait:
- Lebih Dekat Dengan Class SwingWorker
- Download MenuLogin.zip
- Source Code Lengkap Project Menu Login
- Milis NetBeans Indonesia

  • Share/Bookmark
Print This Post

24 Responses to “Membuat Menu Login Di Java Swing dengan Animasi Progress Bar”

  1. Anda memang benar2 memahami anda ,kayaknya anda benar cocok untuk dijadikan teman,karena yah bisa saling memahami

    Thank yah mas

  2. HOHO
    nice tutorial gan :D

  3. Wah thx mas :) jadi semangat nulis2x lagi :)

  4. lambang says:

    mas mau tanya, klo cara mengcapture gambar pake webcam pada aplikasi java caranya gmn, ato mas punya referensi gt?

  5. @Lambang: coba mas search di google dengan keyword Capture webcam java, nanti bakalan keluar beberapa hasil yang mungkin bisa menjadi pointer mas Lambang, soalnya saya sendiri belum pernah bikin aplikasi yang capture webcam :)

  6. Thankzz gan…
    udah share ilmunya..
    maju terus java indonesia…

  7. Java wae piye yoh rumit ning PENAK…. :D

  8. mas kok program tersebut eror yah, gak bisa di-compile. . . . .

    pesan yang diterima “Exception in thread “AWT-EventQueue-0″ java.lang.NullPointerException”

    kenapa itu ya? padahal saya udah mengikuti prosedur dengan benar. . . .

    mohon bantuannya. . . . . . . .

  9. @Arif: Bisa pastein pesan errornya ? Pastein source code-nya sekalian mas disini[1] yah :)

    [1] http://martinusadyh.pastebin.ca/

  10. launk says:

    mas…buat tutorial ejb 3.0…!

  11. @Launk: kwkwkw sabar mas :)

  12. Dj says:

    Mas Bisa Beritahu Link Untuk Belajar Mysql?

  13. Insan Narata says:

    Bang aku ne newbe yang gak tau pa2 soal pemrograman …. bimbingannya dong pls ….. :D

  14. Insan Narata says:

    Khusubnya Netbeans … kalau bisa kirimin tutorialnya keey … thanks’s

  15. MataJuling says:

    Mas,itu kok command prompt nya ga jalan yha?
    mesti instal mysql dulu yha?

  16. @MataJuling: Yups mas, install dulu MySQL Server-nya, trs cobain deh :)

  17. pujiyanto says:

    Tutorial yang bagus Pak. Pak, jika saya ingin membawa “id” ke form lain gimana ya? karen id ini nanti akan dimasukkan dalam database waktu transaksi. terima kasih sebelumnya

  18. Amhy Ma'asy says:

    waw nice post om…
    bahasanya mudah di mengerti dan sangat2 membantu saya membuat form login yang lbh sederhana.. :D
    klau orang kek om serumah sama saya bisa jd programmer handal saya,,,hhehehe…
    keep the spirit om :D

  19. yanni wijaya says:

    Wah… tulisan yang bagus mas
    simple tapi ane sempet sedikit kesulitan, tapi setelah bener2 dipentengin akhirnya programnya sukses running

    thanks mas

    Klo “create-database” nya bisa gak mas langsung dari aplikasi javanya… jadi gak usah lewat command prompt?

  20. @Ahmad: Wah mas Eko tuh tulisan-nya juga bagus2x :)
    @Pak Yanni: Bisa pak :D rencana ke depan sih mau pakai JavaDB untuk demo aplikasi-nya :) Biar bisa langsung di run hasil akhir-nya ;)

  21. Meihta Dwiguna Saputra says:

    untuk :
    public static void initLogin() {
    if (mainForm == null) mainForm = new MainForm();
    boolean notLogin = Boolean.TRUE;
    while (notLogin) {
    notLogin = new LoginDialog().showDialog();
    }
    mainForm = new MainForm();
    mainForm.setVisible(true);
    }

    bukannya harus memanggil constructor dengan parameternya??
    jadi LoginDialog(mainForm, notLogIn)
    CMIIW

  22. @Meihta : By default jika kita memanggil JDialog, kita harus menyertakan parameter ParentComponent dan state modality-nya. Nah untuk menjawab pertanyaan knp saya tidak memanggil konstruktor LoginDialog disertai dengan parameter mainForm (parent component) dan boolean status utk modality ? Kita cek lagi di code LoginDialog()-nya dan coba dibaca lagi kode diatas.

    Pada class LoginDialog diatas, modifikasi dilakukan pada constructor LoginDialog agar dia tidak memerlukan lagi parameter parent component. Nah sebagai ganti-nya, langsung di inisialisasi saja di keyword super(Main.getMainForm(), Boolean.TRUE).

    Nah efeknya apa, kode pemanggilan dialog-nya bisa sedikit lebih clean dan mudah dibaca :) (Ini opini pribadi saya) :D

    Sedangkan pemanggilan Main.getMainForm() pada class LoginDialog ini sebenarnya semata2x hanya ingin melakukan proses sharing JFrame yang digunakan sebagai form utama ke seluruh dialog / panel di aplikasi.

    Nah untuk lebih jelas, coba deh baca2x kode lengkapnya disini[1]

    [1] http://code.google.com/p/martin-personal-project/source/browse/trunk/java/MenuLogin/src/id/web/martinusadyh/menulogin/ui/LoginDialog.java

  23. Chandra says:

    bagaimana kalau password nya di database menggunakan encrypt md5.

    tx

Leave a Reply