secangkir kopi java
JAVA 2 STANDARD EDITION

Oleh: Galih Satria

Copyright © Agustus 2004

expressed or implied. The author makes no warranty of any kind. Not for commercial use.All rights reserved. You may only use this book for private study. . with regrad to these programs or to the documentation contained in this book. scolarship. or research.

Pengantar

Sudah lama Aku ingin mengumpulkan hasil dari petualanganku dengan Java yang sudah berjalan hampir setahun. Ini bukanlah sebuah buku tutorial atau apa – Aku belum pantas menulis buku-buku semacam itu. Ini hanyalah semacam buku harian yang menceritakan waktu yang kuhabiskan untuk bercengkerama dengan Java. Aku sudah bosan menulis buku harian yang berjudul “Gadis-Gadis yang Pernah Kutaksir” karena mereka hanyalah membuat luka-luka kecil tanpa membuat seorang Fatso berbahagia. Aku ingin sesuatu yang baru. Tujuanku menulis buku harian ini adalah semata-mata agar kesulitan-kesulitanku ketika bergaul dengan Java tidak terjadi pada kamu. Ketika Aku mendapat kesulitan dan masalah ketika mengerti sifatsifat Java, tidak ada yang bisa kutanyai. Aku hanya mendapatkan masukan dari buku, forum di internet, dan situs resmi Java sendiri di http://java.sun.com. Bahkan buku yang berbahasa Indonesiapun tak ada yang memuaskanku. Aku mencoba menulis ini agar kesulitanku dulu tercatat secara rapi (cieeee). Ini bukanlah buku harian tentang Bahasa Berorientasi Objek tetapi buku harian tentang Java. Jadi jika kamu mengharapkan ada pembahasan konsep inheritance, polimorfisme, overloading, overriding dan semacamnya, harapan itu hanyalah akan menjadi harapan kosong belaka. Juga maaf buat yang belum mengerti struktur bahasa Java babar blas, aku mengasumsikan kamu sudah pernah membuat aplikasi Java yang sederhana. Aku mengasumsikan kamu sudah pernah menulis program Hello World dengan bahasa Java.

Isi Buku Ini Bab I: Membahas tentang bagaimana membuat sebuah antar muka pemakai (User Interface) dengan menggunakan komponen Swing. Kita
Pengantar

i

akan membuat sebuah Internet Explorer sederhana di situ. Kenapa aku memakai Swing dan bukan AWT? Karena AWT sudah kuno! Hehehe…

Bab 2: Membahas Swing tingkat lanjut. Kita akan membahas konsep Model-View Controller di sana. Kita akan mempelajari bagaimana mengolah data dan menampilkannya secara terpisah dengan komponen JList, JTable, dan JTree.

Bab 3: Membahas tentang bagaimana membuat koneksi ke database dengan Java. Kita akan mempelajari teknologi Java yang disebut Java Database Connectivity (JDBC). Kita juga akan membahas sedikit konsep tentang Basis Data di sana, termasuk Structured Query Language (SQL), Data Definition Language (DDL), dan Data Manipulation Language (DML).

Bab 4: Mendalami konsep JDBC dengan lebih dalam lagi. Kita akan membuat aplikasi Buku Alamat. Kita akan memulai dengan membuat database dengan MySQL, kemudian baru menyusun dan merangkai kode-kode Java satu per satu. Aku akan mengacungkan 3 jempol kalau kamu membaca buku ini hingga bab ini. Aku akan berkata hebat! Hehehe.. bukan apa-apa, soalnya tidak banyak orang yang suka membaca kode-kode Java yang njlimet. Appendix A: Membahas tentang Java Archive (JAR), file yang digunakan untuk mendistribusikan aplikasi Java. Kita tidak akan membahas secara detail tentang JAR, hanya sekedar untuk mengetahui dasar-dasarnya aja. Namanya juga Appendix… Appendix B: Jika kamu new-bie, tetapi sudah mengenal dasar bahasa Java, mungkin kamu perlu membaca ini dulu. Appendix B membahas bagaimana menset J2SDK kita agar bekerja dengan baik, lalu kubahas sedikit tentang packaging di Java, dan beberapa editor Java yang kurekomendasikan.

ii

Secangkir Kopi Java

Apa yang tertuang dalam buku harian ini hanyalah sebagian kecil dari teknologi Java. Dalam suatu topik, aku tidak bisa menjelaskan semua detail yang dimilikinya, meskipun aku berusaha membahas secara lebih mendetail daripada buku-buku berbahasa Indonesia yang pernah kubaca, dengan risiko kamu yang masih new-biee terhadap Java akan sedikit kebingungan. Tapi nggak usah berkecil hati, ada orang yang memulai sesuatu tidak selalu dari awal, tetapi dari yang sulit dulu. Jika kamu masih merasa kurang tentang Java, bukalah internet. Bagiku, internet adalah sumber ilmu tiada batas. Banyak hal tentang Java di sana, baik untuk yang baru membaca Java hari ini maupun yang sudah veteran dalam ber-coding dan di Java. Google Aku merekomendasikan

http://java.sun.com, sebagai acuannya.

mbah

(http://www.google.com)

Oke itu aja, akhir kata kuucapkan Met Ber-Jave Ria! Nuwun inggih para sederek kula sedaya….. ( ini mah Jawa bukan Java )

Tulungagung tercinta, Liburan Juni – Agustus 2004

Galih ‘f4tso’ Satria

Pengantar

iii

................................ Swing Action ...................70 i....................................................20 Model ..................................................................................................................................33 ii............................63 Tree Cell Renderer dan Tree Cell Editor ........... JList..........................View Controller ......................38 Advanced JTable.........................................................................................................139 Membangun User Interface II: Class ViewPane........................................................................................ Menampilkan Dialog Box ................................ Sekilas Database.................................... Ringkasan ............................17 Kotak Input / Input Dialog.. JTable........................122 User Interface I: Class InsertForm ....7 i..............130 Memperkenalkan......................................98 Statement ......................................101 Studi Kasus JDBC – Address Book .........................140 Membangun User Interface Utama: Class AddressBook..............................................................................................................83 ii...................43 iii...........................121 Class MySQLAccess ...................25 Advanced JList............................................................................... Ringkasan ..............................................................................................................99 ResultSet ...................................................... iv Java GUI ( Graphical User Interface ) ............................................................................................................................................................................................................................................... Java Database Connectivity...............68 Tree Event..................................................................................................................................................................................................23 i....................................................................................81 i............. JTree......1 JToolBar – Toolbar pada javax..................................... Class JOptionPane.......................................................................................................................................................................................................... Penulisan Kode Program dengan Java .....................................................................113 ii...............................................................................Daftar Isi Pengantar .....................................10 iii.....................145 Class-Class Pendukung .............swing ............................................................... Instalasi Database dan Pembuatan Database .......i Daftar Isi ............92 First Run! ...........117 Class AddressEntry ...................................................................................................................61 First Run! ............................................................. GridBagLayout........................................111 i.............114 iii......117 Interface DataAccess ............................................................. Database Design .......................................................154 iv Secangkir Kopi Java ..........................................................................................................................................................................................80 Java Database Connectivity [ JDBC ] .....15 Message Box .....96 Koneksi Database ....92 Driver JDBC.......................15 Kotak Konfirmasi ( Confirm Dialog ) ................................................83 Structured Query Language ( SQL ) .................................................................................... Web Browser – Implementasi JEditorPane dan JToolBar ...............................................................................3 ii..................151 iv.....................................

.......................... 159 Appendix B ................................... 161 Tentang Packaging................................................................. 167 Daftar Pustaka ........Appendix A – Mendistribusikan Aplikasi Java dengan JAR ........................................................... 157 Perintah JAR Lainnya ......................................................................................................................... 165 Au’ Revoir! ......................................................................................................... 155 Membuat File JAR ................... 164 Integrated Development Environment ...................................................................... 169 Pengantar v ................................Instalasi J2SDK dan Tentang Packaging .......................... 159 Menjalankan Aplikasi yang Dibundel dalam JAR ..........

.

Oktober 2003 .java gui ( graphical user interface ) Pertemuan Pertamaku dengan Java.

.

io. class yang digunakan untuk merender teks yang sedang diedit ataupun dilihat. public class WebBrowserPane extends JEditorPane { private List history = new ArrayList(). import javax.util. Meskipun demikian. Ide dari web browser ini sangat sederhana. Kamu harus membuat panel tersendiri untuk memparsing dan merender file HTML dengan baik.swing. Selesai! /************************************** * Simple WebBrowser to Understand * * Swing Components * * Written by : fatso – 081103 * **************************************/ package WebBrowser.*. import java.net. Java GUI (Graphical User Interface) 1 . Web Browser – Implementasi JEditorPane dan JToolBar 08 November 2003 – ketika dunia terasa hampa JEditorPane adalah sub class dari class JTextComponent.*.1 – Class WebBrowserPane sebagai subclass dari JEditorPane. JEditorPane bisa merender sebuah file HTML sehingga kita bisa membuat sebuah web browser sederhana. import java. jika kita ingin membuat sebuah web browser yang kokoh. disarankan tidak memakai JEditorPane karena masih buggy – banyak terdapat bug. //konstruktor public WebBrowserPane () { //disable mengedit JEditorPane untuk mengenable //hyperlinks setEditable ( false ).i.*. Saudaranya adalah JTextArea dan JTextField. import java. } Listing 1. kita merequest file HTML dari web server dan menampilkannya di JEditorPane.*. untuk menampilkan halaman HTML pada aplikasi kita. private int historyIndex.

return url.get ( historyIndex ). history. 2 Secangkir Kopi Java ..get ( historyIndex ). Listing 1.. ).. if ( historyIndex >= history. } //displayPage method.printStackTrace ()..size() .1. public URL back () { historyIndex--. } } } < 0 ) 0. untuk menampilkan halaman HTML pada aplikasi kita. historyIndex = history.1. public void goToURL ( URL url ) { displayPage ( url ). Konstruktor akan menset JEditorPane menjadi tidak bisa diedit agar hyperlink file HTML bisa aktif..1 – Class WebBrowserPane sebagai subclass dari JEditorPane.//display u-er-el. if ( historyIndex historyIndex = URL url = ( URL ) displayPage ( url return url.size() . history. } catch ( IOException ex ) { ex. URL url = ( URL ) history. WebBrowserPane ini adalah subclass dari JEditorPane.add ( url ). Method goToURL( URL url ) akan menampilkan URL pada JEditorPane dengan method setPage ( URL pageURL ) dan memodifikasi historyIndex untuk kebutuhan back.size() ) historyIndex = history. } //display next url public URL forward () { historyIndex++. } //display previous history. Di sini kita menambahkan kemampuan JEditorPane untuk mengambil file HTML dari web server. private void displayPage ( URL pageURL ) { try { setPage ( pageURL ). displayPage ( url )..

subclass dari JToolBar.swing Toolbar adalah kumpulan button-button kecil-kecil. Java GUI (Graphical User Interface) 3 . Dan button itu tidak kuberi teks.*. import java. Aku biasanya memakai JButton untuk kupasang di Toolbar.Method forward() akan mengambil URL dari ArrayList dan menampilkannya pada WebBrowserPane.*.awt. yang bertindak sebagai toolbar pada aplikasi web browser kita. biasanya letaknya di bawah menu dari suatu aplikasi.*. import java. Dan terakhir. Listing 1. Method back() adalah kebalikan dari method forward(). method displayPage ( URL pageURL ) adalah method yang bertugas untuk menampilkan URL pada JEditorPane.*. import javax. Cinta pada pandangan pertama? Aku selalu mengalami itu! JToolBar – Toolbar pada javax.swing.event. Namun di sini. Gimana? Nggak bingung kan? Aku aja dulu nggak bingung kok. Kita bisa aja langsung memasang toolbar tanpa harus mensubclass-kan JToolBar. import java.event.*.net.swing. Hmm… tertarik? Let’s go baby! package WebBrowser.awt. hanya icon kecil yang biasanya kuambil dari icon-iconnya KDE Linux. kita akan men-subclass-kan JToolBar. padahal ini adalah pertemuan pertamaku dengan Java dan langsung jatuh cinta. import javax. Method forward() akan mengincrement historyIndex. untuk membiasakan diri dengan konsep inheritance.2 – Class WebToolBar. historyIndex di sini berfungsi sebagai semacam pointer yang menunjuk ArrayList.

private JButton backButton.public class WebToolBar extends JToolBar implements HyperlinkListener { private WebBrowserPane webBrowserPane. } catch ( MalformedURLException mue ) { mue.2 – Class WebToolBar. webBrowserPane. Listing 1. //registering webBrowserPane = browser. private JButton forwardButton. } } } ). webBrowserPane. urlTextField = new JTextField ( 25 ).getText () ).goToURL ( url ). urlTextField.addHyperlinkListener ( this ).png" ) ) ). //konstruktor public WebToolBar( WebBrowserPane browser ) { super ( "Web Navigator" ). 4 Secangkir Kopi Java . //buat back button backButton = new JButton ( new ImageIcon ( getClass(). private JTextField urlTextField.getResource ( "images/undo. yang bertindak sebagai toolbar pada aplikasi web browser kita.printStackTrace (). subclass dari JToolBar.addActionListener ( new ActionListener () { public void actionPerformed( ActionEvent event ) { try { URL url = new URL ( urlTextField.

toString () ).png" ) ) ). subclass dari JToolBar. } }).toString () ). } }). yang bertindak sebagai toolbar pada aplikasi web browser kita. } //hyperlink events public void hyperlinkUpdate( HyperlinkEvent event ) { if ( event. } } } Listing 1.forward ().backButton.ACTIVATED ) { URL url = event.getEventType () == HyperlinkEvent. forwardButton. add ( forwardButton ). //buat next button forwardButton = new JButton ( new ImageIcon ( getClass(). add ( urlTextField ). //add button to toolbar add ( backButton ).setText ( url. webBrowserPane. urlTextField. Java GUI (Graphical User Interface) 5 .back ().addActionListener ( new ActionListener () { public void actionPerformed( ActionEvent event ) { URL url = webBrowserPane.2 – Class WebToolBar.addActionListener ( new ActionListener () { public void actionPerformed( ActionEvent event ) { URL url = webBrowserPane.getURL ().EventType.toString () ).getResource ( "images/redo.goToURL ( url ).setText ( url. urlTextField. urlTextField.setText ( url.

tetapi praktis dan ekonomis. compile. JEditorPane sudah kita set bisa membaca hyperlink. Ketika suatu hyperlink diaktivasi ( diklik ). sim salabim…. Method add ( JComponent component ) adalah method asli milik JToolBar. Sekarang kita akan membangun button-button. Kita gabungkan dua class di atas dalam satu window. Button-button tersebut langsung kita beri icon dari resource yang ada. yaitu membuat launcher code-nya. Sedikit membingungkan memang.. Bedanya. urlTextField kita beri ActionListener. Langkah selanjutnya adalah memasang button-button tersebut pada toolbar. Button back kita beri aksi untuk memanggil method back() dan menset urlTextField dengan URL yang sesuai pada return value method back(). Dia juga akan mempersenjatai dirinya agar bisa mendengarkan hyperlink ketika diklik. mbah canggah dari JToolBar. Lebih tepatnya miliknya JComponent. dia akan memanggil method forward. kita ambil URL-nya dan kemudian kita tampilkan pada JEditorPane. Gaya menambahkan action listener seperti ini namanya anonymous class. Button forward kita beri perlakuan yang mirip dengan button back. Tugasnya adalah memanggil method goToURL dengan URL yang tercantum pada urlTextField.Konstruktor WebToolBar akan memanggil mbahnya untuk memberi judul. Langkah terakhir adalah menentukan jalannya program ketika suatu hyperlink diklik. jadilah monyet! Ini dia launcher code-nya: 6 Secangkir Kopi Java . Sekarang tinggal memberi sentuhan akhir.

Container contPane adalah kanvas dasar pada window kita tempat kita memasang komponen- Java GUI (Graphical User Interface) 7 .net. import java. BorderLayout. public class WebBrowser extends JFrame { private WebToolBar toolBar.2 ) Tak ada yang istimewa di sini.setSize ( 640. } } Listing 1. contentPane.setDefaultCloseOperation ( EXIT_ON_CLOSE ). contentPane. import java.3 – Class WebBrowser.1 dan 1. browser.NORTH ).*. browser.event.awt.*.swing.awt.*. import java.swing. 480 ).CENTER ). import javax.event. } public static void main( String[] args ) { WebBrowser browser = new WebBrowser (). browserPane = new WebBrowserPane ().*.add ( new JScrollPane ( browserPane ).package WebBrowser. yang mengumpulkan dua class yang telah kita tulis sebelumnya ( Listing 1. Container contentPane = getContentPane ().*. import javax. BorderLayout.add ( toolBar. kode peluncur dari aplikasi web browser kita. //konstruktor public WebBrowser() { super ( "Fatso Internet Explorer" ).setVisible ( true ). browser. private WebBrowserPane browserPane. toolBar = new WebToolBar ( browserPane ).

Kita akan mengkompilasi WebBrowserPane dengan command Windows: javac –d c:\classes WebBrowser. CLASSPATH.exit ( 0 ). Agar bisa nye-croll. Terus terang dulu aku bingung setengah mati karena selalu ada eksepsi “NoClassDefFoundError”. Swing sudah melakukan hal itu semua untuk kita. WebBrowserPane kita masukkan pada JScrollPane. Kemudian.WebToolBar javac –d c:\classes WebBrowser. program langsung memanggil System. Mmmm……. masukkan aja ke JCreator atau JBuilder atau IDE yang lain.WebBrowser Baca bismillah dulu dan inilah hasilnye…. dan segala tetek bengek lainnya. setDefaultCloseOperation ( EXIT_ON_CLOSE ) artinya ketika window di-close. Aku yakin kamu sudah bisa bagaimana meng-compile file java yang ada packagenya. 8 Secangkir Kopi Java . Kalau belum. Jika kita memakai AWT ( Abstract Window Toolkit ) kita perlu meng- override window event agar bisa keluar. Ayo diCompile! Di sini aku mengansumsikan kamu sudah master dalam hal setting PATH.WebBrowserPane UNIX: javac –d /home/fatso/classes WebBrowser.WebBrowserPane Parameter –d adalah kita mendefinisikan direktori output dari hasil kompilasi di direktori C:\classes di Windows atau di /home/fatso/classes di UNIX. compile WebToolBar dan WebBrowser berturut-turut dengan perintah: javac –d c:\classes WebBrowser. Direktori ini harus masuk dalam CLASSPATH agar javac bisa mengenali hasil kompilasi kita.komponen. Jika masih bingung. baca Appendix B yang ada di akhir buku ini.

WebBrowser Sudah kukatakan JEditorPane masih buggy. Jadilah webku yang rusak itu. sangat menghargai karyaku itu. lokasi penggodokan situs resmi Galih Satria versi 2. Gambar 1. karena jendela help-nya bisa untuk membuka Yahoo! Java GUI (Graphical User Interface) 9 . Aku senang sekali karena Pak Arun. dosenku. tugas akhir kuliah BPL. karena berbeda dengan teks editor manapun. yang kugunakan untuk menampilkan jendela help. Dia hanya bisa menerima file HTML murni.1 – Tampilan dari web browser ( URL: http://localhost/galihsatria/index.html. WebBrowser ini kuntegrasikan pada teks editorku.1 ).java WebBrowser. Tapi bisa kamu coba dengan sebuah file HTML yang sederhana dan lihat hasilnya… tidak terlalu mengecewakan kok.0. Contoh file HTML pada gambar itu memakai CSS sebagai text formatternya dan si JEditorPane tidak bisa membacanya.

.4 – Class SwingAction. private Action exitAction. Ribet buanget wis… Swing mengatasi kesulitan itu dengan membuat class Action.*. untuk mempermudah manajemen Event Handler 10 Secangkir Kopi Java . demonstrasi Action dalam aplikasi berbasis Java." ). import java.*. mendisabled dirinya karena tak ada yang bisa di-cut. Heh… dowone ceramahku…. dsb.swing.*. Misalnya.event. misalnya. kita cukup mendisabled Action cut dan semua komponen yang merujuk Action cut akan terdisabled secara ostosmastis. kita memiliki method Cut untuk menghapus teks dan mengirimnya ke Clipboard. Menu. import javax. Toolbar.awt. Ketiga komponen itu memiliki aksi sendiri-sendiri. toolbar cut. Dan kita mesti membuat action listener untuk masing-masing komponen secara terpisah. pop up menu cut. exitAction = new ExitAction (). kita tak perlu mengurusi komponen lain yang berhubungan dengan cut. Langsung ajah ke kodenya yach! import java. Kita membuat menu edit cut.awt. Ketika pop up menu cut. Listing 1. //konstruktor public SwingActions() { super ( "Action Deeh. Dan seluruh komponen kita rujuk ke Action tersebut. public class SwingActions extends JFrame { //instans private Action loveAction..ii. Perintah untuk meng-cut bisa kita masukkan ke Action tersebut. Swing action Grapical User Interface ( GUI ) paling tidak memiliki tiga komponen utama. dan Button. loveAction = new LoveAction (). Namun sering sekali kita mendesain ketiga komponen tersebut menjalankan hal yang sama.

demonstrasi Action dalam aplikasi berbasis Java. //bikin toolbar JToolBar toolBar = new JToolBar (). fileMenu. toolBar.setMnemonic ( 'F' ). contPane. //button JButton btnLove = new JButton ( loveAction ). JButton btnExit = new JButton ( exitAction ).add ( loveAction ). //pasang komponen Container contPane = getContentPane ().add ( exitAction ).4 – Class SwingAction. fileMenu.add ( loveAction ).add ( exitAction ).addSeparator (). setSize ( 300. menuBar.CENTER ).NORTH ). untuk mempermudah manajemen Event Handler Java GUI (Graphical User Interface) 11 . JMenuBar menuBar = new JMenuBar ().add ( fileMenu ).//bikin menu JMenu fileMenu = new JMenu ( "File" ). setDefaultCloseOperation ( EXIT_ON_CLOSE ). BorderLayout. panel. BorderLayout. setVisible ( true ). panel.add ( btnLove ). setJMenuBar ( menuBar ).add ( btnExit ). //add action to menu fileMenu. contPane. toolBar. 140 ).add ( toolBar.add ( panel. fileMenu. //panel untuk memasang button JPanel panel = new JPanel ( new FlowLayout () ). } Listing 1.

putValue ( Action.public static void main( String[] args ) { new SwingActions (). //nama putValue ( Action. new ImageIcon ( getClass (). "Cinta.SHORT_DESCRIPTION. } private class LoveAction extends AbstractAction { //konstruktor public LoveAction() { putValue ( Action.NAME. "Klik di sini untuk melihat ungkapan" + "cinta" ).MNEMONIC_KEY.NAME.SMALL_ICON. new Integer ( 'L' ) ). "Exit Action" ). new Integer ( 'X' ) ).showMessageDialog ( SwingActions. putValue ( Action.png" ) ) ). //nama putValue ( Action. "Klik di sini untuk keluar" ).png" ) ) ). putValue ( Action. } } private class ExitAction extends AbstractAction { //konstruktor public ExitAction() { putValue ( Action. "Love Action" ). deritanya " + "tiada pernah berakhir" ).4 – Class SwingAction.SMALL_ICON.getResource ( "exit.getResource ( "love. putValue ( Action. untuk mempermudah manajemen Event Handler 12 Secangkir Kopi Java .MNEMONIC_KEY. new ImageIcon ( getClass (). } public void actionPerformed( ActionEvent e ) { JOptionPane. demonstrasi Action dalam aplikasi berbasis Java.SHORT_DESCRIPTION.this. } Listing 1.

di sini Aku akan memperkenalkan inner class. Nama Type Deskripsi Digunakan sebagai label dari komponen GUI. demonstrasi Action dalam aplikasi berbasis Java. maka label di Action akan diabaikan.SHORT_DESCRIPTION Teks yang digunakan sebagai tool tip text Icon yang ditampilkan pada label komponen Action. Mari kita trace satu per satu: Inner Class LoveAction merupakan subclass dari class AbstractAction.4 – Class SwingAction. Dengan men-subclass-kan pada AbstractAction. kita tinggal melakukan inisialisasi dan menulis implementasi actionPerformed saja.SMALL_ICON GUI Kunci yang digunakan pada keyboard. Inner Class adalah class biasa yang berada di dalam class lain. misalnya. Action. Inner Class sangat bermanfaat untuk membuat Action.NAME Jika komponen tsb. Object object ). Inisialisasi Action dilakukan dengan memanggil method putValue. memiliki label tersendiri. untuk mempermudah manajemen Event Handler Kalau tadi di Web Browser kita menggunakan anonymous class. } } } Listing 1. Action. Action.exit ( 0 ). Java GUI (Graphical User Interface) 13 .MNEMONIC_KEY Misalnya ALT+F untuk File. Semua instans class utama akan dikenali oleh inner class ini. Berikut ini adalah beberapa hal yang bisa dimasukkan pada method putValue ( int type.public void actionPerformed( ActionEvent e ) { System.

ACCELERATOR_KEY CTRL+S untuk menyimpan file.java Dan kita jalankan dengan perintah: java SwingActions Bismillahi rahmanir rahiim…. Action. toolBar.LONG_DESCRIPTION contohnya untuk help. inilah hasilnya! 14 Secangkir Kopi Java . Kemudian actionPerformed pada LoveAction menampilkan pesan pada suatu message box. Kunci untuk menerima perintah berbentuk Action. Dua button ini dipasang dulu dalam sebuah panel sebelum ditempelkan ke kanvas dasar. GUI akan menampilkan message box ini. hasilnya tidak terlalu rapi. Class ExitAction tidak jauh berbeda dengan class LoveAction. Di sini yang dilakukan adalah keluar sistem. Memasang menu. Kita akan bahas JOptionPane setelah ini. Jika komponen yang merujuk action ini diaktivasi ( klik ).ACTION_COMMAND_KEY string yang digunakan di ActionEvent Teks untuk menjelaskan suatu komponen. Ayo DiCompile! Saat yang menyenangkan. Misalnya Action. dsb. karena jika dipasang langsung pada kanvas dasar. Konstruktor SwingActions akan menginisialisasi semua komponen yang diperlukan dan memasangnya ke kanvas dasar contPane. dan terakhir button. pembuatan GUI-nya thok bisa makan waktu yang puanjang. Mari kita compile kode yang sudah kita tulis dengan perintah: javac SwingActions. apalagi jika susunan komponennya begitu kompleks.Kunci untuk shortcut keyboard. Mungkin ini salah satu kelemahan dari Java..

kita bisa memanfaatkan class JOptionPane. meminta input. Ada tiga macam kotak dialog yang disediakan oleh JOptionPane yaitu: dialog konfirmasi. Syntax umum dari JOptionPane ini adalah Java GUI (Graphical User Interface) 15 . bahasaneeee ) semuanya itu dalam class JOptionPane.iii. entah itu konfirmasi. Di sini kita bisa menampilkan baik kotak pesan ataupun kotak konfirmasi. Class JOptionPane. Swing mengenkapsulasi ( weleh. dialog input. atau hanya menampilkan pesan biasa. menampilkan dialog box Kotak dialog sangat diperlukan ketika menginginkan user input. Message Box Untuk menampilkan suatu message box yang indah. dan dialog pesan..

maka kotak dialog akan dilettakkan persis di tengah-tengah window induknya. 16 Secangkir Kopi Java .ERROR_MESSAGE: Menampilkan icon error. Jika tidak null. Jika aku menulis kayak gini: JOptionPane.showMessageDialog ( -.QUESTION_MESSAGE: Menampilkan icon pertanyaan dengan tanda tanya dengan warna hijau. JOptionPane.JOptionPane. int messageType ). Jenis-jenis tersebut dibedakan dari icon yang ditampilkan. Object message ).showMessageDialog ( Component parent.WARNING_MESSAGE: Menampilkan icon peringatan dengan tanda seru dikelilingi segitiga berwarna kuning.showMessageDialog( null. MessageType tersebut adalah: JOptionPane. Maka hasilnya akan kayak gini: Bentuk kedua adalah JOptionPane. JOptionPane. Object message.parameter – ) Java meng-Overload method showMessageDialog hingga tiga bentuk.showMessageDialog ( Component parent. Icon-nya mirip-mirip dengan tanda dilarang masuk dan berwarna merah. "Hai Mata Berbinar!"). Bentuk yang pertama adalah JOptionPane. JOptionPane. Bentuk ini memberi judul pada window dialog dan memberi jenis dari pesan tersebut.String title.INFORMATION_MESSAGE: Menampilkan icon informasi dengan huruf (i) seperti gambar di atas. Parent component adalah induk dari kotak dialog ini.

Object Java GUI (Graphical User Interface) 17 . Untuk menampilkannya. Jawabannya macammacam. ada ya. Asyik kan? Visual Basic mana bisa begini…… Tips: Jika kamu menampilkan dialog box dalam suatu anonymous class ( misalnya dalam actionPerformed-nya button ). Bentuk ini akan mengganti icon default dengan icon yang kamu beri sendiri.showMessageDialog ( null. Java menyediakan empat model dari kotak konfirmasi ini. "Bagaimana hari ini\nApakah” + “indah?". Jika aku menulis seperti ini: JOptionPane. String title.showMessageDialog ( Component parent. untuk mengidentifikasi parent kamu bisa menulis : NamaClass. maka hasilnya akan seperti ini: Bentuk ketiga adalah: JOptionPane. Bentuk Pertama: JOptionPane. "Tanya". ( Component parent.PLAIN_MESSAGE: Menampilkan pesan tanpa icon.showConfirmDialog message ). int messageType. JOptionPane. Object message. Icon icon ).QUESTION_MESSAGE ).- JOptionPane.this Kotak Konfirmasi ( Confirm Dialog ) Dialog konfirmasi sering digunakan untuk mendapatkan persetujuan user apakah suatu proses dijalankan atau tidak. dan batal alias kancil ( cancel ). tidak.

showConfirmDialog(Component parentComponent. Jika kamu mau menentukan kotak dialog yang lebih bebas lagi. Jika aku menulis syntax: JOptionPane.YES_NO_CANCEL_OPTION: Dia akan menampilkan semua tombol: YES. dan CANCEL. OptionType itu adalah: JOptionPane. JOptionPane. int optionType). Bentuk ini selain mengizinkan kamu menentukan tombol apa saja yang tampil. int optionType. Java meng-overload bentuk ketiga seperti ini: JOptionPane. Object message. juga mengizinkan menentukan jenis icon yang tampil yang sudah dibahas pada kotak pesan.YES_NO_OPTION: Hanya akan menampilkan tombol YES dan NO saja. NO. int messageType).showConfirmDialog(null. Bentuk ini akan memberi judul pada kotak dialog dan menentukan tombol-tombol / opsi-opsi yang ditampilkan.showConfirmDialog ( Component parentComponent. Object message. "Jadi nggak?"). Akan muncul hasil yang seperti ini: Bentuk kedua adalah seperti ini: JOptionPane. String title.Ini adalah bentuk yang paling sederhana dari kotak konfirmasi. Contohnye: kalau aku nulis… 18 Secangkir Kopi Java . String title.

Bagaimana cara mendeteksi bahwa user memencet tombol YES.showConfirmDialog ( null.YES_NO_OPTION. Bentuk ini mengizinkan kamu untuk mengganti icon dengan yang sesuai seleramu.showConfirmDialog(Component parentComponent. "Document change. Jadinya: Masih kurang puas? Weleh.weleh… ada bentuk terakhir dari kotak konfirmasi ini yang paling lengkap.showConfirmDialog ( null. JOptionPane.showConfirmDialog akan mereturn sebuah nilai integer yang bisa kamu bisa masukkan ke dalam suatu blok if seperti ini: int result = JOptionPane. int optionType. "Saving Option". buat kotak konfirmasi sendiri dengan men-subclass-kan pada JDialog.. “Akankah dia membuat luka kecil lagi?” ). JOptionPane. JOptionPane. Do you want to save changes?".. Kalau masih kurang puas. CANCEL.YES_OPTION ) { //. int messageType. di benakku timbul pertanyaan. if ( result == JOptionPane. taruh di sini } Java GUI (Graphical User Interface) 19 . atau NO? Oh. Icon icon). String title. jawabnya mudah saja. Ini dia: JOptionPane. jika yes ngapain. Object message.JOptionPane. Wis selamat berkreasi… Ketika aku mengenal kotak konfirmasi.WARNING_MESSAGE ).

aku selalu memakai fungsi getche() dalam blok do-while untuk mendapatkan masukan dari user. Java memiliki enam bentuk kotak input ini. Aku ingat. Bentuk Pertama: JOptionPane.NO_OPTION ) { //. jika no ngapain.. Kurasa. "Berapa umurmu?").showInputDialog ( Component parentComponent. hanya Swing yang memiliki kotak input serame ini.showInputDialog(null. Kotak input yang sangat dinamis dan fleksibel. Bentuk yang paling sederhana.else if ( result == JOptionPane. Akan muncul dialog seperti ini: Bentuk Kedua: 20 Secangkir Kopi Java . Object message ). taruh di sini } else { // yang ini mah pasti cancel } Listing 1. Jika aku menulis JOptionPane. ketika Aku memakai bahasa C semester I dan II kemarin.5 – Bagaimana mendeteksi user menekan tombol tertentu pada kotak dialog konfirmasi Yes No Cancel? Kotak Input / Input Dialog Kotak input penting untuk mendapatkan masukan dari user.

Object message. Bentuk yang paling lengkap dari kotak dialog input ini. "13". Object message.JOptionPane. Bentuk ini sama dengan kotak pesan dengan memberikan jenis icon. Icon icon. null.showInputDialog ( null.showInputDialog(Component parentComponent. "Berapa umurmu?". Object[] selectionValues. Bentuk Ketiga: JOptionPane. Object initialSelectionValue). Bentuk Keempat: JOptionPane. String title. "Umur". Object initialSelectionValue). hanya bedanya di sini terdapat teks box tempat user memasukkan inputan. Object message. int messageType. maka yang digunakan bisa JComboBox atau JList.showInputDialog(Component parentComponent. Maka hasil yang muncul cukup aneh: Java GUI (Graphical User Interface) 21 . Ketiga bentuk terdahulu akan mereturn tipe data String. "14" }.QUESTION_MESSAGE. Jika Aku nulis kayak gini: String[] umur = { "12". Jika tidak null. null ). int messageType). JOptionPane.String title. umur. JOptionPane.showInputDialog(Component parentComponent. maka komponen untuk memasukkan inputan adalah JTextField. Bentuk ini akan memberi nilai default pada teks box pada dialog input. sedangkan bentuk ini akan mereturn Object. Jika selectionValues null.

22 Secangkir Kopi Java . Bentuk Keenam: JOptionPane.showInputDialog(Object message. Kamu harus melakukan explicit casting untuk mendapatkan tipe data yang sebenarnya.Perhatikan bahwa yang muncul bukanlah JTextField. Object initialSelectionValue). Kedua bentuk di atas tidak memiliki parent component atau null.showInputDialog(Object message). melainkan sebuah JComboBox! Dan return value dari bentuk ini adalah Object. Mereka merupakan bentuk yang paling sederhana dari kotak input ini. Bentuk Kelima: JOptionPane.

view controller januari 2004 .model .

.

Misalnya. sedangkan model adalah data yang sesungguhnya yang berada di balik View.. maka kuputuskan untuk memasukkannya ke dalam diary-ku ini. Satu data model bisa memiliki lebih dari satu view. dan bahkan Pascal aku nggak tahu! Model View Controller membedakan suatu data menjadi bagian view dan bagian model. arsitektur MVC itu adalah seperti ini: CONTROLLER MODEL CONTROLLER VIEW VIEW i. please welcome: Jeeeeeeee Liiiiiiist!!!!!! 25 Model View Controller . Ketika data model dimodifikasi lewat controller. MVC yang pernah kupelajari hanyalah JTree dan JTable. Itung-itung juga belajar.. Bagaimana bentuk bahasa itu Aku juga nggak tahu. JList Sejujurnya. yaitu document ini sendiri. he. aduh… kapan kamu akan percaya Aku? Wis. Kalau Aku boleh menggambar diagram. JList relatif paling mudah dimengerti daripada JTable dan JTree.he.. keempat View langsung menyesuaikan diri dengan data model yang baru. Perl. langsung aja kuperkenalkan… Ladies and gentlemen. yaitu Normal. dan empat View. Model-View memudahkan kita untuk mengatur pengolahan data. MVC diperkenalkan oleh Smalltalk-80.Kata buku. Controller bisa berwujud keyboard ataupun mouse. Aku belum pernah menulis JList. Nggak percaya? Aduh. Outline. sama nggak tahunya Aku dengan bahasa Lisp. satu document MS-Word yang sedang kutulis ini memiliki satu model.he. Controller adalah bagian yang mengubah-ubah data model. View adalah bagaimana data tersebut ditampilkan di layar atau di printer. dan Print Layout. Tapi karena JList juga termasuk MVC.. Web.

import java. import java. Listing 2.*.event.*.util. kita boleh memilih lebih dari satu.Kamu bisa membangun JList melalui empat konstruktornya: JList() akan membentuk sebuah JList yang kosong ( buat apa? ).1 – Class ListDemo. Untuk mendapatkannya. JList ( Vector data ) akan membentuk JList dengan data yang ada pada Vector. tetapi harus berurutan. dan multiple-interval selection. Multiple-Interval Selection. JList tidak mendukung scrolling secara langsung.awt. import javax. Seleksi tunggal. ListModel adalah implementasi dari MVC sebenar-benarnya.*. Single-Interval Selection. JList ( Object[] data ) akan membentuk sebuah JList yang berisi data pada array Object[ ] data.swing. Vector adalah array dinamis pada Java yang terdapat dalam package java. private JComboBox combo2. private JComboBox combo1.*. import java. kamu harus memasukkannya ke dalam JScrollPane. Kita akan bahas ini lebih mendetail nanti. single-interval selection. public class ListDemo extends JFrame { private JList list1.event. kita boleh memilih memilih lebih dari satu dan boleh tidak berurutan alias mblejog-mblejog ( tulungagung buanget… ). import javax. JList mendukung tiga macam cara seleksi yaitu: seleksi tunggal ( single selection ). private JList list2. kita hanya boleh memilih satu dari sekian banyak daftar di List.awt.*. JList ( ListModel listModel ) akan membentuk JList dengan sebuah ListModel. komponen swing yang berbasis Model-View 26 Secangkir Kopi Java . menampilkan bagaimana sebuah List dibangun dengan JList.swing.util.

//list dengan data vector Vector listData2 = new Vector ().add ( "Mika Hakkinen" ). komponen swing yang berbasis Model-View Model View Controller 27 .add ( "Jacques Villeneuve" ).add ( "Michael Schumacher" ). createGUI (). "Jambu". list1.add ( "Ayrton Senna" ). listData2. listData2. setEventHandler (). listData2. } private void createGUI() { //list dengan data array String[] listData1 = { "Apel". list1 = new JList ( listData1 ).setSelectionMode ( ListSelectionModel. "Kelapa". menampilkan bagaimana sebuah List dibangun dengan JList.private JLabel statusBar = new JLabel ( "Status Bar" ). list2 = new JList ( listData2 ).SINGLE_SELECTION ). "Pisang". "Semangka".add ( "Rubens Barichello" ). listData2.add ( "Juan Pablo Montoya" ). "Meloon" }.setSelectionMode ( ListSelectionModel.add ( "Ralf Schumacher" ). listData2. listData2.add ( "David Coulthard" ). "Mangga". "Pepaya". "Manggis".SINGLE_SELECTION ). listData2.add ( "Alain Prost" ). list2. listData2. listData2. //combo box data String[] selection = { "SINGLE_SELECTION".add ( "Kimi Raikonnen" ). public ListDemo() { super ( "List Demo" ). listData2. Listing 2. "Jeruk".1 – Class ListDemo.

CENTER ). contPane.add ( scrPane1. BorderLayout. 160 ) ). JScrollPane scrPane2 = new JScrollPane ( list2 ). BorderLayout. panelKanan. JPanel panelKiri = new JPanel (). } private void setEventHandler() { Listing 2. setSize ( 450.add ( scrPane2. 250 ). panelKiri.SOUTH ). panelKanan. menampilkan bagaimana sebuah List dibangun dengan JList. setVisible ( true ). BorderLayout.NORTH ).add ( combo1. combo2 = new JComboBox ( selection ). listPanel. BorderLayout. combo1 = new JComboBox ( selection ). JPanel panelKanan = new JPanel (). 2 ) ).add ( combo2. contPane. scrPane1. "MULTIPLE_INTERVAL_SELECTION" }. Container contPane = getContentPane (). //pasang ke kanvas JScrollPane scrPane1 = new JScrollPane ( list1 ).add ( listPanel. JPanel listPanel = new JPanel ( new GridLayout ( 1. setDefaultCloseOperation ( EXIT_ON_CLOSE ). 160 ) ).CENTER ). BorderLayout. listPanel.CENTER ).NORTH ).add ( panelKiri ).add ( panelKanan ).setPreferredSize ( new Dimension ( 220. komponen swing yang berbasis Model-View 28 Secangkir Kopi Java .1 – Class ListDemo."SINGLE_INTERVAL_SELECTION".setPreferredSize ( new Dimension ( 220. BorderLayout. panelKiri. scrPane2.add ( statusBar.

} else if ( text. MULTIPLE_INTERVAL_SELECTION ).setSelectionMode ( ListSelectionModel.//combo box kiri combo1. //combo box kanan combo2.equals ( "SINGLE_SELECTION" ) ) { list1. menampilkan bagaimana sebuah List dibangun dengan JList.1 – Class ListDemo.setSelectionMode ( ListSelectionModel.addActionListener ( new ActionListener () { public void actionPerformed( ActionEvent e ) { String text = ( String ) combo1.addActionListener ( new ActionListener () { public void actionPerformed( ActionEvent e ) { String text = ( String ) combo2. komponen swing yang berbasis Model-View Model View Controller 29 .SINGLE_SELECTION ). } else if ( text. } else { list1. Listing 2.equals ( "SINGLE_SELECTION" ) ) { list2.equals ( "SINGLE_INTERVAL_SELECTION" ) ) { list1. SINGLE_INTERVAL_SELECTION ). if ( text.getSelectedItem (). } } } ).getSelectedItem ().setSelectionMode ( ListSelectionModel. if ( text.equals ( "SINGLE_INTERVAL_SELECTION" ) ) { list2.setSelectionMode ( ListSelectionModel.setSelectionMode ( ListSelectionModel.SINGLE_SELECTION ). SINGLE_INTERVAL_SELECTION ).

i++ ) { display += ( String ) selectedItems[i] + " ". i < indices.1 – Class ListDemo.getSelectedIndices (). //list listener list1. Object[] selectedItems = list2.length. i++ ) { display += ( String ) selectedItems[i] + " ".setText ( display ). list2. for ( int i = 0. String display = "". MULTIPLE_INTERVAL_SELECTION ). } } } ). } statusBar. for ( int i = 0. } Listing 2.setSelectionMode ( ListSelectionModel. String display = "".addListSelectionListener ( new ListSelectionListener () { public void valueChanged( ListSelectionEvent e ) { int[] indices = list2. Object[] selectedItems = list1. } } ). komponen swing yang berbasis Model-View 30 Secangkir Kopi Java .addListSelectionListener ( new ListSelectionListener () { public void valueChanged( ListSelectionEvent e ) { int[] indices = list1.getSelectedIndices (). getSelectedValues (). i < indices.length. menampilkan bagaimana sebuah List dibangun dengan JList. getSelectedValues ().} else { list2.

Apa yang diklik akan ditampilkan di status bar. JComboBox digunakan untuk mengatur cara JList memilih daftar. Vector diinisialisasi dengan kata kunci new. dan di sini yang digunakan adalah array String.setText ( display ). komponen swing yang berbasis Model-View Di sini ada dua JList yang dibentuk dengan cara yang berbeda.1 – Class ListDemo. menampilkan bagaimana sebuah List dibangun dengan JList. setelah semua komponen dipasang di dalam container. } } ). Ketika suatu anggota JList dipilih. Satu dengan data model array dan satunya lagi memakai Vector. Pada saat diinisialisasi. } } Listing 2. Di sini Aku memakai tipe data String. namun sebenarnya JList bisa dimasuki tipe data Object. Kemudian. Di sini kita menambahkan “telinga” itu dengan cara addListSelectionListener. isi vector masih kosong. JList dipersenjatai agar bisa mendengarkan event. Kita dapatkan kumpulan index dari daftar list yang terpilih dengan memanggil method getSelectedIndices() dan Model View Controller 31 . sehingga isinya ditambahkan dengan memanggil method add. } //launcher public static void main( String[] args ) { new ListDemo (). JComboBox juga memiliki model. Status bar adalah JLabel biasa yang kita tempatkan di container paling bawah ( SOUTH ) dalam layout BorderLayout. program akan memanggil method valueChanged ( ListSelectionModel e ) yang berada dalam interface ListSelectionListener.statusBar.

