P. 1
Secangkir Kopi Java

Secangkir Kopi Java

|Views: 278|Likes:
Dipublikasikan oleh Mas Eko

More info:

Published by: Mas Eko on Jun 14, 2013
Hak Cipta:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

05/06/2015

pdf

text

original

Sections

  • i. Web Browser – Implementasi JEditorPane dan
  • JToolBar – Toolbar pada javax.swing
  • ii. Swing action
  • iii. Class JOptionPane, menampilkan dialog box
  • Message Box
  • Kotak Konfirmasi ( Confirm Dialog )
  • Kotak Input / Input Dialog
  • model - view controller
  • i. JList
  • Advanced JList
  • ii. JTable
  • Advanced JTable
  • iii. JTree
  • First Run!
  • Tree Cell Renderer dan Tree Cell Editor
  • Tree Event
  • i. Ringkasan
  • java database connectivity [ jdbc ]
  • i. Sekilas Database
  • Structured Query Language ( SQL )
  • ii. Java Database Connectivity
  • Driver JDBC
  • Koneksi Database
  • Statement
  • ResultSet
  • studi kasus jdbc – address book
  • i. Database Design
  • ii. Instalasi Database dan Pembuatan Database
  • iii. Penulisan Kode Program dengan Java
  • Class AddressEntry
  • Interface DataAccess
  • Class MySQLAccess
  • User Interface I: Class InsertForm
  • Memperkenalkan, GridBagLayout
  • Membangun User Interface II: Class ViewPane
  • Membangun User Interface Utama: Class AddressBook
  • iv. Ringkasan
  • Membuat File JAR
  • Perintah JAR Lainnya
  • Tentang Packaging
  • Integrated Development Environment
  • Au’ Revoir!
  • Daftar Pustaka

secangkir kopi java
JAVA 2 STANDARD EDITION

Oleh: Galih Satria

Copyright © Agustus 2004

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

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

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

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

.

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