Duh…. Yang terakhir adalah menghubungkan JComboBox dengan JList. Jika lancar. Tiga tipe selecting tersebut ada di interface ListSelectionModel. tak liat AFI 3 dulu……. Oce! Compile kode di atas dengan javac. Method ini mereturn suatu array Object. seperti misalnya: String[] items = ( String[] ) list1.kita simpan dalam array integer.. Jangan melakukan Explicit Casting di sini.1 – Tampilan dari JList kita. Setelah dapat keduanya. Kita juga dapatkan item yang terpilih dengan method getSelectedItems(). Compiler akan meluluskan kode di atas. 32 Secangkir Kopi Java . window yang akan keluar kayak gambar di bawah. dilanjutin nanti pembahasannya.. kita tambahkan satu per satu ke String dan kita tampilkan di JLabel dengan method setText ( String text ). JVM akan menolaknya. patah hati dunk.getSelectedItems(). Pertama kita dapatkan nilai yang terpilih pada JComboBox kemudian kita sesuaikan JList dengan memanggil method setSelectionModel(). Gambar 2. kemudian jalankan dengan java. namun ketika run time. Oce kan? Wis ya.

listFile = directory. //konstruktor public MyListModel( String dir ) { File directory = new File ( dir ).swing.list(). import javax. kita hanya perlu berpikir bagaimana isi dari method-method yang ada dalam interface ListModel. } Listing 2.event.*. Model View Controller 33 . dengan mendaftar sebuah file dari direktori. Di dalam interface ini terdapat method-method yang masih belum diimplementasikan yang bisa kita pakai secara sesuka hati.swing. untuk mendapatkan model dari JList supaya lebih customizable ( hmmm. ListModel adalah interface yang digunakan sebagai model dari JList. import javax.. this. Listing kode di bawah ini adalah sebuah implementasi ListModel yang akan kita gunakan dalam JList nanti. artine opo ). private String[] listFile. Sudah kita bahas habis JList dengan default konstruktor dan default modelnya serta tampilan defaultnya.Advanced JList Well… sekarang akan kuperkenalkan JList tingkat lanjut. import java.directory = directory. public class MyListModel implements ListModel { private File directory. Sekarang kita pingin donk mendandani JList kita supaya lebih menarik lagi… Konstruktor ketiga dari JList adalah JList ( ListModel model ).*.*.io.2 – Class MyListModel yang mengimplementasikan interface ListModel. Kita tak perlu bingung bagaimana JList akan membuat interface ListModel berguna baginya.

Nah! Sekarang sudah kita dapatkan datanya. Konstruktor MyListModel akan melakukan inisialisasi seperti membuat sebuah File dari String dir. } //implementasi ini tidak kita gunakan public void addListDataListener ( ListDataListener l ) { //. Jika kamu ingin menambahkan error checking di sini. } public Object getElementAt ( int i ) { return listFile[i].2 – Class MyListModel yang mengimplementasikan interface ListModel. artine opo ).. Method getSize() adalah method untuk mengetahui seberapa panjang daftar list kita nanti. cek dulu apakah directory benarbenar sebuah folder dengan memanggil isDirectory(). Hasil dari method list() adalah sebuah array String. untuk mendapatkan model dari JList supaya lebih customizable ( hmmm. File directory akan mendaftar siapa saja anak-anaknya dengan method list(). Method getElementAt ( int i ) berusaha untuk mendapatkan sesuatu yang ada di index ke-i.length./////////implementasi interface list model///////////// public int getSize() { return listFile.. Karena data kita adalah array. Di sini kita berikan isi dari array index kei sebagai return value-nya. } public void removeListDataListener ( ListDataListener l ) { //. maka kita bisa memberi informasi panjang array ( length ) sebagai return value getSize(). Dua method terakhir tidak kita gunakan di 34 Secangkir Kopi Java . } } Listing 2..

sebagai daftar dari JList.sini. setIcon ( new ImageIcon ( getClass(). } //method aseli dari interface ListCellRenderer public Component getListCellRendererComponent ( JList list. Listing kode berikut ini akan menggunakan JList sebagai renderer dan MyListModel sebagai data modelnya.getResource( "folder. boolean isSelected.*. Bagaimana mendandaninya supaya ada iconnya? Kita bisa “menempelkan” sebuah JLabel – atau semua anak dari JComponent -.toString() ).awt. import javax. Asyik kan? Aku menemukan cara ini di JDK 1.4 API. 9 ) ). Object value. karena kita tidak memerlukan telinga ketika pada data model terjadi perubahan. Segala kemampuan JLabel bisa ditampilkan di dalam List. untuk mendandani JList supaya berwajah dan merupakan anak JLabel.swing. public class MyListCellRenderer extends JLabel implements ListCellRenderer { //konstruktor public MyListCellRenderer() { setOpaque ( true ). dicuekin aja! JList Renderer Kita sudah menguasai habis soal ListModel. int index. setForeground ( Color. } Listing 2.3 – Class MyListCellRenderer yang mengimplementasikan ListCellRenderer else { kandung dari JLabel..white ).*. if ( isSelected ) { setBackground ( new Color ( 36. boolean cellHasFocus ) { setText ( value. import java. Model View Controller 35 . 72. Kalau terjadi perubahan ya.png" ) ) ).

Class ini juga mengimplementasikan interface ListCellRenderer. Yang kita lakukan di dalam method ini adalah melakukan pendadanan JLabel seperti menset warna background dan foreground baik saat dipilih maupun tidak. Class MyListCellRenderer adalah sub-class dari JLabel yang digunakan sebagai komponen perender dari JList nanti. } private void createGUI() { MyListModel listModel = new MyListModel ( "F:/My Documents" ).*.green ). setForeground ( Color. Listing 2.black ).0" ).3 ) untuk ditampilkan menjadi JList dengan model dan make-up yang baru 36 Secangkir Kopi Java .2 dan 2.setBackground ( Color. Inti dari interface ListCellRenderer adalah method getListCellRendererComponent.3 – Class MyListCellRenderer yang mengimplementasikan ListCellRenderer dan merupakan anak kandung dari JLabel. public class ListDemo2 extends JFrame { private JList list. yang akan mereturn suatu Component yang digunakan JList sebagai perender dirinya. untuk mendandani JList supaya berwajah JLabel. dan menaruh icon untuk mempercantik JLabel.swing. } } Listing 2.awt. public ListDemo2() { super ( "JList Demo ver 2. agar bisa digunakan sebagai renderer dari JList. import javax.*. } return this. createGUI().4 – Class ListDemo2 mengumpulkan dua class terdahulu ( Listing 2. import java.

2 dan 2. list. dengan model file folder F:/My Documents dan Cell Renderer JLabel Model View Controller 37 . setVisible ( true ). } public static void main ( String[] args ) { new ListDemo2(). Kayak apa sih Lih hasil jadinya? Mmm…. getContentPane(). } } Listing 2. pack(). setDefaultCloseOperation ( EXIT_ON_CLOSE ). kirakira kayak gini deh… Gambar 2.3 ) untuk ditampilkan menjadi JList dengan model dan make-up yang baru Listing di atas adalah kode launcher dari dua class terdahulu.list = new JList ( listModel ).add( new JScrollPane ( list ).2 – Customized JList. hanya memasang JList dalam container dan mendadani JList kita agar bisa menampilkan folder My Documents dengan make-up JLabel.setCellRenderer( new MyListCellRenderer() ). BorderLayout.CENTER ).4 – Class ListDemo2 mengumpulkan dua class terdahulu ( Listing 2. Tak ada yang istimewa.

TableModel digunakan untuk menyimpan dan memproses data. Tapi menurutku. JTable memiliki sangat banyak fitur untuk kebutuhan editing dan rendering. Jika kamu menginginkan tabel-mu read only. he. Seperti halnya JList.. namun kamu bisa memaksanya menjadi JComboBox ataupun komponen lain. ColumnModel digunakan untuk manajemen kolom dari tabel. Swing memiliki komponen yang menyajikan data dalam baris dan kolom yang dinamakan JTable. Mereka adalah TableModel. cell editor dari JTable adalah JTextField. JTable tidak secara langsung mendukung scrolling. Secara default. dan ListSelectionModel digunakan untuk memilih baris. atau Microsoft Excel dan melihat tampilan worksheet-nya. itulah yang namanya komponen Table. kolom. Tidak main-main.JTable. JTable akan menyembunyikan headernya jika kamu tidak memasukkannya ke dalam JScrollPane. sekarang kita bicara lebih teknis lagi soal JTable. Secara default. Tetapi kamu bisa memasukkannya ke dalam sebuah JScrollPane untuk mendapatkan dukungan itu. kita emang pengguna Microsoft Windows kok.ii.swing. dan cell dari tabel. Nah.he. JTable memiliki tiga model yang berbeda. JTable Apakah kamu seorang pecinta Windows? Agen Kapitalis Microsoft? Kalau jawabannya ‘ya’. Kamu bisa melihatnya sendiri di dokumentasi javadoc untuk javax.he. JTable adalah fulleditable. Oce. ColumnModel. Aku tidak membahasnya satu per satu karena terlalu bertele-tele. 38 Secangkir Kopi Java .. berarti sama dengan aku donk. JTable memiliki tujuh konstruktor. kamu harus mengoverride-nya lewat TableModel. nggak usah muna. dan ListSelectionModel. JTable memiliki cell editor dan cell renderer.. ☺ Kamu tentu sudah pernah membuka Microsoft Access. JTable juga merupakan sebuah Model-View Controller.

Berikut ini adalah kemungkinan bagaimana kolom JTable dimanipulasi: JTable. Mereka adalah: autoCreateColumnsFromModel: Bertipe boolean. autoResizingMode: Kamu bisa me-resize lebar kolom semaumu selama programmer tidak membatasi lebar maksimal dari kolom setiap saat. aku perlu memperkenalkan properti yang dimiliki oleh JTable. Yuk… Model View Controller 39 . Oke. editingColumn: Kolom dari cell yang sedang diedit.AUTO_RESIZE_NEXT_COLUMN JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS JTable. Tetapi untuk baris. Gunanya untuk menunjukkan apakah kolom-kolom dibuat dari table model. mari kita test beberapa properti dari JTable dalam sebuah tampilan sederhana. Object[] columnNames ). public JTable ( Object[][] rowData. Sebelum kita menginjak ke bagian coding. Nilai defaultnya adalah true. editingRow: Baris dari cell yang sedang diedit.AUTO_RESIZE_ALL_COLUMNS cellSelectionEnabled: Bertipe boolean.AUTO_RESIZE_OFF JTable. kamu tidak bisa seenak udel mengubahnya. Masih segudang lagi properti dari JTable yang bisa kita ubah-ubah sesuai kebutuhan kita. Semuanya bisa dilihat di dokumentasi dari JTable.konstruktor di bawah ini cukup representatif untuk menjelaskan soal JTable. Menunjukkan apakah boleh kita memilih suatu cell secara individual.AUTO_RESIZE_LAST_COLUMN JTable. columnSelectionAllowed: Nilai boolean yang menunjukkan apakah kolom JTable boleh dipilih atau tidak.

//konstruktor public TableDemo() { super ( "Table Properties Demo" ).swing. table. import java. class yang menunjukkan beberapa penggunaan properti JTable dan dibangun dengan konstruktor yang cukup sederhana.intValue(). ( Sederhana?!?!?! ) 40 Secangkir Kopi Java .getText(). import javax. //row margin txtRowMargin. createGUI(). setEventHandler().package galih.addActionListener( new ActionListener() { public void actionPerformed ( ActionEvent e ) { int rowHeight = new Integer ( txtRowHeight.*.5 – Class TableDemo.setRowHeight( rowHeight ).addActionListener( new ActionListener() { public void actionPerformed ( ActionEvent e ) { Listing 2.swing. } private void setEventHandler() { //row height txtRowHeight.*. trim() ). import java.*. } }). public class TableDemo extends JFrame { //instance private JTable table. private JTextField txtRowMargin = new JTextField ( 5 ). private JCheckBox chkShowGrid = new JCheckBox ( "Show Grid" ).awt.awt. private JTextField txtRowHeight = new JTextField ( 5 ).event.

{ "Macromedia Flash MX Action Script for Designer". "Penerbit" }. "Prentice Hall Inc" }.int rowMargin = new Integer ( txtRowMargin. "Jay Greenspan". Deitel".NET Web Developer's Guide". //show grid chkShowGrid. } }). { "Java Handbook". { "OpenGL Programming Guide". Listing 2. { "C# . } //membangun user interface private void createGUI() { //data tabel String[][] tableData = { { "Advanced Java 2 How To Program".setRowMargin( rowMargin ).intValue(). class yang menunjukkan beberapa penggunaan properti JTable dan dibangun dengan konstruktor yang cukup sederhana. ( Sederhana?!?!?! ) Model View Controller 41 .setShowGrid( chkShowGrid. trim() ). "HM.addActionListener( new ActionListener() { public void actionPerformed ( ActionEvent e ) { table. "SynGress Wallet Inc" }. "??". "Patrick Naughton". "Penulis". "Addison-Wesley Publishing Company" }. "M&T Books" }. "Prentice Hall Inc" }. { "MySQL/PHP Applications".5 – Class TableDemo. "Adrian Turtschi".isSelected() ). table. } }). "Doug Sahlin". "Wiley Publishing Inc" } }. //table header String[] tableHeader = { "Judul Buku".getText().

Container cp = getContentPane(). 200 ).//inisialisasi tabel table = new JTable ( tableData. JPanel panel3 = new JPanel ( new GridLayout ( 1 . panel2. setVisible ( true ).5 – Class TableDemo.add( txtRowHeight ). panel2. //init text box txtRowHeight.add( new JLabel ( "Row Margin" ) ). JPanel panel2 = new JPanel ( new FlowLayout() ).add( new JScrollPane ( table ).add( chkShowGrid ). BorderLayout.add( new JLabel ( "Show Grid" ) ).setSelected( true ). cp. txtRowMargin.getRowMargin() ) ). } } Listing 2. } //launcher public static void main ( String[] args ) { new TableDemo(). panel2.add( txtRowMargin ).getRowHeight() ) ). setDefaultCloseOperation ( EXIT_ON_CLOSE ). panel2.add( new JLabel ( "Row Height" ) ). panel2. panel3.CENTER ). //init check box chkShowGrid. 1 ) ).add( panel3. BorderLayout.NORTH ). class yang menunjukkan beberapa penggunaan properti JTable dan dibangun dengan konstruktor yang cukup sederhana. panel2. ( Sederhana?!?!?! ) 42 Secangkir Kopi Java .add( panel2 ). setSize ( 450.valueOf( table.valueOf( table.setText( String. cp. tableHeader ).setText( String.

3 – Hasil dari koding di atas jika dijalankan pakek Java Virtual Machine. Sekarang tentunya kamu ingin tantangan yang lebih berat bukan? ( bukaaan… ). Model View Controller 43 . Oke. Kemudian kedua string itu kita masukkan sebagai parameter dari konstruktor JTable. hanya sedikit yang perlu dijelaskan di sini. Kita mempersiapkan dua array String. Di sini kita juga mengubah-ubah lebar baris dan jarak dari masing-masing baris lewat text box txtRowHeight dan txtRowMargin.Kurasa. Terakhir. kita perlu mendemonstrasikan bahwa ternyata garis pembatas pada JTable bisa dihilangkan dengan memasang sebuah check box di situ. kulayani permintaanmu. Gimana Lih hasilnya? Di kompie-ku. Event yang kita masukkan pada addActionListener akan dikerjakan ketika kita menekan tombol Enter saat salah satu text box itu terfokus. Gimana…? ☺ Advanced JTable Dasar-dasar JTable telah kita kuasai. Yang pertama adalah array dua dimensi untuk data tabel dan yang kedua adalah array satu dimensi untuk kepala kolomnya. hasilnya seperti ini… Gambar 2. Aku akan membahas soal bagaimana mendandani JTable seperti halnya kita mendadani JList.

Class DefaultTableModel adalah subclass dari class AbstractTableModel yang menggunakan Vector sebagai penyimpan datanya. Kita cukup menulis implementasi untuk method: public int getRowCount(). Setiap model harus mengimplementasikan interface TableColumnModel. public Object getValueAt ( int row. Semua table model harus mengimplementasikan interface TableModel. yang nantinya dimanfaatkan oleh JTable sebagai model datanya. Namun kurasa class default-nya sudah cukup untuk memanipulasi kolom dari JTable.Sudah kukatakan sejak awal bahwa JTable memiliki tiga model yang berbeda. Table Model Table Model digunakan untuk memanipulasi data yang akan disajikan di JTable. Kita akan membahasnya satu per satu. Beberapa method dari class DefaultColumnModel adalah: Untuk memanipulasi kolom: public void addColumn(TableColumn tableColumn) public void removeTableColumn(TableColumn tableColumn) 44 Secangkir Kopi Java . implementasi dari TableModel tentunya class cukup yang AbstractTableModel adalah mengimplementasikan hampir seluruh method yang ada pada interface TableModel. Menulis membosankan. public int getColumnCount(). dihapus. sebaiknya jangan menggunakan DefaultTableModel ). int col ). ataupun menambah data baru harus lewat pintu ini. Kita bisa menggunakan class DefaultTableModel jika data yang kita sajikan tidak terlalu rumit ( jika data adalah hasil query dari database. Data yang akan dimodifikasi. Di dalam vector tersebut masing-masing terdapat sebuah array yang elemennya merepresentasikan kolom dari baris tertentu. Table Column Model Table Column Model digunakan untuk mengatur kolom dari JTable.

public void moveColumn(int fromIndex. Class ini digunakan untuk memanipulasi suatu kolom tertentu secara individual pada JTable. int toIndex) public int getColumnMargin() public void setColumnMargin(int newMargin) public TableColumn getColumn(int columnIndex) public int getColumnCount() public int getColumnIndex(Object columnIdentifier) public Enumeration getColumns() public int getTotalColumnWidth() Untuk memilih kolom: public boolean getColumnSelectionAllowed() public void setColumnSelectionAllowed(boolean flag) public int getSelectedColumnCount() public int getSelectedColumns() public ListSelectionModel getSelectionModel() public void setSelectionModel(ListSelectionModel newModel) Class TableColumn Class TableColumn berhubungan dengan semua kolom pada JTable. Class ini tidak dapat dibuat secara langsung ( instantiated ). public int getWidth() public void setWidth(int width) public int getMaxWidth() public void setMaxWidth(int maxWidth) public int getMinWidth() public void setMinWidth(int minWidth) public int getPreferredWidth() public void setPreferredWidth(int minWidth) Model View Controller 45 . tetapi kita bisa mendapatkan objek ini dari method getColumn ( int index ) pada TableColumnModel atau method getColumn ( Object identifier ) pada JTable. menentukan cell renderer dan cell editor. Beberapa method di bawah ini adalah milik class TableColumn untuk mengatur panjang kolom. dan header renderer.

swing.swing. Okay? Let’s go! package galih. private JButton btnRemoveRow = new JButton ( "Remove Row" ).*. Listing 2. private JButton btnRemoveCol = new JButton ( "Remove Column" ).0" ). Di sini diperkenalkan dua model.*. import javax.event.table. import javax. private JButton btnAddRow = new JButton ( "Add Row" ).awt. //konstruktor public TableDemo2() { super ( "Table Demo ver 2. import java. private DefaultTableModel tableModel.*.awt. public class TableDemo2 extends JFrame { //instans private JTable table.Urusan Renderer dan Editor: public TableCellEditor getCellEditor() public void setCellEditor(TableCellEditor anEditor) public TableCellRenderer getCellRenderer() public void setCellRenderer(TableCellRenderer aRenderer) public TableCellRenderer getHeaderRenderer() public void setHeaderRenderer(TableCellRenderer aRenderer) Sekarang kita akan mencoba memanfaatkan class DefaultTableModel untuk menambah dan menghapus data pada JTable.*.swing. 46 Secangkir Kopi Java . private JButton btnAddCol = new JButton ( "Add Column" ). Siapkan dirimu untuk membaca kode gila! Tapi itu akan percum tak bergun jika kamu tidak mencobanya sendiri.6 – Dengan TableModel. yaitu TableModel dan ColumnModel. kita dapat menambah dan menghapus baik baris ataupun kolom. import java.

getColumnModel().addColumn( "Kolom Baru" ). } }). } }). yaitu TableModel dan ColumnModel.removeRow( selectedRow ). "". //nambah kolom kosong btnAddCol.createGUI(). Model View Controller 47 .addActionListener( new ActionListener() { public void actionPerformed ( ActionEvent e ) { DefaultTableColumnModel columnModel = ( DefaultTableColumnModel ) table.getColumn( selectedCol ). //hapus baris btnRemoveRow. Listing 2. setEventHandler(). } private void setEventHandler() { //nambah baris kosong btnAddRow. tableModel.addRow( newRow ). tableModel.getSelectedColumn().addActionListener( new ActionListener() { public void actionPerformed ( ActionEvent e ) { int selectedRow = table. //hapus kolom btnRemoveCol.getSelectedRow().6 – Dengan TableModel. TableColumn tableColumn = columnModel. "" }. Di sini diperkenalkan dua model.addActionListener( new ActionListener() { public void actionPerformed ( ActionEvent e ) { tableModel.addActionListener( new ActionListener() { public void actionPerformed ( ActionEvent e ) { String[] newRow = { "". } }). kita dapat menambah dan menghapus baik baris ataupun kolom. int selectedCol = table.

"Wiley Publishing Inc" }. tableHeader ). btnRemoveRow. //pasang pada container btnAddRow. { "J2ME in A Nutshell".setMnemonic( 'R' ). yaitu TableModel dan ColumnModel. 48 Secangkir Kopi Java . "Prentice Hall Inc" }. "Patrick Naughton". "Penulis".setMnemonic( 'C' ). Deitel". { "MySQL/PHP Applications". Listing 2. { "C# . "HM. { "Macromedia Flash MX Action Script for Designer". "Jay Greenspan". } private void createGUI() { //data tabel String[][] tableData = { { "Advanced Java 2 How To Program". } }). //init table model tableModel = new DefaultTableModel ( tableData.columnModel. "Prentice Hall Inc" }. "SynGress Wallet Inc" }. kita dapat menambah dan menghapus baik baris ataupun kolom. "Doug Sahlin".removeColumn( tableColumn ). "Waah Lupa Aku".6 – Dengan TableModel. { "OpenGL Programming Guide".setMnemonic( 'o' ). //table header String[] tableHeader = { "Judul Buku". "??". table = new JTable ( tableModel ). "Penerbit" }. { "Java Handbook".NET Web Developer's Guide". btnAddCol. "O'Reilly Publishing" } }. Di sini diperkenalkan dua model. "M&T Books" }. "Adrian Turtschi". "Addison-Wesley Publishing Company" }.

btnRemoveCol.setMnemonic( 'v' );

JPanel panel1 = new JPanel ( new GridLayout ( 2, 2 ) ); panel1.add( btnAddRow ); panel1.add( btnAddCol ); panel1.add( btnRemoveRow ); panel1.add( btnRemoveCol );

Container cp = getContentPane(); cp.add( panel1, BorderLayout.NORTH ); cp.add( new JScrollPane ( table ), BorderLayout.CENTER );

setDefaultCloseOperation ( EXIT_ON_CLOSE ); setSize ( 400, 300 ); setVisible ( true ); }

//launcher public static void main ( String[] args ) { new TableDemo2(); } }
Listing 2.6 – Dengan TableModel, kita dapat menambah dan menghapus baik baris ataupun kolom. Di sini diperkenalkan dua model, yaitu TableModel dan ColumnModel.

Okay, cukup sederhana. Inisialisasi tabel hampir sama dengan listing 2.5, yaitu dengan menggunakan dua array String. Hanya saja di sini kita menggunakan class DefaultTableModel sebagai table modelnya. Class DefaultTableModel adalah class yang mengimplementasikan interface TableModel. Class ini sangat powerfull untuk melakukan manipulasi data dari tabel. Sedikit dari blok kode pemasangan pada container. Method
setMnemonic ( char x ) untuk menanam fungsi keyboard ALT + (char

x) pada button. Jika kamu akrab dengan Visual Basic-nya Microsoft,

Model View Controller

49

method ini mirip dengan penambahan karakter “&” agar muncul garis bawah pada suatu huruf pada label. Pada blok setting event handler, di sinilah tempat button-button diberi tugas untuk melakukan pekerjaannya ketika ia di-klik. Button
btnAddRow akan menambah suatu baris kosong pada tabel jika ia di-klik.

Karena yang ditambah adalah datanya, maka kita harus menggunakan tableModel untuk melakukan manipulasi proses ini. Di sini kita menggunakan method addRow ( Object newRow ), dan sebagai datanya kita masukkan sebuah String kosong. Action btnRemoveRow akan menghapus baris yang sedang terpilih. Pertama kita dapatkan nomor barisnya dengan method
getSelectedRow(), dan dengan tableModel, kita hapus baris tersebut

dengan method removeRow ( int row ). Kamu harus menambahkan error handling sendiri di sini, karena jika user meng-klik tombol ini tanpa memilih baris terlebih dahulu, maka Ini akan terjadi eksepsi method

ArrayIndexOutOfBoundsException.

disebabkan

getSelectedRow() mengembalikan nilai -1 jika baris tabel tidak ada yang

terpilih.
btnAddCol akan menambahkan kolom baru. tableModel bisa

melakukan ini dengan gemilang dengan memanggil method addColumn
( Object newCol ). Kamu bisa melakukan pengisian data pada kolom

ini secara langsung dengan mengoverload method ini dengan memanggil method tableModel.addColumn( Object newCol, Vector colData ), atau method tableModel.addColumn ( Object newCol, Object[]
colData ).

Button yang belum kita bahas adalah btnRemoveCol. Mekanisme dalam meremove kolom cukup panjang. Pertama kita dapatkan column model dengan method getColumnModel(). Kemudian kita dapatkan kolom yang sedang terpilih dengan getSelectedColumn(). Kedua method di atas milik JTable. Dengan columnModel.getColumn ( int
selectedCol ),

kita

dapatkan

instans

TableColumn

yang

50

Secangkir Kopi Java

merepresentasikan kolom yang akan kita hapus. Terakhir, kita remove kolom tersebut dengan method removeColumn ( TableColumn tc ). Saat yang menyenangkan… mari kita lihat hasil kerja jari-jari kita di atas keyboard!

Gambar 2.4 – Ada empat button di situ yang di dalamnya terdapat TableModel untuk melakukan manipulasi data.

CellRenderer dan CellEditor Sel pada JTable digambar dengan sebuah cell renderer dan pengeditannya dilakukan dengan sebuah cell editor. Secara umum, JTable merender selnya dengan JLabel dan menggunakan JTextField sebagai cell editornya. Sudah kita ketahui bahwa JTable bisa dimasuki data bertipe Object, artinya apapun bisa masuk ke JTable. Berikut ini adalah tampilan JTable secara default dari beberapa tipe data:

Class
Object Date Number ImageIcon Boolean

Renderer
JLabel JLabel JLabel JLabel JCheckBox

Alignment Rata kiri Rata kanan Rata kanan Rata tengah Rata tengah

Editor
JTextField JTextField JTextField

JCheckBox

Model View Controller

51

*.URL. MyTableModel tableModel = new MyTableModel ( tableData.*. import java. bisa diisi macam-macam. ataupun Qt. table = new JTable ( tableModel ).*. package galih. import javax. import java.swing. "Name".util.swing.Sekarang. 52 Secangkir Kopi Java .table. "Size". tableHeader ).io. Last Modified. lain daripada yang lain. "Last Modified".*. Listing 2. "Hidden". dan yang tak pernah ditemukan pada tool IDE bahasa lain seperti VB. } //inisialisasi tabel dan melakukan createGUI private void init() { //table properties String[] tableHeader = { "T". init ().net. VC++.7 – Class ini berusaha mendapatkan daftar file dari suatu folder dan menampilkan atribut-atributnya seperti Nama.swing. import java.awt. import java. Object[][] tableData = getData ( "F:/My Documents" ). "Attribute"}. import javax. public class TableRendererDemo extends JFrame { //instance private JTable table. dll. kita akan coba membuat suatu JTable yang benar-benar gila. Size.*. //konstruktor public TableRendererDemo() { super ( "Table Cell Renderer and Editor Demo" ).

tc2.setMinWidth ( 25 ). dll. Model View Controller 53 .setMinWidth ( 80 ). "Read Only". tc2. "Encrypted" }. tc4.setRowHeight( 19 ).setCellEditor( cellEditor ).7 – Class ini berusaha mendapatkan daftar file dari suatu folder dan menampilkan atribut-atributnya seperti Nama. tc0. Last Modified. Listing 2.setMaxWidth ( 25 ).setWidth ( 25 ). tc4. tc2. tc3. tc4. DefaultCellEditor cellEditor = new DefaultCellEditor ( cmbAttribute ).setWidth ( 90 ). TableColumn tc4 = table. tc4. tc0. tc0. //set cell editor pada kolom attribute dengan //JComboBox String[] comboData = { "Archive". Size. //lebar dari masing2 kolom TableColumn tc0 = table. table.setMinWidth ( 120 ). TableColumn tc3 = table. TableColumn tc2 = table.getColumn ( "Attribute" ).setMinWidth ( 30 ).setWidth ( 35 ).setShowVerticalLines ( false ).setMaxWidth ( 100 ).getColumn ( "T" ).getColumn ( "Size" ).table. JComboBox cmbAttribute = new JComboBox ( comboData ).setMaxWidth ( 135 ).getColumn ( "Last Modified" ).setPreferredWidth ( 135 ). tc3.setMaxWidth ( 60 ). tc3.

cp.//pasang pada container Container cp = getContentPane().getResource ( "folder. //nama file data[i][1] = children[i]. icon data[i][0] = ( children[i]. } //mendapatkan data dari file public Object[][] getData( String folder ) { //daftar folder yang dikirim File file = new File ( folder ). //ambil data satu per satu. 54 Secangkir Kopi Java .add( new JScrollPane ( table ).getName (). masukkan ke array data for ( int i = 0. MyImageIcon fileIcon = new MyImageIcon ( filePath. setVisible ( true ).7 – Class ini berusaha mendapatkan daftar file dari suatu folder dan menampilkan atribut-atributnya seperti Nama.CENTER ). setSize ( 600.length][6].listFiles (). Last Modified. Size. i < children. true ).png" ). URL filePath = getClass (). i++ ) { //file type. dll. MyImageIcon folderIcon = new MyImageIcon ( folderPath.getResource ( "file. BorderLayout. File[] children = file. Listing 2. false ). Object[][] data = new Object[children. //icon URL folderPath = getClass ().png" ).isDirectory () ) ? folderIcon : fileIcon. setDefaultCloseOperation ( EXIT_ON_CLOSE ). 300 ).length.

String month = String. } //mendapatkan tanggal yang bisa terbaca manusia.canWrite () ) ? "Archive" : "Read Only". calendar. //attribute data[i][5] = ( children[i]. Listing 2. //last modified data[i][3] = getDate ( new Date ( children[i]. } int month1 = calendar. if ( month. //bentuk kilo bytes String display = fileSize + " KB". dll. //hidden or not?? data[i][4] = ( children[i].get ( Calendar. //karena Date berbentuk miliseconds private String getDate( Date date ) { Calendar calendar = Calendar.length () == 1 ) { dateOfMonth = "0" + dateOfMonth.isHidden () ) ? new Boolean ( true ) : new Boolean ( false ).lastModified () ) ).7 – Class ini berusaha mendapatkan daftar file dari suatu folder dan menampilkan atribut-atributnya seperti Nama. data[i][2] = display.length () == 1 ) month = "0" + month.DAY_OF_MONTH ) ). } return data.MONTH ) + 1.valueOf ( calendar. String dateOfMonth = String.valueOf ( month1 ). Size. Model View Controller 55 .getInstance ().//size //ini dalam bytes long fileSize = children[i]. Last Modified. if ( dateOfMonth. fileSize /= 1024.length ().setTime ( date ).get ( Calendar.

AM ) { day = "AM". if ( hour. if ( minutes. Last Modified. dll.int year = calendar.valueOf ( calendar. } else { day = "PM".YEAR ).AM_PM ) == Calendar.valueOf ( calendar.length () == 1 ) { minutes = "0" + minutes. String shortYear = String.7 – Class ini berusaha mendapatkan daftar file dari suatu folder dan menampilkan atribut-atributnya seperti Nama.substring ( 2 ).length () == 1 ) { hour = "0" + hour.get ( Calendar. } //launcher public static void main ( String[] args ) { new TableRendererDemo(). if ( calendar. } String day = "". String hour = String.valueOf ( year ).MINUTE ) ).get ( Calendar. 56 Secangkir Kopi Java .HOUR ) ).get ( Calendar. } } Listing 2.get ( Calendar. } String minutes = String. } return dateOfMonth + "/" + month + "/" + shortYear + " " + hour + ":" + minutes + " " + day. Size.

untuk membuat table model //sendiri. } //mendapatkan nilai pada baris dan kolom tertentu public Object getValueAt( int row. Size.length. } //mendapatkan class dari kolom public Class getColumnClass( int c ) { return getValueAt ( 0. this.//package class MyTableModel. c ).name = name. } //mendapatkan jumlah baris public int getRowCount() { return data. } Listing 2.length. int col ) { return data[row][col].7 – Class ini berusaha mendapatkan daftar file dari suatu folder dan menampilkan atribut-atributnya seperti Nama. private String[] name. Last Modified.data = data. karena kita perlu mengover-ride method //isCellEditable class MyTableModel extends AbstractTableModel { private Object[][] data.getClass (). dll. } //mendapatkan jumlah kolom public int getColumnCount() { return name. String[] name ) { this. //konstruktor public MyTableModel( Object[][] data. Model View Controller 57 . } //mendapatkan nama kolom public String getColumnName( int column ) { return name[column].

this. } } Listing 2.7 – Class ini berusaha mendapatkan daftar file dari suatu folder dan menampilkan atribut-atributnya seperti Nama. jangan protes melulu.. this. Size. boolean isDirectory ) { super ( url ). } } //package class MyImageIcon.url = url. int col ) { //override method ini agar bisa di set tidak bisa //diedit untuk kolom 3 dan kolom yang memiliki class //ImageIcon //get class Class columnClass = getColumnClass ( col ). well..public boolean isCellEditable( int row. Well. dll. Kenapa kita perlu membuat 58 Secangkir Kopi Java . Last Modified.isDirectory = isDirectory. public MyImageIcon( URL url. int column ) { data[row][column] = aValue. return columnClass != ImageIcon. ( Weleh. mari kita bahas perlahan-lahan secara sistematik. tak mengapa. puanjang buanget Lih?!?! Ah. Oke oke.class && col != 3. bersenang-senang kemudian.. Class MyTableModel adalah subclass dari AbstractTableModel. int row.7 ) berusaha menampilkan daftar file dan folder yang ada pada folder F:\My Documents. Class di atas ( Listing 2. untuk menambahkan identifier //bahwa suatu icon merupakan icon untuk folder atau file class MyImageIcon extends ImageIcon { private URL url. untuk latihan kita memang perlu bersakit-sakit dahulu. kapan seneng-senenge?!?! ). } //memberi nilai pada baris dan kolom tertentu public void setValueAt( Object aValue... well. public boolean isDirectory.

isDirectory() ) { data[i][0] = folderIcon. Sekarang kita melihat method getData ( String folder ). Blok yang sedikit rumit terjadi pada data Last Modified. Apa error handlingnya? Bisa kamu tebak sendiri? Kemudian kita menyiapkan icon untuk folder dan file. Kita memasuki blok looping untuk memasukkan data satu persatu. ( 1 KB = 1024 bytes ). kita perlu membaginya dengan 1024.isDirectory())?folderIcon:fileIcon. } else { data[i][0] = fileIcon. maka kita harus mengoverride method isCellEditable ( int row. Kemudian file tersebut kita daftar dengan method listFiles() yang mereturn array File. Proses yang dilakukan pertama adalah menjadikan parameter String folder menjadi sebuah file. Kamu harus menambahkan error handling di sini. Kita menyiapkan data untuk tabel lewat method ini. Untuk menampilkannya dalam Kilo Bytes. Karena secara default JTable adalah full editable. int col ) sesuai dengan kebutuhan kita. Mungkin statement seperti data[i][0]=(children[i]. Itu sebenarnya sama saja dengan blok ifelse seperti ini: if ( children[i].table model sendiri? Nantinya kita akan menampilkan icon folder dan tanggal Last Modified yang tidak bisa diedit oleh user ( read only ). Di sini aku men sub classkan ImageIcon menjadi MyImageIcon untuk menambahkan nilai boolean isDirectory untuk membedakan icon folder atau file. Method lastModified() akan mereturn waktu terakhir file dimodifikasi dalam Model View Controller 59 . } Method length() akan mereturn ukuran file long integer dalam satuan bytes. Masih di method getData ( String folder ). cukup membingungkan bagimu.

Dan dari TableColumn. Class ini tidak dapat diinstantiated secara langsung. Untuk mendapatkan instance dari TableColumn. Dari situ kita tinggal mengatur tampilan tanggalnya sesuai dengan keinginan kita dengan method get ( int constant ). Sebagai gantinya. Kemudian method setTime ( Date date ) akan menset Calendar menjadi waktu kapan file terakhir dimodifikasi. aplikasi ini hanya sekedar membaca dari file dan sama sekali tidak melakukan penulisan ke file. kita mengatur lebar dari masing-masing kolomnya dengan TableColumn. Setelah kita siapkan JComboBox lengkap dengan datanya. Constant lengkapnya bisa kamu lihat di dokumentasi javadoc dari class Calendar. Kita perlu mereparasinya agar menjadi bentuk yang lebih enak dibaca dalam method getDate ( Date date ).1. Kembali ke method init(). Hal kecil yang perlu dilakukan adalah memasang ke dalam container. kita masukkan ke class DefaultCellEditor ( JComponent component ). kita menggunakan method-nya JTable. menentukan apa yang terjadi jika tombol [x] pada window dipencet.. kita menset class tersebut sebagai cell editor dari kolom dengan method setCellEditor ( CellEditor cell ). yaitu getColumn ( Object identifier ). Di sini aku menggunakan JComboBox sebagai editor dari kolom Attribute. dan terakhir: menulis kode launchernya! Apa lagi kalau bukan method sakti public static void main ( String[] args ).mili seconds. menentukan ukuran window. Mari kita pelototi method getDate ( Date date ). Well. Aku perlu mendemokan cell editor di sini. Kita mendapatkan instance dari Calendar dari Calendar. membuatnya visible. Setelah kita melakukan inisialisasi tabel dan datanya. sebagian besar method milik class Date telah di deprecated. 60 Secangkir Kopi Java .getInstance(). kita memakai class Calendar. Sejak JDK 1. Jadi kamu nggak usah kuatir akan dokumen-dokumen kamu. Ingat path “F:\My Documents” harus kamu ganti sesuai dengan yang ada di kompie kamu.

seperti membuat node baru.swing dan class-class pendukungnya berada di package javax. JTree Tinggal satu lagi komponen Model-View Controller yang kurasa penting untuk dibahas.Gambar 2.5 – Asyik nggak? Ada Combo Box di dalam sel tabel. representasi data dipegang oleh class DefaultMutableTreeNode. Dia adalah JTree. Ketika JTree menampilkan sebuah tree. DefaultTreeModel. TreeSelectionModel. Model View Controller 61 . DefaultTreeCellRenderer. yang bisa di-expand dan di-collapse. Contoh yang paling baik untuk menjelaskan JTree adalah hirarki folder yang digambarkan oleh Windows Explorer. JTree sendiri berada di package javax. makanya aku taruh di bagian akhir dari bab ini. JTree adalah komponen yang kompleks.swing. Ada Checkbox dan iconnya lagi!!! iii. letaknya di sebelah kiri.tree. ataupun memodifikasi bapak ataupun anak dari suatu node. dan TreePath. Dan menurutku. JTree adalah komponen yang paling sulit dimengerti. Komponen-komponen pendukung tersebut antara lain DefaultMutableTreeNode. DefaultTreeCellEditor. komponen Swing yang menyajikan data secara hierarki seperti pohon.

TreeModel tidak secara langsung mengatur dan memodifikasi data. DefaultMutableTreeNode kemudian membuat untuk instans merepresentasikan DefaultTreeModel yang sesuai dengan root. DefaultTreeCellEditor digunakan untuk melakukan pengeditan pada node tree dengan sebuah JTextField. Dan class TreePath adalah class pendukung yang merepresentasikan suatu node dalam suatu path.1 ( dulu dikenal dengan sebutan JDK – Java Developer’s Kit ). Tidak seperti ListModel dan TableModel.Ketika DefaultMutableTreeNode merepresentasikan sebuah node. pertama kamu harus membuat root instans dari tree. juga untuk memasang customized icon untuk setiap nodenya.4. 62 Secangkir Kopi Java .6 – Contoh JTree dalam demo SwingSet2 bawaan langsung dari J2SE 1. Untuk membuat sebuah tree model. Class DefaultTreeCellRenderer menyediakan mekanisme untuk merender node tree sebagai sebuah label. DefaultTreeModel mengandle seluruh tree. Class TreeSelectionModel menghandle pemilihan node tree. misalnya. Data dari tree diatur oleh class DefaultMutableTreeNode. Gambar 2.

import java. ataupun TreeModel.swing.swing. private DefaultMutableTreeNode rootNode. import java.*. Hmm…. kita langsung ke kodenya.*. private JButton btnRemove = new JButton("Remove Node"). rasanya kode di atas terlalu ruwet yach??? Model View Controller 63 .*.awt. } Listing 2. import javax. Jika kamu menggunakan konstruktor kosong dari JTree. Kamu bisa menggunakan Array. createGUI(). Ada beberapa konstruktor JTree.tree. public class JTreeDemo extends JFrame { //instans private JTree tree.*. maka yang terjadi adalah tampilan JTree secara default. karena sebenarnya JTree itu ramah sekali – tampangnya aja yang kriminil. Kamu perlu memasukkannya dalam JScrollPane untuk mendapatkan dukungan scrolling.awt. package galih. Semua parameter konstruktor JTree merupakan data yang akan ditampilkan. private JButton btnAdd = new JButton( "Add Node" ).event. import javax. private DefaultTreeModel treeModel.First Run! JTree tidak mendukung scrolling secara langsung. kedengarannya menakutkan ye? Supaya tidak terlalu menakutkan. //konstruktor public JTreeDemo() { super( "Default Tree Demo" ). Vector.8 – Untuk first run.swing. setEventHandler().

tree = new JTree( treeModel ).NORTH ). contPane. btnAdd. BorderLayout. Container contPane = getContentPane(). 300 ). rasanya kode di atas terlalu ruwet yach??? 64 Secangkir Kopi Java .add( btnAdd ). //pasang pada container JPanel panel = new JPanel( new FlowLayout() ).setMnemonic( 'R' ). BorderLayout.setMnemonic( 'A' ). panel.8 – Untuk first run. } } ). setVisible( true ). } //create graphical user interface private void createGUI() { //root node rootNode = createTree(). } } ). btnRemove.//set event handler di sini private void setEventHandler() { btnAdd. } Listing 2.add( btnRemove ). contPane. btnRemove. setSize( 400. panel.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { addNode().add( panel.CENTER ).addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { removeNode(). setDefaultCloseOperation( EXIT_ON_CLOSE ).add( new JScrollPane( tree ). //tree model treeModel = new DefaultTreeModel( rootNode ).