model .view controller januari 2004 .

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Beberapa method di bawah ini adalah milik class TableColumn untuk mengatur panjang kolom. 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 . dan header renderer.public void moveColumn(int fromIndex. Class ini digunakan untuk memanipulasi suatu kolom tertentu secara individual pada JTable. tetapi kita bisa mendapatkan objek ini dari method getColumn ( int index ) pada TableColumnModel atau method getColumn ( Object identifier ) 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. menentukan cell renderer dan cell editor. Class ini tidak dapat dibuat secara langsung ( instantiated ).

*. kita dapat menambah dan menghapus baik baris ataupun kolom. private JButton btnRemoveCol = new JButton ( "Remove Column" ). private JButton btnAddCol = new JButton ( "Add Column" ).awt.*.swing. import javax. private JButton btnRemoveRow = new JButton ( "Remove Row" ). 46 Secangkir Kopi Java .swing.*. import javax. private DefaultTableModel tableModel.awt.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.*. Listing 2. private JButton btnAddRow = new JButton ( "Add Row" ).table. import java. yaitu TableModel dan ColumnModel. public class TableDemo2 extends JFrame { //instans private JTable table.6 – Dengan TableModel. Di sini diperkenalkan dua model.0" ). Okay? Let’s go! package galih.swing. import java.event. Siapkan dirimu untuk membaca kode gila! Tapi itu akan percum tak bergun jika kamu tidak mencobanya sendiri. //konstruktor public TableDemo2() { super ( "Table Demo ver 2.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

java database connectivity [ jdbc ] Desember 2003 .

.

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

yang kudapat dari kuliah Basis Data-nya Pak Imam K semester III kemarin. dan yang berada di dalam tanda [ ] boleh disertakan atau tidak sesuai dengan kebutuhan. arti huruf besar adalah keyword. yang harus disertakan jika kita membutuhkan pengolahan data. yang berhuruf kecil merupakan isian yang bisa diubah sesuai dengan kebutuhan kita.1 – Relationship yang dipakai dalam database AkademikPIKTI 84 Secangkir Kopi Java . aku akan menggunakan database AkademikPIKTI. Sebagai contoh.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. Gambar 3.

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

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

<kolom 2> ] Klausa ini digunakan untuk mengelompokkan fungsi-fungsi agregate. • MAX ( kolom ) untuk mendapatkan nilai tertinggi pada suatu kolom. COUNT(*) FROM anggota GROUP BY JK Untuk menampilkan rata-rata harga koleksi per kode penerbit SELECT idPenerbit.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. • AVG ( kolom ) untuk mendapatkan nilai rata-rata pada suatu kolom. • MIN ( kolom ) untuk mendapatkan nilai terendah pada suatu kolom. Proses tersebut akan mengolah nilai sebuah field atau lebih mulai baris pertama sampai seluruh baris. AVG(harga) FROM koleksi GROUP BY idPenerbit Java Database Connectivity [ JDBC ] 87 . • SUM ( kolom ) untuk mendapatkan jumlah keseluruhan dari suatu kolom. 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> [. Contoh: Untuk menampilkan jumlah anggota perjenis kelamin: SELECT JK. Fungsi-fungsi tersebut yaitu: • COUNT ( * ) untuk mendapatkan jumlah baris.

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

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

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

nrp=pesertakul.matakul WHERE mhs.matakul WHERE mahasiswa.pesertakul WHERE mahasiswa.nrp AND pesertakul.nama FROM mahasiswa.mahasiswa.namakul='Pemrograman Database' 10:\> SELECT * FROM dosen WHERE nip NOT IN (SELECT distinct nipwali from mahasiswa) 11:\> SELECT nrp.kodekul=pesertakul.kodehari AND sesikuliah.nrp FROM dosen.nrp=pesertakul.kodekul=matakul.nrp AND pesertakul.doesn.pesertakul.nama.pesertakul.nipwali=dosen.nama FROM mahasiswa WHERE nrp NOT IN (SELECT distinct nrp FROM pesertakul WHERE (nihuruf='D' OR nihuruh='E')) 12:\> SELECT distinct dosen.nrp AND pesertakul.nilai<56 14:\> SELECT distinct nama.nip AND mahasisea.nihuruf='E' 13:\> SELECT matakul.nip=sesikuliah.kelas='ca' AND matakul.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 .namakul.kodekul AND dosen.nilai FROM mahasiswa.kodejam AND sesikuliah.kodejam=jam.kodekul=matakul.sesikuliah.mahasiswa.nipdosen 09:\> SELECT mhs.kodekul AND matakul.pesertakul.nama.nrp.kodehari=hari.nrp=pesertakul.kodekul AND pesertakul.

MIN(pesertakul.alamat like '*Sidoarjo*' UNION ALL SELECT dosen.nama AS nama.nrp AND pesertakul. Bisa-bisa aku nanti 92 Secangkir Kopi Java .nilai) FROM pesertakul.nilai).maasiswa.nangka*matakul.kodekul GROUP BY matakul. MAX(pesertakul. mahasiswa.kelas.kul).pesertakul.nilai. mahasiswa. Jadi kalau ada sedikit error.nrp. ii.nrp=pesertakul.SUM(nilai. AVG(pesertakul. aku sudah bilang “sori”.sks) FROM mahasiswa.nilai WHERE mahasiswa.kul). mahasiswa.nama.s ks)/SUM(matakul.namakul 19:\> SELECT pesertakul.mahasiswa WHERE mahasiswa.nihuruf=nilai.AVG(pesertakul.nrp GROUP BY 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.kodekul=matakul.nilai.kodekul=matakul.nama.nilaikul.kelas. rasanya tidak etis jika aku kembali membahas konsep JDBC.alamat FROM dosen WHERE dosen.nrp=pesertakul.pesertakul WHERE pesertakul.17:\> SELECT mahasiswa.nilai.kul) FROM matakul. MIN(pesertakul.jeniskel.matakul.kodekul AND pesertakul.alamat AS alamat FROM mahasiswa WHERE mahasiswa. Java Database Connectivity First Run! Setelah kita membahas habis SQL dengan begitu detail.dosen. MAX(pesertakul.nilai).jeniskel 20:\> SELECT mahasiswa.kode 18:\> SELECT matakul.

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

"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

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

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

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

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

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

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

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

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

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

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

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

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

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

studi kasus jdbc – address book .

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

*.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(). import import import import java. private Action lastAction = new LastAction(). private Action firstAction = new FirstAction().*.Membangun User Interface Utama: Class AddressBook Sekarang tiba saatnya untuk mengumpulkan user interface yang telah kita buat dalam satu aplikasi Address Book. javax. private Action nextAction = new NextAction().6 – Aplikasi AddressBook yang menyebabkan kita bisa berinteraksi dengan database. Class ini menyediakan tombol dan menu-menu untuk menjalankan class-class yang telah kita buat. private Action viewContactAction = new ViewContactAction().awt.swing.awt. Listing 4.*. java.border. Gambar 4. private JMenu navMenu.*. private Action prevAction = new PrevAction().swing.event. 145 Studi Kasus JDBC – Adress Book . javax.

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

.

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

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

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

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

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

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

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

You're Reading a Free Preview

Mengunduh
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->