//launcher public static void main( String[] args ) { new JTreeDemo(). if ( parent == null ) return. Listing 2.getChildCount() ).insertNodeInto( new DefaultMutableTreeNode( name ). showInputDialog( this. "Nama Node: " ).removeNodeFromParent( node ). getLastSelectedPathComponent(). treeModel. } //remove node public void removeNode() { //dapatkan node terpilih DefaultMutableTreeNode node = ( DefaultMutableTreeNode ) tree. getLastSelectedPathComponent(). String name = JOptionPane. rasanya kode di atas terlalu ruwet yach??? Model View Controller 65 . } } //add node public void addNode() { //dapatkan node terpilih DefaultMutableTreeNode parent = ( DefaultMutableTreeNode ) tree. if ( node != null ) { treeModel. } //create tree private DefaultMutableTreeNode createTree() { //root node DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode( "Penyanyi" ). parent.8 – Untuk first run. parent.

rockNode.add( new DefaultMutableTreeNode( "Alda" ) ). femaleNode. bandNode.add( rockNode ). bandNode. DefaultMutableTreeNode rockNode = new DefaultMutableTreeNode( "Rock" ).add( new DefaultMutableTreeNode( "B I P" ) ). Listing 2.add( new DefaultMutableTreeNode( "Bon Jovi" ) ).add( new DefaultMutableTreeNode( "Padi" ) ).add( new DefaultMutableTreeNode( "Nirvana" ) ).add( new DefaultMutableTreeNode( "Metallica" ) ). rockNode.add( new DefaultMutableTreeNode( "ADA Band" ) ). bandNode. bandNode. rockNode.add( new DefaultMutableTreeNode( "Boomerang" ) ).add( new DefaultMutableTreeNode( "Agnes Monica" ) ).add( bandNode ).//child node DefaultMutableTreeNode bandNode = new DefaultMutableTreeNode( "Band" ). DefaultMutableTreeNode femaleNode = new DefaultMutableTreeNode( "Fantastic Female" ). rasanya kode di atas terlalu ruwet yach??? 66 Secangkir Kopi Java .8 – Untuk first run.add( new DefaultMutableTreeNode( "Krisdayanti" ) ). rockNode. bandNode. rootNode.add( new DefaultMutableTreeNode( "Godbless" ) ). femaleNode. femaleNode.

Node akan langsung hilang tanpa bekas! Model View Controller 67 . mari kita menuju method createGUI() dulu. rasanya kode di atas terlalu ruwet yach??? Well. kita tinggal memanfaatkan DefaultTreeModel ( untuk memanggil node method removeNodeFromParent MutableTreeNode ). Setelah kita dapatkan node yang akan dihapus. pertama mendapatkan data lewat method createTree() yang mereturn DefaultMutableTreeNode. kita meminta user memasukkan nama node. Jika return value-nya null. return rootNode. } } Listing 2.8 – Untuk first run. seperti biasa. Method createTree() membuat node-node secara satu per satu. JTree bisa di-inisialisasi.add( new DefaultMutableTreeNode( "Nike Ardilla" ) ).femaleNode. Method removeNode() lebih sederhana daripada method addNode(). rootNode. Method addNode() akan dipanggil ketika tombol btnAdd di-klik.add( femaleNode ). Dalam melakukan inisialisasi JTree. maka kita tidak melakukan apa-apa. Tetapi jika tidak null. kemudian membuat instans DefaultMutableTreeNode dan ditambahkan ke node parent. Yang dilakukan adalah mendapatkan node yang terpilih dengan method getLastSelectedPathComponent(). Kita harus melakukan explicit casting di sini karena method tersebut mereturn Object. Dari situ kita bentuk DefaultTreeModel. Method add ( DefaultMutableTreeNode childNode ) akan menjadikan node pemanggil method tersebut menjadi parent dari node yang ada di dalam parameter method tersebut. Setiap node merupakan satu objek class dari DefaultMutableTreeNode. Setelah model selesai. kita perlu tiga langkah.

7 – Hasil dari first run kita terhadap JTree Aku mengenal JTree untuk pertama kalinya sekitar bulan Januari 2004. Tree Cell Renderer dan Tree Cell Editor Seperti halnya komponen Swing tingkat tinggi lainnya.Gambar 2. Interface TreeCellRenderer mendefinisikan bagaimana sel dirender. yang diimplementasikan oleh class DefaultTreeCellRenderer. BBS-ku memakai Java Applet dan koneksi databasenya memakai MySQL JDBC-Native-Connection. Dia juga mengatur warna foreground dan background dari setiap node. Aku menggunakan komponen ini untuk sebuah aplikasi tiruan BBS FTIF ( kampusku ) – jika BBS FTIF memakai Visual Basic dan pure ActiveX Control Data Object Database ( ADODB ). JTree juga memiliki cell renderer. Sampai sekarangpun kabut yang menutupi JTree di depan mataku belum sepenuhnya terkuak. Class ini mengatur icon-icon untuk node leaf. 68 Secangkir Kopi Java . dan node yang terbuka ( expanded ). node yang tertutup ( collapsed ).

Icon-icon untuk JTree secara default bergantung pada lingkungan sistem operasi – jika kamu menggunakan dependent Look And Feel. Jika properti editable pada JTree di-set true.setBackgroundSelectionColor ( Color. Kamu bisa memakai JTextField.setLeafIcon ( leafImageIcon ).setOpenIcon ( openImageIcon ). jTree.setClosedIcon ( closedImageIcon ). kamu bisa melewatkannya melalui konstruktor class DefaultCellEditor. Tapi jika kamu memakai lingkungan MetalLookAndFeel. secara default cell editornya adalah JTextField. JTree juga memiliki cell editor. dua kali untuk membuka node ). Model View Controller 69 . Tetapi JTree secara default sama sekali tidak editable. cmbEditor. //icon expanded node render. icon-icon untuk JTree independen terhadap sistem operasi. cmbEditor. Untuk membuat editor sendiri. render. //icon untuk leaf render. Class ini sama persis dengan editornya JTable.blue ). cmbEditor. //collapsed node render.addItem ( “Lumayan” ). Node JTree diedit jika suatu node diklik tiga kali ( sekali untuk seleksi.Kita bisa melakukan override terhadap method-method DefaultTreeCellRenderer seperti di bawah ini: DefaultTreeCellRenderer render = ( DefaultTreeCellRenderer ) jTree. maupun JCheckBox untuk editornya.addItem ( “Bagus” ).addItem ( “Juelek Sekali” ). JComboBox. jTree. Contohnya seperti di bawah ini: //editor JComboBox cmbEditor = new JComboBox().setCellEditor ( new DefaultCellEditor ( cmbEditor ) ).setEditable ( true ).getCellRenderer().

treeCollapsed(TreeExpansionEvent (TreeExpansionEvent e).setCellEditor ( editor ). Baca bismillah dulu… 70 Secangkir Kopi Java . yaitu valueChanged ( TreeSelectionEvent e ). Bisakah kamu mengetahuinya? ( Tidak? Yaa dicoba donk mbaak ). new DefaultTreeCellRenderer(). treeExpanded Sebagai menu penutup JTree. Ketika suatu node pada JTree dipilih. jTree. yang mencoba mengakses file system dalam hardisk kita. Masalahnya. yaitu seperti ini: DefaultTreeCellEditor editor = new DefaultTreeCellEditor ( jTree. Mereka adalah TreeSelectionEvent dan TreeExpansionEvent. JTree akan memanggil event TreeSelectionEvent.Pengesetan editor dengan di atas terdapat masalah kecil. Ketika suatu node dibuka ( expanded ) atau ditutup ( collapsed ). Tree Event Ada dua event penting yang berhubungan dengan JTree. JTree akan memanggil event TreeExpansionEvent. editor akan muncul dalam satu klik mouse dan meng-overlap si icon. new DefaultCellEditor ( cmbEditor ) ). Listener pemilihan node harus mengimplementasikan interface TreeSelectionListener. kita akan mencoba membuat tiruan hierarki folder pada Windows Explorer dengan tree model buatan kita sendiri. yang berisi satu method. Listener yang menghandel pembukaan atau penutupan node harus yang mengimplementasikan berisi e) interface yaitu TreeExpansionListener dua dan method. Ada alternatif yang lebih baik untuk pemasangan editor.

*. return new TreeFile( dir.isDirectory() ) { File[] fileList = file. } //get root public Object getRoot() { return root.util.listFiles(). import javax. String[] children = dir.*. Listing 2. public class FileSystemModel implements TreeModel { //root private File root.9 – FileSystemModel merupakan model untuk JTree yang menggambarkan hierarki file dan folder pada File System kita.swing.*.tree. Model View Controller 71 .root = root.package galih.swing. if ( file. import java. import java.tree. } //get child count public int getChildCount( Object parent ) { File file = ( File ) parent.swing. int index ) { File dir = ( File ) parent. import javax. //constructor public FileSystemModel( File root ) { this.event. children[index] ).list().*.swing. } //get child public Object getChild( Object parent. //listener private Vector listeners = new Vector().io. import javax.*.

} } return 0. i++ ) { if ( file.equals( children[i] ) ) { return i.length.getLastPathComponent().9 – FileSystemModel merupakan model untuk JTree yang menggambarkan hierarki file dan folder pada File System kita.getName().getParent(). i < children. Object value ) { //prepare to rename file File oldFile = ( File ) path. File file = ( File ) child. for (int i = 0. return file. String parent = oldFile. Object child ) { File dir = ( File ) parent.isFile(). } //get numeric index of child node public int getIndexOfChild( Object parent. } } return -1. } //is leaf? public boolean isLeaf( Object node ) { File file = ( File ) node. String[] children = dir. 72 Secangkir Kopi Java .if ( fileList != null ) { int counter = 0. Listing 2. for ( int i = 0. } return counter.list().length. i++) { counter++. } //value of object changes public void valueForPathChanged( TreePath path. i < fileList.

hasNext() ) { treeListener = ( TreeModelListener ) iterator. int[] childIndices = { getIndexOfChild( parentFile. Iterator iterator = listeners.next().renameTo( target ). newValue ).. private void fireTreeNodesChanged( TreePath path. target ) }. //sending event to each listener while ( iterator. child ).treeNodesChanged( event ). Object[] child ) { TreeModelEvent event = new TreeModelEvent ( this. } } Listing 2. int[] indices. treeListener. Model View Controller 73 . File parentFile = new File( parent ). changedChild ). TreeModelListener treeListener = null. //renaming file File target = new File( parent.9 – FileSystemModel merupakan model untuk JTree yang menggambarkan hierarki file dan folder pada File System kita. Object[] changedChild = { target}..String newValue = ( String ) value. oldFile. node ada yang berubah lhoo. fireTreeNodesChanged( path. } //hai-hai.iterator(). childIndices. path. indices.getParentPath().

} } } Listing 2. karena jika menggunakan class default. String child ) { super( parent. suatu syarat mutlak class yang ingin menjadi model dari JTree. } public String toString() { return getName().?!? ). susunan file pada file system memiliki hierarki tertentu sehingga mudah untuk ditampilkan pada JTree. } public void removeTreeModelListener( TreeModelListener listener ) { listeners. } public TreeFile( File parent.add( listener ). class di atas ( Listing 2. child ). 74 Secangkir Kopi Java . Oce. File child ) { super( parent. Kita harus membuat implementasi sendiri pada kasus ini.9 – FileSystemModel merupakan model untuk JTree yang menggambarkan hierarki file dan folder pada File System kita.public void addTreeModelListener( TreeModelListener listener ) { listeners. Apalagi.remove( listener ).9 ) merupakan implementasi dari interface TreeModel.toString() ). child. } //inner class private class TreeFile extends File { public TreeFile( File parent. kita akan terlalu kesulitan ( ingat DefaultMutableBlaBlaBla….

dalam hal ini adalah File. masih abstrak di awang-awang. namun implementasi nyatanya belum kita tulis. Method getIndexOfChild ( Object parent. kita return nilai index dari looping. JTree secara berulangulang memanggil method getChild ( Object parent. kita return nilai 0 yang menunjukkan bahwa parent tidak memiliki anak. kita panggil method listFiles() yang akan mereturn array File. Model View Controller 75 . so pasti programnya langsung error! Ketika membangun view dari TreeModel. Jika sama. Object child ) berusaha mengetahui index dari child yang dimulai dari 0. Maka kita tinggal mereturn true jika node adalah leaf ( file ) dan false jika bukan leaf ( direktori ). Method getChildCount ( Object parent ) akan mengembalikan jumlah dari anak yang dimiliki parent. Kita harus melakukan casting kepada parent dan child agar menjadi objek File. Kemudian parent akan di-casting ke objek File.Sebenarnya. kita return nilai -1. Interface memungkinkan implementasinya. Interface sangat berguna ketika kita memerlukan sebuah objek. Jika file dari hasil casting bukan direktori. dengan looping. Jika file adalah sebuah direktori. Kita mendapatkan daftar anaknya parent dengan method list() yang mereturn array String children. apakah interface itu? Interface hanyalah sebuah deklarasi dari method-method yang akan digunakan. Nah. int index ). Jika tidak ketemu. kita mencari kesamaan antara tiap-tiap anggota children dengan child. JTree memanggil method isLeaf ( Object node ) untuk mengetahui apakah node mempunyai anak atau tidak. Method ini mereturn sebuah object inner class TreeFile yang mengoverride method toString-nya class File untuk mereturn nama dari file tersebut. kita menggunakan jika kita objek yang belum program ditulis tanpa Tetapi menjalankan implementasi interface itu. Dari situ kita hitung berapa panjang array yang segera kita return-kan. Setiap objek bisa menjadi node dari JTree.

awt. import javax. import java.io. Dari informasi induk dan nama file.awt. Semua listener kita simpan dalam Vector dan pemasukan dan pengeluarannya melalui gerbang method addTreeModelListener dan removeTreeModelListener.swing.tree.*.10 – Class ini menunjukkan hierarki pada file system dengan menggunakan JTree dan FileSystemModel yang telah kita tulis pada listing 2. Bisa kamu lihat di Windows Explorer kalau nggak percaya! Setelah mendapatkan node file yang akan di-rename. Sekarang kita tinjau listing untuk menampilkan TreeModel pada listing 2. kita buat file baru dengan konstruktor File ( String parent. Object value ) ketika user melakukan perubahan pada node. dan objek node yang berubah itu sendiri.*.*. String name ). import java. Kita melakukannya pada method fireTreeNodesChanged.JTree akan memberitahu method valueForPathChanged ( TreePath path.*. Di sini kita akan benar-benar melakukan perubahan nama ( renaming ) file.9 76 Secangkir Kopi Java .*.9 pada JTree dan menampilkannya pada layar monitor Windows ( apa Linux? ) tercinta… package galih. Kita harus memberitahu kepada semua listener bahwa ada node yang berubah dengan mengirim sebuah TreeModelEvent. kita perlu mendapatkan induk dari file tersebut dan meng-casting value sebagai nama baru.tree. import javax. array integer yang berisi index dari tiap-tiap node yang berubah. Kemudian oldFile kita ganti nama ke file baru dengan method renameTo ( File target ).swing.event. Listing 2. import java.swing. Yang kita perlukan untuk membuat sebuah TreeModelEvent adalah TreePath.

private JButton btnExpand = new JButton( "Expand" ). tree. 10 – Class ini menunjukkan hierarki pada file system dengan menggunakan JTree dan FileSystemModel yang telah kita tulis pada listing 2. private JButton btnCollapse = new JButton( "Collapse" ). Listing 2.setShowsRootHandles( true ).fireTreeExpanded( path ). tree. init(). tree = new JTree( treeModel ).addActionListener(new ActionListener() { public void actionPerformed( ActionEvent e ) { TreePath path = tree.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { TreePath path = tree.getLeadSelectionPath(). //konstruktor public JTreeDemo2() { super( "JTree Demo ver. setEventHandler(). } private void init() { //init tree treeModel = new FileSystemModel( new File( "H:\\" ) ). } } ).public class JTreeDemo2 extends JFrame { //instans private JTree tree. private TreeModel treeModel. } } ). } //event private void setEventHandler() { btnExpand.getLeadSelectionPath().9 Model View Controller 77 . btnCollapse. tree.fireTreeCollapsed( path ). 02" ).

png" ) ) ). btnExpand. tree.getResource( "folder_open. btnCollapse.getResource( "file.CENTER ). DefaultTreeCellEditor editor = new DefaultTreeCellEditor( tree. "Coba". tree. renderer.add( new JScrollPane( tree ). 400 ). BorderLayout. getCellRenderer().add( btnCollapse ).getResource( "folder. setSize( 300. renderer.setCellEditor( editor ). Container contPane = getContentPane(). renderer. panel. contPane. renderer. //cell editor --klik 3 kali String[] comboData = { "Demo". 10 – Class ini menunjukkan hierarki pada file system dengan menggunakan JTree dan FileSystemModel yang telah kita tulis pada listing 2. } Listing 2.9 78 Secangkir Kopi Java .//renderer DefaultTreeCellRenderer renderer = ( DefaultTreeCellRenderer ) tree.add( btnExpand ).setClosedIcon( new ImageIcon( getClass().png" ) ) ).NORTH ).setEditable( true ). panel.setMnemonic( 'E' ).add( panel. setDefaultCloseOperation( EXIT_ON_CLOSE ).setOpenIcon( new ImageIcon( getClass().setLeafIcon( new ImageIcon( getClass(). BorderLayout.png" ) ) ). JPanel panel = new JPanel( new FlowLayout() ). JComboBox cmbEditor = new JComboBox( comboData ).setMnemonic( 'C' ). setVisible( true ). "Test!"}. new DefaultCellEditor( cmbEditor ) ). contPane.

Di sini kita tidak membuat renderer baru. } } Listing 2. kita menggunakan class DefaultTreeCellRenderer. Cara memasangnya di JTree sudah kubahas di awal sebelum kita berkoding. Aku memamerkan isi dari drive H:\ di kompie-ku. setOpenIcon. Dan untuk btnCollapse. Method setEventHandler memberi nyawa pada JButton agar bisa membuka dan menutup JTree. Cell Editor yang kita gunakan adalah DefaultTreeCellEditor. kita memanggil method fireTreeCollapsed ( TreePath path ) dari path yang kita dapatkan.//launcher :) public static void main( String[] args ) { new JTreeDemo2(). 10 – Class ini menunjukkan hierarki pada file system dengan menggunakan JTree dan FileSystemModel yang telah kita tulis pada listing 2. Kamu JComboBox – hanya untuk menjadi menunjukkannya bisa menggantinya JTextField agar lebih manusiawi. tapi mengambil dari JTree dengan getCellRenderer() dan mengoverride method setLeafIcon. Method setShowsRootHandles ( boolean show ) membuat icon kunci root node untuk membuka dan menutup node ditunjukkan atau tidak. Kemudian kita set JTree dengan TreeModel yang telah kita persiapkan.9 Method init() melakukan inisialisasi JTree dengan membuat FileSystemModel terlebih dahulu. Untuk btnExpand. Aku memasukkan event ini karena: inilah yang membuatku pusing selama dua minggu memikirkan bagaimana membuka node JTree secara otomatis pada Model View Controller 79 . Di sini aku ke menggunakan kamu. Dalam menset cell renderer. Jangan lupa untuk men-set JTree menjadi editable agar cell editor kita berguna. kita memanggil method fireTreeExpanded ( TreePath path ) setelah mendapatkan path dari method getLeadSelectionPath. dan setClosedIcon untuk mengganti icon default menjadi icon kita.

8 – JTree yang menggambarkan file system. Ringkasan Pada bab ini. ataupun JTree. Jika kamu telah menguasai bab ini. kamu telah mempelajari komponen-komponen Swing yang cukup kompleks secara mendetail. jiwa dari komponen-komponen tersebut. khususnya Swing. 80 Secangkir Kopi Java . bagaimana membuat renderer dan editor sendiri untuk komponen-komponen tersebut.akhir Juni 2004. Dan jawabannya baru kudapatkan tadi malam ( 12 Agustus 2004 ) ketika aku menulis ini! Bagaimana hasilnya? Nih! Gambar 2. memanipulasinya dan menyajikannya secara rapi lewat komponen JList. bagaimana menyimpan data. kamu bisa mengatakan dengan sombong ke dirimu sendiri ( jangan ke orang lain! ). bahwa kamu telah Advanced dalam Java 2 Standard Edition. dengan renderer dan editor yang full customized i. awal liburan semester IV. JTable. Kamu juga telah mempelajari konsep model-view controller.

java database connectivity [ jdbc ] Desember 2003 .

.

he.he. MySQL.. juga bukan database. Postgre sebenarnya juga mendukung.. ( -. apalagi Microsoft Access. SQL independen terhadap arsitektur database sehingga bisa digunakan kepada database apa saja. ).semoga anak SI ga ada yang baca ini ye. sok teu banget aku -. karena aku hanya pernah menggunakan driver JDBC-NativeAPI untuk tiga DBMS tersebut. bahwa Sistem Informasi bukanlah Teknologi Informasi. Kenapa aku mengatakan “setahuku”. Sistem Informasi sendiri merupakan bagian yang sangat kompleks. aku tidak akan membahas konsep basis data secara mendetail. toh aku juga nggak bisa ngonsep. merupakan gabungan antara software dan hardware dan lingkungan ( wuihh. Sedangkan untuk MS-SQLServer 2000 aku memerlukan driver dari third party ( Borland ). Mereka adalah Oracle .). Tapi harap diingat. Aku akan langsung ke bagaimana memanipulasi database dengan Java. Apalagi untuk Microsoft Access. Java Database Connectivity [ JDBC ] 83 . Suetuju?!?! Setahuku... namanya bukan sayur kalo gitu ) jika tidak melibatkan database. dan Cloudspace dari Informix Software.. Structured Query Language ( SQL ) SQL adalah bahasa standar untuk melakukan query kepada database.. bukaaan. Sekilas Database Dunia pemrograman bagaikan sayur tanpa garam dan kuah ( wekk. aku belum pernah menemukan driver langsung kecuali memakai ODBC. ada beberapa DBMS ( Database Management System ) yang mendukung Java secara langsung.i. tapi aku tak pernah memakainya.. Kamu pasti akan menemui database jika aplikasi yang kamu tulis adalah sebuah sistem informasi. Mengapa kok gitu Lih? Karena setiap aplikasi nyaris memerlukan database.he. Karena bab ini tidak berjudul Database.

SELECT Syntax lengkap dari SQL – SELECT adalah: SELECT [DISTINCT] select_list FROM table_source [WHERE search_condition] [GROUP BY group_by_expression] [HAVING search_condition] [ORDER BY order_expression [ASC | DESC] ] Menurut kuliahku Basis Data dulu. dan yang berada di dalam tanda [ ] boleh disertakan atau tidak sesuai dengan kebutuhan. yang kudapat dari kuliah Basis Data-nya Pak Imam K semester III kemarin. arti huruf besar adalah keyword. yang harus disertakan jika kita membutuhkan pengolahan data. aku akan menggunakan database AkademikPIKTI. yang berhuruf kecil merupakan isian yang bisa diubah sesuai dengan kebutuhan kita. Gambar 3. Sebagai contoh.1 – Relationship yang dipakai dalam database AkademikPIKTI 84 Secangkir Kopi Java .

Kriteria tersebut dimasukkan dalam klausa WHERE. sehingga misalnya menjadi [ dosen killer ]. Artinya hasil query yang sama ditampilkan sekali. Misalnya dalam database Perpustakaan. misalnya SELECT nip. Peminjam yang meminjam lebih dari satu kali akan ditampilkan sekali jika query kita: SELECT DISTINCT no_pinjam FROM peminjam WHERE Pada kebanyakan kasus. Contoh: SELECT nrp.SQL minimal contohnya seperti ini: SELECT * FROM dosen Dia akan menampilkan seluruh kolom pada tabel dosen. dipisahkan dengan tanda koma ( . nama kolom harus berada dalam tanda [ ].2 – Hasil Query dengan filter WHERE Java Database Connectivity [ JDBC ] 85 . nama FROM mahasiswa WHERE jeniskel = 'L' Dia akan menampilkan semua nrp dan nama mahasiswa yang berjenis kelamin laki-laki. Kita perlu melakukan filter agar yang tampil sesuai dengan kriteria yang diperlukan. kita tidak cukup melakukan query dengan memilih semua baris. ). ganti tanda asterisk ( * ) menjadi nama kolom. Gambar 3. peminjam boleh meminjam lebih dari satu kali. nama FROM dosen Perhatikan jika nama kolom terdapat spasi. [ DISTINCT ] digunakan untuk menghilangkan duplikasi pada query. Untuk menampilkan kolom yang spesifik.

SELECT * FROM mahasiswa WHERE nama LIKE “__d” • Operasi IN dan NOT IN Seperti arti keyword-nya. • Operasi Perbandingan: =. Simbol _ mewakili satu dari sembarang karakter Contoh: Menampilkan nama mahasiswa yang memiliki nama depan Budi: SELECT * FROM mahasiswa WHERE nama LIKE “Budi%” Menampilkan nama mahasiswa yang memiliki nama dengan huruf ketiga d. Kumpulan nilai ini bisa berupa nilai-nilai yang diisikan ataupun query tunggal ( query yang hasilnya hanya satu kolom saja ). • Operasi LIKE Operasi ini khusus untuk tipe data string. >. operasi ini membandingkan dengan kumpulan nilai. <. Contoh: Menampilkan koleksi yang jenisnya buku dan majalah (idTipeKoleksi=1 atau 2): SELECT * FROM koleksi WHERE idTipeKoleksi IN (1. Operasi ini digunakan untuk mengenali string yang memiliki pola tertentu. 2) Menampilkan anggota yang selain mahasiswa atau dosen (idJenisAnggota selain 2 dan 3) SELECT * FROM anggota WHERE IDJenisAnggota NOT IN ( 2. >=. 3) 86 Secangkir Kopi Java . Simbol yang digunakan: simbol % mewakili 0 – tak terhingga dari sembarang karakter. IS Untuk operasi IS. meskipun ada hal-hal kecil yang berbeda. ataupun “” ( String kosong ).Ada beberapa operasi yang digunakan untuk melakukan filtering. yang diisikan adalah null. <> atau !=. Null tidak sama dengan 0. suatu nilai yang belum diisi nilai atau kosong. <=. Operasi ini pada umumnya sama untuk semua DBMS.

Contoh: Untuk menampilkan jumlah seluruh anggota: SELECT COUNT(*) FROM Anggota Untuk menampilkan tahun kelahiran anggota tertua: SELECT MIN( year ( TglLahir ) ) FROM anggota GROUP BY <kolom 1> [. Fungsi-fungsi tersebut yaitu: • COUNT ( * ) untuk mendapatkan jumlah baris. • AVG ( kolom ) untuk mendapatkan nilai rata-rata pada suatu kolom. • MAX ( kolom ) untuk mendapatkan nilai tertinggi pada suatu kolom. <kolom 2> ] Klausa ini digunakan untuk mengelompokkan fungsi-fungsi agregate. Proses tersebut akan mengolah nilai sebuah field atau lebih mulai baris pertama sampai seluruh baris. Contoh: Untuk menampilkan jumlah anggota perjenis kelamin: SELECT JK. AVG(harga) FROM koleksi GROUP BY idPenerbit Java Database Connectivity [ JDBC ] 87 . • SUM ( kolom ) untuk mendapatkan jumlah keseluruhan dari suatu kolom.Menampilkan anggota yang belum pernah meminjam buku sama sekali: SELECT * FROM anggota WHERE id NOT IN (SELECT DISTINCT idAnggota FROM Peminjaman) FUNGSI AGREGATE Fungsi ini hasilnya diambil dari proses tiap baris pada tabel. • MIN ( kolom ) untuk mendapatkan nilai terendah pada suatu kolom. COUNT(*) FROM anggota GROUP BY JK Untuk menampilkan rata-rata harga koleksi per kode penerbit SELECT idPenerbit.

LATIHAN SQL SELECT Statement SQL Select sangat puenting luar biasa dalam memanage suatu database. dengan ASC mengurutkan mulai dari terkecil hingga terbesar. COUNT(*) FROM koleksi GROUP BY idPenerbit HAVING COUNT(*)>10 ORDER BY Klausa ini digunakan untuk mengurutkan hasil query berdasarkan kolom tertentu. huruf besar dan kecil dianggap sama. tetapi hanya yang jumlahnya >10 saja yang ditampilkan. maka pengurutan dari hasil sama itu dilakukan pada parameter kolom berikutnya. ataupun dalam pembuatan aplikasi. Contoh: Untuk menampilkan jumlah buku per kode penerbit. atau bahkan sELecT. 88 Secangkir Kopi Java .HAVING < kondisi > Klausa ini digunakan untuk melakukan filtering pada fungsi agregate. DESC mengurutkan mulai dari terbesar hingga terkecil. Tips: Berbeda dengan Java. Select. Contoh: SELECT * FROM authors ORDER BY lastName. Order By bisa diikuti parameter lebih dari satu kolom dengan prioritas mulai dari yang paling kiri. Jika kolom terkiri sama. SQL Language adalah case insensitive. Jadi kamu boleh menulis SELECT. Ini adalah WHERE-nya fungsi agregate. SELECT idPenerbit. select. Maka aku perlu menyertakan hasil latihan SQL-ku bersama kuliahnya Pak Imam di sini. Terserah mana yang kamu suka. firstName ASC Ini akan menampilkan seluruh kolom dari tabel authors dan diurutkan berdasarkan kolom lastName dan firstName secara ascending.

14. alamat) yang alamatnya sama-sama di "Sidoarjo". Daftar dosen yang anakwalinya pernah mendapatkan nilai 'E'. 17. rata-rata per nama Mata Kuliah. Daftar matakuliah dan mahasiswa yang harus mengikuti ujian susulan matakuliah tsb (nilai <56). 12. Daftar Mahasiswa (nrp. 9. 13. Java Database Connectivity [ JDBC ] 89 --> rumus IPK = . alamat) dan dosen walinya (nip. 8. 16. Daftar nama matakuliah beserta nilai hurufnya untuk mahasiswa dg NRP='12020012'. nama. 10. 6. Daftar Mahasiswa (nrp. 18. 4. Daftar nama mahasiswa dan nilai matakuliah untuk mahasiswa kelas "C1" dan matakuliah "Pemrograman Database". 7. Daftar Jadwal perkuliahan (hari. 15. nama) beserta nama dosen walinya (nip. Daftar Dosen yang tidak memiliki anak wali. nama. alamat) yang namanya sama. alamat) yang beralamat di "Sidoarjo" Daftar Matakuliah (*) beserta semester diajarkan urut berdasarkan semester dan nama. jeniskel) yang berjenis kelamin lakilaki. jam. 5. nama) SUM(sks*kredit) / SUM(kredit). Daftar mahasiswa (nrp. Jumlah seluruh mahasiswa. nama). 3. terendah. nama. nama. Daftar Mahasiswa (nrp. nama) yang dosen walinya bernama "Irfan Subakti". Total IPK per mahasiswa (nrp. nama) yang dianggap lulus (tidak pernah mendapatkan nilai "D" atau "E"). 2. nama matakuliah dan dosen pengajar). nama.Buat query pada database AkademikPIKTI: 1. Jumlah seluruh mahasiswa per jenis kelamin. Daftar Mahasiswa (nrp. Daftar Mahasiswa (nrp. Nilai tertinggi. Daftar Mahasiswa (nrp. 11.

kodesemester FROM matakul.pesertakul WHERE pesertakul.mhs.nrp.nip.alamat like '*Sidoarjo*') AND(dosen.dosen .nip) AND (mhs. Gabungan seluruh nama.nipwali=dosen.namakul 04:\> SELECT mahasiswa.nrp.namakul. alamat mahasiswa dan dosen yang beralamat di "Sidoarjo" yang urut berdasarkan nama.kodekul 08:\> SELECT hari.nama.nipwali=dosen.jeniskel FROM Mahasiswa WHERE jeniskel='L' 02:\> SELECT nrp.nama like 'Irfan Subati' 06:\> SELECT mhs.alamat.matakul.nilaihuruf FROM mataku.matakul.nip AND dosen..nama.nipwali=dosen. Nilai tertinggi.nip 05:\> SELECT mahasiswa.dosen. terendah.hari.mhs.mahasiswa. 20.nama FROM mahasiswa.dosen WHERE 90 Secangkir Kopi Java .kodesemester ORDER BY matakul.dosen WHERE mahasiswa.pesertakul.nama FROM sesikuliah.namajam.nama.dosen.19.doesn.nip.alamat FROM mahasisiwa.nama FROM Mahasiswa.dosen WHERE (mhs.jam.dosen WHERE mahasiswa.jam.nama.nrp. rata-rata per kelas dan jeniskelamin.dosen.namahari. mahasiswa.semester WHERE matakul.alamat FROM Mahasiswa WHERE alamat like '*Sidoarjo*" 03:\> SELECT matakul.semester.nama.nrp='12020012' and pesertakul.alamat like '*Sidoarjo*') 07:\> SELECT matakul.kodesemester = semester.dosen.kodekul=matakul. Jawaban: 01:\> SELECT nrp.nama.namakul.

namakul.alamat FROM mahasiswa WHERE nama IN(SELECT nama FROM mahasiswa GROUP BY name HAVING COUNT(*) >1) 15:\> SELECT COUNT (*) FROM mahasiswa 16:\> SELECT COUNT (*) FROM mahasiswa GROUP BY jeniskel Java Database Connectivity [ JDBC ] 91 .kodejam AND sesikuliah.mahasiswa.nrp AND pesertakul.kodekul AND matakul.kodejam=jam.mahasiswa.kodekul=matakul.nama FROM mahasiswa.kodekul=pesertakul.nama.nihuruf='E' 13:\> SELECT matakul.sesikuliah.nrp=pesertakul.nip AND mahasisea.nrp=pesertakul.matakul WHERE mahasiswa.pesertakul.nama FROM mahasiswa WHERE nrp NOT IN (SELECT distinct nrp FROM pesertakul WHERE (nihuruf='D' OR nihuruh='E')) 12:\> SELECT distinct dosen.pesertakul WHERE mahasiswa.nilai<56 14:\> SELECT distinct nama.nip=sesikuliah.nrp FROM dosen.kodehari=hari.nrp=pesertakul.nilai FROM mahasiswa.nipwali=dosen.kodekul=matakul.kodehari AND sesikuliah.kodekul AND dosen.pesertakul.nrp AND pesertakul.nama.matakul WHERE mhs.kodekul AND pesertakul.nrp.kelas='ca' AND matakul.nipdosen 09:\> SELECT mhs.doesn.pesertakul.nrp AND pesertakul.namakul='Pemrograman Database' 10:\> SELECT * FROM dosen WHERE nip NOT IN (SELECT distinct nipwali from mahasiswa) 11:\> SELECT nrp.

nama. MIN(pesertakul. aku sudah bilang “sori”.maasiswa. MAX(pesertakul.sks) FROM mahasiswa.kode 18:\> SELECT matakul.alamat FROM dosen WHERE dosen.17:\> SELECT mahasiswa.nama. rasanya tidak etis jika aku kembali membahas konsep JDBC.AVG(pesertakul.kodekul=matakul.kelas. MIN(pesertakul. Jadi kalau ada sedikit error.nihuruf=nilai. mahasiswa. AVG(pesertakul.kul).nangka*matakul.mahasiswa WHERE mahasiswa.nrp=pesertakul.nilai.s ks)/SUM(matakul.nilai).kul).kodekul GROUP BY matakul.kul) FROM matakul.dosen.matakul.nrp GROUP BY pesertakul.namakul 19:\> SELECT pesertakul.pesertakul.alamat like '*Sidoarjo*' ORDER BY nama Aku perlu mohon maaf bahwa SQL-ku diatas tidak ku uji coba ulang – aku tinggal kopi paste dari My Documents-ku. ii.jeniskel 20:\> SELECT mahasiswa.nrp=pesertakul.nilai) FROM pesertakul.nrp AND pesertakul. mahasiswa. Java Database Connectivity First Run! Setelah kita membahas habis SQL dengan begitu detail. MAX(pesertakul.nilai.SUM(nilai.nrp.alamat like '*Sidoarjo*' UNION ALL SELECT dosen.nilaikul.kodekul=matakul.kelas. mahasiswa.nilai).pesertakul WHERE pesertakul.jeniskel.nama AS nama.alamat AS alamat FROM mahasiswa WHERE mahasiswa.nilai WHERE mahasiswa.kodekul AND pesertakul.nilai. Bisa-bisa aku nanti 92 Secangkir Kopi Java .

jdbc.JdbcOdbcDriver" ). Karena itu. public class QueryToDatabase extends JFrame { private StringBuffer hasil.*.dijuluki ngomong doang.sql.forName( "sun.executeQuery( Listing 3. salah satu cara Java mengakses database. } catch ( Exception e ) { e. //konstruktor public QueryToDatabase() { super ( "JDBC .swing.getConnection( "jdbc:odbc:Akademik" ). Kita menggunakan Open Database Connectivity. //statement Statement st = con. //query database ResultSet rsHasil = st. import java. //connect to database Connection con = DriverManager.First Sight!" ). package galih.createStatement(). Ini untuk sekedar mengetahui.*. createGUI(). import javax. mari kita pelototi bagaimana Java mengakses database dengan JDBC.awt. untuk lebih teknisnya kita bahas setelah ini.1 – First run kita terhadap database Akademik. sebagai perkenalan pertama kita dengan JDBC. try { prepareQuery(). Java Database Connectivity [ JDBC ] 93 . import java.odbc.jdbc.*.printStackTrace(). } } //connect to database private void prepareQuery() throws Exception { //loading driver class Class.

"SELECT * FROM dosen" );

//processing hasil = new StringBuffer(); ResultSetMetaData metaData = rsHasil.getMetaData(); int numCol = metaData.getColumnCount();

//kolom, result set mulai dari 1, array dari 0 for ( int i = 1; i <= numCol; i++ ) { hasil.append( metaData.getColumnName( i ) + "\t" ); } hasil.append( "\n" );

while ( rsHasil.next() ) { for ( int i = 1; i <= numCol; i ++ ) { hasil.append( rsHasil.getString( i ) + "\t" ); } hasil.append( "\n" ); }

//close st.close(); con.close(); }

private void createGUI() { JTextArea txtHasil = new JTextArea ( hasil.toString() ); Container contPane = getContentPane(); contPane.add( new JScrollPane ( txtHasil ), BorderLayout.CENTER ); setDefaultCloseOperation ( EXIT_ON_CLOSE ); setSize ( 400, 350 ); setVisible ( true ); }
Listing 3.1 – First run kita terhadap database Akademik. Kita menggunakan Open Database Connectivity, salah satu cara Java mengakses database.

94

Secangkir Kopi Java

//kode sakti! public static void main ( String[] args ) { new QueryToDatabase(); } }
Listing 3.1 – First run kita terhadap database Akademik. Kita menggunakan Open Database Connectivity, salah satu cara Java mengakses database.

Dalam menulis program yang membutuhkan query ke database, yang perlu kita lakukan adalah hal-hal sbb: 1. Menentukan driver dari database. Kita akan bahas lebih mendetail nanti. 2. Membuat ditentukan. 3. 4. Dari koneksi tersebut kita membuat statement. Dari statement tersebut kita melakukan query ke database. Query bisa berbentuk SQL ( Structured Query Language ), DDL ( Data Definition Language ), ataupun DML ( Data Manipulation Language ). koneksi pada database yang alamatnya telah

Method prepareQuery() pada listing 3.1 di atas melakukan query ke database. Method ini meng-throw 2 eksepsi yaitu SQLException dan
ClassNotFoundException.

Kita

menyingkatnya

dengan

melemparkan induk dari dua eksepsi ini, yaitu Exception. Method
Class.forName ( String classDriver )

menentukan class yang digunakan sebagai driver dari database. Class ini harus berada di dalam CLASSPATH. Di sini kita memakai driver JDBCODBC yang telah built-in di dalam library JVM ( Java Virtual Machine ). Kita melakukan koneksi dengan method

DriverManager.getConnection ( String address ) yang mereturn

sebuah object Connection. String

address

adalah alamat letak

Java Database Connectivity [ JDBC ]

95

database

berada.

Tata

nama

untuk

alamat

ini

adalah

“jdbc:<driver>:<database>”.

Dari koneksi tersebut kita membuat statement query dengan method
createStatement().

Kemudian

kita

eksekusi

dengan

executeQuery ( String query ) yang akan menghasilkan sebuah ResultSet. ResultSet kita proses untuk kita tampilkan pada text area. Kita

mendapatkan

nama-nama

kolom

(

field

)

dengan

method

getMetaData(). ResultSetMetaData merupakan ResultSet khusus

yang mengurusi semua atribut dari ResultSet seperti nama kolom, jumlah kolom, dsb.

Gambar 3.1 – Tampilan hasil query yang kita tampilkan pada sebuah JTextArea.

Driver JDBC Koneksi ke database adalah tanggung jawab dari driver. Java 2 SDK hanya memiliki satu driver built-in yaitu tipe driver JDBC-ODBC. Untuk melakukan koneksi dengan tipe lain, kita membutuhkan driver spesifik yang harus diletakkan pada CLASSPATH.

96

Secangkir Kopi Java

Driver JDBC di-load dengan method Class.forName ( String driver ). Contoh: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Class.forName("postgresql.Driver"); Class.forName("oracle.jdbc.driver.OracleDriver"); Driver JDBC dapat mengerti alamat database yang ditulis dalam URL ( Uniform Resource Locator ). Berikut ini adalah tata nama alamat database untuk beberapa database. Setiap alamat database dengan koneksi JDBC-ODBC memiliki format berikut:
“jdbc:odbc:<dns>” <dns> adalah Data Source Name yang digunakan pada ODBC. Dalam

Listing 3.1 DNS yang dipakai adalah Akademik, sehingga alamatnya menjadi “jdbc:odbc:Akademik” Untuk database Oracle, contoh alamat database yang berada pada mesin Eliza dengan nama database Coba adalah:
String url = "jdbc:oracle:thin:user/password@( description=(address_list=( address=(protocol=tcp) host=Eliza ) (port=1521))) (source_route=yes) (connect_data=(sid=Coba)))";

Untuk MySQL, tata nama alamatnya beda lagi. Berikut ini adalah contoh alamat database dengan nama Coba, dengan nama user fatso dan password ganteng.
String url = “jdbc:mysql://localhost/Coba?user=fatso;password=ganteng”;

Tipe Driver JDBC ada empat macam, yaitu JDBC-to-ODBC Bridge Driver, Native-API, JDBC-Net Pure Java Driver, dan Native Protocol Pure Java Driver.

Java Database Connectivity [ JDBC ]

97

Secara default. dengan perintah yang tidak database-specific. Server akan menerjemahkan request ini sebagai request database-specific. koneksi ini bersifat auto commit. Koneksi Database Koneksi ke database dapat didapat dengan memanggil method DriverManager. Pemanggilan method di atas akan mereturn objek Connection. artinya apapun query kita dengan menggunakan koneksi ini. Konfigurasi ini dapat melakukan koneksi secara langsung ke database karena langsung memanggil method yang ada di driver lewat JNI (Java Native Interface). Konfigurasi ini berkomunikasi dengan 2 3 database lewat network protocol.getConnection ( String url.getConnection( String url ) atau DriverManager. Native-Protocol Pure Java. konfigurasi ini adalah yang tercepat. Native-API. URL yang dimaksud telah kita bahas tadi dengan tatanamanya dengan cukup njlimet. tidak semua vendor database membuat driver spesifik untuk Java. Kita dapat mengubah setting ini dengan method 98 Secangkir Kopi Java . String password ). kelemahannya.Tipe Penjelasan JDBC-to-ODBC Bridge Driver. Terkenal sebagai konfigurasi paling lambat. String user. JDBC-Net Pure Java. termasuk MS-ACCESS. JDBC membuat koneksi dengan Microsoft ODBC (Open Database Connectivity). Konfigurasi ini sama dengan 4 No. 1 Konfigurasi ini mengharuskan ODBC terinstall pada komputer client.3 hanya saja menggunakan network protocol yang database-specific. hasilnya mempengaruhi langsung kondisi database.

createStatement(). Java Database Connectivity [ JDBC ] 99 . Ini akan kita bahas segera. dan Prepared Statement. kita dapat membuat statement untuk melakukan query ke database.executeQuery ( “SELECT * FROM mahasiswa” ). Query Statement Aku biasa menggunakan dua method createStatement untuk membuat statement SQL. Contoh: Statement st = con. dsb.executeUpdate ( String updateString ) yang mereturn nilai integer.executeXXX. Dua method ini menghasilkan objek ResultSet dari query yang kita lakukan. Statement Setelah koneksi kita dapat.executeQuery ( String query ). Jika nilainya false.setAutoCommit ( boolean condition ). Method createStatement() menghasilkan result set dengan tipe TYPE_FORWARD_ONLY dan konkurensi CONCUR_READ_ONLY. int resultSetConcurrency ). Update Statement Statement ini biasanya dipakai untuk Data Definition Language ( DDL ) ataupun Data Manipulation Language ( DML ) seperti INSERT INTO. Ada beberapa macam statement yang sering digunakan. Pada akhirnya Update Statement memanggil method Statement. maka query yang kita lakukan tidak mempengaruhi database sebelum kita memanggil method commit(). ResultSet result = st. Update Statement. Kita dapat menghasilkan objek ResultSet dengan memanggil method Statement. Statement SQL dimasukkan dalam objek Statement ketika kita memanggil method Statement. Nilai 0 akan didapat jika method executeUpdate tidak berjalan dengan sukses. yaitu Query Statement. UPDATE. Mereka adalah: createStatement() createStatement ( int resultSetType.

Kita bisa melakukannya dengan cara seperti pseudo-code di bawah ini: for ( int i = 1.Contoh: String query = “INSERT INTO mahasiswa ( nama ) VALUES ( ‘Galih’ )” int code = st. i++ ) { String nama = getUserInput(). umur ) VALUES( '" + nama + "'. meskipun di variabel yang sama. '" + umur + "' )". Ini membebaskan programmer dari tugas manajemen memori manual yang memusingkan. int hasil = st. PreparedStatement merupakan semacam template yang dapat kita gunakan berkali-kali. Referensi lama dari variabel String akan dikumpulkan oleh garbage collector1.executeUpdate( query ). thread JVM. i <= 10. Java memiliki cara yang lebih baik dengan menggunakan PreparedStatement. Prepared Statement Terkadang kita melakukan query berkali-kali dengan query yang sama dengan parameter yang berbeda. setXXX tergantung tipe apa yang dimasukkan. Template ditandai dengan karakter ‘?’ yang diisi dengan method setXXX. ataupun setDouble. Contoh: 1 Garbage Collector merupakan thread berprioritas rendah yang bertugas me-reclaim memori yang tidak digunakan. 100 Secangkir Kopi Java . Misalkan kita ingin memasukkan 10 data baru ke dalam sebuah tabel. Oleh karena itu metode ini kurang efektif. } Dapat kau lihat bahwa kita membuat objek String query sebanyak 10 kali. String query = "INSERT INTO user( nama. setInt. Objek String tidak dapat diperbarui. bisa setString. //bisa dari text field String umur = getUserInput(). Garbage Collector juga menyebabkan Java tidak memerlukan sebuah destructor.executeUpdate ( query ).

commit(). noPaper ).rollback(). } con2. PreparedStatement st4 = con2. String. "2" ). st4. int rowCount = rsReviewer. ?. rsReviewer. noReviewer ). if ( rowCount >= 1 ) { do { String noReviewer = rsReviewer. ResultSet Hasil query dari method Statement. st4.next() ).executeQuery ( String query ) menghasilkan objek ResultSet.setString( 3. int result2 = st4.getRow(). kd_kode.prepareStatement( query4 ). Kita mendapatkan nilai dari suatu baris dan kolom dengan menggunakan method getXXX ( int noKolom ) atau getXXX ( String namaKolom ). prsnl_no )" + " VALUES ( ?. ResultSet adalah representasi dari tabel yang dapat kita gunakan untuk bernavigasi antar baris di tabel. rsReviewer.getString( "prsnl_no" ). Java Database Connectivity [ JDBC ] 101 . } } while ( rsReviewer.last(). Object. return false.setString( 2. ? )". Potongan program di atas memasukkan data berkali-kali sepanjang objek ResultSet rsReviewer dengan template PreparedStatement. st4. XXX merupakan tipe data sepeti Int.first().executeUpdate().setString( 1.String query = "INSERT INTO paper_reviewer ( paper_no. dan semacamnya. if ( result2 == 0 ) { con2.

dan TYPE_SCROLL_SENSITIVE. Biasanya. Perubahan yang terjadi pada database tidak direfleksikan ke result set. yaitu TYPE_FORWARD_ONLY. kamu harus mengetahui bahwa database yang bersangkutan harus mendukung result set updatable. jika tidak. TYPE_FORWARD_ONLY TYPE_SCROLL_INSENSITIVE TYPE_SCROLL_SENSITIVE Interface ResultSet juga memiliki tipe updating yaitu CONCUR_READ_ONLY dan CONCUR_UPDATABLE. Merupakan tipe default dari method Connection. Method ResultSet yang dapat dipanggil hanyalah next(). program akan terlempar ke kondisi eksepsi. TYPE_SCROLL_INSENSITIVE. dan perubahan pada database direfleksikan pada result set. ResultSet dapat meng-update CONCUR_UPDATABLE database. Untuk memakai updatable. Ada beberapa macam tipe scrolling. Kursor dapat bergerak maju mundur. Type Scrolling Kursor ResultSet Type Penjelasan Kursor hanya dapat bergerak maju.ResultSet memiliki kursor pada baris tabel hasil query yang dapat digerakkan. mblejog ke depan atau belakang. Kursor dapat bergerak maju mundur.createStatement(). aku memakai yang read only. Type Konkurensi ResultSet Type Penjelasan ResultSet tidak dapat meng-update CONCUR_READ_ONLY database meskipun dengan pemanggilan method update(). 102 Secangkir Kopi Java . Kamu harus melakukan query lagi untuk melihat perubahan yang terjadi.

percuma aku ngomong JDBC sampai berbusa-busa kalau kamu cuma bengong baca ini. teori dasar-dasar JDBC sudah kita bahas tuntas. 103 Java Database Connectivity [ JDBC ] . absolute(pos) : Menempatkan kursor pada baris ke-pos.supportsResultSetConcurrency() mereturn nilai boolean.getMetaData(). : Menempatkan kursor pada posisi terakhir. Sekarang mari kita membuat sebuah user interface untuk melakukan query sederhana ke database. Menempatkan posisi kursor pada sebelum baris pertama. first() last() afterLast() : Menempatkan kursor pada baris pertama. next() previous() : Menempatkan kursor satu baris ke bawah / depan. Tapi apalah arti teori tanpa praktik? Seperti halnya kamu. : Menempatkan kursor satu baris ke atas / belakang.Kamu dapat mengetahui apakah database mendukung result set updatable atau tidak dengan memanggil method yang Connection. Berikut method untuk navigasi kursor ResultSet: beforeFirst() : Posisi default. relative(1) menggerakkan kursor satu baris ke depan. relative(pos) : Menempatkan kursor pada baris ke-pos relatif dari posisi kursor sekarang. absolute(1) merupakan baris pertama dan absolute(-1) merupakan baris terakhir. Secara default. tidak mau menggerakkan jarimu yang malas itu di atas keyboard. Pemanggilan method next() akan membuat kursor terletak pada baris pertama. Oce. oleh karena itu set dulu ODBC-mu sebelum menulis program berikut. Aku tetap akan menggunakan ODBC. : Menempatkan kursor pada sebelum baris terakhir. kursor diletakkan pada sebelum baris pertama tabel. Navigasi ResultSet ResultSet yang dapat bergerak ke sana ke mari dapat kita gerakkan dengan perintah sederhana.

private Statement statement. private int numberOfRows.package galih.*. public ResultSet resultSet.CONCUR_READ_ONLY ).getColumnClassName( column + 1 ). String query ) throws SQLException.forName( driver ).util. //dapatkan koneksi ke database con = DriverManager. //konstruktor public ResultSetTableModel( String driver. ☺ 104 Secangkir Kopi Java . ClassNotFoundException { //driver database Class. //buat statement statement = con.table. import javax. String url.2 – ResultSetTableModel merupakan model dari JTable yang digunakan untuk merepresentasikan objek ResultSet menjadi sesuatu yang nyata. private ResultSetMetaData metaData.swing.createStatement( ResultSet. Listing 3. //execute query setQuery( query ). //PENTING!! Index ResultSet dimulai dari 1 dan JTable mulai //dari 0 public class ResultSetTableModel extends AbstractTableModel { private Connection con. ResultSet.TYPE_SCROLL_INSENSITIVE.*. } //get column class public Class getColoumnClass( int column ) { try { String className = metaData.sql. import java. import java.getConnection( url ).jdbc.*.

toLowerCase(). } return 0.return Class.indexOf( "_" ) ). } //get jumlah kolom public int getColumnCount() { try { return metaData.getColumnName( column + 1 ). } catch ( SQLException e ) { e.printStackTrace().printStackTrace(). result set 1 String fullName = metaData.printStackTrace(). } //get jumlah baris public int getRowCount() { return numberOfRows.substring( fullName.class. } catch ( SQLException e ) { e.2 – ResultSetTableModel merupakan model dari JTable yang digunakan untuk merepresentasikan objek ResultSet menjadi sesuatu yang nyata. } return Object. return fullName.getColumnCount().forName( className ). } catch ( Exception e ) { e. } Listing 3. ☺ Java Database Connectivity [ JDBC ] 105 . } //get nama kolom public String getColumnName( int column ) { try { //jtable mulai 0. } return "".

getMetaData(). } catch (SQLException e) { e. ☺ Kita akan menggunakan ilmu yang telah kita dapat di bab 2 untuk kita gunakan di “dunia nyata”. } //execute query public void setQuery( String query ) throws SQLException { resultSet = statement.printStackTrace().public Object getValueAt( int row. } return "".2 – ResultSetTableModel merupakan model dari JTable yang digunakan untuk merepresentasikan objek ResultSet menjadi sesuatu yang nyata. numberOfRows = resultSet.close(). //number of rows resultSet. int column ) { try { //gerakkan kursor resultSet.printStackTrace(). metaData = resultSet. } //finalizing protected void finalize() { try { statement.last(). Data yang kita ambil dari database 106 Secangkir Kopi Java . } catch ( SQLException e ) { e. con. return resultSet.getRow().getObject( column + 1 ).close().executeQuery( query ). fireTableStructureChanged().absolute( row + 1 ). } } } Listing 3.

ResultSet tidak memiliki cara langsung untuk mendapatkan jumlah baris. Konstruktor pada Listing 3. JTable mendapatkan jumlah baris melalui method getColumnCount(). membuat koneksi. diasumsikan bahwa class tersebut adalah class dari Object. Setelah itu kita perlu memanggil fireTableStructureChanged() untuk memberitahu JTable bahwa data model telah berubah total sehingga JTable menyesuaikan view-nya. dan membuat statement.2 akan melakukan inisialisasi awal dengan menentukan driver. Method setQuery ( String query ) akan melakukan query dengan memanggil method Statement.executeQuery ( String query ). kemudian memanggil method setQuery ( String query ) untuk melakukan query default. kita gerakkan kursor satu ke bawah dari row.getColumnCount(). Hal sama pada method getColumnName ( int column ). Jika gagal mengidentifikasi class dari suatu kolom. Harus ditambah 1 karena terjadi perbedaan permulaan index dari ResultSet dan JTable. Pada method getValueAt ( int row. Method getColumnClass ( int column ) mendapatkan class dari kolom yang ada di ResultSet. Di sini kita mengembalikan jumlah baris yang dimiliki ResultSet dengan mereturn ResultSetMetaData. Di sini kita juga menggunakan meta data untuk mendapatkan nama kolom dari kolom tertentu. kemudian kita returnkan Object pada column + 1. int column ). Java Database Connectivity [ JDBC ] 107 . Kemudian kita dapatkan atribut dari hasil query dengan memanggil method ResultSet.getMetaData() yang mereturn objek ResultSetMetaData. dan JTable mulai dari 0. maka kita akali dengan menempatkan kursor di last() dan mendapatkan nomor barisnya dengan method getRow().kita masukkan pada sebuah table model yang nantinya digunakan JTable sebagai modelnya. Yang perlu diperhatikan betul bahwa index dari ResultSet mulai dari 1.

*. 108 Secangkir Kopi Java . import java. import javax.jdbc.awt. //default query String query = "SELECT * FROM mahasiswa".jdbc. public class QueryResult extends JFrame { //instans private ResultSetTableModel tableModel.event.sql. import java.*. private JTable table.*.awt. import java. setEventHandler(). private JButton btnSubmit.odbc. System.printStackTrace(). Listing 3.exit( 1 ).*.swing. //konstruktor public QueryResult() { super( "Query ke Database" ). } catch ( Exception e ) { e.JdbcOdbcDriver". //url String url = "jdbc:odbc:Akademik". private JTextArea queryArea.3 – QueryResult menampilkan hasil query yang kita masukkan pada text area dalam sebuah tabel. try { initialize(). //tampilkan ke tabel tableModel = new ResultSetTableModel( driver. } } private void initialize() throws Exception { //driver String driver = "sun. url.package galih. query ).

3. box.createHorizontalBox().add( new JScrollPane( queryArea ) ). queryArea.setQuery( queryArea.NORTH ).add( box.toString(). BorderLayout.add( btnSubmit ). Java Database Connectivity [ JDBC ] 109 .CENTER ). //pasang pada container Box box = Box. //query area queryArea = new JTextArea( query.setDefaultButton( btnSubmit ). cp. setDefaultCloseOperation( EXIT_ON_CLOSE ). } catch ( SQLException ex ) { String exception = ex. setSize( 500. //button btnSubmit = new JButton( "Submit" ).setLineWrap( true ).addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { //new query try { tableModel. queryArea. 100 ). btnSubmit. Listing 3. cp.add( new JScrollPane( table ).getText() ). getRootPane(). 400 ).table = new JTable( tableModel ).setMnemonic( 'S' ).3 – QueryResult menampilkan hasil query yang kita masukkan pada text area dalam sebuah tabel.setWrapStyleWord( true ). box. } private void setEventHandler() { btnSubmit. BorderLayout. Container cp = getContentPane(). setVisible( true ).

setQuery ( String query ) untuk dieksekusi. Gambar 3.this. Method initialize() akan melakukan inisialisasi awal dari driver. dan query default yang dikirimkan ke ResultSetTableModel untuk diproses menjadi sebuah table model. exception.3 – QueryResult menampilkan hasil query yang kita masukkan pada text area dalam sebuah tabel. gitu thok. yaitu mengambil String yang ada pada queryArea dan mengirimkannya ke method ResultSetTableModel. url database. } } Listing 3. Oce.replaceAll( " ". "\n") ). } //pablik setatik void ma-in public static void main( String[] args ) { new QueryResult(). } } }). class pada listing 3. Dari table model tersebut kita bangun JTree.JOptionPane.2 – Hasil query yang ditampilkan pada JTable dengan menggunakan ResultSetTableModel 110 Secangkir Kopi Java . Yang dilakukan di sini cukup sederhana.3 adalah class yang menampilkan hasil query yang kita masukkan pada text area. Udah. Method setEventHandler() akan melakukan pemasangan event pada button Submit ketika di-klik.showMessageDialog( QueryResult.

studi kasus jdbc – address book .

.

1 – Relasi antar entitas pada database address book.Kali ini kita akan mengimplementasikan semua teori-teori tentang JDBC ke dalam sebuah aplikasi buku alamat. i. Aku akan memulainya dari mendesain database. Database Design Untuk database besar hingga lebih dari 10 tabel dengan relasi yang rumit. Di sini aku akan menggunakan database MySQL dan driver yang kugunakan bukan JDBC-ODBC-Bridge lagi tetapi Native API. Gambar 4. saat menikmatinya. instalasi database. Buku alamat sangat tepat untuk dijadikan studi kasus karena tidak terlalu rumit dan dapat mencangkup semua teori dasar JDBC. aku tidak membahas itu. Relasi yang digambarkan dengan cara di atas disebut Relasi Cakar Ayam. Studi Kasus JDBC – Adress Book 113 . pembuatan tabel dengan DDL. hingga penulisan program dan terakhir. biasanya aku memakai Sybase Power Designer 9 untuk mendesainnya. Tetapi sekali lagi karena ini bukan buku tentang database.

Jalankan server dengan mengetik di command prompt: F:\mysql\bin> mysqld-max-nt Atau kamu bisa menjalankan winmysqladmin. sehingga setiap kompie dijalankan. DBMS ini dapat kamu dapatkan secara gruatis tanpa harus mbajak di http://mysql. Kemudian. Setelah server berjalan. server MySQL otomatis akan jalan sendiri. 1 row affected (0. kita bisa memakai perintah: mysql> show databases. or ‘\h’ for help. Your MySQL connection id is 2 to server version: 3. Setelah mendapatkan paket installernya.exe agar menjadi service.com. jalankan setup. jalankan client dengan perintah: F:\mysql\bin> mysql Jika sukses.exe dan ikuti petunjuk yang muncul. or \g.53max-nt Type ‘help. Type ‘\c’ to clear the mysql> _ Kita akan membuat database buku_alamat dengan perintah: mysql> create database buku_alamat.23. di kompieku keluar seperti ini: 114 Secangkir Kopi Java .’ buffer. Instalasi Database dan Pembuatan Database Aku memakai database MySQL ver.ii. Commands end with .06 sec) Untuk melihat apakah database itu benar-benar ada.23. buka command prompt dan pindah direktori ke [my_sql_home]/bin. setelah instalasi selesai. Query OK. 3.53 for Windows NT. kamu akan disambut dengan kata-kata seperti F:\mysql\bin> mysql Welcome to the MySQL monitor. Di kompieku terletak di F:\mysql\bin.

mysql> show databases. null. null. not null. maka kita tulis: mysql> use buku_alamat. kita harus memilih dulu database mana yang akan kita gunakan. null. not null. mari kita buat satu per satu: Tabel Alamat: create table if not exists ALAMAT ( ALAMAT_ID int JALAN varchar(50). Tabel Orang: create table if not exists ORANG ( ORANG_ID int NAMA varchar(30) FOTO longblob. not null. primary key (ORANG_ID) ). Karena kita akan menggunakan database buku_alamat. primary key (ALAMAT_ID) ). not not not not not null. +-------------------------+ | Database | +-------------------------+ | buku_alamat | | fatso | | galihsatria_uk_db | | mysql | | test | +-------------------------+ 5 rows in set (0.01 sec) mysql> _ Sebelum kita membuat tabel dengan DDL. Studi Kasus JDBC – Adress Book 115 . DESA varchar(50) KECAMATAN varchar(50) KABUPATEN varchar(50) PROVINSI varchar(50) NEGARA varchar(40) KODEPOS varchar(10). Oce. null. Database changed mysql> _ Sekarang kita siap membuat tabel.

Tabel Telp: create table if not exists TELP ( ORANG_ID int not null.Tabel Orang_Alamat ( Tabel perantara relasi many-to-many ): create table if not exists ORANG_ALAMAT ( ORANG_ID int not null. EMAIL_ID) ). EMAIL_ID int not null. Index Constraint pada tabel Orang_Alamat dengan Orang untuk “Alamat Dimiliki Orang”: create index DIMILIKI_FK on ORANG_ALAMAT ( ORANG_ID ). Tabel Email: create table if not exists EMAIL ( ORANG_ID int not null. primary key (ORANG_ID. Index Constraint pada tabel Orang dengan Telp: create index ORANG_TELP_FK on TELP ( ORANG_ID 116 Secangkir Kopi Java . primary key (ORANG_ID. primary key (ORANG_ID. TELP_ID int not null. ALAMAT_ID int not null. RUMAH varchar(15). EMAIL_ADDRESS varchar(50). TELP_ID) ). Index Constraint pada tabel Orang_Alamat dengan Orang untuk “Orang Memiliki Alamat”: create index MEMILIKI_FK on ORANG_ALAMAT ( ALAMAT_ID ). ALAMAT_ID) ). MOBILE varchar(20).

mudah bagi kita untuk membaca ataupun mendebugnya ( tapi jujur. Index Constraint pada tabel Orang dengan Email: create index ORANG_EMAIL_FK on EMAIL ( ORANG_ID ). atau koneksi ke database. +----------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+---------+-------+ | ORANG_ID | int(11) | | PRI | 0 | | | NAMA | varchar(30) | | | | | | FOTO | longblob | YES | | NULL | | +----------+-------------+------+-----+---------+-------+ 3 rows in set (0. Studi Kasus JDBC – Adress Book 117 .12 sec) mysql> _ Sayang sekali MySQL versi 3 belum mendukung foreign key constraints.). Nah. Class AddressEntry Class ini adalah sebuah java bean yang bertugas mengenkapsulasi entri data tiap record. Java Bean sangat diperlukan di sini untuk memisahkan mana yang data. misalnya: mysql> describe orang. sekarang kita memulai hal yang menyenangkan: menulis kode programnya! iii. Dengan program yang terpisah secara jelas. Penulisan Kode Program dengan Java Program yang akan kita buat hanya dapat melakukan insert table dan select saja. jadi kita harus amat hati-hati dalam manajemen datanya. Aku sengaja tidak memasukkan fiture update dan searching agar programnya tidak terlalu panjang. Kamu bisa mencek masing-masing tabel dengan perintah DESCRIBE tabel. user interface. di Java aku sangat juaraaang melakukan debugging ).

public class AddressEntry { //instans public int orangID. public String nama = "". } Listing 4. } public Vector getJalan() { return jalan. } public Vector getEmail() { return email. kodepos = new Vector(). kec = new Vector(). } public String getFotoPath() { return fotoPath. } //getters public Vector getDesa() { return desa. public public public public public public public public public Vector Vector Vector Vector Vector Vector Vector Vector Vector jalan = new Vector(). } public Vector getKab() { return kab.util. telp = new Vector().orangID = id.//java-bean untuk entry address book package addressbook. //konstruktor public AddressEntry() { this( 0 ). import java. public String fotoPath = "". } public AddressEntry( int id ) { this. negara = new Vector(). } public Vector getKec() { return kec.*. prov = new Vector(). email = new Vector(). kab = new Vector().1 – Java Bean yang merepresentasikan entri data. desa = new Vector(). 118 Secangkir Kopi Java .

} public void addDesa( Object newDesa ) { desa. } //setters public void setFotoPath( String fotoPath ) { this.add( newDesa ). Studi Kasus JDBC – Adress Book 119 . } Listing 4.orangID = orangID.add( newKecamatan ).add( newJalan ). } //add ke vector public void addJalan( Object newJalan ) { jalan. } public Vector getTelp() { return telp. } public void setNama( String nama ) { this. } public Vector getNegara() { return negara.fotoPath = fotoPath.nama = nama.public Vector getKodepos() { return kodepos. } public void addKab( Object newKab ) { kab.1 – Java Bean yang merepresentasikan entri data. } public String getNama() { return nama.add( newKab ). } public void addKec( Object newKecamatan ) { kec. } public int getOrangID() { return orangID. } public void setOrangID( int orangID ) { this. } public Vector getProv() { return prov.

negara.add( newProv ). Bean di atas memiliki instance yang kita perlukan untuk mengolah data. Method addXXX ( Object data ) digunakan sebagai setter yang memiliki multiple value seperti alamat ( jalan. kab. misalnya antara koneksi database dengan user interface.add( newTelp ). Maka dari itu ia memiliki getter untuk mengambil nilai dari suatu instance. } public void addKodepos( Object newKodepos ) { kodepos. } public void addTelp( Object newTelp ) { telp. kec.clear(). dia hanya sebagai perantara.add( newKodepos ).add( newEmail ). add fungsinya sama dengan setter. desa. prov. email. Java Bean tidak melakukan apa-apa.clear(). ).clear().1 – Java Bean yang merepresentasikan entri data. telp.clear().clear(). dan telp yang setiap satu orang bisa memiliki lebih dari satu. email. kita nanti akan menyimpannya dalam bentuk byte ( long blob ). } //clear element's object public void clearAll() { jalan.public void addProv( Object newProv ) { prov.add( newNegara ). setter untuk men-set nilai ke suatu instance. Untuk foto.clear(). } public void addNegara( Object newNegara ) { negara.clear(). } public void addEmail( Object newEmail ) { email. kodepos.clear(). Tidak praktis bila kita membawa-bawa byte itu dalam bean. } } Listing 4. 120 Secangkir Kopi Java .clear(). desa. dll. dan method clearAll() yang membersihkan nilai dari suatu instance menjadi kosong untuk diisi nilai baru.

public int prev() throws SQLException. String table ). Interface DataAccess Interface DataAccess kita perlukan untuk melakukan akses ke database. //navigasi result set public void first() throws SQLException. kita konversikan path tsb. //insert into database public int saveToDatabase( AddressEntry entry ) throws SQLException.sql.*.maka yang kita simpan adalah pathnya. public int next() throws SQLException. //initializing result set untuk view public void initView(). Foto di dalam bean harus sudah dalam bentuk byte. Ketika telah “tiba” pada objek yang memerlukan byte-nya. Lain lagi ceritanya kalau object antara user interface dengan object koneksi database berada pada mesin yang berbeda. Interface ini mendefinisikan method-method apa saja yang kita perlukan dalam mengakses database. public interface DataAccess { //trigger public int getLastID( String column. import java.2 – Interface DataAccess mendefinisikan method untuk mengakses database Studi Kasus JDBC – Adress Book 121 . Listing 4. ke bentuk bytenya. Method yang didefinisikan di sini tidak tergantung kepada database yang digunakan. Adanya interface ini membuat struktur program lebih jelas lagi. package addressbook. //close connection public void close().

awt. Sayang sekali. //fetch data public AddressEntry fetchData() throws SQLException.public void last() throws SQLException.awt. Method ini juga merupakan desain yang kurang baik karena tergantung kondisi database yang seharusnya tidak terjadi dalam interface DataAccess. next. Untuk navigasi antar kontak/record memakai method first.2 – Interface DataAccess mendefinisikan method untuk mengakses database Method getLastID merupakan trigger untuk mendapatkan auto_number. bean pada listing 4. Di sini aku tidak memakai tipe data AUTO_INCREMENT karena sulit mengatur constraint-nya. method initView menginisialisasi hal yang diperlukan untuk melihat isi database. sedangkan format Bitmap ( bmp ) tidak didukung. GIF. dan PNG. Sedangkan untuk mengambil keseluruhan data dari database memakai method fetchData() yang mereturn objek AddressEntry. dan last. prev.Image untuk ditampilkan dalam user interface. Method-method di luar method yang didefinisikan oleh DataAccess merupakan method yang dibutuhkan secara internal oleh class MySQLAccess.1. 122 Secangkir Kopi Java . } Listing 4.Image getImage(). //foto public java. Method close menutup koneksi dengan database. Method saveToDatabase menyimpan semua entry data ke dalam tabel-tabel sesuai dengan struktur database dan constraint-nya. Method getFoto mengambil foto dalam bentuk objek java. Class MySQLAccess Class ini merupakan implementasi dari interface DataAccess untuk mengakses database MySQL. ketika kupakai objek ini hanya bisa menerima gambar berformat JPG.

?.3 – Class MySQLAccess mengimplementasikan interface DataAccess untuk koneksi ke database dan melakukan interaksi dengan database.?. Studi Kasus JDBC – Adress Book 123 .*. public class MySQLAccess implements DataAccess { //instance private Connection con. //siapkan sql sqlInsertOrang = con.?)" ). provinsi. telp_id.?.prepareStatement( "INSERT INTO email (orang_id. sqlInsertTelp = con. kabupaten. private PreparedStatement sqlInsertOrang.orang_id = " + "orang_alamat. import java. private PreparedStatement sqlInsertTelp.prepareStatement( "INSERT INTO telp (orang_id.*.orang_id "+ "AND orang_alamat. sqlInsertOrangAlamat = con. kodepos " + "FROM orang. sqlInsertEmail = con.?. foto) VALUES (?. private PreparedStatement sqlInsertOrangAlamat.*. nama. negara.awt.prepareStatement( "SELECT jalan.io. private PreparedStatement sqlSelectEmail. kabupaten. private PreparedStatement sqlInsertAlamat." + "kecamatan. private PreparedStatement sqlSelectAlamat.?)" ).sql. private PreparedStatement sqlSelectTelp.?.package addressbook.rumah) " + "VALUES (?. orang_alamat. import java.?.?)" ). import java.alamat_id " + "AND orang. //konstruktor public MySQLAccess() throws Exception { connect().alamat_id = " + "alamat.alamat_id) VALUES (?. //prepare select statement sqlSelectAlamat = con. " + "provinsi. desa.?.email_id.?)" ). alamat " + "WHERE orang. desa.?.?. Listing 4.prepareStatement( "INSERT INTO orang_alamat (orang_id. private PreparedStatement sqlInsertEmail. " + "kodepos) VALUES (?. jalan.prepareStatement( "INSERT INTO alamat (alamat_id.?)" ). private ResultSet rsOrang. " + "email_address) VALUES (?. negara. sqlInsertAlamat = con.orang_id = ? " ). kecamatan.prepareStatement( "INSERT INTO orang (orang_id.

setAutoCommit( false ). ResultSet rsID = st. con = DriverManager. } //akhir konstruktor //connect private void connect() { String driver = "com. con. } catch ( Exception e ) { e.0.3 – Class MySQLAccess mengimplementasikan interface DataAccess untuk koneksi ke database dan melakukan interaksi dengan database. try { Class.//imel sqlSelectEmail = con. } return lastID. } //dapatkan byte dari foto untuk disimpan //sebagai tipe BLOB private FileInputStream getFileStream( File file ) { FileInputStream fileStream = null. String table ) { int lastID = 0.getInt( 1 ).prepareStatement( "SELECT email_address FROM orang. if ( rsID.orang_id AND " + "orang.1/buku_alamat".printStackTrace(). } } //generate auto number public int getLastID( String column. //telp sqlSelectTelp = con.email " + "WHERE orang. String url = "jdbc:mysql://127.prepareStatement( "SELECT rumah FROM orang.printStackTrace().orang_id = telp.Driver". } Listing 4.mysql. } catch ( SQLException e ) { e.orang_id = email. try { String query = "SELECT MAX(" + column + ") FROM " + table. } catch ( IOException e ) { return null.forName( driver ).orang_id AND " + "orang.executeQuery( query ).jdbc. Statement st = con.getConnection( url ).telp " + "WHERE orang.orang_id = ? " ).createStatement().orang_id = ? " ). try { fileStream = new FileInputStream( file ). 124 Secangkir Kopi Java .0.next() ) lastID = rsID.

setBinaryStream( 3. entry. int result = sqlInsertOrang. ( String ) entry.3 – Class MySQLAccess mengimplementasikan interface DataAccess untuk koneksi ke database dan melakukan interaksi dengan database.length() ). } //save to database public int saveToDatabase( AddressEntry entry ) throws SQLException { sqlInsertOrang.executeUpdate().setString( 4.get( i ) ). sqlInsertAlamat. return -1.get( i ) ). i++ ) { sqlInsertAlamat.setString( 6.kec.get( i ) ). ++alamatLastID ). for ( int i = 0.getNama() ).. sqlInsertAlamat. sqlInsertAlamat. ( String ) entry.get( i ) ).jalan. //konversi foto ke byte.setString( 3. ( String ) entry.rollback(). Studi Kasus JDBC – Adress Book 125 . ( int ) file.setString( 2. "alamat" ). sqlInsertAlamat.executeUpdate().prov.setInt( 1. sqlInsertAlamat.setString( 5. entry.setString( 8. } //alamat.get( i ) ). File file = new File( entry.getFotoPath() )..kab.kodepos. ( String ) entry. sqlInsertOrang. ( String ) entry.size().get( i ) ). if ( result == 0 ) { con. dari variabel vector int alamatLastID = getLastID( "alamat_id". } Listing 4.setInt( 1. return -1. result = sqlInsertAlamat. i < entry.negara.getOrangID() ). sqlInsertOrang. fis.desa. ( String ) entry. sqlInsertAlamat. sqlInsertAlamat.get( i ) ). FileInputStream fis = getFileStream( file ).jalan.setString( 2.return fileStream. ( String ) entry.setString( 7.rollback(). if ( result == 0 ) { con.

return -1.getOrangID() ). return 0.setInt( 1.rollback(). ( String ) entry.size(). i++ ) { sqlInsertEmail.setInt( 1.setInt( 2. i++ ) { sqlInsertTelp.//trigger->nyambung antara orang dan alamat pada //tabel orang_alamat sqlInsertOrangAlamat. "telp" ). sqlInsertTelp. } } //telpun int telpLastID = getLastID( "telp_id".setInt( 2. entry.clearAll().executeUpdate().size(). } } //masukkan email int emailLastID = getLastID( "email_id". sqlInsertEmail. return -1. entry.setString( 3. sqlInsertEmail. entry.setInt( 2. } } con.get( i ) ).email. if ( result == 0 ) { con.getOrangID() ).executeUpdate(). 126 Secangkir Kopi Java . result = sqlInsertOrangAlamat. i < entry. if ( result == 0 ) { con. //clear vector pada entry entry. for ( int i = 0.setInt( 1.telp. ( String ) entry.setString( 3. i < entry. sqlInsertOrangAlamat. sqlInsertTelp.3 – Class MySQLAccess mengimplementasikan interface DataAccess untuk koneksi ke database dan melakukan interaksi dengan database. result = sqlInsertTelp. return -1. "email" ). ++emailLastID ). for ( int i = 0.rollback().executeUpdate(). //sukses } //akhir saveToDatabase Listing 4. if ( result == 0 ) { con.getOrangID() ).commit().email.rollback(). ++telpLastID ).get( i ) ). result = sqlInsertEmail.telp. alamatLastID ).

isFirst() ) { rsOrang.3 – Class MySQLAccess mengimplementasikan interface DataAccess untuk koneksi ke database dan melakukan interaksi dengan database. } } //next public int next() throws SQLException { if ( !rsOrang.previous(). return 0. } catch ( SQLException e ) { e.getInt( 1 ). return 0.CONCUR_READ_ONLY ).orangID = rsOrang. if ( rsOrang. } //last record public void last() throws SQLException { rsOrang. 127 Studi Kasus JDBC – Adress Book .isLast() ) return -1. } return -1. //nama entry. ResultSet. if ( rsOrang.isFirst() ) return -1.//init result set public void initView() { try { String query = "SELECT * FROM orang".printStackTrace(). } //previous public int prev() throws SQLException { if ( !rsOrang.next(). } //first public void first() throws SQLException { rsOrang. } //select untuk view public AddressEntry fetchData() throws SQLException { AddressEntry entry = new AddressEntry().isLast() ) { rsOrang. } return -1.executeQuery( query ).createStatement( ResultSet. rsOrang = st.getString( 2 ).nama = rsOrang. Listing 4.TYPE_SCROLL_INSENSITIVE.last().first(). entry. Statement st = con.

next() ) { entry.getString( 7 ) ). createImage( imageBytes ). while ( rsAlamat. ResultSet rsAlamat = sqlSelectAlamat.//alamat sqlSelectAlamat.setInt( 1. sqlSelectEmail.getInt( 1 ) ).getString( 5 ) ). } return Toolkit.getString( 6 ) ).3 – Class MySQLAccess mengimplementasikan interface DataAccess untuk koneksi ke database dan melakukan interaksi dengan database.executeQuery(). entry.addKab( rsAlamat. sqlInsertTelp. entry.getString( 3 ) ).addEmail( rsEmail. entry. rsOrang. while ( rsEmail. while ( rsTelp. ResultSet rsEmail = sqlSelectEmail.getString( 2 ) ). } //email sqlSelectEmail. sqlInsertEmail. Listing 4. } //close connection public void close() { try { sqlInsertAlamat. sqlInsertOrangAlamat. entry.addProv( rsAlamat.close().next() ) { entry.addKodepos( rsAlamat.addNegara( rsAlamat.executeQuery().getInt( 1 ) ). rsOrang. if ( imageBytes == null ) return null.addDesa( rsAlamat. } return entry. 128 Secangkir Kopi Java .close().setInt( 1. rsOrang. entry.addJalan( rsAlamat.getString( 1 ) ).addKec( rsAlamat.getString( 4 ) ). try { imageBytes = rsOrang. ResultSet rsTelp = sqlSelectTelp.close(). } catch ( SQLException e ) { return null.close().setInt( 1.next() ) { entry.close(). entry.getBytes( 3 ). sqlSelectAlamat.close().getString( 1 ) ).getString( 1 ) ).addTelp( rsTelp. } //akhir method fetchData //mengambil foto public Image getImage() { byte[] imageBytes = null. sqlInsertOrang.getDefaultToolkit().close().getInt( 1 ) ).executeQuery(). } //telp sqlSelectTelp.

fungsi agregate milik SQL. kalau kamu enggak begitu suka ama Java.sqlSelectTelp. Method getFileStream ( File file ) digunakan secara internal untuk melakukan streaming dari file untuk dimasukkan ke database dalam bentuk byte.. begitu lihat Listing 4.wah…aku yakin. Method saveToDatabase menyimpan semua entry yang dikapsulasi dalam objek AddressEntry ke dalam database sesuai dengan letak tabelnya masing-masing.getConnection() dan men-set koneksi harus disubmit secara manual dengan setAutoCommit ( false ).close(). Isinya sangat sederhana. letak database dan mendapatkan objek Connection dengan memanggil DriverManager. Method getLastID digunakan untuk mendapatkan ID terakhir dari suatu tabel. Isi dari method connect() adalah melakukan penentuan driver.3. Method ini mereturn objek FileInputStream. Atau bahkan kamu nggak akan pernah baca ini karena buku ini sudah dibuang sejak kamu baca halaman pertama! ☺☺☺ Konstruktor MySQLAccess melakukan inisialisasi dengan melakukan koneksi ke database ( connect() ) dan menyiapkan statement SQL dengan Connection. } catch ( SQLException e ) { e. kamu langsung membuang buku ini. yaitu menjalankan perintah MAX ( column ).wah.3 – Class MySQLAccess mengimplementasikan interface DataAccess untuk koneksi ke database dan melakukan interaksi dengan database.prepareStatement ( String query ).printStackTrace(). Misalnya nama orang dimasukkan ke tabel Studi Kasus JDBC – Adress Book 129 . Wah. } } //untuk garbage collector protected void finalize() { close(). con.. yang nantinya ditambah 1 untuk membuat suatu auto_number.close(). } } Listing 4.

email. Media penyimpanan foto ini adalah LONGBLOB – tipe data yang digunakan untuk menyimpan data yang besar seperti foto. Method berikutnya adalah fetchData2 yang bertugas mengambil data dari database dan dimasukkan ke objek AddressEntry. desain database belumlah sempurna mencapai kaidah BCNF karena aku tidak membahas soal database. koneksi yang lupa ditutup secara eksplisit oleh programmer. Adapun untuk mengambil foto dari database. Method finalize() digunakan untuk menutup koneksi yang garbage collected. dan telp. User Interface I: Class InsertForm Class ini menampilkan sebuah user interface untuk memasukkan nama baru ke dalam database. Harus kuakui bahwa UI ini tidak cukup user friendly. Method-method ini menggerakkan ResultSet. first(). Di sini kita mengambil dari tabel orang terlebih dahulu. tapi cukuplah. artinya data yang diambil dalam bentuk array bytes. Tabel Orang_Alamat merupakan tabel penyambung antara orang dan alamat karena hubungan antara dua entitas itu adalah many-to-many. Kita ambil data dari database dengan getBytes. Semua koneksi ditutup dengan method close(). Sekali lagi. Kita menset parameter dari objek PreparedStatement dengan nilai yang kita ambil dari AddressEntry. Kemudian untuk navigasi antar record ada method next(). 2 130 Secangkir Kopi Java . dan prev().createImage ( bytes[] imagebytes ). Method first() dan last() mereturn sebuah integer untuk mendeteksi apakah record telah mencapai ujung atau belum. caranya tak kalah sederhana. Kenapa aku memakai nama fetchData? Istilah untuk mengambil data dari database bukanlah get tetapi fetch.getDefaultToolkit(). sehingga ditemukan oleh si garbage collector. dan dengan id dari orang tersebut. satu per satu kita mengambil data dari tabel alamat.orang. sedangkan 2 method lainnya adalah void. Dari situ kita returnkan sebuah objek Image dengan Toolkit. last().getXXX().

java.swing. java. private JTextField txtDesa = new JTextField( 30 ).awt. Listing 4. yaitu GridBagLayout.border. import import import import import import import java.*. itung-itung belajar. private JTextField txtJalan = new JTextField( 30 ). email. private JTextField txtKab = new JTextField( 30 ). he.2 – User Interface untuk memasukkan nama baru. javax. atau telepon yang lebih dari satu. Aku belajar layout ini juga ketika menulis ini lho. private JTextField txtProv = new JTextField( 30 ).awt.event.*. private JTextField txtKec = new JTextField( 30 ).4 – InsertForm untuk menambah nama baru ke dalam buku alamat Studi Kasus JDBC – Adress Book 131 .*.sql.swing..*. aku perlu memperkenalkan layout manager yang sangat dinamis namun sulit dipelajari.Gambar 4. private JTextField txtNegara = new JTextField( 30 ).*.he… package addressbook.filechooser.. javax. Untuk memasukkan data alamat.he. Data baru akan dimasukkan ke database ketika kita menekan tombol OK. kamu harus menekan tombol Add.*. java.swing.*. javax.io. public class InsertForm extends JDialog { //instans private JTextField txtNama = new JTextField( 30 ). Sebagai penataan komponen.

private JLabel lblStatus3 = new JLabel( " 0 no. //initialize try { dataAccess = new MySQLAccess(). public AddressEntry person. private JButton btnCancel = new JButton( "Cancel" ). private JPanel panel. private JLabel lblStatus4 = new JLabel( " [kosong] " ). private JButton btnAddAlamat = new JButton( "Add" ). tersimpan" ). "orang" ).4 – InsertForm untuk menambah nama baru ke dalam buku alamat 132 Secangkir Kopi Java . //apakah button-button add telah dipijet private boolean alamatAdded = false. } //akhir konstruktor Listing 4. private JTextField txtNo = new JTextField( 30 ). private JButton btnAddEmail = new JButton( "Add" ). setTitle( "Menambah Entry Baru" ). //counter private int countAlamat = 0. private GridBagConstraints c. private boolean telpAdded = false. private JButton btnBrowse = new JButton( "." ).printStackTrace(). parent. public JButton btnOK = new JButton( "OK" ). private JButton btnAddNo = new JButton( "Add No. private boolean emailAdded = false. } catch ( Exception e ) { e.parent = parent.. //properti untuk akses database public DataAccess dataAccess.setEnabled( false ).getLastID( "orang_id". private JTextField txtEmail = new JTextField( 30 ). private JLabel lblStatus2 = new JLabel( " 0 email tersimpan" ). setEventHandler(). //layout private GridBagLayout gridBag. //konstruktor public InsertForm( JFrame parent ) { this. private int countTelp = 0." ). private JLabel lblStatus1 = new JLabel( " 0 alamat tersimpan" ).private JTextField txtKode = new JTextField( 30 ). } int lastID = dataAccess. createGUI(). private JFrame parent. person = new AddressEntry( lastID + 1 ). private int countEmail = 0.

txtNegara.showMessageDialog( InsertForm.close().setText( "" ).private void setEventHandler() { btnCancel. emailAdded = true.setText( "" ). InsertForm. alamatAdded = true.setText( "" ). btnAddEmail.setText( "" ). } } ). txtKab. try { int result = dataAccess.this.4 – InsertForm untuk menambah nama baru ke dalam buku alamat Studi Kasus JDBC – Adress Book 133 . String message = "".addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { getEntry(). } } ). message ). btnOK.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { dataAccess. txtDesa. txtKec. message = ( result == 0 ) ? "Data tersimpan dengan sukses" : "Data tidak dapat tersimpan".saveToDatabase( person ).setEnabled( true ).dispose(). btnAddNo.setText( "" ). txtProv. txtKode. Listing 4. parent. telpAdded = true. //clear text field txtJalan.this. txtNo. } } ).setText( "" ).setText( "" ). btnAddAlamat.setText( "" ). } } ).addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { addAlamat().addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { addTelp(). txtEmail. JOptionPane.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { addEmail().setText( "" ).

JFileChooser fileChooser = new JFileChooser(). //file filter FileFilter filterBMP = new FileFilter( "bmp". btnBrowse.setEnabled( true ). "gif".setEnabled( true ). } //menampilkan file dialog private void showFileDialog() { String[] allImage = { "bmp". fileChooser. } } ).dispose(). FileFilter filterGIF = new FileFilter( "gif". "JPG Image" ). InsertForm. } catch ( SQLException sql ) { message = "Data tidak dapat tersimpan".setText( file. fileChooser. message ). "Bitmap Image" ). JOptionPane.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { showFileDialog(). fileChooser. sql.addChoosableFileFilter( filterGIF ).addChoosableFileFilter( filterAll ). if ( fileChooser. "GIF Image" ). } }). InsertForm.this. addWindowListener(new WindowAdapter() { public void windowClosing ( WindowEvent e ) { dataAccess.getAbsolutePath() ). "jpg"}.showMessageDialog( InsertForm. "Supported Image" ).4 – InsertForm untuk menambah nama baru ke dalam buku alamat 134 Secangkir Kopi Java . fileChooser.addChoosableFileFilter( filterBMP ). parent.this.printStackTrace().APPROVE_OPTION ) { File file = fileChooser. } } } ).getSelectedFile().addChoosableFileFilter( filterJPG ).this.close().parent.showOpenDialog( this ) == JFileChooser. } } Listing 4.dispose(). FileFilter filterAll = new FileFilter( allImage. lblStatus4. FileFilter filterJPG = new FileFilter( "jpg".

"orang" ).getText() ). return person.addTelp( txtNo. person. tersimpan" ).getText() ).getText().setText( " " + countTelp + " no. person.addKec( txtKec.equals( "" ) ) { person.addKab( txtKab. person. person. if ( !telpAdded ) addTelp(). lblStatus2. countEmail++.addDesa( txtDesa. countTelp++. } Listing 4.getText() ). countAlamat++.getLastID( "orang_id".addJalan( txtJalan.getText() ). //alamat if ( !alamatAdded ) addAlamat().setOrangID( lastID + 1 ).setText( " " + countEmail + " email tersimpan" ). } } //mengambil nilai dari text field public AddressEntry getEntry() { //id int lastID = dataAccess.setFotoPath( lblStatus4.addProv( txtProv.setText( " " + countAlamat + " alamat tersimpan" ).addNegara( txtNegara.getText() ). person.setNama( txtNama.getText() ).addKodepos( txtKode. person.equals( "" ) ) { person.getText() ).getText().getText() ).//memasukkan alamat ke vector private void addAlamat() { person. lblStatus3.getText() ). person. person. if ( !emailAdded ) addEmail().4 – InsertForm untuk menambah nama baru ke dalam buku alamat Studi Kasus JDBC – Adress Book 135 . //nama person. } //add email ke vector private void addEmail() { if ( !txtEmail.getText() ).getText() ). lblStatus1. } } //add telp ke vector private void addTelp() { if ( !txtNo.addEmail( txtEmail.

lblStatus2 ). txtNo ). btnAddNo. lblTelp. txtKec ). c = new GridBagConstraints(). lblStatus3 ). new JLabel( "Provinsi: " ). //label alamat JLabel lblAlamat = new JLabel( "Alamat: " ). lblEmail. addButtonAndStatus( btnAddEmail. lblStatus1 ). txtJalan ).setBorder( new LineBorder( Color. new JLabel( "Desa: " ). //email address JLabel lblEmail = new JLabel( "Email Address: " ).setMnemonic( 'd' ). addSingleComponentInRow( lblEmail ). txtProv ). lblAlamat. c. new JLabel( "Kecamatan: " ). txtEmail ).gray ) ). txtKode ). addRow( new JLabel( "Email: " ). c. txtNegara ). addSingleComponentInRow( lblTelp ).gray ) ). //no telp. new JLabel( "Negara: " ). //button + label status lblStatus3. btnAddEmail.setBorder( new LineBorder( Color. //button + label status lblStatus1. //button + label status lblStatus2. addButtonAndStatus( btnAddAlamat.setMnemonic( 'N' ). addRow( new JLabel( "No: " ). new JLabel( "Kabupaten: " ).gray ) ). txtKab ). btnAddNo.setBorder( new LineBorder( Color.fill = GridBagConstraints. //pasang komponen --> setting constraints //label nama JLabel lblNama = new JLabel( "Nama: " ). JLabel lblTelp = new JLabel( "No Telp: " ).private void createGUI() { gridBag = new GridBagLayout().BOTH. //vertical extra space addRow( new JLabel( "Nama: " ).setBorder( new LineBorder( Color.gray ) ).setBorder( new LineBorder( Color. addButtonAndStatus( btnAddNo. txtDesa ). addSingleComponentInRow( lblAlamat ).setMnemonic( 'A' ).4 – InsertForm untuk menambah nama baru ke dalam buku alamat 136 Secangkir Kopi Java . new JLabel( "Kode Pos: " ).setBorder( new LineBorder( Color. panel = new JPanel( gridBag ). 10 ) ). btnAddAlamat.0.setMaximumSize( new Dimension( 10.gray ) ). //label addRow( addRow( addRow( addRow( addRow( addRow( addRow( + text field new JLabel( "Jalan: " ).gray ) ). Listing 4.weighty = 1. txtNama ).

setDefaultButton( btnOK ). c ).weightx = 0.setPreferredSize( new Dimension( 20.weightx = 0.CENTER ).BOLD.0. 460 ). BorderLayout. c. btnCancel. 11 ) ). gridBag.setMnemonic( 'C' ). c ). contPane.add( lblStatus4 ).gridwidth = GridBagConstraints.1. JLabel lblFoto = new JLabel( "Foto: " ). lblStatus4.gridwidth = 1. } //tambah label dan text field private void addRow( JComponent label.weightx = 1.add( new JPanel().add( label ).setMaximumSize( new Dimension( 20. panel2.9.RELATIVE. panel3. BorderLayout. c.REMAINDER. fl. c.setHgap( 0 ). gridBag. panel. setSize( 350.setConstraints( panel2.add( panel2 ).add( btnBrowse ). BorderLayout. 18 ) ).add( btnOK ).RIGHT ).REMAINDER. //text field c. gridBag. //text field foto FlowLayout fl = new FlowLayout( FlowLayout. c ). btnBrowse. //buat gap contPane. contPane.setMnemonic( 'O' ). JPanel panel3 = new JPanel( new FlowLayout( FlowLayout. Font.RIGHT ) ). getRootPane(). JComponent txtField ) { c.SOUTH ). JPanel panel2 = new JPanel( fl ).add( panel3.add( panel.//foto c. setVisible( true ).EAST ).WEST ).add( btnCancel ). panel.add( new JPanel(). BorderLayout.setConstraints( lblFoto. contPane.gridwidth = GridBagConstraints. c.0. panel3.setFont( new Font( "Arial".weightx = 0.4 – InsertForm untuk menambah nama baru ke dalam buku alamat Studi Kasus JDBC – Adress Book 137 . Container contPane = getContentPane().gridwidth = GridBagConstraints. 18 ) ). //button ok dan cancel btnOK. panel. panel2. Listing 4. c.add( lblFoto ). btnBrowse.setConstraints( label.

setConstraints( comp2.weightx = 0. panel. c. c ).weighty = 0.add( txtField ).setConstraints( txtField.0. inisialisasi objek AddressEntry.REMAINDER.gridwidth = GridBagConstraints. c. email. dan telp hanya satu buah.add( comp2 ).REMAINDER. membuat user interface dan menset event yang terjadi pada tiap-tiap komponen. c ).setConstraints( comp1.gridwidth = 1. aku menunjukkan penambahan file filter pada kotak dialog tersebut supaya hanya membuka file yang dimaksud.gridwidth = GridBagConstraints.0. Method getEntry() memindahkan data-data yang ada pada text field ke dalam objek AddressEntry. sehingga langsung ditambahkan ke Vector. panel. 138 Secangkir Kopi Java . panel. } } Listing 4. } //tambah button 'add' dan label status private void addButtonAndStatus( JComponent comp1. Konstruktor melakukan inisialisasi objek DataAccess untuk akses database.gridBag. c ). Di situ ada blok if yang menunjukkan jika user belum menekan tombol Add.add( comp1 ). gridBag. c ). panel. gridBag. c. aku tidak menjelaskan isi class FileFilter secara mendetail. Pada method showFileDialog() yang digunakan untuk menampilkan dialog membuka file. JComponent comp2 ) { c. gridBag. Tetapi karena keterbatasan halaman. InsertForm merupakan subclass dari JDialog. diasumsikan field alamat. } //tambah label thok private void addSingleComponentInRow( JComponent comp ){ c.add( comp ).setConstraints( comp.4 – InsertForm untuk menambah nama baru ke dalam buku alamat Well.

GridBagLayout menempatkan komponen baik secara vertikal maupun horizontal tanpa membuat komponen harus memiliki ukuran yang sama pada display area. Masing-masing komponen yang diatur oleh GridBagLayout berhubungan dengan sebuah instance dari GridBagConstraints.CENTER. 4. gridheight: Digunakan untuk menentukan jumlah cell dalam satu baris (gridwidth) atau kolom (gridheight). HORIZONTAL. RELATIVE. Kamu harus menset beberapa properti dari objek GridBagConstraints untuk menggunakan layout GridBagLayout secara efektif. SOUTHEAST. maka 3. jika komponen menempati cell 3. Nilai yang valid adalah CENTER. n adalah jumlah angka dalam integer. Nilai yang valid adalah: n.4 ). 5 dia pakai. Studi Kasus JDBC – Adress Book 139 . Nilai yang valid adalah NONE. Masing-masing komponen memiliki GridBagConstraints yang bisa berbeda untuk mengatur letak komponen tersebut. RELATIVE: Komponen akan mengambil semua cell yang tersisa kecuali yang terakhir. Misalnya: anchor = GridBagConstraints. Misalnya dalam 1 baris ada 6 cell. insets: Digunakan untuk menentukan jumlah spasi luar (external padding) antara komponen dan display area. NORTH. REMAINDER. EAST. fill: Digunakan untuk memberitahu layout manager bagian mana yang harus direntangkan (stretch) ketika display area lebih besar dari ukuran normal komponen. gridwidth. untuk memasang komponen pada panel aku menggunakan layout manager GridBagLayout. NORTHEAST.Memperkenalkan.BOTH. WEST. SOUTHWEST. Properti tersebut antara lain: anchor: Digunakan untuk memberitahu layout manager di mana harus meletakkan komponen ketika komponen lebih kecil daripada display area. dalam pixel. GridBagLayout Pada method createGUI() pada InsertForm ( listing 4. BOTH. Misalnya: fill = GridBagConstraints. dan NORTHWEST. dan VERTICAL.

0 berarti komponen tidak mendapatkan ruang (tetap).0 berarti komponen mendapat semua ruang tambahan. Barulah setelah siap semuanya. dengan ipadx = 4 dan ipady = 5. Dan lagi-lagi mengunakan JEditorPane sebagai alat yang siap pakai. dan addSingleComponentInRow(). ipady: Merupakan spasi internal (internal padding).REMAINDER: Komponen merupakan komponen terakhir dalam satu baris atau kolom. Nilai yang valid adalah tipe double antara 0.0. karena class ViewPane merupakan subclass dari class JEditorPane. addRow(). aku menggunakan format HTML. REMAINDER 1 2 3 4 5 6 RELATIVE ipadx. gridy: Menentukan letak pojok kiri atas komponen. Pada method createGUI(). kita mengubah beberapa properti dari GridBagConstraints kemudian kita pasang ke GridBagLayout dengan setConstraints(). gridx. gridx = 0 dan gridy = 0 berarti komponen terletak pada cell pertama (pojok kiri atas) dari grid. sebelum memasang suatu komponen. Membangun User Interface II: Class ViewPane Untuk menampilkan data tiap nama dari database. 140 Secangkir Kopi Java . weighty: Menentukan bagaimana membagi ruang tambahan ketika komponen di-resize. maka ukuran total komponen menjadi 34 x 25 pixel. kita menambahkan komponen pada panel. addButtonAndStatus(). weightx. 0. 1. Jika komponen memiliki panjang 30 pixel dan lebar 20 pixel.0 – 1.

private AddressEntry entry.awt. import import import import java.printStackTrace(). //konstruktor public ViewPane() { setEditable( false ). buildPage().getImage(). dataAccess. java. public class ViewPane extends JEditorPane { private DataAccess dataAccess. } //navigasi public void first() { try { dataAccess.*. java. buildPage(). dataAccess.5 – Class ViewPane merupakan anak dari JEditorPane yang digunakan untuk menampilkan data orang yang ada di database.*.event.*. } } //foto public Image getImage() { return dataAccess.initView().printStackTrace(). } catch ( Exception e ) { e. } catch ( Exception e ) { e.printStackTrace(). Studi Kasus JDBC – Adress Book 141 .*.swing.fetchData(). javax.package addressbook.first(). dataAccess.io. } } //refreshing data public void refresh() { try { dataAccess. buildPage(). } catch ( Exception e ) { e. } } Listing 4. entry = dataAccess.first().fetchData(). entry = dataAccess.first().fetchData(). try { dataAccess = new MySQLAccess().initView(). entry = dataAccess.awt.

append( "<strong>" ). entry = dataAccess.fetchData().printStackTrace(). buildPage(). try { code = dataAccess. buildPage().append( "Nama: " ). } public void closeDatabase() { dataAccess. } private void buildPage() throws Exception { StringBuffer script = new StringBuffer().append( "<html><body bgcolor='#F0F4F0' " + "leftmargin='0' topmargin='0'>" ). entry = dataAccess. buildPage(). } return code.5 – Class ViewPane merupakan anak dari JEditorPane yang digunakan untuk menampilkan data orang yang ada di database. } catch ( Exception e ) { e. script.last(). script. } return code. } public int prev() { int code = 0.printStackTrace().printStackTrace().next().close().fetchData(). //nama script.fetchData(). } catch ( Exception e ) { e. script. } catch ( Exception e ) { e.public void last() { try { dataAccess.append( entry. Listing 4.append( "<div align='center'>" + "<font face='Comic Sans MS' size='3'>" ).prev(). script. entry = dataAccess. try { code = dataAccess.getNama() ). 142 Secangkir Kopi Java . } } public int next() { int code = 0.

append( "Kabupaten/Kota: " + ( String ) entry.append( "Email:<br>" ).append(( (String) entry.<br>" ). } //email script.//alamat script. i < entry.kec.append( "Kecamatan: " + ( String ) entry. script. if ( !(temp = (String) entry.append( "</strong>" ).get( i ) + "<br>" ). } script. for ( int i = 0.append( "Provinsi: " + ( String ) entry.prov.get( i ) + "<br>" ). script.get( i ) ). if ( i != entry. i < entry. script.email. script.telp. script.email.get( i ) + "<br>" ).append( temp + "<br>" ).size(). setContentType( "text/html" ).equals( "" ) ) script. } } Listing 4. for ( int i = 0.telp. } //telp script.desa. i < entry. i++ ) { script. setText( script.append( ".append( "0" + ( i + 1 ) + ". 143 Studi Kasus JDBC – Adress Book .append( "Desa/Kel: " + ( String ) entry.telp.desa.append( ( String ) entry.negara.size() .size().append( ( String ) entry.append( temp + "<br>" ).get( i ) ).size(). String temp = "".kab.append( "</body></html>" ). " ).append( "<br>" ).kodepos.get( i ) + "<br>" ). for ( int i = 0.toString() ).1 ) script.append( "</font></div>" ). script. setCaretPosition(1).jalan.5 – Class ViewPane merupakan anak dari JEditorPane yang digunakan untuk menampilkan data orang yang ada di database. i++ ) { script.equals( "" ) ) script. if ( !( temp = ( String ) entry.get( i ) + "<br>" ).append( "<br><br>Alamat: <br>" ).get(i)) . i++ ) { script. script.get( i ) ).toUpperCase() + "<br>" ).append( "<br>Telp:<br>" ). script.

karena sudah terbentuk di konstruktor. Setelah semua selesai. Method buildPage() sendiri merupakan penyusun script HTML untuk ditampilkan di JEditorPane.first() untuk mengarahkan record ke posisi pertama. Method-method navigasi seperti first(). Penyusun script-nya memakai StringBuffer. JEditorPane content-type-nya diset “text/html”. Gambar 4. Kemudian. dan “text/rtf” untuk format RTF (Rich Text Format). Ada tiga macam content type pada JEditorPane yaitu: “text/html” untuk format HTML. dia akan memanggil buildPage() untuk menyusun datadata dalam format HTML. bedanya ia tidak membuat objek dataAccess yang baru. buildPage(). last(). dan prev() mengarahkan dataAccess Dari situ kita akan dan kemudian mengisi objek membangun halaman dengan DataEntry.3 – Tampilan ViewPane setelah diisi script dengan format HTML 144 Secangkir Kopi Java .initView() untuk melakukan query dan memanggil dataAccess. Setelah itu mengisi objek AddressEntry dengan fetchData(). next(). Hal yang sama dilakukan pada method refresh().Konstruktor ViewPane melakukan inisialisasi dengan membuat objek DataAccess dan langsung memanggil method dataAccess. “text/plain” untuk format teks biasa.

event. private Action viewContactAction = new ViewContactAction().*. java.6 – Aplikasi AddressBook yang menyebabkan kita bisa berinteraksi dengan database. import import import import java.*. private Action nextAction = new NextAction().*.swing. 145 Studi Kasus JDBC – Adress Book . javax. private Action firstAction = new FirstAction(). Gambar 4. Class ini menyediakan tombol dan menu-menu untuk menjalankan class-class yang telah kita buat. private Action prevAction = new PrevAction().awt.awt. Listing 4. private JMenu navMenu.4 – Tampilan awal aplikasi yang telah kita buat dengan susah payah package addressbook. //main class public class AddressBook extends JFrame { //instans private Action newDataAction = new NewDataAction(). javax.*.Membangun User Interface Utama: Class AddressBook Sekarang tiba saatnya untuk mengumpulkan user interface yang telah kita buat dalam satu aplikasi Address Book. private Action lastAction = new LastAction().border.swing.

navMenu. menuBar. } }).\nParuh terakhir liburan semester IV". menuBar. //menu JMenuBar menuBar = new JMenuBar().setEnabled( false ).add( helpAbout ). dataMenu.add( prevAction ).setMnemonic( 'H' ).exit( 0 ).showMessageDialog( AddressBook. JMenu helpMenu = new JMenu( "Help" ).setMnemonic( 'A' ).add( nextAction ). menuBar.add( navMenu ). Listing 4. JMenu dataMenu = new JMenu( "Data" ).add( firstAction ). public AddressBook() { super( "Address Book Aplication" ). message ).add( viewContactAction ). dataMenu.add( lastAction ). JOptionPane. helpMenu. helpMenu. JMenuItem helpAbout = new JMenuItem( "About" ).addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { String message = "Studi Kasus JDBC-Untuk Buku Secangkir" + "Kopi Java\n(c) Fatso--20 Agustus 2004" + ".setMnemonic( 'N' ).add( dataMenu ). JToolBar toolBar. JMenuItem exitMenu = new JMenuItem( "Keluar" ).add( exitMenu ).6 – Aplikasi AddressBook yang menyebabkan kita bisa berinteraksi dengan database. 146 Secangkir Kopi Java . exitMenu. } } ). exitMenu. navMenu. dataMenu.setMnemonic( 'K' ). JLabel lblFoto = new JLabel().private private private private private ImagePanel panelBack.addSeparator(). ViewPane viewPane. dataMenu. navMenu = new JMenu( "Navigasi" ). dataMenu. navMenu. helpAbout. navMenu.this.add( newDataAction ).addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { System.add( helpMenu ).setMnemonic( 'D' ). helpAbout. navMenu. navMenu. boolean initialized = false.

setJMenuBar( menuBar ).jpg" ) ).getImage() ). Studi Kasus JDBC – Adress Book 147 .add( toolBar.add( toolBar. //toolbar toolBar. } else { lblFoto. //closing window addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { viewPane. toolBar.//toolbar toolBar = new JToolBar(). if ( image != null ) { ImageIcon imageIcon = new ImageIcon( viewPane. toolBar.6 – Aplikasi AddressBook yang menyebabkan kita bisa berinteraksi dengan database.add( toolBar. } private void addFoto() { //foto Image image = viewPane.add( toolBar.closeDatabase().CENTER ). lblFoto. setDefaultCloseOperation( EXIT_ON_CLOSE ). BorderLayout.add( panelBack. BorderLayout.NORTH ). setVisible( true ).setIcon( null ). lblFoto. navMenu. addFoto().setText( "Tidak Ada Foto" ). prevAction ).add( firstAction ). lastAction ). 500 ). JScrollPane scrPane = new JScrollPane( viewPane ). //container panelBack = new ImagePanel( getClass(). } lblFoto.getImage().setText( "" ). nextAction ).setIcon( imageIcon ).add( newDataAction ). cp. cp. setSize( 700.setEnabled( true ). Container cp = getContentPane(). lblFoto.repaint(). } } ). Listing 4. } public void viewEntry() { if ( !initialized ) { viewPane = new ViewPane().getResource( "icons/back.add( viewContactAction ).

validate().getResource( "icons/first.SHORT_DESCRIPTION.getResource( "icons/filenew. contPane.black.setEnabled( true ). contPane. initialized = true.SMALL_ICON. } else { viewPane.CENTER ). addFoto(). addFoto(). } private class NewDataAction extends AbstractAction { public NewDataAction() { putValue( Action.setBorder( BorderFactory.EAST ). putValue( Action.repaint().png" ) ) ).setEnabled( false ). putValue( Action.SMALL_ICON. "Awal" ). Container contPane = getContentPane(). putValue( Action. nextAction. } } public static void main( String[] main ) { new AddressBook(). prevAction. contPane. 148 Secangkir Kopi Java .SHORT_DESCRIPTION. } } private class FirstAction extends AbstractAction { public FirstAction() { putValue( Action.NAME. new Integer( 'A' ) ).refresh().this ). contPane. putValue( Action.first().MNEMONIC_KEY. putValue( Action. new ImageIcon( getClass(). 4 ) ). "Menambah entri baru" ).MNEMONIC_KEY.NAME. putValue( Action. BorderLayout.add( scrPane. "Awal Records" ). new Integer( 'T' ) ). "Tambah Baru" ). } public void actionPerformed( ActionEvent e ) { new InsertForm( AddressBook. } } Listing 4. new ImageIcon( getClass(). } public void actionPerformed( ActionEvent e ) { viewPane. contPane.add( lblFoto.remove( panelBack ).6 – Aplikasi AddressBook yang menyebabkan kita bisa berinteraksi dengan database.createLineBorder( Color.png" ) ) ).lblFoto. BorderLayout.

putValue( Action.png" ) ) ). prevAction.getResource( "icons/last. nextAction. if ( code == -1 ) setEnabled( false ).NAME.png" ) ) ). "Sebelumnya" ).NAME.next(). new ImageIcon( getClass(). "Record Selanjutnya" ).SMALL_ICON.MNEMONIC_KEY. "Akhir" ). } public void actionPerformed( ActionEvent e ) { viewPane. addFoto(). } public void actionPerformed( ActionEvent e ) { int code = viewPane. } public void actionPerformed( ActionEvent e ) { int code = viewPane. putValue( Action. putValue( Action.NAME. nextAction. putValue( Action. putValue( Action.6 – Aplikasi AddressBook yang menyebabkan kita bisa berinteraksi dengan database. Listing 4.setEnabled( true ). putValue( Action. putValue( Action.last().SHORT_DESCRIPTION. } } private class LastAction extends AbstractAction { public LastAction() { putValue( Action.SMALL_ICON.SHORT_DESCRIPTION.png" ) ) ). new Integer( 'B' ) ). Studi Kasus JDBC – Adress Book 149 . new Integer( 'K' ) ).MNEMONIC_KEY.prev(). setEnabled( false ). putValue( Action. new ImageIcon( getClass().SHORT_DESCRIPTION. new ImageIcon( getClass(). addFoto().getResource( "icons/next. "Record Sebelumnya" ).setEnabled( false ). } } private class NextAction extends AbstractAction { public NextAction() { putValue( Action.MNEMONIC_KEY. putValue( Action. new Integer( 'L' ) ).SMALL_ICON. "Selanjutnya" ).setEnabled( true ).getResource( "icons/prev.private class PrevAction extends AbstractAction { public PrevAction() { putValue( Action. "Akhir Records" ).

"Melihat Daftar" ). Class-class internal semuanya mengatur tentang Action yang mengatur navigasi antar record seperti FirstAction. } public void actionPerformed( ActionEvent e ) { viewEntry(). NewDataAction bertugas memunculkan 150 Secangkir Kopi Java . Setelah melakukan pergantian panel.6 – Aplikasi AddressBook yang menyebabkan kita bisa berinteraksi dengan database. new ImageIcon( getClass(). new Integer( 'M' ) ). prevAction. hanya sedikit yang perlu dijelaskan di sini. addFoto(). inisialisasi dilakukan pada saat Action viewContact diaktifkan. putValue( Action. Dia membuat ImageIcon dari objek Image yang didapat dari database. Method addFoto() memasang foto pada form. Well.if ( code == -1 ) setEnabled( false ). dan PrevAction. LastAction. yaitu pada konstruktor dan pada method viewEntry(). } } private class ViewContactAction extends AbstractAction { public ViewContactAction() { putValue( Action.getResource( "icons/fileopen.png" ) ) ). putValue( Action. "Melihat Daftar" ). kemudian memasang pada JLabel.SMALL_ICON. Untuk method viewEntry(). aku me-remove panel berbackground (dari class ImagePanel) dan menggantinya dengan panel viewPane dan lblFoto. Jika action tersebut ditekan lagi. viewEntry() hanya melakukan refreshing. putValue( Action...well.setEnabled( true ). Inisialisasi dilakukan di dua tempat. } } //akhir private class } //akhir class AddressBook Listing 4.MNEMONIC_KEY. kamu harus memanggil method validate() agar panel yang baru dipasang segera tampak di layar.SHORT_DESCRIPTION. bukan inisialisasi lagi.NAME. Perhatikan kembali pada method viewEntry(). NextAction.

*. } catch ( Exception e ) { e.dialog InsertForm. private URL pathURL. public class ImagePanel extends JPanel { //image private BufferedImage origImage.awt.getDefaultToolkit(). Sedangkan class ViewContactAction bertugas menampilkan data-data orang beserta fotonya yang disusun oleh ViewPane dan JLabel.event. private Image image.border. //constructor public ImagePanel( URL url ) { try { pathURL = url. Aku sering ditanyai teman-temanku bagaimana caranya memasang background image pada aplikasi Java layaknya aplikasi VB.event. import import import import import import import java. javax.swing.printStackTrace(). java.*. java.*. Studi Kasus JDBC – Adress Book 151 .awt.*. Class-Class Pendukung Class ImagePanel Class ini merupakan subclass dari JPanel yang bertujuan menampilkan background dari panel tersebut. } public void createImage( URL url ) throws Exception { image = Toolkit.7 – Class ImagePanel.swing. javax.net. createImage( url ).*.*. javax. untuk menampilkan JPanel yang memiliki background gambar.*.createImage( url ). Listing 4.image.awt. java. } } public URL getURL() { return pathURL.swing. Inilah jawaban yang kulakukan sebisaku… package addressbook.

getWidth().waitForAll(). super.getWidth().printStackTrace(). try { medTrack.MediaTracker medTrack = new MediaTracker( this ).TYPE_INT_RGB ). image. 0.getHeight( null ). origImage.addImage( image. } catch ( Exception e ) { e. medTrack.7 – Class ImagePanel. } Graphics2D graphics = origImage. graphics. BufferedImage. graphics. super.drawImage( image.getHeight() ).createGraphics().getWidth( null ).getHeight().setPreferredSize( new Dimension( 60. null ). 152 Secangkir Kopi Java . untuk menampilkan JPanel yang memiliki background gambar. origImage = new BufferedImage( image.setBorder( BorderFactory. } //get minimum size public Dimension getMinimumSize() { return getPreferredSize(). } } Listing 4. null ). } //get preffered size public Dimension getPreferredSize() { return new Dimension( origImage.paintComponent( g ). 0. } //get height public int getHeight() { return origImage.createLoweredBevelBorder() ). Graphics2D graphics = ( Graphics2D ) g. 0 ). } //get width public int getWidth() { return origImage. 60 ) ). null. } //draw image panel public void paintComponent( Graphics g ) { super.drawImage( origImage.

Pertama-tama sumber dari URL diubah menjadi objek Image dengan Toolkit. Proses selanjutnya adalah membuat BufferedImage dari Image yang sudah diregister ke MediaTracker sebagai image yang bertipe RGB (Red Green Blue).createImage ( URL url ). Kita perlu meng-override method paintComponent untuk menggambar kembali image dengan method drawImage. bisa audio. supaya image tidak kelihatan terpotong.java Studi Kasus JDBC – Adress Book 153 . Objek Image dapat digambar pada panel dengan memanggil method drawImage. Letaknya di [JAVA_HOME]/demo/jfc/FileChooserDemo/src/ ExampleFileFilter. bisa image. tetapi Sun Microsystem.7) adalah method createImage() yang memproses gambar dari URL (Uniform Resource Locator) menjadi background. Kemudian kita meregister image tersebut ke objek MediaTracker. Method getPreferredSize() juga di-override agar mengembalikan nilai ukuran dari image. Class FileFilter Class FileFilter digunakan untuk menentukan tipe file apa saja yang muncul pada kotak dialog JFileChooser.getDefaultToolkit(). Kamu bisa mendapatkan source code class ini di demo-nya Java 2 SDK. BufferedImage digunakan untuk membuat objek Graphics2D yang bertugas menggambar image pada panel. Bukan aku sendiri yang menulis class ini. MediaTracker berfungsi untuk melakukan penelusuran (tracking) pada suatu media.Inti dari class ini (Listing 4.

5 – Tampilan keseluruhan dari aplikasi AddressBook setelah kita jalankan iv. Memang masih banyak kekurangan yang terdapat pada aplikasi ini. Oce?!?! 154 Secangkir Kopi Java . Ringkasan Kamu telah mempelajari bagaimana membuat sebuah aplikasi nyata mengenai JDBC.Gambar 4. Tugasmu adalah memperbaikinya. tapi paling tidak sudah dapat menunjukkan bagaimana JDBC berinteraksi dengan database.

Appendix A Mendistribusikan Aplikasi Java dengan Java Archive ( JAR ) .

.

Membuat File JAR Format dasar untuk membuat file JAR adalah: jar cvf nama-jar-file. aplikasi-aplikasi Java dikompilasi menjadi byte code yang diinterpretasikan oleh Java Virtual Machine.exe yang tinggal klik 2 kali untuk menjalankan. sehingga ketika aplikasi kita jadi. : Mengeluarkan output pada stderr (versi 1. File JAR juga membuat kita dapat melakukan digital signing untuk mengamankan class-class kita dari yang tidak berhak (ehm). Tentunya tidak praktis untuk mendistribusikan class-class tersebut ke end-user yang kebanyakan tidak memiliki pengetahuan khusus tentang Java. Manifest file adalah file teks yang menunjukkan dimanakah main-class berada.2) apa saja yang dilakukan ketika file JAR dibuat.1) atau stdout (versi 1. Java memiliki cara untuk mengumpulkan class-class tersebut dalam file yang disebut Java Archive (JAR).jar input-file Keterangan: c v : Menandakan kita membuat file JAR baru. dkk. javah. Main-class maksudnya class di mana terdapat method sakti: public static void main (String[] args). Kita bisa ditertawakan oleh programmer C++ atau VB yang hasil akhir aplikasinya adalah file *. Tool untuk membuat file JAR telah dibundel dalam Java 2 Standard Development Kit (dulu dikenal dengan JDK) di bawah folder [JAVA_HOME]/bin bersama file-file javac. java. File JAR adalah file yang mirip dengan file ZIP dengan fungsi tambahan berupa Manifest file. Seringkali kita membuat sebuah aplikasi yang terdiri lebih dari satu class untuk memudahkan enkapsulasi data.Untuk memenuhi syarat multi-platform-nya. Appendix A – Mendistribusikan Aplikasi Java dengan JAR 157 .class. kita mendapatkan banyak sekali class-class yang mendukung aplikasi kita. Byte code tersebut disimpan dalam sebuah file berekstensi *.

misalnya terletak di F:\Java\JDBC\classes\addressbook.mf di bawah folder META-INF berbunyi seperti di bawah ini: 158 Secangkir Kopi Java . Untuk file lebih dari satu dipisahkan dengan. pastikan file manifest. arahkan ke classes. Mestinya.dst. coba menjalankannya dengan perintah [JAVA_HOME]/bin/jar cvf AddressBook. F:\Java\JDBC\classes> _ >> catatan: jika perintah jar tidak dikenali.. Input-file : File-file yang kita tambahkan pada JAR file.jar addressbook/* added manifest adding: addressbook/AddressBook$1.jar dengan alat kompresi seperti WinRAR. Buka command prompt.class(in = 920) (out= 561)(deflated 39%) . buka AddressBook.jar yang jika kita klik dua kali akan menjalankan main-class-nya. Lakukan seperti di bawah ini: F:\Java\JDBC\classes> jar cvf AddressBook...class(in = 688) (out= 393)(deflated 42%) adding: addressbook/AddressBook$2.class ----+ icons --------+ Letak file untuk icon Kita akan membundelnya dalam file JAR.. 1. juga menerima directory dan WildCards ( * ).f : Menandakan bahwa hasil disimpan di file. Contoh: Aplikasi yang kita buat pada bab tiga menghasilkan class-class yang berada pada struktur directory seperti di bawah ini: + addressbook ----+ Letak file *. terbuat file JAR baru bernama AddressBook.jar : Nama file JAR yang akan kita buat. arahkan ke direktori tempat folder AddressBook berada. bukan pada standard output ( stdout). Tetapi jika gagal.jar addressbook/* 2. nama-jar-file.

0 Main-Class: addressbook. Untuk command line. ketika kita klik 2 kali pada explorer.jar [archived-file(s)] file.jar input-file(s) manifest-file dan dengan file input bernama input-file(s). Jika input-file sudah ada pada file.jar. kamu perlu menambahkan tag-tag berikut di dalam tag <applet> Appendix A – Mendistribusikan Aplikasi Java dengan JAR 159 . [archived-file(s)] adalah filefile yang diekstrak. khusus untuk JRE versi 1.2 ke atas bisa diketik seperti di bawah ini: java –jar filejar.jar Untuk applet yang dibundel dalam file JAR.jar inputfile(s) dengan file input input-file(s). Mengupdate file JAR bernama file.jar dengan manifest file baru bernama jar cmf manifest-file file. untuk file input lebih dari satu dipisah dengan spasi. maka file tersebut akan di-overwrite Keterangan Melihat isi dari file JAR bernama jar- Menjalankan Aplikasi yang Dibundel dalam JAR Jika dalam komputer client sudah terdapat Java SDK atau Java Runtime Environment.jar Jar uf file.jar.jar file. maka aplikasi sudah bisa berjalan secara ostosmastis – dengan syarat manifest-file-nya sudah benar.AddressBook Perintah JAR Lainnya Di bawah ini adalah beberapa perintah tool JAR yang lain: Perintah jar tf jar-file.jar Meng-ekstrak file JAR bernama jarjar xf jar-file. Meng-update file JAR bernama file.Manifest-Version: 1.

baik juga bagi kita untuk menyertakan installer-nya. tetapi kusarankan jangan memakai bahasa Java.bat).exe ataupun ke dalam batch file (*. kita cek dulu apakah ada Java Runtime Environment di sana.<applet code=MainClass. Shell yang paling sering digunakan adalah sh (bourne shell – biasa disebut shell). tanamkan command line ke dalam file shell script. dan csh (C shell). jika belum kita install-kan dulu JRE-nya. Atau. bash (bourne-again shell).class archive=filejar.exe asli.exe itu adalah: 1. WinZIP. tetapi yang bersifat native – platform dependent – seperti Visual C++ di Windows ataupun C++ dengan kompiler gcc di Linux.installshield. 160 Secangkir Kopi Java .com). jika nggak mau repot.com) atau Install Anywhere (http://zerog. Jika kamu pengguna UNIX dan keluarganya.exe. Kita bahas Shell di UNIX lain kali yach! Dalam mendistribusikan aplikasi Java. Kita bisa membuat sendiri installer-nya. kita bisa memakai utility installer dari Installshield Wizard (http://www.jar” ke dalam executable *. Maksudku. jika kita bisa membuat *. Menanamkan command line “java –jar filejar. kita tidak bisa memaksa aplikasi Java menjadi executable ala Windows dengan membuat file *. ataupun WinACE 2. File *. Kita hanya bisa membuat file *.exe yang tidak sepenuhnya *.jar width=120 height=120> </applet> JAR adalah hasil akhir dari sebuah aplikasi Java.exe. yang kita lakukan dalam *. Sebelum kita menanamkan aplikasi kita ke komputer user. Meng-kompres file JAR menjadi self-extracting.exe seperti ini dapat dikenali dengan membukanya dengan utility kompresing seperti WinRAR. Jika kita pengguna Microsoft Windows.

Appendix B Instalasi Java 2 Standard Development Kit (J2SDK) dan Tentang Packaging .

.

jar Sebenarnya. Misalnya.jar. variabel PATH akan merujuk ke: PATH=C:\j2sdk1. C:\j2sdk1.2. Byte Code Java di-interpretasikan oleh JRE. Biasanya merupakan class-class yang dibundel dalam file JAR di bawah folder [JAVA_HOME]/jre/lib.jar.*.4.jar.jar.com/products/j2se.4.2\jre\lib\ext\ldapsec.jar. dan Macintosh.4. Menggunakan contoh di atas.swing.2\lib\dt. C:\j2sdk1.2 dan versi 1. J2SDK memiliki versi 1.2\lib\tools. instalasi J2SDK terletak di C:\j2sdk1.4.2\jre\lib\ext\dnsns.sun.5-nya masih beta. C:\j2sdk1. pilih Operating System yang cocok dengan komputer kamu. Sedangkan variabel CLASSPATH akan merujuk ke library JRE. misalnya: import java. apa sih fungsi CLASSPATH itu? Ingat. Solaris.2\jre\lib\rt. C:\j2sdk1. import javax. Maka.4.2\jre\lib\ext\sunjce_provider.4.Java 2 SDK dapat kamu dapatkan dari situs resmi Java di http://java. dst… Appendix B – Instalasi J2SDK dan Tentang Packaging 163 .jar.2\jre\lib\ext\localedata. inilah yang sering kusebut JAVA_HOME.4. SunOS.2\bin. Linux. Nah. jalankan installernya dan ikuti petunjuk-petunjuk instalasi. maka variabel CLASSPATH akan berbunyi seperti ini: CLASSPATH=C:\j2sdk1. Langkah selanjutnya adalah menset environment variable PATH dan CLASSPATH.4.4. Ikuti petunjuk cara download di sana. C:\j2sdk1. bahwa Java adalah bahasa yang terkompilasi sekaligus terinterpretasi.awt. Tersedia J2SDK untuk Microsoft Windows.4. C:\j2sdk1. CLASSPATH adalah letak class-class library yang biasa kamu panggil lewat keyword import.*. Ketika aku menulis buku ini. PATH adalah letak tool-tool J2SDK dan CLASSPATH adalah letak library dari Java Runtime Environment. Semuanya bisa kamu dapatkan secara cuma-cuma alias gruatis! Setelah mendapatkan J2SDK.

2/bin/jre/lib/rt. java. misalnya: javax. Nanti akan muncul class baru di dalam folder sesuai dengan nama package-nya.. Kita pergi ke folder tempat source code berada dan mengkompilasinya dengan tool javac. cari bagian environment variables). dsb.. galih. com.swing. atau export di Linux.bash-profile Cara meng-kompilasi kode Java yang berpackaging adalah seperti melakukan kompilasi biasa. Untuk Linux: kalau tidak salah ( Tentang Packaging Untuk memudahkan pemisahan dan tata nama.awt.jdbc.2/bin [galih@eliza galih]$ EXPORT CLASSPATH=. Class dengan nama galih.c:\j2sdk1.mysql.JTreeDemo. 2000. ) ada di [user_home]/. misalnya: Windows: C:\windows> SET PATH=.bat.JFrame.Kamu bisa menset environment variable dengan perintah SET di Windows.:/usr/j2sdk1.swing.4.4. kode java menggunakan package dalam penamaan class-nya. simpan variabel-variabel PATH dan CLASSPATH di: Untuk Windows 9x dan ME: file autoexec. atau setevn di UNIX.JTreeDemo akan berada di folder 164 Secangkir Kopi Java .4.jar Cara di atas membuat environment variable yang kita masukkan tersimpan secara sementara.:/usr/j2sdk1. klik properties.ActionListener.4. Jika kamu ingin mereka tersimpan secara permanent.c:\j2sdk1.2\bin C:\windows> SET CLASSPATH=. dan XP: di System properties (klik kanan icon My Computer.2\jre\lib\rt. kebanyakan sih C:\ Untuk Windows NT. Biasanya berada di drive system.jar Linux: [galih@eliza galih]$ EXPORT PATH=. Jadi jika ada class dengan nama sama dapat dibedakan dengan adanya packaging.Driver. kita mesti menset lagi.swing. artinya ketika komputer direstart.

kaki kiri. kita harus berada di bapaknya folder package tersebut. dan…) untuk kehebatannya. terbentuk file class yang berada di direktori: C:\javaku\latihan\classes\galih\swing\JTreeDemo. Tetapi menurutku. Ketika kukompilasi dengan javac. Beberapa IDE yang kurekomendasikan antara lain: Borland JBuilder: Dari Borland (http://www.swing. hal itu sangatlah tidak praktis dan ruibet buanget wis – kita tak mau dipusingkan dua kali dengan masalah kompilasi setelah energi kita dihabiskan untuk menulis program.galih/swing/JTreeDemo. Dan kita juga cukup melakukan satu klik untuk melakukan kompilasi maupun menjalankannya.class Untuk menjalankannya aku harus mengarahkan current directory ke folder classes dan menjalankannya dengan java: C:\javaku\latihan\classes> java galih. aku punya class bernama galih. berbeda warna antara keyword dan Stringnya. kaki kanan.JTreeDemo.swing. tangan kiri.com). Terintegrasi dengan baik fiture seperti J2SE. Memiliki editor yang canggih dan memudahkan kita untuk menjalankan programnya. sehingga bisa warna-warni. dan EJB.inprise. selesai! Integrated Development Environment Kita bisa menulis program Java dalam sebuah Notepad dan mengkompilasinya dengan command line.class. Cara yang praktis dan menyenangkan dalam menulis Java adalah menggunakan sebuah IDE – Integrated Development Environment – yang memiliki editor khusus Java. serta Servlet! Appendix B – Instalasi J2SDK dan Tentang Packaging 165 . J2EE. Untuk menjalankannya. Memiliki code insight. Misalnya. J2ME. kita dapat mengetahui kesalahan penulisan program tanpa melakukan kompilasi dengan javac. IDE yang menurutku terhebat sepanjang masa! Aku memberi dia 5 jempol (tangan kanan.JTreeDemo Nah.

JCreator: Sayang sekali JBuilder yang sakti itu memiliki kelemahan yang signifikan. pakailah Forte for Java. Jika kamu ingin membuat aplikasi Java dengan 100% menggunakan teknologi dari Sun. Jeruk kok minum jeruk…? 166 Secangkir Kopi Java . ia dapat disimpan di disket dengan sebuah File Splitter. Dibuat dari bahasa Java seperti JBuilder. yaitu bueratnya mintak ampun..com).he. JBuilder 9 meminta minimal memory 256 MB agar dapat berjalan lancar. JCreator cocok untuk programmer Java yang menggunakan Java untuk aplikasi standar dan tidak memerlukan fungsi-fungsi hebat yang dimiliki JBuilder..he.sun. Forte for Java: Tool IDE Java yang dibuat aseli oleh Sun Microsystem (http://www. Dia juga memiliki editor yang hebat.. JCreator mengatasinya! Dengan ukuran installer yang kurang dari 3 Mega. he.

co. Aku mesti kuliah lagi. yang selalu memberikan aku yang terbaik. Security Java. – dan tidak ada orang yang bisa ditanyai – tidak terjadi pada kamu yang ingin mengetahui Java lebih mendalam.uk. maafkan aku jika aku telah lancang menulis sebuah buku seakan-akan aku adalah pakarnya Java. Sekali lagi. Tetapi… yah… liburanku telah usai. Jadi. aku bukanlah seorang pakar dalam Java. Sampai sekarang. tak satupun buku Java berbahasa Indonesia yang membahas Java tingkat lanjut (tingkat mahir). kritik. Au Revoir! 167 . back to campus. Karena aku tahu. Buku sebagai tanda bahwa aku melalui liburan panjang kali ini dengan indah cemerlang. dan masih banyak lagi.. cacian. JSP. File Permission dan Java Sandbox. Meski harus kuakui. makian. Mungkin lain kali aku bisa menulis lagi.? Maka dari itu. Aku sebenarnya masih ingin membahas teknologi Java lebih banyak lagi. akhirnya buku pertamaku ini selesai juga. Tuhan Semesta Alam. yang sangat sayang padaku.Au’ Revoir! Segala puji syukur untuk Allah SWT. Tidak ada pasarnya kali ye. dan apapun itu akan kuterima dengan tangan terentang lebar di fox_galih@yahoo. maka aku bilangnya bukan Auf Wiedersehn tetapi Au Revoir! Seperti penulis lainnya. Aku berharap buku ini dapat memuaskan keingintahuan kamu akan bahasa Java dalam bahasa Indonesia. bagi kamu yang benci dan malas membaca buku bahasa Inggris. aku masih belajar tentang dunia pemrograman Java. segala saran. Servlet. buku ini masih banyak kelemahannya. yang telah memberiku karunia tak ternilai. aku juga ingin mengucapkan terima kasih kepada: Allah SWT. Aku masih ingin menulis tentang JApplet. Tujuanku semata-mata hanyalah agar kesulitan-kesulitanku ketika menyelami Java karena keterbatasan bahasa Inggris.

sehingga liburan panjang semester IV ini amat berwarna. Komputerku tersayang. Maafkan aku telah merusak slot memori-mu sehingga kini kau melayaniku dengan hanya kekuatan 256 MB. yang paling cantik. Eliza yang cantik. Bpk. Sori ye buat pacarnya Nafik. bahwa setiap sesuatu yang kubuat selalu kupersembahkan kepada mereka. membuat luka di hatiku dengan pisau kecil mereka. yang selalu mengerti aku. yang menjadi pelampiasanku di kala aku patah hati.. yang paling imut. dan yang tambah guendut: Nafi’ah. bukan warna kelabu.ha. Mungkin kalau aku tidak mengenal Java. Ide itu muncul ketika aku lagi ngelamunin dia! Ha. yang memperkenalkan aku dengan Java. Arunanto.. namun mungkin mereka tak akan pernah tahu. Dan last but not least. yang membuatku menulis buku ini.. namun warna yang benar-benar indah cemerlang. meski mereka selalu menyakitiku. Meski tak pernah membuatku mengerti apa itu cinta anak muda. FX. adekku yang paling maniez.ha. Gadis-gadis cantik yang pernah kusayangi. pinjem sebentar… 168 Secangkir Kopi Java . dosenku BPL. sekarang aku sedang pusing memikirkan pointer-nya C++.

2003.com/developer/Books/javaprogramming/JAR/index.4. http://java. Unspecified writer. Swing Example. Writing Advanced Applications for the Java Platform.E. http://java.com Java 2 SDK.M. Daftar Pustaka 169 .sun.borland. Palo Alto: Sun Microsystem Inc. http://www. 2003.com/docs/books/jdcbook/index. Palo Alto: Sun Microsystem Inc.Deitel.Santry.1. 2002.J.sun. Standard Edition Documentation version 1. Unknown Source. Austin.com.sun. 2002. 1999.Daftar Pustaka H.html. S. The Java Archive (JAR) File Format. P. Monica. Palo Alto: Sun Microsystem Inc. New Jersey: Prentice Hall Inc.html. Advanced Java 2 Platform How To Program. Calvin and Pawlan. http://java. JBuilder 9 Documentation.Deitel.