Anda di halaman 1dari 304

Java Desktop

Aplikasi POS Berarsitektur Three Tier Menggunakan Swing, Hibernate dan Spring

I nu Bi!a
i nubi!a"org #i nubi!a

Kata Pengantar
Menulis adalah kegiatan paling saya suka di sela-sela kesibukan sehari-hari. Menulis, terutama pengetahuan, akan memberikan efek berantai kepada seluruh pembacanya. Menulis juga membuka gerbang peradaban yang bernama Sejarah. Tidak ada sejarah tanpa budaya menulis. Java Desktop ini adalah buku pertama saya, dan semoga menjadi yang pertama dari sekian banyak buku yang bisa saya tulis. si dari buku ini berasal dari pengalaman saya membuat aplikasi desktop java selama kurang lebih tiga tahun. !anyak pelajaran berharga yang saya petik dari pengalaman tersebut, baik pada saat menulis maupun pada saat membuat aplikasi. Seiring dengan "aktu saya ingin menuangkan dalam sebuah buku dan membaginya dengan teman-teman pembaca. #aktu yang saya habiskan untuk menulis buku ini ternyata lebih panjang dari yang saya perkirakan, tutorial S"ing dan JD!$, cikal bakal dari buku ini, saya tulis a"al tahun %&&'. (emudian semenjak pertengahan tahun %&)& saya meluangkan setiap "aktu luang saya, termasuk hari libur, menyelesaikan buku ini hingga pada bulan *ebruari %&)) buku ini saya rampungkan. +arapan saya buku ini bisa memberikan pengetahuan yang berguna bagi karir maupun pekerjaan teman-teman pembaca. Saya juga berharap pembaca dari buku ini bisa meningkatkan taraf hidup nya, baik dalam meniti karir maupun memulai karir sebagai developer. ,engajar seperti guru SM( atau Dosen dapat menggunakan buku ini sebagai panduan mata kuliah -ekayasa ,erangkat .unak. (alau anda dan institusi anda mendapatkan manfaat dari buku ini dan ingin berkontribusi balik, saya menerima donasi yang nantinya akan saya sumbangkan ke panti asuhan ,ermata +ati yang beralamatkan di / Jl. -oda 0o. %1, (elurahan !abakan ,asar, (ecamatan !ogor Tengah, !ogor2 Telepon/ 3&%4)5 67)% '7&. email / permatahatibogor8gmail.com, url / http/99permatahatibogor."ordpress.com, http/99saveorphan.dagdigdug.com Donasi bisa anda salurkan melalui rekening !$: %;7&<'667) atas nama fnu !ima *atkhan. :tau anda bisa mengirim pulsa ke nomer M7 saya dengan mengirim sms T, &64;1%))646' =nominal> ke )4), saya akan mengganti pulsa yang anda kirimkan dan menyumbangkan ke panti asuhan ,ermata +ati. Mohon kirimkan email kon?rmasi donasi sebagai catatan, saya akan mempublikasikan donasi anda di blog saya ifnubima.org. (alau donasi anda belum tercatat mohon ingatkan saya dengan mengirim email notifokasi. Donasi anda adalah masa depan anak-anak ini /

@ersi print buku Java Desktop ini bisa dibeli dari """.nulisbuku.com. +asil penjualan buku ini juga akan disumbangkan ke panti asuhan ,ermata +ati !ogor.

Artivisi Intermedia adalah partner resmi dari buku Java Desktop. Artivisi menyediakan training inhouse maupun regular dengan materi yang ada di buku ini. Trainer di Artivisi sudah sangat berpengalaman menggunakan teknik-teknik yang diterangkan dalam buku ini selama bertahun-tahun, selain itu Artivisi juga berpengalaman menyelenggarakan training Java untuk berbagai macam instansi, mulai dari pemerintahan, swasta hingga perorangan. anyak pengetahuan tentang best practice yang tidak bisa dicakup dalam buku ini dan hanya bisa disampaikan secara verbal dan praktek lewat training pro!esional yang Artivisi sediakan. Training pro!esional dapat mempercepat proses belajar hanya dalam " hari training, sedangkan membaca buku ini hingga selesai memerlukan waktu yang jauh lebih panjang. Training po!esional juga memastikan bahwa peserta benar-benar belajar langsung dengan bantuan trainer pro!esional sehingga pengetahuan yang diperoleh cepat dimengerti. #eserta juga dapat mengajukan studi kasus yang sedang dihadapi di perusahaan, sehingga setelah training selesai, peserta mempunyai project template yang bisa diteruskan sekembalinya dari training. $etelah training selesai, peserta langsung bisa membuat aplikasi tanpa membutuhkan waktu berbulan-bulan belajar, cukup " hari training saja. Artivisi Intermedia dapat dikontak lewat email in!o%artivisi.com, atau telp & '()*++))*", dengan -eliawati. Terimakasih sebesar-besarnya saya ucapkan untuk teman saya -obi (urnia"an Akurnia"anB8gmail.comC, http/99kurnia"anB.com yang telah berbaik hati mendesign sampul depan buku ini. -ekomendasi saya sepenuhnya kalau ada pembaca buku ini membutuhkan jasa designer. D5.

Lisensi
!uku ini mempunyai dua lisensi pendidikan9perorangan9komunitas. untuk institusi pendidikan dan untuk institusi non Jika anda me"akili institusi pendidikan seperti sekolah, akademi dan universitas lisensinya adalah E$reative $ommons :ttribution-0on$ommercial-Share:like 7.& Fnported .icenseG artinya adalah/ Tidak diperkenankan digunakan untuk tujuan komersial. Misalnya digunakan sebagai materi training profesional atau dicetak menjadi buku untuk tujuan mencari untung. Dianjurkan untuk digunakan sebagai bahan ajar di kelas, terutama -ekayasa ,erangkat .unak atau Sistem !erorientasi Hbjek. Diperkenankan untuk membuat produk turunan dari buku ini asal produk turunanya juga dilisensikan sebagai $reative $ommons dan saya sebagai penulis diakui sebagai pembuat a"al materi ini. +al ini agar memungkinkan institusi pendidikan mengganti sampul, header, footer dan sebagian teks dari buku ini untuk mencerminkan institusi pendidikan tersebut.

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a cop o! this license" visit http#$$creativecommons.or%$licenses$b -ncsa$3.0$ or send a letter to Creative Commons" &&& Castro Street" Suite '00" (ountain )iew" Cali!ornia" '&0&*" USA. Jika anda me"akili institusi non pendidikan, perorangan atau komunitas, lisensinya adalah E$reative $ommons :ttribution-0on$ommercial-0oDerivs 7.& Fnported .icenseG artinya adalah / Tidak diperkenankan digunakan untuk tujuan komersial. Misalnya digunakan sebagai materi training profesional atau dicetak menjadi buku untuk tujuan mencari untung. Dianjurkan menyebar luaskan buku ini baik secara soft copy 3pdf5 maupun hard copy. Diperkenankan meletakkan ?le pdf buku ini di internet untuk dido"nload orang lain, tetapi lebih dianjurkan untuk menyebar link do"nload resmi buku ini / http/99tanyajava.com9do"nload9javadesktop Tidak diperkenankan melakukan perubahan terhadap isi buku ini. *ormat dokumen yang diperkenankan hanya pdf asli yang dido"nload dari link do"nload resmi.

This work is licensed under the Creative Commons Attribution-NonCommercial-No+erivs 3.0 Unported License. To view a cop o! this license" visit http#$$creativecommons.or%$licenses$b -ncnd$3.0$ or send a letter to Creative Commons" &&& Castro Street" Suite '00" (ountain )iew" Cali!ornia" '&0&*" USA.

Pendahuluan
!ertahun-tahun yang lalu saya melihat sebuah ?lm, judulnya EThe $ount of Monte $ristoG yang bercerita tentang seorang anak pelayan yang bisa menjadi seorang bangsa"an berkat bantuan temanya. Menjadi seorang bangsa"an 3menaikkan status sosial5 seseorang tidak cukup hanya dengan mempunyai harta, karena harta selalu bisa habis. Iuote dari ?lm tersebut yang selalu terngiang di kepala saya adalah E Jll give you something that nobody can take a"ay from you, kno"ledgeG. Saya ingin selalu bisa menjadi orang yang mengucapkan kata-kata tersebut ke semua orang. !uku ini adalah salah satu yang bisa saya lakukan, saya juga meng-host podcast java berbahasa indonesia/ ndo Java ,odcast 3http/99ifnubima.org9indo-java-podcast95 bersama rekan saya Dito Subandono. Selain itu saya juga aktif di berbagai milis Java seperti JFK, 0et!eans- ndonesia dan J.inuL. !elajar membuat aplikasi tidak bisa dilakukan tanpa proses melihat-mencontek-mencoba, buku ini ditujukan sebagai tempat anda melihat dan mencontek bagaimana sebuah aplikasi Java Desktop dibuat. !uku ini juga berusaha untuk mengajak anda mencoba menulis kode yang disediakan sehingga siklus melihat-mencontek-mencoba menjadi lengkap. ab ) kita akan membahas tentang Java *undamental, bab ini dibagi menjadi dua bagian besar/ belajar sintaks java dan belajar HH, menggunakan java. Di dalam bab ini juga dibahas tentang java 4 language enhancement yang mencakup beberapa perubahan fundamental di dalam sintaks java. ab ( membahas tentang tools yang kita gunakan, 0et!eans. !agaimana membuat project, menambahkan library, menambahkan library ke pallete, menggunakan editor dan debugger, dan seterusnya. ,enguasaan akan DM diperlukan untuk menaikkan produkti?tas, tanpa penguasaan DM yang baik, produkti?tas tinggi susah untuk dicapai. ab . membahas tentang koneksi ke database menggunakan JD!$. Di bab ini mulai dibahas tentang design-pattern dalam membuat kode. D:H dan Service adalah design-pattern sangat penting dalam akses database. Dilanjutkan dengan membahas H-M, +ibernate dan Spring untuk akses data. Dengan menggunakan +ibernate, produkti?tas programmer menjadi meningkat drastis dibanding menggunakan JD!$ murni. Spring digunakan sebagai ElemG untuk merekatkan berbagai macam komponen aplikasi, termasuk nanti digunakan sebagai tulang punggung arsitektur three tier ab / membahas tentang S"ing dan komponen-komponenya. Dibahas juga pattern M@$ yang digunakan komponen S"ing dalam mengolah dan menampilkan data. ab " membahas bagaimana membuat aplikasi ,HS. Dimulai dari membuat halaman master, dilanjutkan dengan membuat halaman pembelian dan penjualan. ab + membahas bagaimana membuat report dengan Jasper-eport. Di dalamnya termasuk juga teknik mengcompile report yang dibuat secara otomatis menggunakan ant script ba"aan dari 0et!eans. ab 0 membahas bagaimana mengimplentasikan arsitektur three tier menggunakan Spring -emoting. ab * merupakan bab terakhir yang membahas bagaimana membuat installer menggunakan B,ack, sehingga aplikasi mudah didistribusikan dengan adanya ?le installer. ,embaca bisa langsung meloncat ke !ab 7 kalau merasa sudah mempunyai dasar-dasar pengetahuan sintaks java maupun HH, . ,embaca juga bisa mele"ati bab < kalau sudah mengetahui dasar-dasar komponen S"ing. !uku ini mempunyai format penulisan untuk memudahkan pembaca. (ode akan ditampilkan dalam format yang berbeda dengan teLt biasa. (ode akan ditampilkan dalam sebuah kotak dengan font Monaco seperti contoh di ba"ah ini / public class HelloWorld{ public static void main(String[] args){ System.out.println(Hello World!!) ! ! $ommand line ditampilkan dalam format yang berbeda dan dia"ali dengan tanda N me"akili

prompt. $ontohnya seperti ini / " #avac HelloWorld.#ava Hutput dari command line di atas ditampilkan dalam format yang berbeda, seperti contoh di ba"ah ini. Hello World!! (alau anda melakukan copy-paste dari buku ke 0et!eans perlu diperhatikan bah"a beberapa karakter yang ada di dalam buku dikategorikan sebagai karakter illegal oleh 0et!eans 9 Java $ompiler. ,erbedaan ini terjadi karena encoding yang digunakan kemungkinan berbeda. perbedaan paling sering terjadi ada pada penggunaan karakter E 3petik dua5 yang berbeda dengan teLt editor O, periksa terlebih dahulu perbedaan ini sebelum memeriksa apakah kodenya benar atau salah. Source code buku ini bisa dido"nload dari F-. berikut ini / http/99project-template.googlecode.com9?les9java-desktop-book.Bip (ritik, saran, ide maupun laporan kesalahan ketik 9 narasi bisa dialamatkan ke ifnubima8gmail.com atau ke akun t"itter 8ifnubima. :khir kata, selamat belajar semoga ilmu yang ada dalam buku ini bermanfaat untuk pembaca. $ingapore, 1ebruari (')).

Daftar Isi
Kata Pengantar.......................................................................................................................... iii Lisensi........................................................................................................................................ v Pendahuluan.............................................................................................................................. vi Pengenalan Java......................................................................................................................... 2 Instalasi JDK..........................................................................................................................3 HelloWorld............................................................................................................................ 3 Keyword, Identifiers dan A ses ontrol................................................................................ ! Keyword "ahasa Pe#rogra#an Java ...............................................................................! Identifiers ......................................................................................................................... $ A%%ess &odifier................................................................................................................ ' Anato#i (lass Java................................................................................................................' De larasi (lass..................................................................................................................) De larasi Interfa%e ........................................................................................................... * (lass vs +,-e%t.................................................................................................................. &ethod............................................................................................................................ .. (onstru%tor.......................................................................................................................2 Pro/erty............................................................................................................................! Konstanta........................................................................................................................ .' 0tru tur A/li asi Java...........................................................................................................' Pa% age........................................................................................................................... .' I#/ort...............................................................................................................................1 Jar.................................................................................................................................... .1 (lass/ath......................................................................................................................... .* 2aria,el dan &e#ory &anage#ent.....................................................................................23 2aria,el .......................................................................................................................... 23 Passing ,y value dan Passing ,y referen%e ....................................................................22 4i/e Data Pri#itif........................................................................................................... 23 Wra//er (lass................................................................................................................. 2! Array............................................................................................................................... 2$ 5ar,age (olle%tor........................................................................................................... 21 +/erator............................................................................................................................... 33 +/erator Assign#ent ..................................................................................................... 33 +/erator 6elasi............................................................................................................... 3. +/erator Instan%eof.........................................................................................................32 +/erator Arit#ati .......................................................................................................... 33 +/erator Kondisi.............................................................................................................3$ +/erator "itwise............................................................................................................. 3$ +/erator "it 0hift............................................................................................................3) +/erator Logi a.............................................................................................................. 3* 7low (ontrol........................................................................................................................!3 If ..................................................................................................................................... !. 0wit%h............................................................................................................................. !. 89%e/tion............................................................................................................................. !3 0inta s 89%e/tion............................................................................................................!3 (all 0ta% , 0ta% 4ra%e dan :n%aught 89%e/tion ..........................................................!! (lass 89%e/tion...............................................................................................................!'

Hirar i (lass 89%e/tion.................................................................................................. !) 4hrows dan 4hrow.......................................................................................................... $3 Perulangan ; Iterasi.............................................................................................................. $2 for.................................................................................................................................... $2 while ...............................................................................................................................$3 do<while.......................................................................................................................... $! ++P dengan Java.................................................................................................................$! 8n a/sulasi..................................................................................................................... $$ Inheritan%e, I0<A dan HA0<A......................................................................................... $$ Poli#orfis#e =Poly#or/his#>........................................................................................$) +verriding dan +verloading........................................................................................... $1 (asting 2aria,el 6eferen%e............................................................................................. $* Interfa%e.......................................................................................................................... $* (olle%tion dan 5eneri%s.......................................................................................................'3 to0tring............................................................................................................................'3 e?uals dan hash%ode........................................................................................................'. Java (olle%tion 7ra#ewor ............................................................................................ '! List.................................................................................................................................. '! 0et................................................................................................................................... '$ &a/................................................................................................................................. ') 0orting.............................................................................................................................'* (lass (olle%tions dan (lass Arrays.................................................................................). (lass Penting....................................................................................................................... )' 0tring, 0tring"uilder, 0tring"uffer................................................................................. )' Date, (alendar, Date7or#at............................................................................................)1 Joda 4i#e........................................................................................................................ 1. "igDe%i#al dan (urren%y...............................................................................................1) I;+........................................................................................................................................ *3 7ile.................................................................................................................................. *3 6eader............................................................................................................................. *. Writer.............................................................................................................................. *. In/ut0trea#.....................................................................................................................*2 +ut/ut0trea#.................................................................................................................. *2 I#ageI+.......................................................................................................................... *3 0o% et..............................................................................................................................*! Java $ :/date........................................................................................................................... *) 7eel of Java.......................................................................................................................... *) 8nhan%ed for Loo/.............................................................................................................. *) 7or Loo/ 0e,elu# Java $............................................................................................... *) 7or Loo/ di Java $.......................................................................................................... *1 Auto,o9ing;:n,o9ing......................................................................................................... ** Pri#itif dan Wra//er.......................................................................................................** 0tati% I#/ort...................................................................................................................... .33 :tility (lass.................................................................................................................. .33 2arargs............................................................................................................................... .33 7ungsi Dengan Ju#lah Para#eter 4ida 4eta/..............................................................33 4y/e0afe 8nu#...................................................................................................................3. 4i/e Data 8nu#............................................................................................................ .3. 5eneri%s............................................................................................................................. .32 4i/e Data di Dala# (olle%tion..................................................................................... .32

Annotations.........................................................................................................................33 &etadata.........................................................................................................................33 Kesi#/ulan........................................................................................................................ .3! Instalasi.............................................................................................................................. .3' &e#,uat Pro-e%t.................................................................................................................3' &ena#,ah an Li,rary........................................................................................................3) &engguna an 8ditor......................................................................................................... .3* &engguna an 2isual Designer.......................................................................................... ..' &e#,uat 2isual (o#/onent............................................................................................. ..' "e er-a dengan -endela /allet............................................................................................ ..) "e er-a dengan -endela /ro/erties.......................................................................................) "e er-a dengan -endela Ins/e%tor...................................................................................... ..) De,ugging ...........................................................................................................................) A ses Data,ase dengan JD"(............................................................................................... .2. &engenal JD"(................................................................................................................ .2. Data,ase Driver................................................................................................................. .2. &e#,uat Kone si...............................................................................................................22 &enyia/ an 4a,le ..............................................................................................................23 &enga#,il dan &e#ani/ulasi Data dari Data,ase............................................................23 &engguna an Pre/ared0tate#ent..................................................................................... .2$ "at%h 89e%ution..................................................................................................................2) &enangani 4ransa%tion.......................................................................................................2) &enda/at an ID yang Digenerate +to#atis..................................................................... .21 JD"(<+D"( "ridge......................................................................................................... .21 &e#anggil 7un%tion dan 0toredPro%edure....................................................................... .2* &odel, Dao dan 0ervi%e Pattern..............................................................................................3. 8ntity (lass ; &odel.......................................................................................................... .3. DA+ Pattern...................................................................................................................... .32 0ervi%e Pattern................................................................................................................... .33 +6&, Hi,ernate dan 0/ring....................................................................................................3) +,-e%t 6elational &a//ing.................................................................................................3) Hi,ernate ............................................................................................................................3) +,-e%t /ersisten%e...............................................................................................................31 +,-e%t<relational #is#at%h.................................................................................................31 5ranularity ................................................................................................................... .31 0u,ty/es ....................................................................................................................... .31 Identity ......................................................................................................................... .31 Asso%iation ....................................................................................................................31 @avigasi data .................................................................................................................3* I#/ele#entasi +6& untu &engatasi &asalah Ketida sesuaian.................................... .3* Identitas..........................................................................................................................3* Asosiasi......................................................................................................................... .3* @avigasi data..................................................................................................................3* &a//ing 0ederhana........................................................................................................... .!3 Konfigurasi Hi,ernate ..................................................................................................... .!. &en-alan an Hi,ernate ......................................................................................................!3 (lass<%lass Penting dala# Hi,ernate .................................................................................!! &engguna an Hi,ernate dengan 0/ring +6&................................................................. .!! Hi,ernate DA+ #engguna an 0/ring.......................................................................... .!$ 5eneri% DA+................................................................................................................ .!'

0/ring 0ervi%e............................................................................................................... .!) De%larative 4ransa%tion vs Progra#ati% 4ransa%tion.....................................................!* 0/ring (onfiguration dan 0/ring A//li%ation (onte9t......................................................$3 :tility %lass untu #engenerate ta,le dan initial data.................................................. .$! Hi,ernate &a//ing............................................................................................................ .$! 8ntity dan "asi% #a//ing............................................................................................. .$$ Id 5eneration................................................................................................................ .$' (lass Diagra#............................................................................................................... .$1 +ne<4o<+ne.................................................................................................................. .$* +ne<4o<&any dan &aster<Detail...................................................................................'3 &any<to<&any.............................................................................................................. .'2 (o#/onent.................................................................................................................... .'3 (olle%tion+f8le#ent.................................................................................................... .'! Inheritan%e......................................................................................................................'! Data,ase Inde9 ..............................................................................................................'$ HAL................................................................................................................................... .'' Pro-e%tion...................................................................................................................... .') (ondition........................................................................................................................') Para#eter "inding........................................................................................................ .'1 +rder "y.........................................................................................................................'* Agregat...........................................................................................................................'* 0u,?uery....................................................................................................................... .'* Join................................................................................................................................ .'* &asalah LaByInitialiBation89%e/tion, @C. 0ele%t, LaBy fet%h dan 8ager fet%h...........'* 4ransfor#ation...............................................................................................................)3 Hi,ernate (a%he..................................................................................................................). 7irst level %a%he............................................................................................................ .). 0e%ond level %a%he........................................................................................................ .). 0wing.......................................................................................................................................)$ Java 7oundation (lass ...................................................................................................... .)$ 7eature J7(.........................................................................................................................)$ 0wing Pa% age....................................................................................................................)' 0wing HelloWorld............................................................................................................. .)' Install Java Develo/#ent Kit.........................................................................................)' &e#,uat /rogra# HelloWorld .................................................................................... .)) &ela u an o#/ilasi /rogra# HelloWorld................................................................. .)) &en-alan an /rogra# HelloWorld............................................................................... .)) &e#,uat 0wing HelloWorld dengan @et"eans ................................................................)) Ko#/onen 0wing ................................................................................................................. .)* 0tru tur Ko#/onen 0wing................................................................................................ .)* "e er-a dengan JLa,el, J4e9t7ield dan J"utton.................................................................)* "e er-a dengan J(he% "o9 dan J6adio"utton................................................................. .12 "e er-a dengan JList dan J(o#,o"o9 ..............................................................................1! "e er-a dengan &enu, Po/u/ &enu dan 4ool,ar............................................................. .1' &e#,uat &enu............................................................................................................. .1) &e#,uat Po/u/ &enu .................................................................................................*3 &e#,uat 4ool,ar.......................................................................................................... .*. &e#,uat Dialog dan J7ile(hooser................................................................................... .*3 &e#,uat /re<defined dialog dengan J+/tionPane........................................................*3 &e#,uat J7ile(hooser................................................................................................. .*'

Konse/ &2(...........................................................................................................................** &odel dala# Ko#/onen 0wing ....................................................................................... 233 4a,le&odel................................................................................................................... 23. List&odel ..................................................................................................................... 232 6enderer ............................................................................................................................232 8ditor ................................................................................................................................ 233 A/li asi P+0.......................................................................................................................... 23) Data &aster........................................................................................................................231 &endesign 0%reen ........................................................................................................ 23* &e#,uat %lass &ain dan Inisialisasi 0/ring A//li%ation (onte9t...............................2.2 &eleng a/i ode PersonPanel...................................................................................... 2.$ Data 4ransa si................................................................................................................... 22' &e#/ersia/ an 0%reen 4ransa si Pen-ualan................................................................221 &e#,uat 0ervi%e dan DA+ untu 0ales dan Produ%t.................................................. 232 &eleng a/i Kode di (lass Produ%tLoo u/Dialog....................................................... 23$ &eleng a/i Kode (lass 0alesPanel..............................................................................23) Jas/er6e/orts..........................................................................................................................2!* Pengenalan ........................................................................................................................2!* Persia/an............................................................................................................................2!* La/oran 4ransa si Harian..................................................................................................2$3 &e#,uat Jas/er6e/orts &engguna an i6e/ort 2isual Designer................................2$. &e#,uat 7ield.............................................................................................................. 2$2 &en%o#/ile 7ile -r9#l &en-adi -as/er &engguna an Ant 4as ................................2$! &e#/ersia/ an 6e/ort0ervi%e..................................................................................... 2$' &e#,uat :I 6e/ort...................................................................................................... 2$* Arsite tur 4hree 4ier.............................................................................................................. 2'3 &atri s Per,andingan antar /roto ol re#oting............................................................ 2'! I#/le#entasi Arsite tur 4hree 4ier.............................................................................. 2'! &e#,uat 0erver dan (lient (lass.................................................................................2'1 IB/a% ..................................................................................................................................... 2)3 &e#,uat Installer dari 0a#/le di IBPa% ..........................................................................2)3 D&L Konfigurasi IBPa% ...................................................................................................2)$ 4ag IntsallationEinstallationF....................................................................................... 2)) 4ag Infor#ation EinfoF.................................................................................................2)) 2aria,el, 4ag 2aria,el Evaria,leF dan 4ag dyna#i% varia,el Edyna#i%varia,leF.....2)) Kondisi dan 4ag Kondisi E%onditionsF ....................................................................... 2)1 4ag 5:I Preferen%e Egui/refsF....................................................................................2)* 4ag Lo%aliBation Elo%aleF.............................................................................................213 4ag 6esour%es Eresour%esF...........................................................................................213 Panel E/anelsF.............................................................................................................. 213 Panel<Panel yang Disedia an IBPa% .................................................................................212 HelloPanel dan H4&LHelloPanel................................................................................ 213 (he% edHelloPanel.......................................................................................................213 InfoPanel dan H4&LInfoPanel.................................................................................... 213 Li%en%ePanel dan H4&LLi%en%ePanel........................................................................ 213 Pa% sPanel.................................................................................................................... 213 4argetPanel....................................................................................................................213 InstallPanel....................................................................................................................213 7inishPanel....................................................................................................................213 &e#,uat Installer A/li asi P+0....................................................................................... 213

Persia/an....................................................................................................................... 21! &e#,uat 0tartu/ 0%ri/t................................................................................................ 21! &e#,uat Ant 0%ri/t Installer........................................................................................21) Penutu/................................................................................................................................... 21* 6eferensi dan "a%aan Le,ih Lan-ut....................................................................................... 2*3

!:K :0 ) J:@: *F0D:MM0T:.

Pengenalan Java
!erbicara mengenai Java, kita sebenarnya membicarakan tentang dua hal yang saling berkaitan. Pang pertama adalah Java sebagai bahasa pemrograman dan Java sebagai platform pengembangan aplikasi. Di bab Java *undamental ini kita akan belajar mengenai Java sebagai bahasa pemrograman, kita akan belajar bagaimana menulis kode Java dengan benar tanpa ada kesalahan sintaks. Setelah mele"ati bab Java *undamental kita akan belajar Java sebagai platform pengembangan aplikasi. !ahasa pemrograman Java pada a"alnya dibuat oleh James Kosling pada tahun )114 sebagai bagian dari Sun Microsystem Java ,latform. Sintaks Java banyak diturunkan dari $ dan $QQ tetapi lebih sederhana, ketat dan mempunyai akses ke HS yang lebih terbatas. +al ini karena Java ditujukan sebagai bahasa pemrograman yang cukup sederhana untuk dipelajari dan mudah dibaca. :plikasi Java ditulis sebagai ?le berekstensi .java yang dicompile menjadi ?le .class. *ile .class ini adalah bytecode yang bisa dijalankan di semua Java @irtual Machine, tidak peduli apapun HS-nya ataupun arsitektur processornya. Java adalah bahasa yang ditujukan untuk semua kebutuhan, concurent, berbasis class, object oriented serta didesain agar tidak tergantung terhadap lingkungan dimana aplikasi dijalankan 3HS dan processor5. Java ditujukan agar bisa Editulis sekali, bisa jalan di manapunG. Sekarang ini Java adalah bahasa pemrograman paling populer dan paling banyak digunakan untuk membuat aplikasi baik aplikasi di embedded system, mobile, desktop hingga "eb application. Java mempunyai empat prinsip penting yang dijadikan sebagai tujuannya, keempat prinsip ini adalah / ). %. 7. <. 4. Java harus Esederhana, object oriented dan mudah dimengertiG Java harus Ekuat dan amanG Java harus Enetral terhadap arsitektur system 3HS,processor5 dan bisa jalan di manapunG Java harus bisa dijalankan dengan Ekinerja yang tinggiG Java harus Einterpreted, threaded dan dinamisG

Dengan kelima prinsip di atas, aplikasi java mempunyai popularitas yang sangat tinggi terutama di dunia enterprise application. Dimana semua prinsip di atas sangat cocok untuk jenis aplikasi ini. ndustri yang mempunyai budget tinggi untuk T seperti perbankan dan telekomunikasi menggunakan Java secara ekstensif. !anyak aplikasi dengan skala raksasa dibangun menggunakan platform Java. Java ,latform terdiri dari tiga buah pro?le / Java MM 3Java Micro Mdition5 adalah java yang bisa berjalan di dalam embedded system seperti Java $ard dan +andphone. Java SM 3Java Standard Mdition5 adalah java yang bisa berjalan di dalam ,$ maupun server sebagai aplikasi standalone maupun aplikasi desktop. Java MM 3Java Mnterprise Mdition5 adalah pro?le java yang ditujukan untuk membuat aplikasi Mnterprise seperti #eb :pplication 3Servlet5 dan Mnterprise Java !ean 3MJ!5. nstalasi platform Java terdiri dari dua paket aplikasi. ,aket yang pertama adalah J-M 3Java -untime Mnvironment5, paket ini terdiri dari semua aplikasi yang dibutuhkan agar sebuah aplikasi Java bisa berjalan, seperti library dan J@M 3Java @irtual Machine5. ,aket kedua adalah JD( 3Java Development (it5, paket ini terdiri dari J-M dan ditambah dengan perkakas untuk membuat aplikasi Java seperti java compiler 3javac5, java documentation 3javadoc5 dan java archive 3jar5. !uku ini membahas tentang bagaimana membuat aplikasi Java, sehingga diperlukan JD( terinstall terlebih dahulu di system anda sebelum bisa menjalankan contoh-contoh program yang ada di sini. Selama kita membahas Java *undamental, cukup install JD( saja dan gunakan teLt editor sederhana seperti notepad, vi, mcedit, teLtedit, notepadQQ, maupun emacs. Setelah mele"ati bab ini, kita akan menggunakan 0et!eans untuk membuat aplikasi yang sebenarnya. !uku ini mengasumsikan pembacanya sudah pernah belajar dasar-dasar :lgoritma

pemrograman sehingga cukup mengerti konsep-konsep dasar seperti variabel, struktur data, tipe data, iterasi, kondisi, operator dan logika matematika. Dengan asumsi ini, buku ini tidak lagi membahas pengertian apa itu variabel atau apa itu tipe data, kita langsung menerangkan bagaimana variabel di Java, bagaimana tipe data di Java dan seterusnya. (alau anda belum mengerti mengerti mengenai konsep-konsep algoritma pemrograman sebaiknya baca dahulu buku :lgoritma pemrograman yang cukup banyak tersedia di toko buku. !agian pertama bab ini akan membahas bagaimana menyiapkan system anda agar bisa membuat kode sederhana dengan java, mengcompile dan menjalankan kode yang sudah dicompile.

Instalasi JDK
nstalasi JD( dia"ali dengan mendo"nload JD( dari "ebsite oracle / http/99""".oracle.com9technet"ork9java9javase9do"nloads9indeL.html Setelah proses do"nload selesai, lanjutkan dengan instalasi JD(. ,roses instalasi sangat sederhana, klik dua kali ?le yang sudah dido"nload dan anda akan diarahkan melalui langkah demi langkah proses instalasi. Setelah selesai, java akan diinstall ke folder instalasi, kalau di "indo"s, instalasi java ada di $/R,rogram *ilesRJavaRjdk).;.&S%7 dimana ).;.&S%7 adalah versi dari jdk. ,astikan bah"a instalasi sukses dengan menjalankan perintah ini di command prompt / " #ava $version .angkah berikutnya adalah memastikan perkakas development seperti java compiler 3javac5 dapat diakses dari command prompt. $aranya adalah dengan memasukkan folder instalasi java ke dalam path. kuti langkah berikut ini untuk menambahkan folder instalasi java ke dalam path ). %. 7. <. 4. klik kanan my computer, pilih properties setelah terbuka jendela properties, pilih tab advance di dalam path path advance klik tombol system variables di dalam jendela system variables pilih baris yang terdapat path, klik tombol edit tambahkan folder $/R,rogram *ilesRJavaR).;.&S%7Rbin diakhir dari pathnya, jangan lupa menambahkan D sebagai pemisah

;. test langkah-langkah di atas dengan menjalankan perintah berikut ini dari command prompt / " #avac $version #avac %.&.'()) Setelah langkah-langkah di atas berhasil dijalankan, kita siap untuk membuat kode pertama menggunakan Java. .angkah instalasi java untuk Mac dan .inuL tidak saya sertakan dalam buku ini, saya menganggap pengguna Mac dan .inuL cukup cerdas untuk melakukanya sendiri Teaaa.

HelloWorld
(ode +ello#orld selalu menjadi kode pertama yang coba dibuat di berbagai macam bahasa pemrograman. Tradisi menulis kode +ello#orld sudah dilakukan selama bertahun-tahun. Menulis kode +ello#orld di Java sangat mudah, mari kita coba. !uat sebuah folder kosong untuk menyimpan ?le .java yang akan kita buat, misalnya di c/Rsample-code atau 9home9user9sample-code setelah itu buka teLt editor dan tulis kode berikut ini / public class HelloWorld{ public static void main(String[] args){ System.out.println(*HelloWorld!*) ! ! Simpan dengan nama HelloWorld.#ava+ ingat nama class harus sama persis dengan nama ?le,

jadi kalau nama class-nya adalah HelloWorld maka nama ?lenya adalah HelloWorld.#ava. Setelah disimpan, compile ?le HelloWorld.#ava menggunakan javac. Jangan lupa untuk memastikan bah"a sekarang berada di dalam folder yang sama dengan folder yang digunakan untuk menyimpan ?le HelloWorld.#ava tersebut. " #avac HelloWorld.#ava (alau proses kompilasi berjalan dengan baik, maka tidak ada pesan sama sekali dan di folder yang sama akan dibuat ?le +ello#orld.class, setelah kompilasi selesai sekarang kita jalankan class +ello#orld. " #ava HelloWorld HelloWorld! " ,erhatikan bah"a yang dijalankan dalam kode di atas adalah class +ello#orld bukan ?le +ello#orld.class. Sampai di sini kita sudah bisa melakukan kompilasi ?le .java dengan menggunakan java compiler 3javac5 dan menjalankan class menggunakan J@M 3java5. Setelah bisa membuat kode +ello#orld, sekarang kita akan memeriksa anatomi class java dan memahami bagian-bagian dari class java.

Keyword, Identifiers dan Akses kontrol


,ada dasarnya aplikasi java adalah sekumpulan class-class yang saling berbicara satu dengan yang lain dengan cara mengeksekusi method class lain dan mengirimkan pesan dengan memasukkan parameter ke dalam method. Dalam bagian ini kita akan belajar mengenai anatomi class dalam java, key"ord, kemudian identi?ers dalam java dan konsep akses kontrol.

Keyword Bahasa Pemrograman Java


,ada bab pengenalan java ini kita akan membahas mengenai dasar-dasar bahasa java. (alau kita belajar bahasa ndonesia pasti yang pertama kita bahas adalah kosa-kata dan pembentukan kalimat seperti S,H(. !ahasa pemrograman Java tidak serumit bahasa indonesia yang mempunyai jutaan kosa kata, Java hanya mempunyai << buah kosa kata 3(ey"ord5. Semua (ey"ords ini adalah kepunyaanya bahasa Java, kita harus menggunakanya dengan benar dan tidak boleh digunakan untuk tujuan lain, misalnya sebagai nama variabel atau nama class. !erikut ini adalah daftar << buah (ey"ord java / abstract char double for int private strictfp thro"s assert !oolean class else goto interface protected super transient enum break const eLtends f long ,ublic s"itch try byte continue ?nal implements native return synchroniBed void case default ?nally import ne" short this volatile catch do Uoat instanceof package static thro" "hile

(ita akan membahas (ey"ord di atas seiring dengan bab-bab dalam buku ini. !eberapa (ey"ord sudah cukup familiar di semua bahasa pemrograman, sehingga tidak perlu lagi diterangkan secara mendetail.

Identifiers
denti?ers adalah nama-nama yang bisa dideklarasikan dalam java tetapi bukan bagian key"ord java, yang termasuk dalam identi?ers antara lain/ class, interface, variabel9property dan method. Tata cara penamaan identi?ers di java diatur oleh beberapa aturan/ :turan dari compiler untuk menentukan apakah nama identi?ers diperbolehkan atau tidak. (onvensi penamaan identi?ers daru Sun yang biasa disebut sebacai OJava $ode $onventionO. Standard penamaan Java!ean.

(ita akan bahas satu per satu aturan di atas. :turan dari compiler tentang penamaan identi?ers sangat jelas, karena akan ada error pada "aktu kompilasi kalau aturan ini dilanggar. !erikut ini aturan penamaan identi?ers yang digunakan oleh compiler :turan pertama sudah kita bahas sebelumnya adalah semua key"ord java tidak boleh digunakan sebagai identi?ers. denti?ers harus dia"ali oleh huruf, simbol mata uang dolar3N5 atau karakter penghubung underscore 3S5. :ngka tidak boleh digunakan sebagai karakter pertama identi?ers. Setelah karakter pertama, berikutnya boleh diikuti oleh huruf, simbol mata uang dolar, karakter penghubung, dan angka. Tidak ada pembatasan panjang identi?ers denti?ers di java bersifat case-sensitif, foo dengan *oo adalah dua buah identi?ers berbeda. 0ama public class harus sama persis dengan nama ?le .java

!erikut ini adalah contoh identi?ers yang diijinkan / int (, int "y int ((((((%-(r int (" int ini(adala.(nama(identi/iers(yang(pan#ang(se0ali(bertele(tele(dan(alay !erikut ini adalah contoh identi?ers yang tidak diijinkan oleh compiler java int %)1test(test int ,2 int ,3 int ,3 int .titi0 Java $ode $onvention adalah sekumpulan aturan Otidak resmiO yang dibuat oleh Sun. Salah satu bagian dari $ode $onvention itu membahas bagaimana menamakan identi?ers yang seragam. .atar belakang dibuatnya Java $ode $onvention ini berasal dari penelitian yang menyebutkan bah"a usaha untuk menulis kode 3development5 hanya berkisar %&V saja, sedangkan 6&V usaha dikerahkan untuk memelihara kode dan menambahkan feature baru ke dalam aplikasi. +al ini mendorong Sun untuk menyusun Java $ode $onvention agar usaha untuk membaca kode lebih mudah dan pada akhirnya kode menjadi lebih mudah untuk dipelihara dan dipahami. !erikut ini beberapa konvensi yang digunakan dalam Java $ode $onvention $lass dan nterface selalu dia"ali dengan huruf besar. Setiap kata selalu dia"ali dengan huruf besar untuk memudahkan pembacaan. Kaya ini biasa disebut dengan O$amel $aseO. $ontohnya/ -unnable, +ashMap, :rray.ist dan seterusnya. Selain itu, class haruslah merupakan kata benda, bukan kata sifat atau kata kerja. Method selalu dia"ali dengan huruf kecil. Setiap kata setelah huruf pertama dia"ali dengan huruf besar. Method haruslah kata kerja untuk menandakan bah"a method ini melakukan suatu kegiatan 9 aksi. $ontohnya / get ndeL, set ndeL, println, paint, dan seterusnya. @ariabel menggunakan camel case yang dia"ali dengan huruf kecil, seperti method. @ariabel

sebaiknya pendek, jelas, terdengar enak dan kata benda. $ontohnya / indeL, panjang, lebar, indeL,ertama dan seterusnya. (onstanta di java dibuat dengan mendeklarasikan sebuah variabel sebagai statif dan ?nal, semua hurufnya adalah huruf besar yang antar kata dipisahkan oleh simbol underscore 3S5. $ontohnya / *-:MMS# DT+, M--H-SMMSS:KM dan seterusnya.

(onsep Java!ean dibuat oleh Sun sebagai dasar dari komponen dalam aplikasi java, salah satu kegunaan praktisnya adalah penggunaan Java!ean oleh DM seperti 0et!eans agar komponenkomponen S"ing bisa dimanipulasi secara visual. *rame"ork modern seperti Spring dan MJ! juga sudah mengadopsi konsep Java!ean, sehingga istilah Java!ean sangat sering muncul di dokumentasi frame"ork ini, Spring menggunakan istilah bean saja bukan Java!ean, tapi secara teknis keduanya sama persis. Fntuk memahami konsep Java!ean, ada satu istilah yang disebut dengan ,roperties. ,ada dasarnya properties adalah sebuah instance variabel, yaitu variabel yang berada tepat di ba"ah class, yang access modi?er-nya private. (arena bersifat private maka harus dibuat method untuk mengakses properties dari luar class tersebut. Method untuk mengakses properties biasa disebut sebagai getter dan method untuk mengubah nilai properties disebut sebagaui setter. !erikut ini aturan penamaan method yang digunakan untuk mengakses properties 3getter setter5 dari Java!ean/ (alau tipe data properties bukan boolean maka method untuk mengakses properties dia"ali dengan get. misalnya get#idth, getSiBe, get ndeL dan seterusnya. (alau tipe data properties adalah boolean maka method untuk mengakses properties dia"ali dengan is. Misalnya isMmpty, is-unning dan seterusnya. Semua method setter harus dia"ali dengan set. Misalnya setSiBe, set ndeL, set#idth dan seterusnya 0ama method diturunkan dari nama variabel yang diberi a"alan get, set atau is. :turan penulisan camel case berlaku untuk method getter dan setter. Method setter harus public, return void dengan satu parameter yang tipe datanya sama persis dengan tipe data variabel. Method setter harus public, return tipe data yang sama dengan tipe data variabel, dan tanpa parameter. Java!ean harus mempunyai default constructor, yaitu constructor yang tidak mempunyai parameter sama sekali.

Access Modifier
public, protected, default dan private adalah empat buah level access modi?er, fungsi dari access modi?er adalah mengatur bagaimana bagian-bagian kode java diakses dari bagian yang lain. :da bagian yang boleh diakses oleh siapapun karena kode di dalamnya sudah dirancang untuk itu, ada juga bagian yang hanya boleh diakses oleh class yang sama karena memang kodenya tergantung dengan bagian lain dari class tersebut dan tidak bisa digunakan oleh bagian lain. :ccess modi?er public menandakan bisa diakses oleh siapapun tanpa batasan. :ccess modi?er protected bisa diakses oleh class turunanya dan class-class lain yang berada dalam package yang sama. :ccess modi?er default tidak memerlukan key"ord, kalau tidak ada salah satu dari tiga access modi?er lain maka yang digunakan adalah access modi?er default. (alau access modi?er default digunakan, maka hanya class dari package yang sama saja yang bisa mengakses, termasuk class itu sendiri. Pang terakhir adalah access modi?er private yang hanya mengijinkan diakses oleh class yang sama.

Anatomi Class Java


!ab ini akan menjelaskan tentang anatomi class Java. ,ertama kita akan belajar tentang

bagaimana mendeklarasikan class dan interface, kemudian kita akan belajar tentang class member. Method, constructor dan variabel adalah tiga buah class member, dan ketiganya juga akan kita bahas dalam bagian terpisah. Memahami bagaimana mendeklarasikan class dan class membernya adalah pengetahuan paling dasar dalam membuat aplikasi java. ,erhatikan baik-baik aturan apa saja yang diperbolehkan dan dilarang dalam membuat class Java. :turan ini cukup banyak dan mengikat, a"alnya akan sedikit terasa merepotkan dan membutuhkan "aktu untuk menghafal aturan-aturan tersebut. Setelah beberapa lama, aturan itu menjadi mudah dipahami dan dihafal. Tidak ada yang lebih baik dibanding belajar dari praktek, oleh karena itu kita akan praktek menulis kode. Jangan dile"ati sesi menulis kode, usahakan tulis semua kode yang ada dalam bab ini, compile dan jalankan kodenya. Dengan begitu anda akan lebih cepat menghafal aturan dalam bahasa Java. Tanpa latihan berulang-ulang maka akan membutuhkan "aktu lebih lama lagi menguasai bahasa Java.

Deklarasi Class
$lass di dalam java dideklarasikan menggunakan key"ord class diikuti dengan nama class. Setelah nama class ada kurung kura"al buka 3W5 menandai a"al dari class dan kurung kura"al tutup 3X5 yang menandai akhir dari class. Hbject adalah instansiasi dari class. (ita bisa membayangkan bah"a class adalah sebuah cetakan dan object adalah materi hasil cetakan dari class. Setiap object akan mempunyai state 3instance variabel9properties5 yang membedakan satu object dengan object lain, kemudian object juga mempunyai behaviour 3method5 dimana logic dari class disimpan. $lass adalah jantungnya Java, class adalah bagian terkecil dari kode di java yang bisa berdiri sendiri. Setiap kali kita akan membuat sebuah kode java, yang pertama harus dideklarasikan adalah class. Java mengijinkan class dide?nisikan dalam beberapa cara berbeda. $ara pertama adalah mende?nisikan sebuah public class di dalam ?le .java. $ontohnya bisa kita lihat di ba"ah ini / public class 4erson { ! Simpan di dalam ?le ,erson.java, kemudian compile ?le .java di atas menggunakan java compiler 3javac5. " #avac 4erson.#ava Setelah proses kompilasi berhasil, lihat isi folder dengan menggunakan perintah dir 3"indo"s5 atau ls 3YniL5. Terlihat bah"a class ,erson dibuatkan satu buah ?le .class, dan nama dari ?le .class-nya sama persis dengan nama class-nya. (ode di atas adalah deklarasi minimal dari sebuah class Java, ada key"ord class diikuti oleh nama class-nya kemudian diikuti oleh kurung kura"al buka dan tutup. $ara kedua adalah beberapa class dideklarasikan di dalam satu ?le .java, tetapi dalam satu ?le .java hanya boleh dideklarasikan satu buah public class yang namanya sama dengan nama ?le .java. $ontohnya sebagai berikut / public class 4erson{! class 4erson){! class 4erson1{! class 4erson5{! Simpan di dalam ?le ,erson.java, kemudian compile ?le .java di atas menggunakan java compiler 3javac5. " #avac 4erson.#ava Setelah proses kompilasi berhasil, lihat isi folder dengan menggunakan perintah dir 3"indo"s5 atau ls 3YniL5. Terlihat bah"a setiap class dibuatkan satu buah ?le .class, dan nama dari ?le .classnya sama persis dengan nama class-nya. 4erson.class 4erson).class 4erson1.class 4erson5.class $ara ketiga adalah mendeklarasikan class sebagai inner class. !isa kita lihat bah"a cara kedua di

atas, deklarasi class kedua dan seterusnya berada di luar dari class pertama, kemudian ?le .class yang dihasilkan berbeda-beda, dan penamaan class-nya tidak menyertakan nama class public-nya, semuanya adalah class berbeda tetapi diletakkan dalam ?le yang sama. (onsep inner class berbeda, karena sekarang class yang dideklarasikan di dalam class lain 3inner class5. nner class sangat terikat dengan class dimana inner class itu berada. Misalnya dari sisi penamaan, nama inner class harus dia"ali dengan nama class dimana inner class berada kemudian diikuti dengan nama inner class itu sendiri. Misalnya contoh di ba"ah ini / public class 4erson{ private class 4erson){! private static class 4erson1{! class 4erson5{! ! $ompile ?le .java di atas menggunakan java compiler 3javac5. " #avac 4erson.#ava Setelah proses kompilasi berhasil, lihat isi folder dengan menggunakan perintah dir 3"indo"s5 atau ls 3YniL5. Terlihata bah"a setiap class dibuatkan satu buah ?le .class, nama ?le .class untuk inner class dia"ali dengan nama class di mana inner class berada kemudian ada tanda N dan diakhiri dengan nama innner class-nya. 4erson.class 4erson"4erson).class 4erson"4erson1.class 4erson"4erson5.class $ara deklarasi terakhir adalah anonymous inner class, yaitu inner class yang tidak mempunyai nama, loh kok bisaZ feature ini sering digunakan kalau kita ingin mengimplementasikan interface di satu tempat dan implementasi itu tidak pernah digunakan di tempat lain. $ontohnya sebagai berikut ini / public class 4erson{ private 6unnable t.read 7 ne8 6unnable(){ public void run(){ System.out.println(*HelloWorld /rom 9.read*) ! ! ! ,erhatikan kode di atas, ada sebuah variabel dengan nama thread, variabel tersebut adalah object dari class -unnable. (arena -unnable adalah interface, maka kita perlu membuat class yang implement interface, tetapi implementasinya tidak perlu membuat class baru dengan nama tertentu, cukup langsung ne" -unnable dan implementasikan method run langsung di situ. Simpan ke ?le ,erson.java dan coba compile menggunakan javac, setelah kompilasi berhasil lihat isi dari direktori, akan ada dua buah ?le class yaitu ,erson.class dan ,ersonN).class, nah class yang terakhir inilah anonymous inner class. (alau ada dua inner class atau lebih, penamaanya menjadi ,ersonN%.class, ,ersonN7.class dan seterusnya. Setelah kita membahas cara deklarasi java, sekarang kita bahas aturan-aturan yang harus dipatuhi pada "aktu pendeklarasian class di Java. :turan-aturan tersebut antara lain / +anya boleh ada satu class public dalam satu ?le .java, non public class boleh lebih dari satu di dalam satu ?le .java 0ama class public harus sama dengan nama ?le .java (omentar bisa diletakkan di mana saja Jika class berada dalam sebuah package, maka harus ada deklarasi package di bagian paling atas dari ?le .java mport berada antara deklarasi package dan deklarasi class

Deklarasi import dan package berlaku untuk semua class dalam ?le .java, tidak mungkin mende?nisikan dua buah class yang mempunyai package berbeda di dalam satu ?le .java

Dalam aturan di atas, ada poin yang menyebutkan tentang package. ,ackage adalah feature yang sangat penting dalam Java, pada dasarnya package adalah sebuah folder yang memisah-misahkan class. $lass dengan fungsi yang mirip akan dikelompokkan dalam satu package yang sama, hal ini dimaksudkan untuk memudahkan pengelolaan class agar mudah dipahami. (ita bisa meletakkan beberapa key"ord pada "aktu pendeklarasian class. Jenis key"ord pertama yang bisa digunakan adalah access modi?er, key"ord access modi?er terdiri dari empat level / public, default, protected dan private. +anya tiga dari empat level tersebut yang benar-benar merupakan key"ord, access modi?er default bukan merupakan key"ord karena kalau tidak ada satupun dari ketiga access modi?er digunakan di dalam deklarasi class maka kita menyebutnya default. (ita akan bahas satu per satu efek dari penggunaan access modi?er pada deklarasi sebuah class. Jika sebuah class dideklarasikan sebagai public, maka semua class yang lain dapat melihat class tersebut. Melihat di sini dalam arti bisa mengimport, menginstansiasi, mengeLtends dan memanggil method yang ada dalam class. Jika sebuah class dideklarasikan sebagai default atau tidak ada access modi?er sama sekali, maka hanya class dari package yang sama atau class turunanya yang dapat melihat class tersebut. $lass tidak bisa dideklarasikan sebagai protected. ,rivate hanya bisa digunakan oleh inner class saja, sedangkan class lain tidak bisa ditandai sebagai private. Selain access modi?er, class bisa dideklarasikan menggunakan key"ord ? nal. Jika class dideklarasikan dengan key"ord ?nal maka class ini tidak bisa dieLtends oleh class lain, salah satu alasan kenapa class ditandai ?nal agar tidak ada implementasi lain selain class ini. Semua class "rapper seperti String ditandai sebagai ?nal agar tidak ada yang mengeLtends class String ini. (ey"ord abstract bisa digunakan untuk mendeklarasikan class, hal ini akan menyebabkan abstract class tidak dapat diinstansiasi atau dibuat objectnya.

Deklarasi Inter ace


nterface pada dasarnya adalah sebuah class, hanya saja method-method di dalamnya hanya berupa deklarasi saja, tidak ada implementasi dari method-method tersebut. Secara teknis bisa dikatakan bah"a interface adalah class yang bersifat abstract, semua methodnya adalah public dan abstract, serta semua variabel yang ada dalam interface adalah static ?nal atau biasa disebut sebagai konstanta. Deklarasi interface menggunakan key"ord interface diikuti dengan nama interface. $ontoh paling sederhana dari sebuah interface bisa kita lihat dalam kode di ba"ah ini/ inter/ace 4erson:ao{! :turan penamaan interface sama dengan penamaan class, kemudian aturan pendeklarasian interface juga sama dengan pendeklarasian interface. +anya saja tidak ada istilah inner interface layaknya inner class. Sebagai contoh kita akan membuat class ,ersonDao mpl yang mengimplementasikan interface ,ersonDao, di dalam interface ,ersonDao ada tiga buah method/ save, delete dan get!y d sehingga class ,ersonDao mpl harus mengimplementasikan ketiga method ini. public class 4erson{ private ;ong id private String nama public String get<ama(){ return nama ! public void set<ama(String nm){ nama 7 nm ! public ;ong get=d(){ return id ! public void set=d(;ong i){ id 7 i

nterface dideklarasikan dengan menggunakan key"ord interface. Di dalamnya ada methodmethod yang dideklarasikan tetapi belum ada implementasinya, ditandain dengan adanya titik koma 3D5 setelah deklarasi method. (alau method sudah diimplementasikan maka setelah deklarasi method harus ada pasangan kurung kura"al buka tutup 3WX5 yang menandai blok kode yang akan dieksekusi kalau method tersebut dipanggil. public inter/ace 4erson:ao{ void save(4erson p) void delete(4erson p) 4erson get>y=d(;ong id) ! $lass mengimplementasikan interface dengan menggunakan key"ord implements. Semua method dalam interface bersifat public sehingga "alaupun dalam deklarasi interface tidak ada public tetapi di class yang mengimplementasikan interface harus meletakkan access identi?ers public pada deklarasi methodnya. public class 4erson:ao=mpl implements 4erson:ao{ public void save(4erson p){ System.out.println(*menyimpan 4erson*) ! public void delete(4erson p){ System.out.println(*meng.apus person*) ! public 4erson get>y=d(;ong id){ 4erson p 7 ne8 4erson() p.set=d(id) p.set<ama(*abc*) return p ! ! Sebuah class bisa mengimplementasikan lebih dari satu interface, antara satu interface dengan interface yang lain dipisahkan dengan tanda koma, seperti contoh sederhana di ba"ah ini / public inter/ace 4erson:ao=mpl implements 4erson:ao+ Seriali?able{! nterface biasanya digunakan sebagai OkontrakO agar sebuah class yang mengimplementasikan interface mempunyai semua method yang ada dalam interface itu, tetapi kita tidak ingin mengekspose implementasinya. Salah satu contoh penggunaan interface adalah JD!$ :, . di dalam JD!$ :, terdapat banyak interface seperti $onnection, -esultSet, Statement, ,reparedStatement dan seterusnya. Setiap database yang ingin bisa diakses dari Java akan mengimplementasikan JD!$ :, ini dengan cara membuat class yang mengimplementasikan semua interface dalam JD!$ :, . Sehingga kalau kita ingin melakukan koneksi ke MySI. ataupun ke Hracle, interfacenya sama, yang berbeda hanya implementasinya saja. mplementasi dari JD!$ :, ini sering dikenal sebagai JD!$ Driver. Mengenai JD!$ kan kita bahas lebih lanjut di bagian akses data ke database, sekarang kita fokuskan ke nterface. nterface juga digunakan dalam best practice yang sering disebut dengan Ocode to interfaceO, best practice ini menganjurkan developer untuk menggunakan interface antar layer dalam aplikasi. Misalnya contoh di atas kita membuat sebuah interface dengan nama ,ersonDao untuk melakukan operasi penyimpanan object person, dengan membuat interface seperti ini kita bisa mempunyai implementasi berbeda-beda untuk proses penyimpanan object person. Di contoh di atas implementasi ,ersonDao sangat sederhana hanya menulis string ke stdout, kita juga bisa membuat misalnya ,ersonDaoJdbc untuk menyimpan object person ke database dengan menggunakan JD!$, atau bisa juga dibuat ,ersonDao+ibernate untuk menyimpan object person ke database menggunakan +ibernate. (alau anda masih sulit memahami dua paragraf terakhir tentang interface, tidak masalah, tujuan utama bab ini adalah menjelaskan tentang bagaimana membuat interface, seiring

dengan bab-bab selanjutnya kita akan belajar lebih jauh mengenai beberapa teknologi yang sempat disinggung di atas.

Class vs !"#ect
Hbject adalah instansiasi dari sebuah $lass. (alau kita analogikan, class itu sebuah cetakan sedangkan object itu adalah barang dari hasil cetakan. $lass juga bisa dikatakan sebagai kategori, sedangkan object adalah sesuatu yang memenuhi syarat-syarat yang harus dipenihi agar masuk dalam kategori tersebut. Jadi bisa dibilang satu class bisa mempunyai banyak object, setiap object mempunyai sifat yang sama persis seperti yang dide?nisikan dalam class tersebut. (ita ambil contoh adalah class ,erson, kemudian kita buat sebuah instance dari class ,erson yaitu ifnu. (alimat di atas kalau di"ujudkan dalam kode menjadi seperti di ba"ah ini / 4erson i/nu 7 ne8 4erson() Dua kata paling kiri adalah proses deklarasi sebuah object dengan tipe ,erson, kemudian di sebelah kanan tanda sama dengan 3[5 terjadi proses instansiasi object dari class ,erson menggunakan key"ord ne". Setiap kali kita bertemu key"ord ne" artinya hanya satu, yaitu instansiasi object dari sebuah class. (ey"ord ne" secara detail dalam level yang paling ba"ah, menyebabkan J@M akan membuat object di dalam memory.

Method
Method adalah sekumpulan kode yang diberi nama, untuk merujuk ke sekumpulan kode tersebut digunakan sebuah nama yang disebut dengan nama method. Method mempunyai parameter sebagai input dan nilai kembalian sebagai output. (ita bisa juga membayangkan method itu adalah sebuah mesin, ada input yang dibutuhkan dan output yang dihasilkan. Deklarasai method terdiri dari beberapa bagian, bagian pertama adalah access modi?er dari method, apakah public, private, protected atau default. !agian berikutnya adalah tipe kembalian dari method, kalau method tidak mengembalikan apa-apa maka key"ord void yang digunakan. !agian ketiga adalah nama method, sesuai dengan aturan java code convention, nama method dia"ali dengan huruf kecil dan setiap kata setelahnya dia"ali dengan huruf besar 3camel case5. Setelah nama method ada parameter. Sebuah method bisa juga tidak mempunyai parameter, punya satu, dua dan seterusnya. Setelah java 4 ada feature yang disebut dengan varargs, feature ini memungkinkan method untuk mempunyai jumlah parameter yang bervariasi. @arargs akan kita bahas di bab tentang Java 4 .anguage enhancement, jadi tidak akan dibahas dalam bab ini. !agian terakhir dari method adalah deklarasi thro"s eLception, dimana kita bisa mendeklarasikan tipe eLception yang akan dithro"s oleh method. !ab tentang eLception akan membahas lebih lanjut tentang thro"s eLception. 0ama method dan parameter adalah pembeda antara satu method dengan method yang lainya. (alau dua method namanya beda ya pasti dianggap dua buah method berbeda. (alau dua method namanya sama dianggap sebagai method yang berbeda kalau parameternya berbeda, method dengan nama sama dan parameter berbeda ini disebut dengan overloading dalam konsep HH, . (alau method mempunyai nama yang sama dan parameter yang sama tetapi tipe return atau thro"s eLceptionya berbeda maka akan menyebabkan error pada "aktu kompilasi. Jadi kalau mende?nisikan method baru, pastikan bah"a namanya tidak sama dengan method lain atau setidaknya parameternya berbeda baik dari sisi jumlahnya, tipe parameter atau posisi parameter. Dari penjelasan di atas, struktur method seperti di ba"ah ini adalah benar/ public void main(String[] args){ ! public String met.od6eturnString(){ return *ini string* ! private void met.od>erparameter(String parameter%+ =nteger parameter)) {! public void met.od9.ro8s@,ception() t.ro8s =A@,ception {! protected String protectedBet.od(Sting parameter%+ =nteger parameter)) t.ro8s =A@,ception { return *ini string* ! public void met.od>erbeda() {! public void met.od>erbeda(String parameter%) {! public void met.od>erbeda(String parameter%+ =nteger parameter)) {! public void met.od>erbeda(=nteger parameter%+ String parameter)) {!

public void met.od>erbeda(:ouble parameter%+ :ouble parameter)) {! :da beberapa key"ord yang bisa ditambahkan dalam deklarasi method. (ey"ord yang paling sering digunakan adalah static. !agian kode Java yang dideklarasikan dengan menggunakan static akan menjadi anggota dari class, bukan anggota dari object, silahkan kembali ke bab berikutnya kalau masih belum bisa membedakan mana class dan mana object. (arena method yang ditandai dengan static adalah bagian dari class, maka bisa diakses langsung dari nama $lass itu sendiri, tidak perlu membuat object. Method static hanya bisa memanggil method lain dalam satu class yang juga ditandai static. Method main yang biasa kita gunakan untuk menjalankan aplikasi java juga ditandai dengan static, misalnya kita akan memanggil method lain dari method static, maka method lainya ini juga harus ditandai dengan static. (ita lihat contoh berikutnya / public class Static9est { public static void main(String[] args) { CCstatic met.od memanggil static met.od lain dalam class yang sama conto.Bet.odStatic() CCmet.od static #uga bisa dipanggil dari nama classnya Static9est.conto.Bet.odStatic() ! public static void conto.Bet.odStatic() { System.out.println(*met.od static dipanggil*) ! ! (alau kode di atas dicompile, kemudian dijalankan maka hasilnya seperti di ba"ah ini / " #avac Static9est.#ava " #ava Static9est met.od static dipanggil met.od static dipanggil " terlihat bah"a method contohMethodStatic dipanggil dua kali, baik menggunakan nama class maupun tidak. (ey"ord lain yang bisa digunakan oleh method adalah ?nal, synchroniBe dan native. (ey"ord ?nal akan menyebabkan method tidak bisa dioverride, kita bahas topik ini di bab HH, . (ey"ord synchroniBe akan menyebabkan hanya satu thread yang bisa mengeksekusi method ini dalam satu "aktu, kalau ada thread lain maka harus mengantri sampai thread sebelumnya selesai menjalankan method tersebut. (ey"ord native menandai implementasi method akan diletakkan dalam kode native, misalnya ditulis menggunakan $9$QQ, kemudian menggunakan Java 0ative nterface 3J0 5 untuk mengakses implementasi method tersebut. Topik mengenai J0 dan native tidak kita bahas di dalam buku ini dan diserahkan kepada anda, pembaca buku ini, untuk mempelajari topik advace ini dari sumber lain.

Constructor
$onstructor adalah method yang spesial, karena mempunyai aturan-aturan sebagai berikut/ mempunyai nama yang sama persis dengan nama class tidak mempunyai tipe return digunakan untuk menginstansiasi object hanya mempunyai access modi?er, tidak ada key"ord lain yang diletakkan sebelum nama method pada deklarasi constructor.

Seperti halnya method pada umumnya, constructor bisa mempunyai parameter serta melempar 3thro"s5 eLception. $onstructor yang tidak mempunyai parameter disebut dengan default constructor. Setiap class pasti mempunyai setidaknya satu constructor, kalau dalam deklarasi class tidak ada constructor sama sekali, Java secara default akan mempunyai default constructor ini. (alau ada satu saja constructor dengan parameter, maka default constructor tidak akan dibuat, kalau masih mau ada default constructor maka harus dideklarasikan secara

eksplisit. Mari kita lihat contoh kodenya / public Donstructor9est { public void met.odSeder.ana(){ System.out.println(*met.od seder.ana dipanggil*) ! public static void main(String[] args){ Donstructor9est test 7 ne8 Donstructor9est() test.met.odSeder.ana() ! ! (ode di atas memperlihatkan bah"a class $onstructorTest tidak mende?nisikan constructor sama sekali, tetapi constructor ne" $onstructorTest35 dapat dipanggil tanpa menyebabkan adanya error. +al ini disebabkan karena Java akan membuatkan default constructor kalau class tidak mende?nisikan cosnstructor sama sekali. public class Donstructor<on:e/ault9est { public Donstructor<on:e/ault9est(String te,t) { met.odSeder.ana(te,t) ! public void met.odSeder.ana(String te,t){ System.out.println(*met.od seder.ana dipanggil dengan te,t 3 * E te,t) ! public static void main(String[] args){ CCerror pada 8a0tu compile 0arena ada constructor yang dide0larasi0an CCse.ingga de/ault constructor men#adi 8a#ib dide0larasi0an Donstructor<on:e/ault9est test 7 ne8 Donstructor<on:e/ault9est() CCconstructor non de/ault dengan satu parameter bertipe string Donstructor<on:e/ault9est test% 7 ne8 Donstructor<on:e/ault9est(*ini test*) ! !

kalau kode di atas coba dicompile maka terdapat satu buah error seperti di ba"ah ini / " #avac Donstructor<on:e/ault9est.#ava Donstructor<on:e/ault9est.#ava3%%3 cannot /ind symbol symbol 3 constructor Donstructor<on:e/ault9est() location3 class Donstructor<on:e/ault9est Donstructor<on:e/ault9est test 7 ne8 Donstructor<on:e/ault9est() F % error " $onstructor dapat memanggil constructor lain dalam class yang sama menggunakan key"ord this. (ode untuk memanggil constructor lain ini harus berada di baris pertama dari constructor, kalau tidak maka akan ada error pada "aktu kompilasi. !erikut ini contohnya / public class DonstructorDallDonstructor9est { public DonstructorDallDonstructor(){ t.is(*constructor memanggil constructor*) CC0ode lain di sini+ tida0 bisa dileta00an di atas 0ey8ord t.is ! public DonstructorDallDonstructor(String te,t) { met.odSeder.ana(te,t) ! public void met.odSeder.ana(String te,t){ System.out.println(*met.od seder.ana dipanggil dengan te,t 3 * E te,t) ! public static void main(String[] args){

DonstructorDallDonstructor9est test 7 ne8

DonstructorDallDonstructor9est()

DonstructorDallDonstructor9est test 7 ne8 DonstructorDallDonstructor9est tor9est(*ini test*) ! !

$onstructor mana yang dipanggil pada "aktu menggunakan key"ord this ditentukan dari parameternya.

Pro$erty
,roperty adalah variabel yang dideklarasikan di dalam class sejajar dengan method. @ariabel yang berada di dalam method bukan merupakan property, tetapi disebut sebagai local variabel. .ayaknya variabel yang lain, property mempunyai tipe data dan nama. !erdasarkan aturan java bean, property akan dibuatkan method getter dan setter untuk membungkus property. Secara umum, disarankan untuk memberikan access modi?er private kepada semua property, kalau ingin mengakses property tersebut maka buatlah method getter dan setter. Deklarasi property dia"ali dengan access modi?er kemudian diikuti dengan tipe data dan akhirnya adalah nama dari property. ,roperty bisa langsung diinisialisasi nilainya atau tidak, kalau tidak diberi nilai, maka nilai default yang akan diset sebagai nilai a"al property. $ontohnya seperti di ba"ah ini / private String string4roperty !eberapa key"ord lain juga bisa digunakan untuk mendeklarasikan property. (ey"ord static bisa digunakan untuk mendeklarasikan property, static akan membuat property menjadi milik class bukan milik object. ,roperty static bisa diakses dari nama classnya dan tidak perlu ada object yang diinstansiasi. (arena property static menjadi milik class, maka kalau property static ini diganti isinya maka semua kode yang mengakses property static ini akan melihat nilai yang sama. $ontohnya seperti di ba"ah ini / public class 4ropertyStatic9est { public static String nilaiStatic public static void main(String[] args) { CCproperty static dipanggil mengguna0an nama class 4ropertyStatic9est.nilaiStatic 7 *nilai dari main* CCproperty static #uga bisa dipanggil tanpa nama class dari class yang sama System.out.println(nilaiStatic) CCmet.od main adala. met.od static+ .anya bisa memanggil met.od static #uga met.odGba.4ropertyStatic() CCnilai property static beruba. setela. met.od met.odGba.4ropertyStatic CCdipanggil System.out.println(nilaiStatic) ! public static void met.odGba.4ropertyStatic() { 4ropertyStatic9est.nilaiStatic 7 *nilai dari met.odGba.4ropertyStatic* ! ! (alau class di atas dicompile dan dijalankan, hasilnya adalah seperti di ba"ah ini / " #avac 4ropertyStatic9est.#ava " #ava 4ropertyStatic9est nilai dari main nilai dari met.odGba.4ropertyStatic " variabel static bisa sangat berguna untuk memudahkan mengakses suatu variabel karena tinggal menggunakan nama class saja, jadi tidak perlu memba"a-ba"a nilai variabel ke dalam object yang memerlukanya. Tetapi pada skenario berbeda property static ini malah merepotkan, terutama di lingkungan aplikasi "eb yang berjalan dalam cluster. :ntara satu cluster satu dan cluster yang lain nilai static ini bisa berbeda dan menyebabkan aplikasi

menjadi tidak konsisten. (arena dalam buku ini kita tidak bekerja dalam lingkungan cluster, kita bisa menganggap property static sebagai praktek yang aman. 0antinya di dalam aplikasi contoh, kita akan cukup banyak menggunakan property static untuk menyederhanakan kode. (ey"ord berikutnya yang bisa diletakkan dalam property static adalah ?nal. :danya key"ord ?nal dalam deklarasi property menyebabkan property hanya bisa diinisialisasi 3diberi nilai5 sekali saja, setelah itu nilainya tidak bisa dirubah, perilaku ini biasa kita sebut dengan konstanta/ sekali diberi nilai tidak bisa berubah nilainya. (alau kita memaksa merubah nilainya maka akan terjadi error pada "aktu kompilasi atau kalau java compiler tidak sanggup menentukan errornya akan terjadi pada "aktu aplikasi berjalan. $ontohnya kita akan merubah property nilaiStatic di contoh kode sebelumnya dengan menambahkan key"ord ?nal, seperti di ba"ah ini / public class 4ropertyStaticHinal9est { public static /inal String nilaiStatic public static void main(String[] args) { 4ropertyStaticHinal9est.nilaiStatic 7 *nilai dari main* System.out.println(nilaiStatic) met.odGba.4ropertyStatic() System.out.println(nilaiStatic) ! public static void met.odGba.4ropertyStatic() { 4ropertyStaticHinal9est.nilaiStatic 7 *nilai dari met.odGba.4ropertyStatic* ! ! (etika kode dikompilasi maka akan terjadi error yang menerangkan bah"a Etidak bisa mengubah nilai variabel yang ditandai dengan ?nalG. Hutputnya seperti di ba"ah ini / " #avac 4ropertyStaticHinal9est.#ava 4ropertyStaticHinal9est.#ava353 cannot assign a value to /inal variable nilaiStatic 4ropertyStaticHinal9est.nilaiStatic 7 *nilai dari main* F 4ropertyStaticHinal9est.#ava3%'3 cannot assign a value to /inal variable nilaiStatic 4ropertyStaticHinal9est.nilaiStatic 7 F ) errors " Jadi kalau begitu kapan property yang ditandai dengan ?nal bisa diberi nilaiZ ,ada "aktu mendeklarasikan property. $ontoh di ba"ah ini adalah cara yang benar menginisialisasi nilai ke property yang ditandai dengan ?nal / public class 4ropertyHinal9est { public /inal String nilaiHinal7*inisialisasi* public static void main(String[] args) { 4ropertyHinal9est /inal9est 7 ne8 4ropertyHinal9est() System.out.println(/inal9est.nilaiHinal) ! ! ,erhatikan kode di atas, property nilai*inal langsung diberi nilai pada "aktu deklarasi. (arena sekarang property nilai*inal kita harus membuat object dari class ,roperty*inalTest agar bisa mengakses property nilai*inal, berbeda dengan property yang ditandai static dimana kita bisa langsung mengaksesnya tanpa membuat object. Masih ada key"ord lain yang bisa kita letakkan dalam deklarasi property, yaitu volatile. (ey"ord ini menyebabkan property tidak akan ikut disimpan ketika object diserialiBe. ,roses serialiBe adalah proses mengubah object ke dalam bentuk yang bisa ditransfer le"at media 9H, misalnya object ini disimpan ke hardisk atau dikirim ke komputer lain le"at jaringan. ,roses sebaliknya adalah deserialiBe dimana dari bentuk ini diubah lagi menjadi bentuk object di dalam J@M. Topik

serialiBe dan deserialiBe akan sedikit kita bahas nanti pada "aktu membahas arsitektur three tier.

Konstanta
Java mempunyai key"ord const yang bisa digunakan untuk mendeklarasikan konstanta. Tetapi dalam prakteknya, dan ini adalah praktek yang disarankan oleh Sun Microsystem, konstanta sebaiknya dideklarasikan menggunakan gabungan key"ord static dan ?nal. .ebih baik lagi, kalau konstanta diletakkan di dalam interface, karena semua property dalam interface secara default akan bersifat public static ? nal, "alaupun dideklarasikan tanpa ketiga key"ord tersebut. (onstanta dalam java juga mempunyai aturan penamaan yang diterangkan dalam Java $ode $onvention. 0ama konstanta semuanya huruf besar dan dipisahkan dengan underscore 3S5 kalau terdiri dari dua kata atau lebih. $ontoh pembuatan konstanta yang baik adalah seperti berikut ini / public inter/ace Donstants{ =nteger BIJ(GS@6 7 %' String I44;=DI9=A<(<IB@ 7 *4AS* Stiring ;IK=(;IK= 7 *;* String 4@6@B4GI< 7 *4* ! ,erhatikan kode di atas menggunakan interface, bukan class. (emudian semua property tidak perlu dideklarasikan sebagai public static ?nal karena secara default semua property dalam interface sudah mempunyai ketiga key"ord tersebut. (alau kita deklarasikan $onstants di atas sebagai class maka ketiga key"ord tersebut harus disertakan agar property dianggap sebagai konstanta. public class Donstants{ public static /inal =nteger BIJ(GS@6 7 %' public static /inal String I44;=DI9=A<(<IB@ 7 *4AS* public static /inal Stiring ;IK=(;IK= 7 *;* public static /inal String 4@6@B4GI< 7 *4* ! Sampai di sini kita sudah belajar tentang perbedaan class dan object, kemudian bagaimana antomi dari class java. !erikutnya kita akan belajar mengenai struktur aplikasi java, bagaimana kode diorganisasi dalam package, kemudian bagaimana mengimport class lain yang berada dalam package yang berbeda. (emudian kita juga membahas apa itu jar 3java archive5 dan bagaimana membuatnya, sekaligus belajar bagaimana konsep classpath bekerja untuk menemukan class yang dibutuhkan aplikasi.

Struktur Aplikasi Java


Dalam bab ini kita akan mempelajari struktur aplikasi java, di dalam aplikasi java kita akan menggunakan package untuk mengorganisasi class-class dalam package agar rapi dan dipisahpisahkan berdasarkan fungsinya. mport digunakan untuk mengimport class yang berada dalam package yang berbeda. $lass-class dalam modul yang sama biasanya diletakkan dalam satu jar agar mudah didistribusikan, class-class dalam jar ini biasa juga disebut sebagai library. (alau aplikasi memerlukan class dari jar lain, kita harus meletakkan jar tersebut di dalam classpath agar bisa ditemukan oleh J@M. Semua konsep package, import, jar dan classpath sangat penting untuk mengatur struktur aplikasi Java. Dengan pengaturan yang rapi aplikasi bisa mudah dipelihara dan tidak memerlukan "aktu yang lama untuk mempelajari kodenya. (ita akan bahas satu per satu konsep-konsep tersebut di bab berikutnya.

Package
,akcage dalam java adalah sebuah mekanisme untuk mengorganisasi penamaan class ke dalam modul-modul. $lass yang mempunyai fungsionalitas serupa dan kemiripan cukup tinggi biasanya diletakkan dalam satu package yang sama. (alau ingin menggunakan class lain yang

berada dalam package yang berbeda harus diimport terlebih dahulu menggunakan key"ord import. $lass-class dalam package agar mudah didistribusikan biasanya diletakkan dalam satu buah jar yang pada dasarnya adalah sebuah ?le Bip saja. ,aragraf di atas menerangkan hubungan antara package, import dan jar dalam aplikasi java. Selanjutnya kita akan belajar bagaimana membuat package dan mengimport class dari package lain, kemudian membuat ?le jar dari class yang sudah dicompile. Selain bertujuan untuk mengorganisasi class, package juga digunakan untuk menghindari penamaan class yang bisa bertubrukan dalam aplikasi Java. (alau kita membuat sebuah class dengan nama yang sangat umum, misalnya class Fser, kemungkinan besar developer lain akan membuat class dengan nama yang sama, nah bagaimana kalau kita menggunakan library yang didalamnya terdapat nama class yang sama dengan class yang kita buatZ class manakah yang akan dipilih oleh JavaZ masalah penamaan ini dipecahkan dengan menggunakan package. ,ackage dimana sebuah class berada akan menjadi bagian dari nama lengkap sebuah class, misalnya class String sebenarnya nama lengkapnya adalah java.lang.String karena class String berada dalam package lang.util. Fntuk menghindari penamaan class yang sama, setiap developer disarankan untuk menggunakan package yang uni\ue untuk aplikasi yang digunakan. Misalnya ada % buah class dengan nama $lass:, yang satu berada di dalam package a.b.c sehingga nama lengkapnya adalah a.b.c.$lass: sendangkan satu lagi berada di dalam package d.e.f sehingga nama classnya adalah d.e.f.$lass:. !agaimana menjamin nama package yang uni\ueZ gunakan nama domain "ebsite institusi anda, maka anda akan mendapatkan nama package yang uni\ue. :da sebuah aturan tidak tertulis dari Sun untuk menggunakan nama domain institusi yang dibalik untuk digunakan sebagai package diikuti dengan nama aplikasi. Misalnya kita bekerja untuk perusahaan ,T coding sejahtera yang mempunyai "ebsite codings.com, kemudian kita membuat aplikasi keuangan yang disingkat dengan :($S 3aplikasi keuangan coding sejahtera5 maka kita akan membuat package dengan com.codings.akcs. !agaimana kalau kita membuat aplikasi opensourceZ gunakan nama domain dimana project tersebut dihosting. Misalnya untuk class-class yang digunakan di buku ini akan menggunakan package com.googlecode.projecttemplate.pos, hal ini karena kode dalam buku ini dihosting di project-template.googlecode.com dan nama aplikasinya adalah pos 3point of sales5. ,ackage pada dasarnya adalah struktur folder untuk meletakkan kode ?le java, tetapi tidak bisa sembarangan menyusun struktur folder ini, hal ini dimaksudkan agar kode lebih rapi, teratur dan tidak bercampur campur. Fntuk membuat package kita akan menggunakan contoh kode class ,erson di atas, tetapi kita letakkan di dalam package com.googlecode.projecttemplate.pos.model. .angkah pertama kita buat struktur folder comRgooglecodeRprojecttemplateRposRmodel / " m0dir com " m0dir comCgooglecode " m0dir comCgooglecodeCpro#ecttemplate " m0dir comCgooglecodeCpro#ecttemplateCpos " m0dir comCgooglecodeCpro#ecttemplateCposCmodel Setelah itu buat ?le ,erson.java dengan kode di ba"ah ini pac0age com.googlecode.pro#ecttemplate.pos.model public class 4erson{ private ;ong id private String nama public String get<ama(){ return nama ! public void set<ama(String nm){ nama 7 nm ! public ;ong get=d(){ return id !

public void set=d(;ong i){ id 7 i !

,erbedaan class ,erson di atas dengan class ,erson di contoh sebelumnya berada pada baris pertama dimana ada key"ord package untuk mendeklarasikan di pacakge apa class ,erson ini berada. $ara mengcompile class yang berada dalam package di atas seperti di ba"ah ini / " #avac comCgooglecodeCpro#ecttemplateCposCmodelC4erson.#ava Setelah mengenal package, kita akan belajar bagaimana menggunakan import untuk mendeklarasikan class-class yang berada di dalam package yang berbeda.

Im$ort
mport digunakan untuk menyederhanakan penulisan class. Tanpa menggunakan import kita harus menuliskan nama lengkap class besarta packagenya. Dengan menggunakan import, kita deklarasikan di mana class yang digunakan tersebut berada sehingga selanjutnya tidak perlu lagi menuliskan nama package dari sebuah class. :da dua pengecualian di mana import tidak diperlukan, pertama untuk class-class yang berada dalam package yang sama dan kedua adalah class-class yang berada dalam package java.lang. (ita akan membuat interface yaitu ,ersonDao yang di dalamnya ada class ,erson, nah kedua class ini akan berada dalam package yang berbeda sehingga di dalam interface ,ersonDao harus mengimport class ,erson. ,ertama kita buat dulu struktur folder untuk ,ersonDao / " m0dir comCgooglecodeCpro#ecttemplateCposCdao Setelah itu buat interface ,ersonDao dengan menyertakan package dan import pac0age com.googlecode.pro#ecttemplate.pos.dao import com.googlecode.pro#ecttemplate.pos.model.4erson public inter/ace 4erson:ao{ void save(4erson p) void delete(4erson p) 4erson get>y=d(;ong id) ! (alau menulis kode dengan menggunakan teLt editor biasa rasanya cukup repot menangani import ini, misalnya ada %& class yang digunakan dalam satu class, maka harus ada %& baris import untuk setiap class. Fntuk sedikit memudahkan proses import ini bisa menggunakan "ildcard 3Y5, jadi kita bisa import sekaligus semua class dalam satu package dengan menggunakan "ildcard ini. $ontohnya di ba"ah ini / import com.googlecode.pro#ecttemplate.pos.model.L mport di atas akan menyertakan semua class di dalam package model, tetapi kelemahanya adalah proses pencarian class di dalam package menjadi sedikit lebih lama pada "aktu eksekusi program, kalau tidak terpaksa sebaiknya import menggunakan "ildard dihindari. 0antinya kalau sudah menggunakan DM seperti 0et!eans proses import ini menjadi sangat gampang karena dibantu oleh feature dari 0et!eans tidak perlu lagi menggunakan "ildcard.

Jar
Sampai di sini kita sudah tahu bagaimana class, package dan import bekerja. 0ah kalau classnya sudah banyak, kita bisa mengumpulkanya menjadi satu agar mudah untuk didistribusikan. (umpulan class yang disimpan dalam satu ?le disebut jar 3Java :rchive5. Jar sebenarnya hanyalah ?le Bip semata, kalau punya aplikasi yang bisa membuka ?le Bip kita juga bisa membuka ?le jar. (alau di "indo"s bisa klik kanan ?le jar kemudian open "ith "inBip, isi dari ?le jar bisa dilihat dengan gampang. Jar bisa dibuat dengan menggunakan command line tools dari JD( yaitu jar. Di bagian sebelumnya kita sudah membuat dua class yaitu ,erson dan ,ersonDao, kedua class ini akan diletakkan di dalam ?le jar dengan nama pos.jar, caranya sangat gampang, gunakan tools jar

dari JD( seperti di ba"ah ini / " #ar cv/ pos.#ar . Di dalam ?le jar terdapat meta data untuk menerangkan isi dari ?le jar tersebut yang disebut sebagai manifest. *ile manifest.mf berisi keterangan tentang jar, misalnya kapan dibuatnya, dibuat oleh siapa, apa nama main classnya dan seterusnya. *ile manifest.mf harus diletakkan di dalam folder MMT:- 0*. Jar yang dibuat oleh tool jar dari JD( akan dibuatkan ?le manifest default yang berisi keterangan sederhana. Setelah mengerti konsep dari jar, berikutnya kita belajar tentang classpath. $lasspath digunakan untuk mende?nisikan di mana saja java bisa menemukan class yang diperlukan oleh aplikasi.

Class$ath
$lasspath adalah cara java untuk menemukan di mana ?le jar yang berisi library class yang digunakan dalam aplikasi. (alau class yang digunakan tidak ditemukan dalam classpath, maka java akan mengeluarkan $lass0ot*oundMLception. (esalahan ini sering kali terjadi dan kita bisa langsung menyimpulkan bah"a class yang diperlukan tidak berada dalam classpath. 0e"bie sering kebingungan dengan error ini, maka saya merasa perlu untuk menerangkan konsep classpath dengan sedikit panjang lebar agar tidak terjadi kebingungan. 0e"bie yang belajar membuat aplikasi dari a"al menggunakan DM seperti 0et!eans sering kebingungan ketika akan menginstall aplikasi, biasanya pertanyaan yang muncul adalah bagaimana membuat versi eLe dari aplikasi java yang sudah dibuat. Saya bisa menjamin bah"a membuat eLe dari program java yang sudah dibuat adalah tindakan sia sia, pertama karena malah akan menghilangkan feature utama java / run any"here, ingat eLe tidak bisa jalan di HS selain "indo"s. (edua karena convert java ke eLe tidak gampang, perlu tools yang mahal harganya dan tidak ada jaminan bah"a hasil convert ke eLe akan bisa jalan mulus seperti aslinya. 0ah kalau tidak diconvert ke dalam eLe bagaimana cara membuat launcher agar user tinggal klik dua kali dan aplikasi jalanZ Ja"abanya adalah dengan membuat ?le bat di "indo"s atau ?le sh di selain "indo"s. Di dalam ?le bat 9 sh tersebut terdapat command line untuk menjalankan aplikasinya. Fntuk membuatnya diperlukan sedikit pengetahuan tentang classpath ini. Di bagian sebelumnya kita sudah belajar membuat sebuah ?le jar yang berisi dua buah class / ,erson dan ,ersonDao, nah kita sekarang akan membuat sebuah class lagi yang akan mengimport class ,erson dan mempunyai main method agar bisa dijalankan. 0amakan saja classnya adalah $lasspathMLercise, kemudian simpan class ini di folder yang berbeda dengan folder sebelumnya. Misalnya folder sebelumnya ada di c/Rsample-code, buat lagi sebuah folder kosong di c/Rsamplecode-classpath. import com.googlecode.pro#ecttemplate.pos.model.4erson public class Dlasspat.@,ercise{ public void main(String[] args){ 4erson p 7 ne8 4erson() p.set<ame(*ini nama person*) System.out.println(p.get<ame()) ! ! $ompile class di atas menggunakan javac " #avac Dlasspat.@,ercise.#ava kalau class di atas dijalankan seperti di ba"ah ini tanpa classpath maka akan keluar $lass0ot*oundMLception / " #ava Dlasspat.@,ercise @,ception in t.read *main* #ava.lang.<oDlass:e/Hound@rror3 comCgooglecodeCpro#ecttemplateCposCmodelC4erson at Dlasspat.@,ercise.main(Dlasspat.@,ercise.#ava35) Daused by3 #ava.lang.Dlass<otHound@,ception3 com.googlecode.pro#ecttemplate.pos.model.4erson at #ava.net.G6;Dlass;oader"%.run(G6;Dlass;oader.#ava3)')) at #ava.security.IccessDontroller.do4rivileged(<ative Bet.od)

at #ava.net.G6;Dlass;oader./indDlass(G6;Dlass;oader.#ava3%M') at #ava.lang.Dlass;oader.loadDlass(Dlass;oader.#ava31'-) at sun.misc.;aunc.er"IppDlass;oader.loadDlass(;aunc.er.#ava31'%) at #ava.lang.Dlass;oader.loadDlass(Dlass;oader.#ava3)5N) ... % more $lasspath seperti yang sudah kita bahas di atas, digunakan untuk memberitahu java di mana bisa menemukan class-class yang dibutuhkan. 0ah kalau cara menjalankan kodenya diganti dengan seperti di ba"ah ini / " #ava $cp c3Osample$codeOpos.#ar . Dlasspat.@,ercise ini nama person " ,erhatikan command line di atas, terdapat argumen -cp yang menandakan bah"a kita akan mende?nisikan daftar classpath. *ile jar dan folder bisa dimasukkan sebagai daftar classpath, seperti contoh di atas kita mendaftarkan ?le jar c/Rsample-codeRpos.jar dan folder yang sedang aktif, di"akili dengan tanda titik 3.5. (alau anda bekerja di linuL 9 uniL terdapat perbedaan di tanda pemisah antar classpath, kalau "indo"s menggunakan titik koma3D5, HS selainya menggunakan titik dua3/5 seperti di ba"ah ini " #ava $cp CGsersCi/nuCsample$codeCpos.#ar3. Dlasspat.@,ercise ini nama person " (ita juga bisa menggunakan relative path supaya tidak terjadi error kalau ?lenya dipindahpindah ke folder lain / " #ava $cp ..Csample$codeCpos.#ar3. Dlasspat.@,ercise ini nama person " 0ah kembali lagi ke masalah ?le bat 9 sh yang sudah kita bahas sebelumnya. (ita bisa meletakkan perintah di atas ke dalam ?le ini dan mengeksekusi kedua ?le tersebut layaknya eLecutable ?le. Setelah java ; terdapat feature "ildcard di classpath, dimana kita bisa menginclude semua ?le jar yang ada dalam sebuah folder. Sebelum feature ini ada, kita harus mendaftarkan semua ?le jar satu per satu ke dalam classpath. ,erintah di atas bisa sedikit diubah menjadi seperti di ba"ah ini / " #ava $cp ..Csample$codeCL.#ar3. Dlasspat.@,ercise ini nama person " Sampai di sini kita sudah belajar hal-hal dasar tentang class, package, import, jar dan classpath. !erikutnya kita akan belajar lebih banyak tentang bahasa java dan HH, .

Variabel dan

emory

ana!ement

Di bagian ini kita akan banyak membahas tipe-tipe data yang bisa berada dalam J@M dan bagaimana J@M meletakkannya dalam memory. !agian terakhir akan membahas bagaimana Karbage $ollector bekerja membersihkan J@M dari data yang sudah tidak digunakan lagi.

%aria"el
Setelah belajar dasar-dasar bagaimana membuat kode java, kita akan membahas dasar-dasar bahasa java mulai dari bab ini. +al pertama yang akan kita pelajari adalah memory management di java, untuk memahami bagaimana variabel disimpan dalam memory oleh J@M kita akan belajar tentang stack dan heap. ,rogram java akan berada dalam stack atau heap selama daur hidupnya, instance variabel dan object selalu berada di heap sedangkan local variabel berada di dalam stack. Mari kita lihat kode java di ba"ah ini, dan bagaimana bagian-bagian itu disimpan dalam heap atau stack/

public class 4erson{ private ;ong id CCinstance variable private String nama CCinstance variable public static void main(String[] args){ 4erson i/nu CClocal variableCre/erence variabel i/nu i/nu 7 ne8 4erson() CCob#ect 4erson diinstansiasi i/nu.set=d(%-l) i/nu.set<ama(*i/nu bima*) 4erson 0lonengan=/nu 7 i/nu CClocal variable yang menun#u0 0e ob#ect 0lonengan=/nu.set<ama(*0lonengan i/nu) CC yang sama ! public void set=d(;ong a=d){ t.is.id 7 a=d ! public ;ong get=d(){ return t.is.id ! public void set<ama(;ong a<ama){ t.is.nama 7 a<ama ! public String get<ama(){ return t.is.nama ! CClocal variable a=d

CClocal variable a<ama

.ocal variabel adalah variabel yang berada di dalam method, variabel ini hanya hidup selama method dieksekusi, begitu program keluar dari method maka variabel ini akan diserahkan ke garbage collector untuk dibersihkan. @ariabel di dalam parameter method adalah salah satu contoh local variabel. -eference variabel adalah variabel yang menunjuk ke object, seperti ifnu dan klonengan fnu, keduanya juga merupakan local variabel karena di diklarasikan di dalam method main. id dan nama adalah instance variabel, keduanya dideklarasikan di dalam class ,erson. -eference variabel ifnu dan klonengan fnu menunjuk ke object yang sama, maka ketika klonengan fnu mengganti nilai nama maka object yang dipegang oleh variabel ifnu juga akan ikut terganti namanya. :naloginya misalnya begini, reference variabel itu adalah alamat, sedangkan object adalah sebuah rumah. Misalnya sebuah rumah mempunyai dua alamat, yang satu alamat menggunakan nama jalan satu lagi alamat menggunakan ,H !H]. (ita bayangkan misalnya pak pos mengirim barang ke alamat ,H !H] ataupun alamat jalan, maka barang akan sampai ke rumah yang sama. !egitu juga dengan instance variable ifnu dan klonganengan fnu, jika satu dirubah maka yang lain ikut berubah karena keduanya menunjuk ke alamat object yang sama. (onsep reference ini penting untuk selalu diingat ketika bekerja dengan object, banyak sekali masalah yang bisa dipecahkan hanya dengan menggunakan pemahaman tentang yang baik tentang reference ini. !erikut ini adalah gambar yang memvisualisasikan keadaan heap setelah kode di atas selesai dieksekusi /

ifnu main() main() setNama() setId() et!od ifnu klonenganIfnu aNama aId "ocal variabel Stack String object

Klonengan ifnu String object

Instance variabel: - id - nama

Person object

Setelah mengetahui bagaimana reference variabel bekerja, kita akan membahas bagaimana perilaku reference variabel ini jika digunakan sebagai parameter dalam method.

Passing "y value dan Passing "y re erence


Method dalam java bisa mempunyai parameter, setiap parameter pada dasarnya adalah local variabel, tipe dari variabel itu bisa berupa reference 3object5 atau bisa juga berupa tipe data ba"aan dari java. (edua jenis variabel ini akan diperlakukan berbeda oleh java, jika kita menggunakan tipe variabel dengan tipe data ba"aan java maka yang terjadi adalah passing by value, artinya data yang dilempar dari kode pemanggil ke dalam method, yang diba"a adalah nilai dari variabelnya, jika nilai variabel di dalam method berubah maka nilai variabel di pemanggil tidak ikut berubah. Mari kita lihat contoh kodenya / public class 4ass>yPalue{ public static void uba.<ama(String nama){ nama 7 *dian* System.out.println(*nama baru di dalam met.od3 * E nama) ! public static void main(String[] arg){ String nama 7 *i/nu* System.out.println(*nama lama dari met.od main3 * E nama) uba.<ama(nama) System.out.println(*nama lama dari met.od main3 * E nama) ! ! Terdapat variabel nama di dalam method main yang dilempar ke method ubah0ama, karena tipe datanya String 3tipe data ba"aan dari java5, maka ketika variabel nama diubah di dalam method ubah0ama maka tidak akan mempengaruhi nilai variabel nama di dalam method main. (alau kita compile dan jalankan kodenya akan keluar output seperti di ba"ah ini / " #avac 4ass>yPalue.#ava " #ava 4ass>yPalue nama lama dari met.od main3 i/nu nama baru di dalam met.od3 dian nama lama dari met.od main3 i/nu @ariabel dengan tipe reference seperti / object atau tipe data array, jika digunakan sebagai parameter dalam method maka akan terjadi prosess passing by reference. :rtinya data yang dilempar dari kode pemanggil ke dalam method, yang diba"a adalah reference 3alamat5 dari

variabelnya. Jika variabel di dalam method berubah maka nilai variabel di pemanggil juga ikut berubah. Mari kita modi?kasi sedikit kode di atas dengan mengganti tipe data nama dari String menjadi array String. public class 4ass>y6e/erence{ public static void uba.<ama(String[] nama){ nama['] 7 *dian* System.out.println(*nama baru di dalam met.od3 * E nama[']) ! public static void main(String[] arg){ String[] nama 7 ne8 String[%] nama['] 7 *i/nu* System.out.println(*nilai lama dari met.od main3 * E nama[']) uba.<ama(nama) System.out.println(*nilai lama dari met.od main3 * E nama[']) ! ! Setelah kita ganti variabel nama dari tipe data String menjadi String=>, maka method ubah0ama akan menggunakan pass by reference, sehingga kalau nilai di dalam variabel nama diubah didalam method ubah0ama maka variabel yang sama di dalam method main juga ikut berubah. Mksekusi kode di atas akan menghasilkan output seperti di ba"ah ini / " #avac 4ass>y6e/erence.#ava " #ava 4ass>y6e/erence nilai lama dari met.od main3 i/nu nama baru di dalam met.od3 dian nilai lama dari met.od main3 dian " (ita sudah membahas apa itu pass by value dan apa itu pass by reference, di dalam penjelasan di atas disebutkan tentang Etipe data ba"aan javaG, nah tipe data jenis ini ada dua, tipe data primitif dan "rapper class. (ita akan bahas kedua jenis tipe data ini di bagian selanjutnya.

&i$e Data Primiti


(alau java disebut tidak full HH, , hal ini dikarenakan adanya tipe data primitif ini. Jadi tipe data primitif bukanlah object, tipe ini tidak mempunyai method dan hanya mempunyai data saja. Tipe data primitif ada delapan 365 macam /
Tipe data Fkuran byte 6 bit Min -)%6 MaL )%' (eterangan Kunakan tipe data ini kalau range datanya kecil untuk menghemat memori dibanding dengan int, terutama kalau datanya berupa array Sama dengan byte, gunakan kalau perlu optimisasi penggunaan memory, terutama kalau datanya berupa array int adalah tipe data yang paling sering digunakan untuk representasi angka bulat. int adalah pilihan default jika tidak diperlukan optimisasi memori. (alau jangkauan angkanya kurang lebar gunakan long. Kunakan tipe data ini jika jangkauan angkanya lebih lebar daripada int Uoat adalah tipe data pecahan yang dide?nisikan oleh standard MMM '4<. Digit di belakang koma tidak bisa diatur, jika ingin merepresentasikan angka yang bisa diatur jumlah digit di depan dan di belakang koma, gunakan !igDecimal double adalah tipe data pecahan yang dide?nisikan oleh standard MMM '4<. Digit di belakang koma tidak bisa diatur, jika ingin merepresentasikan angka yang bisa diatur jumlah digit di depan dan di belakang koma, gunakan !igDecimal. Tipe data boolean hanya mempunyai dua nilai, true atau false.

short int

); bit 7% bit

-7%';6

7%';'

%)<'< %)<'<6 67;<' 7;<6 1.%%M 1.%%MQ Q&)6 &)6 -

long

;< bit

Uoat

7% bit

double

;< bit

boolean

char

);

JRu&&&& JRu^^J J atau & atau ;4474

char adalah tipe data yang bisa menyimpan nilai unicode. Digunakan untuk merepresentasikan karakter unicode yang didalamnya terdapat abjad, angka, simbol dan karakter lainya.

Fntuk setiap tipe data primitif, kita bisa memberikan nilai literal. 0otasi nilai literal untuk tiap tipe data di atas berbeda-beda, berikut ini adalah bentuk literal untuk setiap tipe data / byte b 7 %'' s.ort s 7 %'' int i 7 )& CCdecimal int i 7 '1) CCoctal sama dengan )& decimal int i 7 ',%a CC.e,adecimal sama dengan )& decimal long l 7 %''l /loat / 7 %''.'/ double d 7 %''.' double d 7 %.''e) booelan bo 7 true c.ar c 7 QcQ Fntuk tipe data primitif yang berupa angka, kita bisa melakukan pertukaran data. ,roses pertukaran data antar tipe data yang berbeda disebut dengan casting. :da casting yang dilakukan secara implisit, ada juga casting yang dilakukan secara eksplisit. $asting secara implisit dilakukan tanpa adanya kode tambahan, biasanya terjadi kalau kita memasukkan tipe data dengan ukuran yang lebih kecil ke tipe data yang lebih besar, misalnya dari byte ke int. byte b 7 %'' int i 7 b $asting secara eksplisit dilakukan jika kita memasukkan data dengan ukuran lebih besar ke ukuran lebih kecil, misalnya dari int ke byte. ,erlu diperhatikan bah"a presisi data akan berubah dari ukuran ke besar ke ukuran lebih kecil, sehingga kalau nilainya melebihi jangkauan, maka terjadi pemotongan nilai dan hasilnya bisa tidak terduga. Misalnya di ba"ah ini / int i 7 %'' byte b 7 (byte) i $ontoh di atas tidak terjadi pemotongan nilai karena )&& masih di dalam jangkauan byte, kalau contoh di ba"ah ini akan terjadi pemotongan nilai / int i 7 %''' byte b 7 (byte) i nilai variabel b tidak akan )&&&, karena jangkauan byte hanya sampai )%' saja. Silahkan mencoba menjalankan operasi di atas untuk mengetahui berapa nilai akhir dari variabel b setelah terjadi pemotongan, apakah dugaan anda benarZ

'ra$$er Class
#rapper class adalah tipe data ba"aan java yang berupa object, setiap tipe data primitif mempunyai padanan di "rapper class ini. #alaupun "rapper ini berupa class, variabel yang memegang objectnya bukanlah variabel reference. :rtinya kalau ada dua buah variabel yang memegang nilai sama, satu variabel nilainya diganti maka variabel yang lain tidak akan ikut berubah nilainya. Sifat ini disebut dengan immutable.
,rimitif byte short int long Uoat double boolean #rapper class nteger Short nteger .ong *loat Double !oolean

char

$haracter String

Sebelum java 4, selain String, semua class "rapper tidak bisa langsung diberi nilai literal. ,erlu proses konversi dari nilai primitif ke "rapper classnya dan sebaliknya. !erikut ini contoh bagaimana memberi nilai ke dalam variabel dengan tipe data "rapper class sebelum java 4. =nteger , 7 ne8 =nteger(%') int i 7 ,.intPalue() long l 7 %''l ;ong y 7 ;ong.valueA/(l) int i 7 =nteger.parse=nteger(*%''*) (onversi dari satu tipe data "rapper class ke tipe data "rapper class yang lain tidak bisa menggunakan mekanisme casting seperti di dalam tipe data primitif. +al ini dikarenakan pada dasarnya "rapper class adalah class, sedangkan casting dalam class hanya bisa dilakukan kalau ada hubungan inheritance antara kedua class yang sedang akan dicasting. (alau proses casting antara dua class dilakukan secara ceroboh akan menyebabkan $lass$astMLception pada "aktu kode dijalankan.

Array
:rray adalah object di java yang dapat menyimpan kumpulan data dengan tipe yang sama. :rray dapat menyimpan data dengan tipe primitif, "rapper class maupun reference. #alaupun array bisa menyimpan tipe data primitif, tetapi array selalu berada di heap, atau bisa dibilang apapun tipe arraynya, array itu sendiri adalah object. Fntuk bisa bekerja dengan array, kita perlu melakukan tiga langkah / Mendeklarasikan variabel array Menginisialisasi object array Mengisi array dengan data

:da beberapa cara berbeda untuk melakukan ketiga hal tersebut, kita akan membahas satu per satu. :rray dideklarasikan dengan mende?nisikan tipe datanya diikuti dengan tanda kurung kotak buka dan tutup kemudian diikuti nama variabelnya. $ontohnya sebagai berikut / int[] data $ara deklarasi array di atas adalah cara yang dianjurkan. Semua variabel yang diletakkan setelah int=> akan bertipe array, misalnya kita modi?kasi sedikit deklarasi di atas agar variabel yang dideklarasikan lebih dari satu, seperti di ba"ah ini / int[] data+ 0ey+ values $ara kedua mendeklarasikan array adalah dengan menulis tipe data kemudian diikuti oleh nama variabel serta kurung kotak buka dan tutup setelah nama variabel. $ontohnya sebagai berikut / int data[] $ara ini tidak direkomendasikan, karena kalau ingin mendeklarasikan lebih dari satu variabel array, maka kurung kotak buka tutup harus ditulis di setiap variabel. Jika kurung kotak buka tutup tidak ditulis, maka variabel tersebut bertipe int, bukan array. $ontohnya adalah / int data[]+ 0ey[]+ values variabel data dan key bertipe array int sedangkan variabel values bertipe int, bukan array. Jumlah kurung kotak menentukan dimensi array, misalnya kita ingin membuat array dua dimensi 3di dalam array ada array5 dan tiga dimensi 3di dalam array ada array dari array5. $ontohnya / String[][] array:ua:imensi String[][][] array9iga:imensi Setelah berhasil mendeklarasikan array, sekarang "aktunya menginisialisasi object array. $aranya sangat sederhana, menggunakan key"ord ne" dan mende?nisikan panjang arraynya,

contohnya seperti berikut ini / int[] data data 7 ne8 data[%'] (ode di atas artinya / buat variabel data dengan tipe array int, inisialisasi arraynya dengan panjang )& dan isi dengan nilai &D (enapa diisi dengan nilai &Z hal ini dikarenakan tipe data primitif tidak bisa bernilai null, harus ada nilai defaultnya. Dalam hal ini tipe data int akan selalu mempunyai nilai default &. (alau tipe data arraynya adalah "rapper class atau object, array akan berisi null, seperti contoh di ba"ah ini / String[] data data 7 ne8 String[%'] Fkuran dari array bersifat "ajib, kalau kita menginisialisasi array tanpa disertai ukuran panjang array, maka kodenya akan gagal dicompile. $ontohnya seperti di ba"ah ini / String[] data 7 ne8 String[] nisalisasi array multidimensi sedikit berbeda dengan array satu dimensi. (ita bisa mendeklarasikan array dua dimensi sekaligus dengan isinya, misalnya contoh di ba"ah ini akan membuat matriks )&L)& sehingga bisa menampung )&& data. String[] array:ua:imensi 7 ne8 String[%'][%'] (etika menginisialisasi array multidimensi, ukuran array hanya "ajib diisi di dimensi pertama, sedangkan dimensi kedua tidak "ajib disebutkan ukuranya. +al ini mengakibatkan isi dari array yang berupa array masih bernilai null dan harus diinisalisasi dahulu sebelum diisi dengan nilai. String[] array:ua:imensi 7 ne8 String[%'][] Memasukkan data ke dalam array dilakukan dengan menyebutkan indeL dimana data akan diletakkan. Seperti contoh di ba"ah ini / int data 7 ne8 int[5] data['] 7 % data[%] 7 %) data[1] 7 %M ,erhatikan bah"a indeL dari array dimulai dari & dan selalu bernilai positif. (alau indeL yang dimasukkan diluar jangkauan yang benar, akan muncul :rray ndeLHf!oundMLception. Mari kita simulasikan bagaimana error :rray ndeLHf!oundMLception terjadi / public class Irray@rror { public static void main(String[] args) { int[] data 7 ne8 int[5] data[%] 7 %' data[1] 7 N data[5] 7 M ! ! Simpan dalam ?le :rrayMrror.java, kompilasi ?le java tersebut kemudian jalankan programnya/ " #avac Irray@rror.#ava " #ava Irray@rror @,ception in t.read *main* #ava.lang.Irray=nde,AutA/>ounds@,ception3 5 at Irray@rror.main(Irray@rror.#ava3&) " Terlihat bah"a array mempunyai panjang <, indeL terbesar adalah 7 karena indeL array dimulai dari &, kemudian kode data=<> berusaha mengakses indeL < yang berada di luar jangkauan. Sekarang kita lihat bagaimana cara memasukkan data ke dalam array multidimensi. Seperti yang sudah kita bahas sebelumnya, cara menginisialisasi array multidimensi ada dua, yang pertama adalah mengisi ukuran semua dimensi array, dan yang kedua adalah mengisi dimensi

pertama saja. (alau cara pertama yang kita pilih untuk menginisialisasi array, maka data bisa langsung dimasukkan ke dalam array seperti contoh di ba"ah ini / int[][] data 7 ne8 int[1][1] data[']['] 7 % data['][%] 7 % data['][)] 7 % data[%]['] 7 % (alau cara kedua yang dipilih, maka kita harus menginisialisasi array untuk dimasukkan ke dalam array dimensi pertama, bingungZ +mm mari kita lihat contoh saja agar lebih mudah. =nt[][] data 7 ne8 int[1][] data['] 7 ne8 int[R] CCinit array yang dimasu00an 0e array dimensi pertama data[']['] 7 %' data['][)] 7 %' data['][1] 7 %' data[%] 7 ne8 int[)] CCinit array yang dimasu00an 0e array dimensi pertama data[%]['] 7 %'' data[%][%] 7 )'' 0ah bisa kita lihat bah"a sebelum mengisi nilai ke dalam array dimensi yang kedua, maka array dimensi pertamanya harus diisi dengan array. Dengan cara ini, maka ukuran dimensi array menjadi tidak seragam. Dari materi array yang sudah kita bahas di atas, sepertinya bekerja dengan array cukup repot dan tidak praktis, terlalu banyak yang harus ditulis. Menyadari hal ini, Java menyediakan cara cepat untuk mendeklarasikan, menginisialisasi dan mengisi nilai array hanya dalam satu baris, baik untuk aray satu dimensi maupun array dua dimensi. !erikut ini contoh sintaksnya / int[] data 7 {%+)+1+5+&! int[] dua:imensi 7 {{%+)+1!+{)+1!+{1!! String[][] array:ua:imensi 7 {{*satu*+*dua*+*tiga*!+{*empat*+*lima*!! $ara di atas sangat rapi dan mempersingkat banyak kode, tetapi ada satu kelemahan cara di atas, bisa dilihat bah"a tidak ada tipe data yang eksplisit untuk operand di sebelah kanan. (elemahan di atas di atasi dengan adanya feature Eanonymous arrayG dengan menyertakan tipe data dari array ketika diinisialisasi. $ontohnya / int[] data 7 ne8 int[]{%+)+1+5+&! int[] dua:imensi 7 ne8 int[][]{{%+)+1!+{)+1!+{1!! String[][] array:ua:imensi 7 ne8 String[][]{{*satu*+*dua*+*tiga*!+ {*empat*+*lima*!! #alaupun ada key"ord ne", tidak perlu dide?nisikan berapa panjang dari arraynya, karena panjang dari array ditentukan dari nilai yang diletakkan di dalam kurung kura"al. Tipe data array sangat penting ketika array akan digunakan sebagai perameter sebuah fungsi, mari kita lihat kode di ba"ah ini / public class InonymousIrray{ public static void printIrray(String[] data){ System.out.println(data) ! public static void main(String[] args){ printIrray(ne8 String[]{*satu*+*dua*+*tiga*!) ! ! (arena pada dasarnya array adalah object, maka array juga mempunyai method dan property. Salah satu yang paling berguna adalah length. ,roperti ini digunakan untuk mengetahui berapa panjang dari array tersebut. $ontohnya sebagai berikut / int[] data 7 ne8 int[=nteger.BIJ(PI;G@] System.out.println(*pan#ang data 3 * E data.lengt.) Java juga mempunyai sebuah class yang berisi perkakas untuk mengolah data, misalnya

melakukan sorting, melakukan pencarian binary bahkan hingga mengeprint isi array agar bagus tampilanya. $lass tersebut adalah java.util.:rrays. Silahkan lihat Java Documentation bagaimana cara menggunakan perkakas yang ada dalam class java.util.:rrays ini.

(ar"age Collector
Karbage collector adalah mekanisme J@M untuk menghapus object yang ada di memory kalau sudah tidak dibutuhkan. Karbage collector adalah salah satu feature penting J@M, karena developer tidak lagi perlu secara eksplisit menghapus object dari memory di dalam kode aplikasi. Developer tidak perlu lagi membuat kode untuk menghapus object dari memory seperti di $9$QQ. Di $9$QQ kode yang diperlukan untuk membuat object dan menghapus object dari memory cukup menyita "aktu developer, Java menghilangkan ke"ajiban untuk developer menulis kode penghapusan object dari memory dengan menyerahkan sepenuhnya proses tersebut ke garbage collector. #alaupun begitu, developer tidak terbebas dari praktek yang baik untuk menghindari aplikasi mengalami kehabisan memory 3memory leak5, error ini ditandai dengan adanya HutHfMemoryMLception. Karbage $ollector bisa juga digunakan sebagai istilah untuk merujuk ke feature managemen memory terotomasi di Java. ,ada aplikasi bisnis, setiap kali user melakukan kegiatan di dalam aplikasi, pasti ada object yang dibuat, kemudian dimanipulasi, disimpan di database dan pada akhirnya tidak diperlukan lagi. Menulis kode untuk mengelola memory secara manual bukanlah pekerjaan yang mudah, "alaupun tidak bisa diukur secara pasti, usaha yang diperlukan developer bisa dua kali kalau pengelolaan memory dilakukan secara otomatis. Di dalam java memory digunakan oleh heap, stack, tempat kumpulan variabel java dan tempat hidupnya method. +eap adalah tempat dimana semua object java berada, di tempat inilah Karbage $ollector akan melakukan tugasnya, jadi tugas utama dari Karbage $ollector adalah memastikan heap mempunyai cukup ruang selama eksekusi aplikasi. (etika Karbage $ollector berjalan, tujuanya hanya satu yaitu menghapus object dalam heap yang sudah tidak digunakan lagi. 0ah, kemudian pertanyaanya adalah/ kapan Karbage $ollector berjalanZ Karbage $ollector dikontrol sepenuhnya oleh J@M. +anya J@M yang bisa memutuskan kapan Karbage $ollector akan berjalan. Dari kode yang kita tulis, ada cara untuk EmenganjurkanG Karbage $ollector, tetapi tidak ada jaminan bah"a J@M akan langsung mengerjakan anjuran untuk menjalankan Karbage $ollector ini. ,ada satu "aktu bisa saja J@M mematuhi anjuran ini, bisa juga di "aktu yang lain tidak dijalankan. Dalam spesi?kasi J@M tidak ada jaminan bah"a kalau kita menganjurkan Karbage $ollector untuk dijalankan, maka pasti J@M mematuhi anjuran ini. (ita tidak bisa menggantungkan keberhasilan aplikasi kita terhadap kepatuhan J@M atas anjuran kita untuk menjalankan Karbage $ollector. ,ertanyaan berikutnya adalah / de?nisi dari Esudah tidak digunakan lagiG itu apaZ Jika suatu object tidak dapat lagi diakses oleh thread yang masih hidup, maka bisa dipastikan bah"a object tersebut sudah tidak bisa digunakan lagi. Hbject dalam keadaan inilah yang akan dihapus Karbage $ollector dari dalam heap. Java akan kehabisan memory kalau aplikasi terus membuat object baru dan object-object tersebut masih bisa diakses oleh thread yang sedang hidup sehingga Karbage $ollector tidak bisa menghapus dari heap, sampai pada akhirnya heap penuh. (ita bisa secara sengaja membuat sebuah object tidak bisa lagi diakses dari thread yang masih hidup, cara yang paling mudah adalah dengan mengeset variabel yang memegang reference ke object tersebut menjadi null. $ontohnya seperti berikut ini / :ate d 7 ne8 :ate() d 7 null Setelah variabel d di set ke null maka object Date di atas tidak bisa lagi diakses oleh variabel lainya karena alamat ke object tersebut tidak ada lagi yang tahu. $ara lainya adalah dengan mengganti nilai dari variabel dengan object lain, sehingga object sebelumnya tidak lagi bisa diakses. $ontohnya seperti berikut / :ate d 7 ne8 :ate() d 7 ne8 :ate() (ode di atas membuat dua buah object dari class Date, object pertama akan dihapus dari heap ketika Karbage $ollector berjalan.

@ariabel lokal yang dideklarasikan di dalam sebuah method boleh dihapus oleh Karbage $ollector kalau eksekusi method selesai. (alau tidak diperlukan, sebaiknya variabel dideklarasikan di dalam method agar mudah dihapus dari memory. ,erhatikan contoh berikut ini / import #ava.util.:ate public class SarbageDollector{ public static void main(String[] args){ :ate d 7 get:ate() CCla0u0an sesuatu di sini System.out.println(d) ! public static :ate get:ate() { String>u//er bu//er 7 ne8 String>u//er(*garbage collectable*) :ate date 7 ne8 :ate() return date ! ! (ode di atas terdapat dua buah object di dalam method getDate, object pertama adalah String!u^er dan object kedua adalah Date. Hbject String!u^er bisa dihapus oleh Karbage $ollector setelah eksekusi method getDate selesai dilaksanakan, sedangkan object Date tidak bisa dihapus karena referencenya dipegang oleh variabel d di dalam method main. Seperti yang sudah kita bahas, kita bisa EmenganjurkanG Karbage $ollector untuk berjalan dari dalam kode aplikasi kita. $aranya adalah memanggil method gc dari class System seperti di ba"ah ini / System.gc() Di dalam J@M tidak ada garansi bah"a setelah method gc dipanggil maka Karbage $ollector akan segera berjalan. :da kalanya Karbage $ollector langsung berjalan ada kalanya tidak. Secara praktek, kita tidak perlu memanggil kode ini, kecuali kalau anda membuat aplikasi Java MM. ,emanggilan System.gc35 laBim dilakukan dalam aplikasi Java MM, "alaupun sebenernya tidak dianjurkan, terutama setelah operasi pembacaan data dari server atau dari media penyimpanan. Mari kita coba sedikit eksperimen untuk mengetes apakah setelah method gc dipanggil Karbage $ollector langsung berjalan apa tidak, eksperimen ini melibatkan kode untuk menghitung berapa banyak memory yang tersedia dalam J@M. import #ava.util.:ate public class @0sperimenSarbageDollector{ public static void main(String[] args){ 6untime rt 7 6untime.get6untime() System.out.println(*#umla. memory a8al 3 * E rt.totalBemory()) /or(int i7' i T %'''''' iEE) { :ate d 7 ne8 :ate() d 7 null ! System.out.println(*#umla. memory tersedia sebelum gc3 * E rt./reeBemory()) System.gc() System.out.println(*#umla. memory tersedia setela. gc3 * E rt./reeBemory()) ! ! +asil eksekusi kode di atas sebagai berikut / " #avac @0sperimenSarbageDollector.#ava " #ava @0sperimenSarbageDollector #umla. memory a8al 3 NR'''%M) #umla. memory sebelum gc 3 -&R%-5'N #umla. memory setela. gc 3 N5)5'N1) " Dalam kasus di atas setelah eksekusi method gc, Karbage $ollector segera berjalan sehingga

memory yang digunakan aplikasi menjadi berkurang, ditandai dengan naiknya jumlah memory yang tersedia. :da istilah stop-the-"orld ketika kita bicara tentang Karbage $ollector, istilah ini digunakan untuk menggambarkan keadaan di dalam J@M dimana semua thread akan berhenti bekerja ketika Karbage $ollector berjalan. Kejala yang terlihat adalah aplikasi tiba-tiba berhenti sebentar 3pause5 dan tidak dapat melayani re\uest dari user. Setelah java ; diperkenalkan parallel Karbage $ollector yang bisa berjalan parallel dan tidak menyebabkan aplikasi mengalami keadaan stop-the-"orld. Sun JD( mempunyai beberapa algoritma Karbage $ollector, kita bisa memilih algoritma apa yang digunakan dengan menggunakan parameter J@M. (ita tidak membahas lebih lanjut tentang Karbage $ollector, karena topik ini adalah topik yang sangat lanjut dan seharusnya dikerjakan oleh developer berpengalaman. !ahkan, sebaiknya anda tidak mengutak-utik algoritma Karbage $ollector kalau aplikasi masih berjalan dengan baik, hanya dalam keadaan yang cukup terpaksa maka kita bisa mencoba memilih algoritma apa yang cocok digunakan. Sampai di sini kita sudah belajar tentang tipe data di java dan bagaimana memory management untuk setiap tipe data tersebut. Di bab berikutnya kita akan belajar bagaimana tipe data ini dioperasikan menggunakan operator.

"perator
Hperator digunakan untuk mengubah nilai variabel, operator inilah yang menentukan bagaimana aplikasi memanipulasi data. Di bab operator ini tidak akan terlalu banyak penjelasan, hanya sekedar referensi untuk mengetahui bagaimana operator digunakan dalam Java. Jenis operator sendiri tidak terlalu berbeda dengan bahasa pemrograman yang lain. !erbeda dengan $QQ yang dapat mengoverload operator, di Java operator tidak dapat dioverload.

!$erator Assignment
Hperator :ssignment menggunakan simbol sama dengan 3[5, kita sudah melihat bagaimana operator ini digunakan di bab-bab sebelumnya. Hperator ini mempunyai dua buah operand, sebelah kiri sama dengan dan sebelah kanan sama dengan. Hperand sebelah kiri harus berupa variabel, sedangkan sebelah kanan bisa berupa nilai literal atau variabel yang lain. :rah operasinya adalah dari kanan ke kiri, artinya nilai sebelah kanan akan dicopy ke sebelah kiri. Setelah operasi sukses dilakukan nilai variabel di sebelah kiri akan sama dengan nilai operand di sebelah kanan. :da beberapa hal yang harus diperhatikan dalam menggunakan operator assignment ini, antara lain/ Jika tipe data variabel adalah primitif, ukuran data sangat berpengaruh terhadap hasil operasi. ,astikan anda mengetahui proses casting secara implisit atau eLplisit, kalau proses casting terjadi secara eksplisit pastikan bah"a nilai datanya berada dalam rentang nilai variabel di sebelah kiri, karena casting secara eksplisit akan memotong data sesuai ukuran variabel di sebelah kiri. ngat bah"a tipe data reference bukan merupakan object, tetapi alamat dimana object sebenarnya berada. (etika kita melakukan assigment ke variabel dengan tipe data reference, yang terjadi adalah proses pengcopyan alamat object dari operand di sebelah kanan ke operand di sebelah kiri, sedangkan objectnya sendiri tetap satu, setelah operasi selesai maka kedua operand akan merujuk ke alamat object yang sama. (alau anda sudah belajar $9$QQ konsep ini disebut dengan pointer, tetapi jangan salah, di java konsep pointer tidak dikenal, yang dikenal adalah konsep reference. (etika mengassign nilai ke variabel dengan tipe data reference, perlu diingat aturan tentang supertypes, subtypes dan arrays. (etiga konsep itu akan dibahas lebih lanjut ketika kita belajar tentang konsep HH, di java di bab selanjutnya.

Hperator assigment bisa digabungkan dengan operator lain menghasilkan operator campuran, misalnya Q[, -[, Y[ dan 9[, operator campuran ini digunakan untuk menyingkat penulisan kode, contohnya kode di ba"ah ini /

, , y y

7 7 7 7

, , y y

E U L C

%'' % 1 %'

bisa disingkat menggunakan operator campuran menjadi / , E7 %'' , $7 % y L7 1 y C7 %' Sebenarnya operator campuran ada sebelas 3))5 buah, tetapi hanya empat di atas saja yang sering digunakan.

!$erator )elasi
Hperator relasi selalu menghasilkan data boolean 3true atau false5, operator ini sering digunakan untuk mengecek sebuah kondisi dan diletakkan di dalam percabangan 3if5. Hperator relasi ada enam jenis, antara lain / A lebih kecil C lebih besar A[ lebih kecil sama dengan C[ lebih besar sama dengan [[ perbandingan _[ tidak sebanding

$ontoh penggunaan operator relasi / int , 7 1'' i/ (, V %''){ CCla0u0an sesuatu ! +asil dari operasi relasi bisa diassign ke variabel dengan tipe boolean, misalnya / int , 7 1'' boolean b 7 , T %' Hperator C, A, C[ dan A[ bisa digunakan untuk membandingkan semua tipe data bilangan bulat, bilangan pecahan dan karakter 3char5, baik dalam bentuk variabel ataupun dalam bentuk literal. Sedangkan operator perbandingan 3[[ dan _[5 bisa digunakan untuk mengoperasikan semua tipe data, dari primitif, "rapper class hingga tipe data reference. Hperator perbandingan cukup intuitif jika digunakan untuk membandingkan nilai data dengan tipe primitif, yang perlu di"aspadai adalah membandingkan dua buah variabel dengan tipe data pecahan, hal ini dikarenakan tipe data pecahan double atau Uoat tidak bisa dikendalikan nilai di belakang koma, sehingga terkadang kita harus berkompromi dengan hanya membandingkan hanya sampai sekian angka di belakang koma saja. Hperator perbandingan menjadi cukup kompleks kalau digunakan untuk membandingkan nilai dari tipe data reference. Dua buah data dengan tipe data reference disebut sebanding jika keduanya memiliki alamat yang sama, atau bisa juga diartikan keduanya menunjuk ke object yang sama di dalam memory. +ati-hati menggunakan operator perbandingan terhadap tipe data "rapper class, karena hasilnya bisa diluar dugaan. Mari kita lihat kode di ba"ah ini / public class DompareWrapperDlass { public static void main(String[] args){ =nteger i 7 ne8 =nteger(%') =nteger , 7 ne8 =nteger(%') System.out.println(*ne8 =nteger(%') 77 ne8 =nteger(%')W* E (i77,)) !

! Tebak apa hasilnyaZ Pa, kalau kita compile class di atas dan dijalankan kodenya akan menghasilkan output / " #avac DompareWrapperDlass.#ava " #ava DompareWrapperDlass ne8 =nteger(%') 77 ne8 =nteger(%')W/alse " (alau kita modi?kasi sedikit kode di atas seperti di ba"ah ini, public class DompareWrapperDlass { public static void main(String[] args){ =nteger i 7 %' =nteger , 7 %' System.out.println(*%' 77 %'W* E (i77,)) ! ! Ternyata hasilnya adalah sebagai berikut / " #avac DompareWrapperDlass.#ava " #ava DompareWrapperDlass %' 77 %'Wtrue " :pakah anda terkejutZ ,erhatikan di kode pertama, variabel i dan L diassign dengan sebuah object baru menggunakan key"ord ne", artinya antara variabel i dan L akan menunjuk ke dua buah object nteger yang berbeda di memory, "alaupun sebenarnya nilai kedua object tersebut adalah sama/ )&. Sedangkan kode ke-dua, variabel i dan L diassign dengan nilai literal )&, kode ini menggunakan feature autoboLing9unboLing dari java 4 untuk mengassign nilai literal )& ke dalam "rapper class, sehingga kedua object ini sama-sama menunjuk ke nilai yang sama, yaitu literal )&. :nda harus benar-benar jeli untuk menggunakan operator perbandingan ini kalau tipe datanya reference atau "rapper class. Kunakan method e\uals yang ada di "rapper class atau di tipe data reference untuk membandingkan apakah kedua data mempunyai kesamaan secara logika, karena operator perbandingan sebenarnya membandingkan alamat memory bukan membandingkan apakah kedua object secara logika sama atau tidak. (ita akan membahas topik Eobject e\ualityG lebih lanjut di bab HH, tentang method e\uals dan hash$ode, jadi kalau sekarang masih belum terlalu ngeh tentang topik ini, masih ada satu sesi lagi yang akan membahas lebih dalam di bab selanjutnya.

!$erator Instanceo
Hperator instanceof hanya dapat digunakan untuk mengoperasikan dua buah tipe data reference. Hperator ini digunakan untuk mengecek tipe dari sebuah variabel, berikut ini contohnya / String s 7 *ini string* i/(s instanceo/ String){ CCla0u0an sesuatu di sini ! ;ong l 7 %'l <umber , 7 l i/(, instanceo/ ;ong){ CCla0u0an sesuatu di sini ! Hperator instanceof dapat menyebabkan error ketika kompilasi kalau tipe data variabel reference tersebut tidak berhubungan. Misalnya kita mempunyai tipe data nteger tetapi dioperasikan dengan class String seperti di ba"ah ini /

=nteger i 7 %' i/(i intanceo/ String){ CCla0u0an sesuatu di sini !

CCmenyebab0an error pada 8a0tu 0ompilasi

Hperator instanceof biasanya digunakan sebelum melakukan do"ncast dari subtype ke supertype agar tidak terjadi $lass$astMLception. .ebih lanjut mengenai topik ini akan kita bahas dalam bab HH, di java, karena perlu mengetahui konsep inheritance sebelum bisa memahami apa itu subtype dan supertype.

!$erator Aritmatik
Hperator aritmatik pasti sudah sangat familiar, karena operator ini tidak jauh berbeda dengan operator aritmatik yang ada di pelajaran matematika. Simbol yang digunakan dalam java adalah / Q penambahan - pengurangan Y perkalian 9 pembagian

,enggunaan keempat operator di atas sangat standard, sama persis seperti di pelajaran matematika, misalnya / int , 7 %' E %'' int y 7 %'' U int ? 7 %'' L R int a 7 %'' C ) Java juga mengenal operator modulus 3V5 atau biasa dikenal sebagai pembagi sisa. Misalnya )& V 4 hasilnya adalah & 3)& dibagi 4 sisa &5, atau )& V 7 hasilnya adalah ) 3)& dibagi 7 sisa )5. $ontohnya sebagai berikut / int , 7 %'' X %Hperator Q 3plus5 selain digunakan sebagai penambahan juga digunakan sebagai penggabungan String 3String concatenation5. $ontohnya / String s 7 *ini * E * String* String concatenation menjadi sedikit kompleks kalau dirangkai dengan angka, contohnya/ String s 7 *ini * E * String* int a 7 %' long b 7 %'' System.out.println(s E a E b) (etika salah satu operand bertipe String, maka seluruh operasi Q akan menjadi String concatenation, variabel a dan b juga dianggap sebagi String, output dari kode di atas adalah / ini String%'%'' (alau kita ingin menjumlahkan variabel a dan b terlebih dahulu sebelum digabungkan dengan String s, maka kita bisa meletakkan kurung di antara variabel a dan b, seperti kode di ba"ah ini / String s 7 *ini * E * String* int a 7 %' long b 7 %'' System.out.println(s E (a E b)) +asil kode di atas adalah / ini String%%' Java, seperti halnya $9$QQ juga mengenal operator increment dan decrement / QQ increment 3post?L dan pre?L5 -- decrement 3post?L dan pre?L5

(edua operator ini disebut juga unary operator karena hanya membutuhkan satu operand saja, sedikit berbeda dengan operator aritmatik lain yang membutuhkan dua buah operand. Hperator increment akan menaikkan nilai dari operand sebesar satu satuan, sedangkan decrement akan menurunkan nilai dari operand sebanyak satu satuan. (edua operator ini adalah bentuk lebih pendek lagi dari operator gabungan 3Q[ dan -[5. !erikut ini contoh bentuk paling panjang hingga paling pendek / int , 7 %' , 7 , E % CCbentu0 paling pan#ang , E7 % CCmengguna0an operator gabungan E7 ,EE CCmengguna0an operator increment int y 7 %'' y 7 y $ % CCbentu0 paling pan#ang y $7 % CCmengguna0an operator gabungan $7 y$$ CCmengguna0an operator decrement Hperator increment dan decrement bisa diletakkan setelah operand 3post?L5 maupun sebelum operand 3pre?L5, kedua bentuk ini sama-sama menaikkan atau menurunkan nilai operand sebanyak satu satuan, tetapi evaluasi terhadap operasinya mempunyai nilai berbeda. +asil evaluasi operator increment yang diletakkan setelah operand sama dengan nilai operand sebelum dievaluasi, sedangkan hasil evaluasi operator increment yang diletakkan sebelum operand adalah lebih banyak satu satuan daripada nilai operan sebelum dievaluasi, hmm sepertinya agak susah dimengerti yaZ baiklah, mari kita lihat contoh di ba"ah ini agar lebih jelas / public class =ncrement9est{ public static void main(String[] args){ int , 7 %' System.println(*,EE 7 * E ,EE) System.println(*Setela. evaluasi+ , 7 * E ,) , 7 %' System.println(*EE, 7 * E EE,) System.println(*Setela. evaluasi+ , 7 * E ,) ! ! (alau dicompile dan dijalankan kode di atas, hasilnya adalah sebagai berikut " #avac =ncrement9est.#ava " #ava =ncrement9est ,EE 7 %' Setela. evaluasi+ , 7 %% EE, 7 %% Setela. evaluasi+ , 7 %% " 0ah bisa kita lihat bah"a hasil setelah evaluasi adalah sama 3))5, tetapi ketika operator increment sedang dievaluasi hasilnya berbeda. (alau post?L hasilnya masih sama dengan nilai operand, kalau pre?L hasilnya lebih banyak satu satuan dibanding nilai operand. :turan ini juga berlaku untuk operator decrement public class :ecrement9est{ public static void main(String[] args){ int , 7 %' System.println(*,$$ 7 * E ,$$) System.println(*Setela. evaluasi+ , 7 * E ,) , 7 %' System.println(*$$, 7 * E $$,) System.println(*Setela. evaluasi+ , 7 * E ,) ! ! (alau dicompile dan dijalankan kode di atas, hasilnya adalah sebagai berikut

" #avac =ncrement9est.#ava " #ava =ncrement9est ,$$ 7 %' Setela. evaluasi+ , 7 M $$, 7 M Setela. evaluasi+ , 7 M " Fntuk bahan latihan, coba tebak berapa output dari kode berikut iniZ public class ;ati.an=ncrement{ public static void main(String[] args){ int , 7 %' System.out.println($$,) System.out.println(,EE E )% E EE,) ! ! tebakan saya salah /3 Tabaikan Tgapenting.

!$erator Kondisi
Hperator (ondisi adalah ternary operator, artinya operator ini mempunyai tiga buah operand. Hperator kondisi akan mengevaluasi suatu kondisi yang nilainya benar 3true5 atau salah 3false5, kemudian mengasign suatu nilai ke dalam variabel. Dengan kata lain, operator ini mirip dengan if tetapi bertujuan untuk mengassign nilai ke sebuah variabel berdasarkan suatu kondisi. Hperator kondisi menggunakan simbol Z 3tanda tanya5 dan / 3titik dua5. $ontohnya sebagai berikut / int , 7 %'' String s 7 (, T %') W *0urang dari sepulu.* 3 *lebi. dari sama dengan sepulu.* (ode di atas artinya/ kalau variabel L kurang dari sepuluh maka assign String Okurang dari sepuluhO ke dalam variabel s, sebaliknya/ kalau L lebih dari sama dengan sepuluh maka assign String Olebih dari sama dengan sepuluhO ke dalam variabel s. Hperator kondisi bisa dirangkai untuk lebih dari satu kondisi, misalnya kalau kondisi pertama benar assign suatu nilai ke varibel, kalau salah tes lagi kondisi kedua, kalau benar assign nilai yang lain ke variabel dan akhirnya kalau kedua kondisi juga salah assign nilai terakhir ke variabel. Struktur kodenya seperti di ba"ah ini / int , 7 %'' String s 7 (, T %') W *0urang dari sepulu.* 3 (, V %'') W *lebi. dari seratus* 3 *lebi. besar sama dengan sepulu. dan 0urang dari sama dengan seratus* (ode di atas artinya/ kalau variabel L kurang dari sepuluh assign String Okurang dari sepuluhO ke variabel s, selainya/ kalau L lebih dari seratus assign String Olebih dari seratusO ke dalam variabel s, kalau kedua kondisi salah/ assign String Olebih besar sama dengan sepuluh dan kurang dari sama dengan seratusO ke dalam variabel s.

!$erator Bitwise
Hperator bit"ise digunakan untuk melakukan operasi binary terhadap variabel maupun literal dengan tipe angka. Hperator bit"ise dan operator bit shift 3dibahas di bab berikutnya5 sangat jarang digunakan dalam aplikasi berbasis database, kalau anda merasa tidak punya banyak "aktu untuk belajar manipulasi bit sebaiknya segera loncat ke bab berikutnya. (alau anda mempunyai rasa keingintahuan tinggi dan ingin melihat lo" level manipulasi bit, silahkan melanjutkan membaca bab ini dan bab bit shift. :da beberapa operator bit"ise / ` 3dan5 membandingkan dua buah rangkaian binary dan mengembalikan nilai ) jika keduanya bernilai ) a 3atau5 membandingkan dua buah rangkaian binary dan mengembalikan nilai ) jika keduanya bernilai ) atau salah satu bernilai )

b 3Lor5 membandingkan dua buah rangkaian binary dan mengembalikan nilai ) jika hanya salah satu bernilai ) c negasi, merubah nilai nol menjadi satu dan sebaliknya

Mari kita lihat contoh kode untuk lebih mengerti bagaimana operator ini bekerja / int , 7 %% int y 7 %1 int ? 7 , Y y Setelah operasi selesai nilai variabel B adalah 1. !agaimana cara perhitunganyaZ kita harus menyusun angka )) dan )7 dalam bentuk binary, kemudian melakukan operasi ` 3dan5 ke setiap binary di posisi yang sama, hanya kalau keduanya bernilai ) maka hasilnya ), sisanya &. ,erhatikan diagram di ba"ah ini untuk memperjelas operasi ` / % ' % % 7V N E ' E ) E % 7 %% % % ' % 7V N E 5 E ' E % 7 %1 ((((((((((((((((((((((((((((( Y % ' ' % 7V N E ' E ' E % 7 M Sekarang kita lihat contoh untuk operator a 3atau5 / int , 7 %% int y 7 %1 int ? 7 , Z y Setelah operasi selesai nilai variabel B adalah )4. Susun angka )) dan )7 dalam bentuk binary, kemudian lihat susunan angka binarynya, kalau salah satu atau kedua angka binary pada posisi yang sama bernilai ) maka hasilnya adalah ), kalau keduanya & maka hasilnya &. ,erhatikan diagram di ba"ah ini untuk memperjelas operasi a / % ' % % 7V N E ' E ) E % 7 %% % % ' % 7V N E 5 E ' E % 7 %1 ((((((((((((((((((((((((((((( Z % % % % 7V N E 5 E ) E % 7 %R !erikutnya kita lihat contoh untuk operator b 3Lor5 / int , 7 %% int y 7 %1 int ? 7 , F y Setelah operasi selesai nilai variabel B adalah ;. Susun angka )) dan )7 dalam bentuk binary, hanya kalau salah satu dari kedua angka binary bernilai ) maka hasil operasinya ), selain itu hasilnya &. ,erhatikan diagram di ba"ah ini untuk memperjelas operasi b / % ' % % 7V N E ' E ) E % 7 %% % % ' % 7V N E 5 E ' E % 7 %1 ((((((((((((((((((((((((((((( F ' % % ' 7V ' E 5 E ) E ' 7 & !erikutnya kita lihat contoh untuk operator c 3negasi5 / int , 7 %% int ? 7 [, Setelah operasi selesai nilai variabel B adalah -)%. (ok bisaZ Sebelum kita bahas kenapa hasilnya bisa negatif, perlu kita bahas dahulu bagaimana komputer merepresentasikan bilangan negatif dan positif. ,rocessor dan memory pada dasarnya hanya mengenal bilangan binari, angka desimal yang kita lihat juga pada dasarnya disimpan sebagai binari. :ngka binari tidak mempunyai notasi negatif atau positif, untuk menandakan angka negatif atau positif dalam memory, digunakanlah teori yang disebut dengan %Js complement. Fntuk mendapatkan representasi binari nilai negatif dilakukan tiga langkah, pertama ubah nilai positifnya menjadi binary, lakukan negasi dan terakhir tambahkan satu ke hasil negasi. Mari kita lihat bagaimana membuat representasi binari dari nilai negatif -)). ,ertama kita buat

representasi binari dari angka )), tipe data yang dioperasikan adalah integer, maka panjang datanya adalah 7% bit, seperti di ba"ah ini / ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' % ' % % Setelah proses negasi, dimana nilai & menjadi ) dan sebaliknya, maka representasi binarynya menjadi / % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % ' ' .angkah terakhir dari proses %Js complement ini adalah menambahkan ) ke binari hasil negasi, sehingga hasil akhir representasi binari dari d)) adalah / % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % ' % Satu hal yang pasti, kalau angka digit sebelah paling kiri & maka angkanya pasti positif, sebaliknya jika digit paling kiri bernilai ) maka angkanya adalah negatif. (alua kita mendapatkan representasi binari dari sebuah angka negatif, maka untuk mengetahui berapa nilainya perlu dilakukan operasi kebalikan dari %Js complement / kurangi satu kemudian negasikan menjadi angka positifnya. 0ah, kita coba kembalikan bentuk -)) di atas menjadi bentuk positifnya / % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % ' % $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $% % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % ' ' $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ [ ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' % ' % % 7V %% positi/ (embali lagi ke operasi negasi dari integer di atas, sekarang kita bisa menja"ab kenapa negasi )) hasilnya adalah -)%. 0ah kita lihat Hperasi berikut ini / ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' % ' % % 7V %% $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ [ % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % ' ' 0ita 0embali0an 0e bentu0 positi/nya 3 % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % ' ' $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $% % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' ' % ' $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ [ ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' % % ' % 7V %) !ingungZ Saya juga pas nulis buku ini juga baru ingat bagaimana membuat representasi negatif ke dalam binari, jadi tidak perlu berkecil hati, dalam prakteknya, operasi bit seperti ini jarang sekali digunakan.

!$erator Bit *hi t


Selain operator bit"ise yang mengoperasikan bit secara logika, ada operator bit shift yang menggeser-geser posisi bit. Di java operator bit shift ada 7 / CC geser bit ke kanan secara aritmatik AA geser bit ke kiri secara aritmatik CCC geser bit ke kanan secara logika

Sebenarnya ada juga konsep geser bit ke kanan secara logika, tetapi karena hasilnya sama persis dengan geser bit ke kiri secara aritmatik, tidak disediakan operatornya di Java. Fntuk memperjelas bagaimana operasi geser-geser bit ini, mari kita lihat contoh di ba"ah ini/ int , 7 %% int y 7 , VV ) CC, digeser 0e 0anan dua lang0a. +asilnya adalah y bernilai %. ,erhatikan diagram di ba"ah ini / % ' % % 7V N E ' E ) E % 7 %% CC % geser bit di atas ke kanan dua kali dan tambahkan & di depan, sehingga % buah nilai ) di sebelah kanan menjadi hilang, hasilnya /

' ' % ' 7V ' E ' E ) E ' 7 ) $ontoh berikutnya adalah geser bit ke kiri / int , 7 %% int y 7 , TT ) CC, digeser 0e 0iri dua lang0a. +asilnya y bernilai )%. ,erhatikan diagram di ba"ah ini / % ' % % 7V N E ' E ) E % 7 %% CC % geser bit di atas ke kiri dua kali dan tambahkan & di belakang, sehingga % buah nilai ) di sebelah kanan bergeser ke kiri, hasilnya / % % ' ' 7V N E 5 E ' E ' 7 %) !agimana kalau operasi bit shift ini dilaksanakan terhadap angka negatifZ Hperasi penggeseran bit menggunakan tipe data int yang mempunyai panjang 7% bit, kita sudah belajar bagaimana caranya merepresentasikan nilai negatif dalam notasi binari. Misalnya kita akan menggeser -)) ke kanan dua langkah seperti kode di ba"ah ini / int , 7 $%% int y 7 , VV ) CC, digeser 0e 0iri dua lang0a. +asilnya adalah -7, kita lihat bagaimana operasi binarinya % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % ' % 7V $%% $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ TT ) % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % 7V $1 Dapat dilihat di atas, bah"a pergeseran ke kanan angka negatif akan menambahkan angka ) di sebelah kiri dan menggeser sisanya ke kanan, berbeda dengan pergeseran ke bit ke kanan pada angka positif yang menambahkan angka & di sebelah kiri dan menggeser sisanya ke kanan. +al ini menyebabkan pergeseran ke kanan tidak akan merubah angka positif menjadi negatif atau sebaliknya. ,ergeseran bit ke kiri untuk angka negatif dilakukan dengan menambahkan angka & di bit paling kanan, jadi berbeda dengan pergeseran ke kanan yang tergantung angkanya negatif atau positif, untuk pergeseran ke kiri selalu angka & yang ditambahkan di posisi paling kanan. +al ini menyebabkan pergeseran ke sebelah kiri bisa mengakibatkan angka berganti tanda dari posiitif menjadi negatif atau sebaliknya, tergantung apakah setelah operasi pergeseran nilai digit paling kiri & 3positif5 atau ) 3negatif5. Misalnya kita akan menggeser nilai maksumum positif integer ke kiri dua langkah seperti di kode berikut ini / int , 7 =nteger.BIJ(PI;G@ int y 7 , TT ) CC, digeser 0e 0iri dua lang0a. 0ilai y akan menjadi -< setelah operasi di atas selesai dilaksanakan, mari kita lihat operasi binarinya/ ' % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 7V BIJ(PI;G@ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ TT ) % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' ' 7V $5 ,enggeseran bit ke kanan secara logika sedikit berbeda dengan pergeseran ke kanan secara aritmatik, hal ini terjadi karena angka yang ditambahkan di bit paling kiri selalu & tidak tergantung angka yang akan digeser negatif atau positif. +asil pergeseran bit ke kanan secara logika berbeda dengan pergeseran bit ke kanan secara aritmatik kalau angka yang akan digeser bernilai negatif. Misalnya kita akan menggeser ke kanan secara logika dua langkah angka -)), seperti kode berikut ini / int , 7 $%% int y 7 , VVV ) CC, digeser 0e 0iri dua lang0a. +asilnya adalah y bernilai )&'7'<)6%). ,erhatikan diagram di ba"ah ini / % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % ' % 7V $ %%

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ VVV ) ' ' % % % % % % % % % % % % % % % % % % % % % % % % % % % % ' % 7V %'-1-5%N)% !aiklah, mari kita akhiri bermain-main dengan bit, kita lanjutkan ke operator yang sangat penting yaitu operator logika.

!$erator Logika
Di kurikulum ilmu komputer, operasi logika diajarkan dalam satu semester penuh di mata kuliah .ogika Matematika, kenapa sampai satu matakuliah sendiri untuk mempelajari logika matematikaZ +al ini dikarenakan operasi logika sangat penting dalam sebuah aplikasi, membuat rangkaian logika yang rapi dan mudah dimengerti untuk aplikasi yang rumit adalah pekerjaan yang cukup sulit. Terkadang kita akan mendapati kode dengan banyak sekali kondisi sehingga yang membaca kode menjadi sangat bingung bagaimana alur aplikasi berjalan. ,engalaman saya juga sering mendapati cukup banyak bug aplikasi diakibatkan oleh operasi logika yang salah. Jadi mari kita bahas operator logika di Java dengan keseriusan yang tinggi. :da enam logical operator yang bisa digunakan dalam java / ` operator dan, di bab sebelumnya operator ini juga digunakan sebagai operator bit"ise kalau operandnya bertipe angka a operator or, di bab sebelumnya operator ini juga digunakan sebagai operator bit"ise kalau operandnya bertipe angka b operator Lor, di bab sebelumnya operator ini juga digunakan sebagai operator bit"ise kalau operandnya bertipe angka _ operator logika negasi `` operator singkat dan aa operator singkat or

Mari kita bahas satu per satu operator di atas. Dimulai dari operator `, seperti sudah dibahas di atas, operator ini juga digunakan sebagai bit"ise kalau operandnya bertipe angka. (alau operandnya bertipe boolean maka operator ` akan menghasilkan nilai true kalau kedua operand bernilai true, selainya akan menghasilkan nilai false. ,erhatikan contoh kode di ba"ah ini / int , 7 %' int y 7 %% boolean ? 7 (, V %') Y (y T %'') @ariabel B akan bernilai false karena operand sebelah kiri 3L C )&5 bernilai false dan operand sebelah kanan 3y C[ )&5 bernilai true. (edua operasi di sisi kiri dan kanan akan tetap dieksekusi "alaupun sudah dipastikan bah"a operand sebelah kiri bernilai false dan apapapun nilai operand di sebelah kanan tetap akan menghasilkan nilai false. !erbeda dengan operator ``, dimana operator `` tidak akan mengeksekusi operand di sebelah kanan kalau sudah tahu bah"a operand sebelah kiri bernilai false. +al inilah alasan kenapa operator `` dinamakan operator singkat dan. ,erilaku operator `` ini penting kalau kita ingin memastikan bah"a suatu variabel object tidak bernilai null sebelum memanggil method dari object tersebut, perhatikan contoh kode di ba"ah ini/ public class ;ogicalAperator{ public static void main(String[] args){ String nama 7 null boolean ? 7 (nama !7 null) Y nama.e\uals(*i/nu*) System.out.println(?) ! ! (ode di atas akan mengakibatkan 0ull,ounterMLception karena "alaupun sudah tahu bah"a operan sebelah kiri bernilai false, operand sebelah kanan tetap dieksekusi. .ihat hasil eksekusi kode di atas / " #avac ;ogicalAperator.#ava

" #ava ;ogicalAperator @,ception in t.read *main* #ava.lang.<ull4ointer@,ception at ;ogicalAperator.main(;ogicalAperator.#ava35) " 0ah sekarang kita ubah sedikit kode di atas dengan megganti operator ` menjadi operator `` seperti kode di ba"ah ini / public class ;ogicalAperator{ public static void main(String[] args){ String nama 7 null boolean ? 7 (nama !7 null) YY nama.e\uals(*i/nu*) System.out.println(?) ! ! +asil eksekusinya akan lancar tidak mengakibatkan adanya 0ull,ointerMLception. " #avac ;ogicalAperator.#ava " #ava ;ogicalAperator /alse " Hperator a juga digunakan dalam operasi bit"ise jika operandnya adalah angka. Jika operandnya berupa boolean, operator a akan menghasilkan nilai true kalau salah satu atau kedua operand bernilai true. Hperand a hanya akan menghasilkan nilai false kalau kedua operand bernilai false. :turan ini berlaku juga untuk operator aa, perbedaanya adalah kalau operator a kedua operand akan tetap dieksekusi "alaupun operand sebelah kiri bernilai true. ,adahal kalau operand di kiri bernilai true, apapun nilai operand sebelah kanan pasti hasilnya adalah true. Sedangkan untuk operator aa, kalau operand sebelah kiri bernilai true maka operand sebelah kanan tidak akan dieksekusi dan nilai true dikembalikan sebagai hasil operasinya. Silahkan edit sedikit kode di atas dan ganti operator ` menjadi a untuk mengetahui bagaimana hasil evaluasi kode di atas kalau menggunakan oprator a. Hperator b disebut opertor Lor, hasil operasi Lor akan bernilai true kalau nilai operand di sebelah kiri berbeda dengan operand di sebelah kanan. Misalnya operand sebelah kiri bernilai true dan sebelah kanan bernilai false atau sebaliknya. (alau kedua operand sama sama false atau sama sama true maka hasilnya adalah false. ,erhatikan contoh di ba"ah ini / int , 7 %' int y 7 %% boolean ? 7 (, V %') F (y T %'') variabel B akan bernilai true karena 3L C )&5 bernilai false dan 3y A )&&5 bernilai true. Hperator _ disebut sebagai inversi atau negasi, operator ini akan membalik nilai boolean true menjadi false dan false menjadi true. Misalnya kode di ba"ah ini / int , 7 %' int y 7 %% boolean ? 7 !((, V %') F (y T %'')) variabel B akan bernilai true karena operasi 3L C )&5 b 3y A )&&5 bernilai false. Secara umum, hanya operator ``, aa dan _ yang akan kita gunakan dalam contoh aplikasi di buku ini, sisanya jarang sekali digunakan dalam aplikasi sebenarnya.

#low Control
(ontrol terhadap aliran eksekusi aplikasi adalah salah satu feature utama dari sebuah bahasa pemrograman. Java menyediakan beberapa cara untuk melakukan kontrol aliran eksekusi aplikasi. if dan s"itch adalah dua jenis yang paling sering digunakan, selain itu ada mekanisme eLception yang bisa mempengaruhi aliran eksekusi program. Dalam bab ini kita akan membahas ketiganya secara intensif, terutama bagaimana best practice penggunaan eLception.

I
Statement if digunakan dalam aplikasi untuk mengatur aliran eksekusi program berdasarkan kondisi tertentu. Sintaks dasarnya adalah sebagi berikut / int , 7 %' i/(, 77 %' ) { System.out.println(*la0u0an sesuatu di sini 0alau 0ondisi di dalam i/ bernilai true*) ! (ode di dalam kurung kura"al buka dan tutup akan dieksekusi kalau kondisi di dalam statement if bernilai true. Statement if bisa digabungkan dengan else, kode di dalam else akan dieksekusi kalau kondisi di dalam if bernilai false, contohnya / int , 7 %% i/(, 77 %' ) { System.out.println(*la0u0an sesuatu di sini 0alau 0ondisi di dalam i/ bernilai true*) ! else { System.out.println(*la0u0an sesuatu di sini 0alau 0ondisi di dalam i/ bernilai /alse*) ! :da juga bentuk else if yang dirangkai untuk mengetes beberapa kondisi, seperti di ba"ah ini int nilai 7 -N i/(nilai T 5' ) { System.out.println(*nilai T 5' 7 :*) ! else i/ (nilai V7 5' YY nilai T &') { System.out.println(*nilai V7 5' YY nilai T &' 7 D*) ! else i/ (nilai V7 &' YY nilai T -') { System.out.println(*nilai V7 &' YY nilai T N' 7 >*) ! else i/ (nilai V7 N' YY nilai T %'') { System.out.println(*nilai V7 N' YY nilai T7%'' 7 I*) ! else { System.out.println(*range nilai .arus antara ' $ %''*) ! Tanda kurung kura"al tidak diperlukan kalau blok kode yang dieksekusi di dalam if hanya satu baris saja, tetapi praktek ini tidak dianjurkan karena menimbulkan kebingungan, misalnya / int , 7 ' i/(, V7 ') System.out.println(*nilai positi/*) ,erhatikan bah"a kalau if tidak diikuti dengan tanda kurung kura"al maka yang dianggap sebagai blok kode di dalam if adalah satu statement tepat di setelah if, kalau ada beberapa statement setelah if, maka sisanya tidak dianggap bagian dari blok kode if. $ontohnya / int , 7 ' i/(, V7 ') System.out.println(*nilai positi/*) System.out.println(*selalu die0se0usi. >u0an bagian dari blo0 0ode i/*) (alau kode di atas dieksekusi, println kedua akan selalu dieksekusi apapun nilai kondisi di dalam if, hal ini karena println kedua bukan bagian dari blok kode untuk if.

*witch
S"itch biasanya digunakan kalau kita ingin mengevaluasi nilai dari sebuah variabel yang mempunyai banyak kemungkinan. !entuk sintaks s"itch lebih singkat dan bersih dibanding kalau menggunakan if-else if-else. +ingga Java ; s"itch hanya bisa digunakan kalau variabelnya bertipe angka atau enum. !erikut ini bentuk dasar dari s"itch / int , 7 %'

s8itc.(,){ case % 3 System.out.println(*satu*) brea0 case ) 3 System.out.println(*dua*) brea0 de/ault 3 System.out.println(*bu0an satu atau dua*) ! Dalam s"itch terdapat konsep yang disebut denga fall-through, konsep ini kalau kita bayangkan mirip dengan efek domino, kalau kartu pertama rubuh akan menimpa kartu berikutnya menimpa kartu berikutnya lagi seterusnya hingga ada yang menghentikan efek dominonya. .ihat kode di atas, terdapat key"ord break yang digunakan untuk menghentikan fall-through. (alau kita hilangkan break dari kode di atas, maka kalau ada satu kondisi dari case yang dipenuhi maka kode di dalam case di ba"ahnya akan terus dieksekusi hingga ketemu break atau blok kode s"itch berakhir. :gar memudahkan pemahaman tentang fall-through ini, coba buat kode seperti di ba"ah ini dan coba eksekusi kodenya/ public class Hall9.roug.{ public static void main(String[] args){ int , 7 % s8itc.(,){ case % 3 System.out.println(*satu*) case ) 3 System.out.println(*dua /all$t.roug.*) case 1 3 System.out.println(*tiga /all$t.roug.*) case 5 3 System.out.println(*empat /all$t.roug.*) de/ault 3 System.out.println(*de/ault /all$t.roug.*) ! ! ! +asil eksekusinya / " #avac Hall9.roug..#ava " #ava Hall9.roug. satu dua /all$t.roug. tiga /all$t.roug. empat /all$t.roug. de/ault /all$t.roug. " ,erhatikan bah"a setelah kondisi di case benar, maka semua kode di dalam case akan dieksekusi hingga ketemu break atau blok kode s"itch berakhir. (alau kita ubah sedikit kode di atas dengan meletakkan break di dalam case ) seperti di ba"ah ini / public class Hall9.roug.{ public static void main(String[] args){ int , 7 % s8itc.(,){ case % 3 System.out.println(*satu*) brea0 CCstop /all$t.roug. dan 0eluar dari s8itc.

! ! !

case ) 3 System.out.println(*dua /all$t.roug.*) case 1 3 System.out.println(*tiga /all$t.roug.*) case 5 3 System.out.println(*empat /all$t.roug.*) de/ault 3 System.out.println(*de/ault /all$t.roug.*)

Maka hasil eksekusinya akan berbeda / " #avac Hall9.roug..#ava " #ava Hall9.roug. satu " if dan s"itch adalah Uo" control yang digunakan kalau aplikasi berjalan dengan baik, artinya Uo" control oleh if dan s"itch digunakan untuk mengendalikan aliran eksekusi aplikasi kalau sema berjalan seperti yang dikehendaki. Java mempunyai cara untuk mengontrol aliran aplikasi kalau terjadi error di dalam aplikasi, namanya adalah eLception. (ita bahas apa itu eLception di bab berikutnya.

$%&eption
:plikasi biasanya tidak pernah berjalan mulus )&&V setiap "aktu, justru banyak sekali kejadian dimana aplikasi mengalami kondisi yang tidak diinginkan, entah ada masalah dengan data yang tidak benar, input9output yang tiba-tiba terputus, koneksi ke database yang tidak lancar hingga error yang sengaja dibuat oleh user untuk mencari celah keamanan aplikasi. (ode yang ditulis untuk menghandle masalah dan membuat aplikasi tangguh dalam segala segala medan sangat penting perananya, bahkan menurut penelitian jumlahnya mencapai 6&V dari total kode yang dibuat developer. Mengingat pentingnya penanganan kesalahan, Java menyediakan feature penanganan kesalahan yang elegan, mudah digunakan dan tepat sasaran. *eature ini disebut dengan eLception handling, dengan feature ini kita tidak perlu mengetest hasil kembalian dari suatu fungsi untuk mengetahui apakah ada error apa tidak, dengan begitu pengecekan kesalahan bisa lebih elegan dan jelas.

*intaks +,ce$tion
(ey"ord yang digunakan dalam eLception handling ada tiga / try, catch, ?nally, thro" dan thro"s. (ita akan belajar bagaimana menggunakan try dan catch terlebih dahulu baru kemudian kita belajar tentang ?nally. $ontoh-contoh kode akan menggunakan beberapa class input9output untuk membaca ?le, tidak perlu bingung bagaimana caranya menggunakan 9H, kita akan membahas 9H dalam satu bab tersediri, yang penting pahami dahulu bagaimana sintaks eLception handling serta best practicenya. (arena pentingnya konsep ini, sebaiknya ulangi membaca bab ini jika belum paham benar bagaimana konsepnya. Sintaks penggunaan try dan catch adalah sebagai berikut ini / try { CCdi sini adala. baris yang dilindungi ole. try+ CCleta00an 0ode yang potensial mengalami e,ception di sini ! catc.(Dlass@,ception variabel@,ception){ CC0alau ter#adi e,ception la0u0an sesuati CCsetida0nya la0u0an logging CCblo0 catc. yang 0osong bisa di0ategori0an sebagai 0ode 0onyol dan mengeri0an CCpasti0an ada 0ode untu0 memberi 0eterangan tentang e,ception apa yang ter#adi ! catc.(@,ception;ain variabel@,ception){

CCidem

(ode di dalam tryWX adalah kode yang melempar eLception 3thro"5, kalau kode di dalamnya berjalan normal dan tidak ada eLception yang terjadi, eksekusi akan sampai ke baris terakhir. Sebaliknya, kalau ada eLception dengan tipe $lassMLception maka eksekusi akan loncat dalam blok catch pertama, kalau ada eLception dengan tipe MLception.ain maka eksekusi akan loncat ke dalam blok catch kedua. Misalnya kita ingin membaca ?le dari harddisk, kira-kira struktur kodenya akan seperti di ba"ah ini / try{ bu0aHile:ariHarddis0 bacaHile>aris4er>aris tampil0an=siHileKeDonsole ! catc.(=A@,ception e,){ tampil0an@rror:i;og:anDonsole ! (alau kode untuk buka ?le dari harddisk gagal, maka eksekusi langsung loncat ke catch, kode untuk baca baris dan menampilkan isi ?le tidak akan dieksekusi. Dengan begitu, aplikasi tetap bisa berjalan dan tidak langsung keluar. Sintaks eLception berikutnya adalah try-catch-?nally. :da tambahan satu blok kode lagi, yaitu ?nally. (alau kode di dalam try menimbulkan eLception maka kode akan loncat ke dalam blok kode di catch, sedangkan kode di dalam ?nally akan selalu dieksekusi baik eLception terjadi di dalam try atau tidak. (ode yang ada dalam ?nally biasanya adalah kode untuk melepaskan resource, membersihkan variabel yang sudah tidak dipake lagi, bisa dibilang kode di ?nally itu digunakan untuk bersih-bersih aplikasi agar tidak menggunakan resource yang sudah tidak diperlukan lagi. Sintaksnya adalah seperti di ba"ah ini / try { CC0ode yang ada e,ception ! catc. (@,ception4ertama e,){ CC.andle e,ception dengan tipe @,ception4ertama ! catc. (@,ceptionKedua e,){ CC.andle e,ception dengan tipe @,ceptionKedua ! /inally{ CCbersi.0an resource yang dipa0ai+ bai0 ter#adi e,ception ataupun tida0 ! try bisa langsung diikuti oleh ?nally tanpa adanya catch sama sekali, hal ini bisa dilakukan kalau di dalam try eLception yang terjadi adalah unchecked eLception. :rtinya, eLceptionya tidak "ajib ditangkap 3catch5, loh kalau tidak ditangkap apa yang terjadiZ Pang terjadi adalah konsep yang disebut dengan uncaught eLception atau eLception yang tidak tertangkap yang pada akhirnya menyebabkan aplikasi berhenti berjalan. Fntuk mengetahui bagaimana mekanismenya saya akan menjelaskan tentang stack trace.

Call *tack- *tack &race dan .ncaught +,ce$tion


$all Stack adalah urutan pemanggilan method di dalam aplikasi java. :"al dari pemanggilan method tentu saja adalah method main, kemudian di dalam method main tersebut pasti ada kode untuk memanggil method lain dalam suatu class, kemudian method tersebut memanggil lagi method yang lain dan seterusnya sehingga proses pemanggilan methodnya bertumpuktumpuk. 0ah tumpukan pemanggilan method ini yang kita sebut dengan call stack. !ayangkan call stack itu layaknya sebuah gedung bertingkat, fondasi gedung bertingkat tersebut adalah method main. Setiap lantai di atasnya adalah method lain yang dipanggil oleh method main dan seterusnya sampai ke atas. Fncaught eLception menyebabkan sebuah method keluar dari eksekusinya untuk dilanjutkan ke method berikutnya sambil berharap bah"a ada kode untuk menangkap eLception itu. Dalam ilustrasi gedung bertingkat, uncaught eLception adalah kejadian dimana sebuah lantai dalam gedung runtuh, runtuhan lantai tersebut berharap ada yang menahan 3menangkap5 di lantai ba"ahnya, kalau tidak ada

satupun lantai yang menangkap runtuhan ini maka secara keseluruhan gedung akan kolaps, atau aplikasi akan berhenti bekerja. Stack trace adalah rekaman jejak call stack ketika eLception terjadi, kita bisa melihat urutan pemanggilan method dari a"al sampai akhir dimana eLception terjadi. Dengan adanya stack trace kita bisa menganalisis root cause 3penyebab utama5 terjadinya eLception. Menemukan root cause dari sebuah eLception sangat penting dalam proses memperbaiki aplikasi, selama root cause belum ditemukan, biasanya kita hanya bisa menebak-nebak apa yang terjadi dengan aplikasi tetapi tidak bisa memastikan bagian mana yang bermasalah. Stack trace dengan gamblang akan menunjukkan root cause terjadinya eLception, penting sekali untuk melakukan log terhadap stack trace ini agar mempercepat pencarian kesalahan dalam aplikasi. Mari kita lihat ilustrasi di atas dengan menggunakan kode. (ita akan membuat sebuah class dengan beberapa method, di dalam method ini akan memanggil method lain sampai pada method terakhir kita sengaja membuat kode yang menghasilkan eLception, kemudian kita akan bisa melihat stack trace dari eLception tersebut dan menentukan root causenya. public class Stac09race6ootDause { public void met.od4ertama() { System.out.println(*met.od pertama dipanggil*) met.odKedua() ! public void met.odKedua() { System.out.println(*met.od 0edua dipanggil*) met.odKetiga() ! public void met.odKetiga() { System.out.println(*met.od 0etiga dipanggil*) met.odKeempat() ! public void met.odKeempat() { System.out.println(*met.od 0eempat dipanggil*) met.odKelima() ! public void met.odKelima() { System.out.println(*met.od 0elima dipanggil*) String abc 7 null abc.toString() CC0ode ini a0an menyebab0an <ull4ointer@,ception ! public static void main(String[] args) { Stac09race6ootDause strc 7 ne8 Stac09race6ootDause() strc.met.od4ertama() System.out.println(*0ode ini tida0 a0an die0se0usi * E *0arena program suda. 0eluar * E *0eti0a e,ception di met.odKelima tida0 ditang0ap*) ! ! (ita lihat kode di atas, terdapat enam buah method/ method,ertama sampai method(elima dan method main. Method main akan memanggil method,ertama, method,ertama akan memanggil method(edua dan seterusnya hingga pada akhirnya method(elima sengaja dibuat agar melempar 0ull,ounterMLception tanpa satupun method sebelumnya menangkapnya. ,erhatilan ilustrasi call stack di ba"ah ini /

) met!odKelima() ' met!odKeem(at() # met!odKetiga() % met!odKedua() $ met!odPertama() & main() *all Stack
Method main sebagai fondasi dari call stack adalah method pertama yang dipanggil, berikutnya method,ertama hingga method(elima. Di dalam method(elima terjadi eLception yang tidak ditangkap oleh method di ba"ahnya sehingga aplikasi keluar. (ode di atas kalau dieksekusi akan menghasilkan keluaran seperti berikut ini / " #avac Stac09race6ootDause.#ava " #ava Stac09race6ootDause met.od pertama dipanggil met.od 0edua dipanggil met.od 0etiga dipanggil met.od 0eempat dipanggil met.od 0elima dipanggil @,ception in t.read *main* #ava.lang.<ull4ointer@,ception at Stac09race6ootDause.met.odKelima(Stac09race6ootDause.#ava3)%) at Stac09race6ootDause.met.odKeempat(Stac09race6ootDause.#ava3%&) at Stac09race6ootDause.met.odKetiga(Stac09race6ootDause.#ava3%)) at Stac09race6ootDause.met.odKedua(Stac09race6ootDause.#ava3N) at Stac09race6ootDause.met.od4ertama(Stac09race6ootDause.#ava35) at Stac09race6ootDause.main(Stac09race6ootDause.#ava3)R) " Stack trace adalah output yang dimulai dari kalimat EMLception in thread OmainO...G hingga ke ba"ah. Dari output stack trace di atas kita bisa melihat dengan jelas apa jenis eLception yang terjadi, dari mana a"al mulanya hingga di class apa dan di baris berapa kejadian eLception itu terjadi. ,emahaman yang sangat baik terhadap stack trace ini sangat menentukan kemampuan developer dalam mencari kesalahan aplikasi untuk berikutnya membuat solusi dari kesalahan 3bug5 tersebut. :da pepatah kuno developer bilang/ Ekemampuan developer junior dan senior dalam menulis program tidak akan jauh berbeda karena dibatasi kemampuan manusia mengetik yang terbatas, tetapi kemampuan junior developer dan senior dalam menganalisa kesalahan plus mencari solusi kesalahan itu bisa berbeda hingga puluhan ribu kali. Junior developer bisa berhari hari tidak bisa menemukan kesalahan dan solusinya, sedangkan senior developer bisa hanya dengan sekali lihat langsung tahu dimana salahnya dan bagaimana mengatasi kesalahan tersebutG.

Class +,ce$tion
MLception bisa berasal dari dua tempat/ J@M dan :plikasi. MLception yang berasal dari J@M bersifat umum dan bisa terjadi di semua aplikasi, seperti di contoh sebelumnya kita mendemonstrasikan terjadinya 0ull,ointerMLception, $lass0ot*oundMLception dan ndeLHutHf!ounMLception. (ita juga bisa membuat class eLception sendiri yang spesi?k terhadap aplikasi. Membuat class eLception yang spesi?k terhadap aplikasi kita sangat disarankan, dan merupakan best practice yang sering disarankan. Mari kita lihat bagaimana caranya membuat class eLception untuk aplikasi kita sendiri /

public class @,ception4ertama e,tends @,ception{ public @,ception4ertama() {! public @,ception4ertama(String pesan) { super(pesan) ! ! ,erhatikan bah"a class MLception,ertama di atas harus meneLtends class MLception yang sudah disediakan oleh JD(. Dalam kode di atas ada dua buah key"ord yang belum kita bahas yaitu super dan eLtends, tidak perlu kha"atir tentang dua buah key"ord tersebut, kita akan membahasnya nanti di bab tentang HH, , sekarang fokuskan perhatian ke bagaimana cara membuat class eLception. Setelah class eLception dibuat seperti di atas, kita akan membuat kode sederhana yang menggunakan class eLception di atas. ,erhatikan kode di ba"ah ini / public class @,ception4ertama9est { public static void main(String[] args) { try{ System.out.println(*e0se0usi e,ception pertama*) t.ro8 ne8 @,ception4ertama(*ini pesan e,ception pertama*) ! catc.(@,ception4ertama e,){ e,.printStac09race() ! ! ! $lass di atas mendemonstrasikan bagaimana class eLception yang sudah kita buat digunakan. Terlihat ada sintaks try-catch yang digunakan untuk menghandle eLception yang kita thro". Tidak perlu kha"atir tentang apa itu key"ord thro", kita akan bahas di bab selanjutnya. $lass eLception secara default akan mempunyai semua method yang dipunyai oleh class MLception, salah satu method yang sering digunakan adalah printStackTrace. *ungsi ini gunanya adalah untuk menampilkan stack trace ke console. (alau sudah lupa apa itu stack trace, silahkan buka-buka lagi bab sebelumnya yang membahas stack trace. Seperti yang kita lihat, cara membuat class eLception yang spesi?k untuk aplikasi kita sangat mudah, silahkan buat class eLception yang mendeskripsikan error yang spesi?k, hal ini memudahkan analisa stack trace kalau terjadi eLception dalam aplikasi.

/irarki Class +,ce$tion


Dalam bab ini kita akan membahas hirarki class eLception, kita belum membahas konsep HH, cukup banyak hingga bab ini, jadi kalau belum terlalu mengerti apa itu inheritance, jangan terlalu kha"atir, yang penting sekarang pahami dahulu bagaimana hirarki class MLception.

.bject

/!ro0able

+rror

+,ce(tion

-untime+,ce(tion

Seperti yang anda bisa lihat, hirarki kelas eLception dimulai dari Hbject, kemudian ada class Thro"able yang merupakan parent class dari semua jenis MLception. :da dua buah class turunan langsung dari class Thro"able yaitu class Mrror dan class MLception. $lass MLception sendiri mempunyai satu turunan yaitu -untime MLception. Mrror biasanya tidak disebabkan karena kesalahan yang terjadi dalam aplikasi, tetapi lebih karena keadaan J@M yang tidak normal, misalnya error karena kehabisan memory. Mrror tidak perlu dihandle dalam try-catch karena tidak ada cara untuk mengatasi keadaan Mrror. Secara teknis sebenarnya error bukanlah eLception karena bukan merupakan turunan dari MLception. !erbeda dengan Mrror, MLception merepresentasikan kesalahan yang terjadi dalam aplikasi. (ita bisa melakukan recovery untuk mengatasi MLception. JD( mempunyai banyak sekali class turunan dari MLception, nama class-class ini sangat descriptive sehingga hanya dengan melihat nama class MLceptionya kita sudah bisa menebak kesalahan apa yang terjadi dalam aplikasi. $lass -untimeMLception adalah class spesial yang disebut juga dengan unchecked eLception. 0ama unchecked eLception digunakan karena -untimeMLception tidak "ajib dicatch. $ontoh turunan dari -untimeMLception adalah 0ull,ointerMLception, $lass$astMLception, ndeLHutHf!oundMLception dan masih banyak lagi. Mari kita lohat contoh kode yang menyebabkan -untimeMLception / public class 6untime@,ception9est { public static void main(String[] args){ int i 7 =nteger.parse=nt(*abc*) System.out.println(*0ode setela. e,ception*) ! ! (ode di atas akan menyebabkan -untimeMLception karena berusaha mengubah string OabcG menjadi angka. ,erhatikan bah"a tidak "ajib ada statement try-catch untuk menghandle -untimeMLception. Tanpa ada try-catch dalam kode di atas, maka kalau terjadi eLception kode akan segera keluar dari method, nah karena ini adalah method main dan tidak ada lagi method yang lain 3ingat analogi call stack dengan gedung tinggi5, aplikasi akan langsung keluar, dan string Ekode setelah eLception tidak akan ditampilkanG. " #avac 6untime@,ception9est.#ava " #ava 6untime@,ception9est @,ception in t.read *main* #ava.lang.<umberHormat@,ception3 Hor input string3 *abc* at #ava.lang.<umberHormat@,ception./or=nputString(<umberHormat@,ception.#ava35N) at #ava.lang.=nteger.parse=nt(=nteger.#ava355M) at #ava.lang.=nteger.parse=nt(=nteger.#ava35MM) at 6untime@,ception9est.main(6untime@,ception9est.#ava31) " Misalnya kita tidak yakin dengan String yang akan diubah menjadi integer berhasil atau tidak, kita bisa meletakkan statement try-catch, kalau ada error nilai integer kita set menjadi &, lanjutkan program ke baris berikutnya, modi?kasi kodenya seperti di ba"ah ini / public class 6untime@,ception9est { public static void main(String[] args){ int i 7 ' try{ i 7 =nteger.parse=nt(*abc*) ! catc.(<umberHormat@,ception e,) { e,.printStac09race() ! System.out.println(*0ode setela. e,ception*) ! ! (alau kita jalankan kode di atas, maka setelah terjadi eLception pada "aktu mengeksekusi

method parse nt, eksekusi akan meloncat ke dalam catch, mencetak stack trace ke console kemudian melanjutkan eksekusi untuk mencetak string Ekode setelah eLceptionG ke console. Dengan modi?kasi di atas, kode menjadi lebih handal dan tidak menyebabkan program keluar sebelum eksekusi selesai semuanya. " #avac 6untime@,ception9est.#ava " #ava 6untime@,ception9est #ava.lang.<umberHormat@,ception3 Hor input string3 *abc* at #ava.lang.<umberHormat@,ception./or=nputString(<umberHormat@,ception.#ava35N) at #ava.lang.=nteger.parse=nt(=nteger.#ava355M) at #ava.lang.=nteger.parse=nt(=nteger.#ava35MM) at 6untime@,ception9est.main(6untime@,ception9est.#ava3R) 0ode setela. e,ception " $lass MLception yang bukan turunan dari -untimeMLception disebut dengan checked eLception. (ode yang didalamnya ada eLception dengan tipe ini harus diletakkan dalam blok try, kalau tidak, maka akan terjadi kompilasi error. Sebagai contoh kita akan menulis kode untuk membuka ?le, kode ini mengandung checked eLception yaitu HMLception. ,ertama kita lihat dulu kode tanpa try, kode ini akan menyebabkan adanya kompilasi error / import #ava.io.Hile=nputStream public class D.ec0ed@,ception9est { public static void main(String[] args) { Hile=nputStream inputStream 7 ne8 Hile=nputStream(*bu0a$/ile.t,t*) System.out.println(*0ode setela. bu0a /ile*) ! ! hasil kompilasi kode di atas adalah / " #avac D.ec0ed@,ception9est.#ava D.ec0ed@,ception9est.#ava353 unreported e,ception #ava.io.Hile<otHound@,ception must be caug.t or declared to be t.ro8n Hile=nputStream inputStream 7 ne8 Hile=nputStream(*bu0a$/ile.t,t*) F % error " terlihat pada output proses kompilasi di atas bah"a konstruktor ne" *ile nputStream3Obuka?le.tLtO5D melempar eLception yang harus ditangkap 3catch5 atau dideklarasikan untuk dilempar 3thro"5 lagi. Di bab ini kita baru belajar bagaimana menangkap eLception, sedangkan bagaimana caranya melempar lagi eLception kita bahas di bab berikutnya. Fntuk mengatasi error kompilasi di atas, kita akan menambahkan try-catch di kode di atas. import #ava.io.Hile=nputStream import #ava.io.Hile<otHound@,ception import #ava.io.=A@,ception public class D.ec0ed@,ception9est { public static void main(String[] args) { try{ Hile=nputStream inputStream 7 ne8 Hile=nputStream(*bu0a$/ile.t,t*) ! catc.(Hile<otHound@,ception e,){ e,.printStac09race() ! catc.(=A@,ception e,) { e,.printStac09race() ! System.out.println(*0ode setela. bu0a /ile*) ! !

,erhatikan bah"a konstruktor ne" *ile nputStream3Obuka-?le.tLtO5D menyebabkan dua buah eLception yaitu *ile0ot*oundMLception dan HMLception. (edua eLception ini ditangkap dan dihandle dalam catch yang berbeda, kita bisa juga menangkap hanya HMLception karena pada dasarnya *ile0ot*oundMLception adalah turunan HMLception, sehingga cukup ditangkap sekali saja maka kedua tipe sudah dihandle. $ontohnya seperti di ba"ah ini / import #ava.io.Hile=nputStream import #ava.io.Hile<otHound@,ception import #ava.io.=A@,ception public class D.ec0ed@,ception9est { public static void main(String[] args) { try{ Hile=nputStream inputStream 7 ne8 Hile=nputStream(*bu0a$/ile.t,t*) ! catc.(=A@,ception e,) { e,.printStac09race() ! System.out.println(*0ode setela. bu0a /ile*) ! ! HMLception dan *ile0ot*oundMLception adalah turunan MLception, sehingga bisa juga kita tangkap dengan tipe MLception, kalau ini yang kita lakukan maka semua class eLception turunan dari MLception akan ikut ditangkap juga. ,raktek Etangkap semua eLception tanpa pandang buluG seperti ini dikategorikan sebagai praktek kurang baik, karena semua jenis eLception akan dihandle dengan cara yang sama, padahal kita bisa menghandle eLception dengan lebih baik kalau bisa memilah-milah cara menghandle eLception berdasar tipenya. Menangkap eLception terbalik dengan menangkap koruptor, kalau koruptor harus ditangkap tanpa pandang bulu, sedangkan eLception harus ditangkap dengan cara dipilah-pilah berdasarkan tipenya.

&hrows dan &hrow


!ab sebelumnya sudah membahas bah"a untuk menghandle eLception caranya ada dua / cara pertama yaitu dengan menggunakan try-catch yang sudah kita bahas, cara kedua adalah dengan melempar eLception ke method pemanggilnya. Solusi kedua ini terbalik dengan solusi pertama yang langsung menghandle eLception di tempat, solusi kedua ini malah melempar tanggung ja"ab ke method pemanggilnya untuk menghandle eLception, jadi methodnya cuci tangan dan tidak bertanggung ja"ab. 0ah sekarang pertanyaanya, bagimana kalau tidak ada satupun method pemanggilnya yang menangkap eLception iniZ (alau hal ini terjadi, maka aplikasi akan keluar dari eksekusi 3ingat analogi call stack dengan gedung tinggi5. Sintaks untuk melempar tanggung ja"ab menangkap eLception menggunakan key"ord thro"s yang diletakkan di deklarasi method. +mm, bingungZ Mari kita lihat contohnya agar tidak bingung. Misalnya kita tidak ingin menangkap eLception HMLception dan *ile0ot*oundMLception seeperti dalam contoh sebelumnya, kodenya seperti berikut ini / import #ava.io.Hile=nputStream import #ava.io.Hile<otHound@,ception import #ava.io.=A@,ception public class 9.ro8s@,ception9est { public static void main(String[] args) t.ro8s Hile<otHound@,ception+ =A@,ception { Hile=nputStream inputStream 7 ne8 Hile=nputStream(*bu0a$/ile.t,t*) System.out.println(*0ode setela. bu0a /ile*) ! ! ,erhatikan kode di atas, tanpa ada try-catch kodenya tidak akan menyebabkan error pada "aktu kompilasi. (uncinya ada pada key"ord thro"s di sebelah method main, dengan adanya thro"s ini maka method main tidak "ajib melakukan try-catch terhadap kedua tipe eLception. 0ah karena method main adalah method paling ba"ah dari call stack, maka kalau ada eLception yang tidak dihandle oleh method main ini aplikasi akan langsung keluar. ngat, aturan ini hanya berlaku untuk checked eLception, sedangkan unchecked eLception tidak perlu

ditry-catch ataupun thro"s. (ita lihat lagi contoh bagaimana kalau eLception dilempar di satu method dan pada akhirnya eLception tersebut ditangkap di method pemanggilnya. / import #ava.io.Hile=nputStream import #ava.io.Hile<otHound@,ception import #ava.io.=A@,ception public class 9.ro8s@,ception9est { public static void main(String[] args) { try { met.od9ida0>ertanggung]a8ab() ! catc.(Hile<otHound@,ception e,){ e,.printStac09race() ! catc.(=A@,ception e,) { e,.printStac09race() ! System.out.println(*0ode di dalam met.od main*) ! public static void met.od9ida0>ertanggung]a8ab() t.ro8s Hile<otHound@,ception+ =A@,ception { Hile=nputStream inputStream 7 ne8 Hile=nputStream(*bu0a$/ile.t,t*) System.out.println(*0ode setela. bu0a /ile*) ! ! di dalam method methodTidak!ertanggungJa"ab, eLception tidak dihandle tetapi dilempar ke metod pemanggilnya dengan menggunakan sintaks thro"s. Sedangkan method main yang memanggil method methodTidak!ertanggungJa"ab, akhirnya menghandle eLception sehingga eksekusi aplikasi tidak langsung keluar dan dilanjutkan dengan mecetak string di ba"ahnya baru kemudian keluar. !eberapa bab terakhir kita terus membahas bagaimana caranya menghandle eLception dengan cara menangkap atau melempar eLception ke method pemanggilnya. 0ah, kalau kita menangkap sesuatu pasti pada a"alnya kan ada yang melempar eLception ini. +ukum sebab-akibat juga berlaku untuk eLception, dimana ada sebab 3thro" eLception5 ada juga akibat 3handle eLception dengan try-cath atau thro"s5. (ey"ord thro" 3tanpa s5 adalah a"al dimana eLception dibuat untuk kemudian dilempar pertama kalinya. Sintaks thro"s sangat sederhana, pertama kita harus membuat object dari class MLception atau turunanya, kemudian letakkan key"ord thro" diikuti object dari class MLception tersebut, miripmirip dengan penggunaan return. $ontoh bagaimana menggunakan thro" bisa dilihat dalam bab $lass MLception. (ey"ord thro" banyak digunakan dalam class-class library dalam java untuk memberitahu kode dalam aplikasi kita bah"a telah terjadi error. Sebagian besar libary java yang berhubungan dengan 9H 3 nput9Hutput5 akan menthro" eLception kalau ada masalah dalam 9H, misalnya dalam contoh pembacaan ?le di atas ada eLception yang menerangkan bah"a ?le tidak ketemu 3*ile0ot*oundMLception5 atau ada masalah pada saat pembacaan ?le 3 HMLception5. (ey"ord thro" jarang sekali digunakan dalam kode aplikasi, kecuali dalam keadaan dimana kita ingin memberitahu bagian lain dalam aplikasi bah"a sudah terjadi error. :rsitektur aplikasi modern biasanya mengikuti pola Eseparation of concernG, artinya pemisahan kode-kode tertentu dalam lapisan berbeda. Misalnya kode untuk mengakses database dan kode untuk user interface 3F 5 diletakkan dalam lapisan yang berbeda, tidak boleh bercampur. $lass-class yang digunakan untuk mengakses database tidak boleh bocor ke lapisan F dan sebaliknya class-class F tidak boleh sampai merembes ke class untuk mengakses database. 0ah, kalau misalnya class yang mengakses database ingin melempar eLception ke class F , maka kita harus membuat class eLception sendiri dan class inilah yang akan kita lempar ke class F . !agaimana implementasi Eseparation of concernG ini akan kita bahas lagi lebih lanjut di bab setelah bab Java *undamental.

'erulan!an ( Iterasi
,erulangan atau terasi adalah konsep yang selalu ada dalam semua bahasa pemrograman, begitu juga dengan java. !entuk iterasi dalam Java ada beberapa, yang pertama adalah for, kemudian ada "hile dan do-"hile. (ita akan membahas satu per satu setiap bentuk perulangan di bagian berikutnya.

or
(ey"ord for digunakan untuk melakukan iterasi kalau jumlah iterasinya tertentu, misalnya kita ingin melakukan iterasi sebanyak )&L atau )&&L. terasi menggunakan for memerlukan tiga buah parameter, parameter pertama digunakan sebagai batas ba"ah iterasi, parameter kedua adalah kondisi kapan iterasi berhenti dan parameter terakhir dugunakan untuk menaikkan atau menurunkan counter. (ita lihat sintaks dasar dari for seperti di ba"ah ini / /or( parameter% parameter) 3 parameter1) { ! sintaks iterasi for dia"ali dengan key"ord for, kemudian diikuti dengan kurung buka, setelahnya ada tiga buah parameter yang dipisahkan dengan titik dua 3/5, kurung buka tutup dan diakhiri dengan pasangan kurung kura"al buka-tutup untuk menandakan blok kode yang akan dieksekusi berulang-ulang hingga iterasi berhenti. !erikut ini contoh konkrit penggunaan iterasi menggunakan for / public class Hor9est { public static void main(String[] args) { /or(int i 7 ' iT %' iEE) { System.out.println(*iterasi 0e$* E i) ! ! ! ,erhatikan sintaks for di atas, parameter pertama diisi dengan int i [ &, ini artinya adalah kita akan menggunakan variabel i sebagai counter 3penghitung5 untuk for dia"ali dari &. ,arameter kedua diisi dengan i A )&, artinya iterasi for akan terus belangsung selama i bernilai kurang dari )& dan berhenti ketika i sudah mencapai nilai sepuluh. ,arameter ketiga diisi dengan iQQ artinya setiap kali iterasi maka counter i akan naik satu nilai. (etiga parameter ini mengindikasikan bah"a iterasi dilakukan dari i bernilai &, berakhir ketika i mencapai nilai )& dan setiap kali iterasi i naik satu-satu, total akan terjadi )&L perulangan. +asil eksekusi dari kode di atas adalah sebagai berikut / " #avac Hor9est.#ava " #ava Hor9est iterasi 0e$' iterasi 0e$% iterasi 0e$) iterasi 0e$1 iterasi 0e$5 iterasi 0e$R iterasi 0e$& iterasi 0e$iterasi 0e$N iterasi 0e$M " terasi for juga bisa berlangsung mundur, contohnya seperti di ba"ah ini / public class HorBundur9est { public static void main(String[] args) { /or(int i 7 %' i V ' i$$) { System.out.println(*iterasi 0e$* E i) !

! ! +asil eksekusinya akan sedikit berbeda, seperti di ba"ah ini / " #avac HorBundur9est.#ava " #ava HorBundur9est iterasi 0e$%' iterasi 0e$M iterasi 0e$N iterasi 0e$iterasi 0e$& iterasi 0e$R iterasi 0e$5 iterasi 0e$1 iterasi 0e$) iterasi 0e$% " ngat, iterasi for digunakan kalau kita tahu berapa kali iterasi dilaksanakan, hal ini dikarenakan iterasi for memerlukan parameter a"al, kondisi berhenti dan berapa banyak counter bertambah9berkurang dalam setiap iterasi. (alau iterasi tidak diketahui berapa kali dilakukan dan hanya tahu bah"a selama suatu kondisi tertentu masih benar iterasi akan terus berlangsung maka kita bisa menggunakan "hile.

while
Seperti yang sudah kita bahas sedikit di atas, bentuk iterasi "hile digunakan kalau kita tidak tahu berapa kali interasi akan berlangsung, tetapi tahu kapan iterasi berhenti dari sebuah kondisi tertentu. !entuk sintaks "hile sangat sederhana dan hanya memerlukan satu saja parameter kondisi yang bernilai boolean true atau false, selama kondisi ini masih bernilai true maka iterasi akan terus dilaksanakan. (alau nilai kondisi adalah false maka iterasi "hile akan berhenti. !entuk sintaksnya adalah seperti di ba"ah ini / 8.ile( 0ondisi ) { ! Sintaks "hile dia"ali dengan key"ord "hile kemudian diikuti dengan kurung buka, di dalam kurung buka ada satu kondisi, dan diakhiri kurung tutup, setelah itu ada pasangan kurung kura"al buka tutup. (ita akan membuat contoh kecil yang akan mengambil nilai "aktu sekarang, mengetes apakah "aktu sekarang ini kalau dibagi 7 sisanya &, selama tidak memenuhi kondisi di atas maka iterasi dijalankan terus menerus. (ode untuk contoh di atas adalah seperti berikut ini / public class W.ile9est { public static void main(String[] args) { 8.ile(System.current9imeBillis() X 1 !7 ') { System.out.println(*8a0tu se0arang dibagi 1 masi. ada sisanya*) ! ! ! Jumlah iterasi dalam kode di atas tidak menentu, terkadang iterasi bisa terjadi banyak kali, sedikit kali atau bahkan tidak terjadi iterasi sama sekali. " #avac W.ile9est.#ava " #ava W.ile9est 8a0tu se0arang dibagi 1 masi. ada sisanya 8a0tu se0arang dibagi 1 masi. ada sisanya " (alau kita ingin agar iterasi terjadi setidaknya sekali saja maka kita bisa menggunakan do-"hile yang akan kita bahas di bab berikutnya.

do0while
!entuk iterasi do-"hile digunakan kalau kita ingin agar setidaknya satu iterasi terjadi baru kemudian ditest kondisinya apakah iterasi berikutnya dilaksanakan atau tidak. Sama dengan bentuk iterasi "hile, bentuk iterasi do-"hile juga memerlukan satu parameter kondisi di dalam "hile-nya. Sintaks do-"hile adalah seperti berikut ini / do { ! 8.ile( 0ondisi ) (ita modi?kasi sedikit kode di atas dengan menggunakan bentuk iterasi do-"hile, seperti di ba"ah ini / public class W.ile9est { public static void main(String[] args) { do { System.out.println(*8a0tu se0arang dibagi 1 masi. ada sisanya*) 8.ile(System.current9imeBillis() X 1 !7 ') ! ! kalau kita eksekusi kode di atas, maka setidaknya string di atas diprint sekali, kalau misalnya kondisi di dalam "hile masih benar maka string-nya akan dipring lagi sampai kondisi di dalam "hile bernilai false. Sampai di sini pembahasan sintaks java sudah mencukupi, di bagian selanjutnya kita akan membahas HH, dengan java. ,embahasan HH, akan lebih banyak berikisar tentang teori dan praktek pemrograman yang baik. #alaupun Java adalah bahasa pemrograman HH, , tetapi kalau kita tidak mempraktekkan HH, dengan baik, bentuk kodenya malah akan mirip bahasa prosedural. Jadi praktek penggunaan HH, memerlukan disiplin dari perogrammernya.

""' den!an Java


Menjadi developer Java, mengharuskan anda untuk menyelami konsep HH, dengan sangat dalam. Tiap hari anda harus bermimpi tentang inheritance dan hirarki class Java, kekuatan polymorphism menjadi senjata pamungkas kode anda, kohesi dan loosely coupling menjadi napas anda pertama bangun tidur, dan composition menjadi sarapan anda di pagi hari. Teaa Tlebay. Sudah banyak terjadi kasus dimana seorang developer java yang sudah berpengalaman bertahun-tahun tetapi konsep HH,nya sangat lemah, sehingga kode java malah mirip kode $ dimana banyak method static dan tidak ada desaign pattern yang diimplementasikan sama sekali. :tau programmer java yang a"alnya developer @isual !asic menulis kode java sama persis dengan kebiasanya menggunakan @!, yaitu dengan meletakkan semua kode yang diperlukan dalam satu blok kode action dari sebuah tombol. +asilnya tentu saja spagetti code, enak tapi kelihatan campur aduk, ru"et, berceceran dan berantakan. Maka dari itu, HH, menjadi topik yang sangat penting dalam buku ini. (onsep HH, harus benar-benar dikuasai agar kode yang dihasilkan menjadi rapi, self eLplained/ hanya dengan melihat kode sudah paham apa maksudnya tanpa membaca dokumentasi dan logis. ,enerapan konsep HH, membuat kode menjadi sangat berkualitas dan harganya mahal karena kualitas yang baik tersebut. Fntuk menambah motivasi membuat kode berkualitas baik, bayangkan bah"a anda akan menjadi developer selama beberapa bulan saja, kemudian ada seseorang yang akan memantain kode anda selama berpuluh-puluh tahun berikutnya. Hrang ini adalah megalomaniac madosastic berdarah dingin tanpa perasaan yang tidak pernah mandi berbulan-bulan. Setiap kali maintainer ini naik emosinya karena harus membaca kode anda yang berantakan, dia akan segera menuju rumah dimana anda tinggal, kemudian menyiksa anda dengan benda tumpul, menjepit anda di antara keteknya yang bau dan berusaha menyayat anda dengan golok berkarat. Tlebaylagi Thoror. (onsep HH, yang baik juga dapat membuat aplikasi kita menjadi cukup modular, dalam beberapa kasus kita bisa mengganti satu class saja untuk melakukan enhancement terhadap

aplikasi tanpa perlu mengotak-atik class lainya. Misalnya suatu perhitungan diletakkan dalam sebuah interface, ketika dalam development kita mengimplementasikan sebuah class dengan perhitungan tertentu. (etika beberapa saat aplikasi berjalan, ternyata ada perhitungan yang berbeda, nah kita tinggal mengimplementasikan interface yang sama dan menginisialisasi perhitungan dengan menggunakan class yang kedua. +oplaaa, maka aplikasi akan menghitung dengan menggunakan class kedua ini. mplementasi HH, yang baik akan mena"arkan dua kualitas ke dalam aplikasi kita / modular 3modularity5 dan mudah dipelihara 3maintenability5. Tetapi kualitas tersebut tidak datang begitu saja, anda harus berusaha keras dengan disiplin tinggi untuk mencapainya. Java memberi anda landasan yang kuat dengan feature HH, , tetapi Java tidak bisa mencegah anda menulis kode yang tidak berkualitas baik, anda masih tetap bisa menulis kode Java dengan gaya prosedural ataupun gaya spagetti. 0ah kita akan membahas satu per satu apa itu HH, , siapkan mental anda karena konsep HH, cukup abstract dan perlu "aktu untuk dicerna. Silahkan baca bab per bab secara berulang-ulang hingga anda mengerti esensi dari teori HH,. Sekalian juga hafalkan bagaimana konsep tersebut kalau diimplementasikan ke dalam bentuk kode.

+nka$sulasi
Mnkapsulasi adalah konsep dimana sebuah logic kode dibungkus dalam satu bentuk kode yang menggambarkan dunia nyata. $lass adalah sebuah enkapsulasi dari perilaku yang di"akilinya dalam dunia nyata. Setiap entitas dalam dunia nyata mempunyai karakteristik dan perilaku. (arakteristik ini di"ujudkan sebagai property, sedangkan perlilaku di"ujudkan dalam sebuah method. (edua hal ini / karakteristik dan perilaku dienkapsulasi menjadi satu entitas dalam class. !ahasa prosedural tidak mempunyai feature enkapsulasi ini, sehingga kalau kita melihat kode kita tidak bisa melihat "ujud abstraksi kode tersebut dengan dunia nyata. Semua hanya berbentuk fungsi 9 method, sedangkan datanya berceceran di sana sini. HH, memberikan konsep yang sangat praktis tentang bagaimana menjembatani logic yang ada di dunia nyata dengan "ujudnya dalam kode. Sehingga ketika kita bicara dengan user aplikasi yang tidak mengetahui kode, kita tetap bisa bicara dengan istilah yang sama. Misalnya kita berbicara tentang customer, kita bicara customer yang nyata dan juga sekaligus berbicara tentang class $ustomer yang ada dalam kode. Dengan adanya enkapsulasi, programmer yang pada a"alnya tidak terlibat dalam analisis aplikasi, dan hanya bisa melihat kode bisa dengan mudah mengasosiasikan kode tersebut dengan keadaan nyata. Mnkapsulasi menyebabkan kode menjadi self eLplained, artinya hanya dengan melihat kode kita dapat mengetahui apa logic di balik kode ini, atau kita bisa mengetahui apa maksud dari kode yang sedang kita baca. Java dari a"al didesain sebagai bahasa untuk membuat aplikasi Mnterprise. Sebenernya antara aplikasi enterprise dan aplikasi main-main tugas kuliah kodenya tidak jauh berbeda, yang jauh berbeda adalah ukuranya. (alau aplikasi main-main tugas kuliah, ukuran kodenya paling masih beberapa kilobyte saja, tetapi aplikasi dengan skala enterprise bisa sampai bergiga-giga. Developer yang mengerjakan aplikasi juga jauh sekali perbandinganya, karena aplikasi enterprise bisa dikerjakan hingga ratusan orang. Dengan ukuran sebesar itu, tidak mungkin membuat dokumentasi yang mendetail tentang kodenya, oleh karena itu sebisa mungkin setiap kode yang ditulis oleh developer sudah self eLplained.

Inheritance- I*0A dan /A*0A


nheritance 3turunan5 ada di mana-mana dalam Java. Sangat tidak mungkin membuat aplikasi tanpa melibatkan konsep nheritance, faktanya setiap class yang kita tulis adalah turunan dari class Hbject. :nda ingin buktiZ ngat-ingat lagi bab tentang operator, di sana ada satu operator instanceof, operator ini digunakan untuk mengetes apakah sebuah object merupakan tipe dari suatu class. Hperator ini akan mengembalikan true kalau tipe dari object tersebut adalah class yang ada di operand sebelah kanan dari operator instanceof, sebaliknya nilainya adalah false. (ita lihat contohnya di ba"ah ini / public class =n.eritance9est { public static void main(String[] args){ =n.eritance9est test 7 ne8 =n.eritance9est() i/(test instanceo/ Ab#ect) {

System.out.println(*test tipenya Ab#ect*) ! else { System.out.println(*test tipenya bu0an Ab#ect*) ! ! !

(alau kita compile kode di atas dan dijalankan, outputnya adalah seperti di ba"ah ini / " #avac =n.eritance9est.#ava " #ava =n.eritance9est test tipenya Ab#ect " Terbukti bah"a "alaupun tidak secara eksplisit kita de?nisikan nheritanceTest sebagai turunan dari Hbject, faktanya nheritaceTest adalah turunan dari Hbject karena operator instanceof mengembalikan nilai true ketika object dari nhertanceTest dioperasikan dengan class Hbject. mplementasi inheritance dalam kode menggunakan key"ord eLtends. (alau kita ingin membuat sebuah class turunan dari class yang lain, kita gunakan key"ord eLtends setelah deklarasi nama class diikuti dengan class yang ingin digunakan sebagai orang tua dari class tersebut. Misalnya kita ingin akan membuat dua buah class, class pertama adalah $ustomer sedangkan class kedua adalah Member$ustomer, dimana class Member$ustomer adalah turunan dari class $ustomer. (ode class $ustomer adalah seperti di ba"ah ini / public class Dustomer {! kode class Member$ustomer adalah seperti di ba"ah ini public classs BemberDustomer e,tends Dustomer {! $lass Member$ustomer dalam hal ini mempunyai hubungan S-: dengan class $ustomer. (alimat lengkapnya adalah EMember$ustomer S-: $ustomerG. +al ini dikarenakan Member$ustomer adalah turunan $ustomer, analoginya kita bisa menggunakan kucing dan he"an. (ucing adalah turunan dari he"an, maka kucing adalah he"an. Sama juga seperti Member$ustomer adalah turunan dari $ustomer, maka Member$ustomer adalah $ustomer. :pa tujuan dari inheritance dilihat dari sisi kodeZ Pang pertama adalah mempromosikan code reuse, yaitu penggunaan kembali kode yang sudah ditulis. +al ini dikarenakan, sebagai turunan dari $ustomer, Member$ustomer akan mempunyai semua sifat-sifat 3kode5 dari class $ustomer. Misalnya kita ubah sedikit kode di atas, kita tambahkan property dan method di dalam class $ustomer / public class Dustomer { private ;ong id public void set=d(;ong a=d){ t.is.id 7 a=d ! public ;ong get=d() { return t.is.id ! ! kemudian class Member$ustomer tetap seperti semula / public class BemberDustomer e,tends Dustomer {! !uat lagi satu class untuk mengetes konsep inheritance / public class Dustomer9est { public static void main(String[] args) { BemberDustomer member 7 ne8 BemberDustomer() member.set=d(%''l) System.out.println(*id customer 3 * E member.get=d()) ! !

(alau kita compile ketiga class di atas dan dijalankan outputnya adalah sebagai berikut ini / " #avac BemberDustomer.#ava Dustomer.#ava Dustomer9est.#ava " #ava Dustomer9est id customer 3 %'' " Terlihat bah"a tidak ada error dalam proses kompilasi, padahal class Member$ustomer tidak mende?nisikan apapun, tetapi method set d dan get d dapat digunakan. +al ini dikarenakan Member$ustomer mengeLtends $ustomer, sehingga method set d dan get d diturunkan. $atat juga bah"a property id sendiri tidak diturunkan ke dalam Member$ustomer, karena property id menggunakan private sebagai access modi?er. +ubungan +:S-: lebih sederhana penjelasanya dibanding hubungan S-:. +ubungan +:S-: atau biasa disebut dengan komposisi 3composition5 terjadi kalau sebuah class mempunyai sebuah property. Misalnya kita bisa melihat dalam kode di atas $ustomer +:S-: .ong dengan nama id. (ita akan membuat sebuah satu buah class lagi dengan nama :ddress, class ini akan digunakan oleh class $ustomer untuk mende?nisikan alamat $ustomer. (odenya seperti di ba"ah ini / public class Iddress { private String street private String city private String postDode ! +ubungan antara $ustomer dan :ddress adalah +:S-:, diimplementasikan dengan membuat property di dalam class $ustomer dengan tipe :ddress. (ita ubah sedikit kode dari class $ustomer di atas menjadi seperti di ba"ah ini / public class Dustomer { private ;ong id private Iddress address public void set=d(;ong a=d){ t.is.id 7 a=d ! public ;ong get=d() { return t.is.id ! public void setIddress(Iddress aIddress) { t.is.address 7 aIddress ! public Iddress getIddress() { return t.is.address ! ! (ode di atas memperlihatkan hubungan $ustomer +:S-: :ddress. Manfaat kedua dari inheritance adalah polimor?sme, kita akan membahas tentang polimor?sme di bab di ba"ah ini.

Polimorfisme 1Polymor$hism2
:rti polimor?sme secara har?ah 3makna kata5 adalah banyak bentuk. Sebuah object bisa diassign ke dalam tipe yang berbeda-beda. $ontohnya Member$ustomer, class Member$ustomer S-: / Hbject, karena semua class pasti eLtends Hbject $ustomer, karena Member$ustomer eLtends $ustomer Member$ustomer

Jadi kalau ada variabel dengan tipe Hbject, $ustomer atau Member$ustomer bisa diassign dengan instance dari Member$ustomer. $ontohnya seperti di ba"ah ini / Ab#ect o 7 ne8 BemberDustomer()

Dustomer c 7 ne8 BemberDustomer() BemberDustomer mc 7 ne8 BemberDustomer() Ab#ect ob#ect 7 mc Dustomer cust 7 mc nterface juga bisa digunakan dalam skenario S-: ini, misalnya untuk class Member$ustomer bisa mengimplementasikan sebuah interface, kemudian interface ini bisa digunakan sebagai tipe variabel yang bisa diassign dengan instance dari Member$ustomer. $lass Member$ustomer akan kita ubah sedikit seprti berikut ini / public class BemberDustomer e,tends Dustomer implements Seriali?able {! Sekarang kita bisa mendeklarasikan variabel dengan tipe SerialiBable dan mengassign instance dari Member$ustomer ke dalam variabel tersebut. :tau dengan kata lain Member$ustomer S-: Serialiable, seperti contoh di ba"ah ini / Seriali?able s 7 ne8 BemberDustomer() Jadi Member$ustomer mempunyai banyak bentuk 3polimor?sme5. (ita akan sering melihat kode dengan pola seperti ini, variabel akan dideklarasikan dengan tipe interface tetapi diinstansiasi dengan class yang mengimplementasikan interface tersebut. ,raktek seperti ini dikategorikan sebagai praktek yang baik sehingga banyak diikuti oleh developer Java.

!verriding dan !verloading


Setiap kali sebuah class mengeLtends class lain, class tersebut bisa mengoverride method yang ada di dalam class orang tuanya. :lasanya karena di class anaknya ingin mengimplementasikan method tersebut dengan cara yang berbeda. Misalnya dalam class Member$ustomer akan mengoverride method set d untuk memeriksa apakah id yang dimasukkan bernilai null atau tidak, kalau nilainya null maka sebuah pesan dicetak ke dalam console. Setelah pesan dicetak, method set d yang dipunyai oleh orang tua dari class $ustomer, hal ini bisa dilakukan dengan menggunakan key"ord super. $ontohnya adalah seperti ini / import #ava.io.Seriali?able public BemberDustomer e,tends Dustomer implements Seriali?able { public void set=d(;ong a=d) { i/(id 77 null) { System.out.println(*nilai id tida0 bole. null*) ! else { super.set=d(a=d) ! ! Hverriding method dilakukan dengan cara mendeklarasikan method yang sama persis denga method yang ada di class orang tuanya. Deklarasi dari method harus sama persis, mulai dari access modi?ernya, key"ord yang digunakan, nama method, jumlah parameter dan letak parameter, hingga deklarasi thro"s eLception. :pa yang terjadi kalau misalnya kita mendeklarasikan sebuah variabel dengan tipe $ustomer tetapi diinstansiasi dengan object Member$ustomer, kemudian kita panggil method set dZ :pakah method set d yang ada dalam $ustomer atau Member$ustomer yang akan dieksekusiZ Method yang dioverride akan terikat dengan instance dari variabel, bukan tipe dari variabel, jadi ja"aban dari pertanyaan di atas adalah / yang dieksekusi adalah method set d dari class Member$ustomer bukan dari class $ustomer. Mari kita tulis kode untuk melihat bagaimana aturan ini diimplementasikan dalam kode / public Averriding9est{ public static void main(String[] args){ Dustomer c 7 ne8 Dustomer() Dustomer mc 7 ne8 BemberDustomer() ;ong id 7 null CCmet.od set=d yang dipanggil adala. yang dari class Dustomer 0arena c CCdide0larasi0an dengan tipe Dustomer dan diinstansiasi dengan class

CCDustomer c.set=d(id) CCmet.od set=d yang dipanggil adala. yang dari class BemberDustomer CC8alaupun mc dide0larasi0an dengan tipe Dustomer mc.set=d(id) ! !

Method overloading adalah salah satu feature dalam bahasa pemrograman Java, dimana dua buah method bisa dideklarasikan dengan nama yang sama asal argumenya berbeda, baik dari jumlahnya, tipenya atau urutan dari parameternya. !erikut ini adalah method yang berbeda "alaupun namanya sama / public void set=d(;ong a=d) {! public void set=d(=nteger a=d) {! public void set=d(;ong a=d+ boolean c.ec0<ull) {! public void set=d(boolean c.ec0<ull+;ong a=d) {! Hverloading dan overriding juga berlaku terhadap constructor, karena pada dasarnya constructor adalah method.

Casting %aria"el )e erence


,olimor?sme mengijinkan sebuah variabel yang dideklarasikan dengan menggunakan class orang tuanya diinstansiasi dengan object dari class anaknya. +al ini sesuai dengan kaidah hubungan S:. 0ah, bagaimana kalau misalnya variabel yang sudah dideklarasikan dengan class orang tua kemudian diinstansiasi dengan menggunakan class anaknya akan diassign lagi ke variabel lain dengan tipe class anaknyaZ +al ini bisa dilakukan dengan menggunakan casting. Sintaks casting sudah kita pelajari sedikit di bab tipe data primitif, kita akan ulang sedikit di bab ini untuk tipe data reference. (ita lihat bagaimana casting terhadap tipe data reference / Dustomer c 7 ne8 BemberDustomer() CCcasting ber.asil 0arena c diinstansiasi0an dengan class BemberDustomer BemberDustomer mc 7 (BemberDustomer) c c 7 ne8 Dustomer() CCcasting gagal dan ter#adi DlassDast@,ception 0arena c diinstansiasi0an CCdengan class Dustomer mc 7 (BemberDustomer) c String s 7 *ini string* CC0ode ini gagal dicompile 0arena String tida0 mempunyai .ubungan sama se0ali CCdengan BemberDustomer mc 7 (BemberDustomer) s

Inter ace
nterface sudah dibahas sedikit di dalam bab deklarasi interface. Dalam bab ini akan kita bahas lebih lanjut tentang atura-aturan mengimplementasikan interface. (etika kita mendeklarasikan class yang mengimplementasikan interface, sebenarnya kita sudah menandatangani kontrak untuk mengimplementasikan semua method di dalam interface. (ita ambil contoh lagi interface ,ersonDao yang sudah kita gunakan di bab sebelumnya. (ode interface ,ersonDao adalah seperti di ba"ah ini / public inter/ace 4erson:ao{ void save(4erson p) void delete(4erson p) 4erson get>y=d(;ong id) ! Misalnya kita buat class ,ersonDao mpl yang akan mengimplementasikan interface ,ersonDao di atas, maka semua method ,ersonDao harus diimplementasikan juga, seperti di ba"ah ini / public class 4erson:ao=mpl implements 4erson:ao{

public void save(4erson p){ System.out.println(*menyimpan 4erson*) ! public void delete(4erson p){ System.out.println(*meng.apus person*) ! public 4erson get>y=d(;ong id){ 4erson p 7 ne8 4erson() p.set=d(id) p.set<ama(*abc*) return p ! ! :da satu cara yang bisa dilakukan jika kita tidak ingin mengimplementasikan semua method yang ada dalam interface, yaitu dengan menambahkan key"ord abstract dalam deklarasi class serta mendeklarasikan method yang tidak ingin diimplementasikan menggunakan key"ord abstract, seperti dalam kode ,ersonDao mpl yang sedikit dimodi?kasi di ba"ah ini / public abstract class 4erson:ao=mpl implements 4erson:ao{ public void save(4erson p){ System.out.println(*menyimpan 4erson*) ! public void delete(4erson p){ System.out.println(*meng.apus person*) ! public abstract 4erson get>y=d(;ong id) ! ,ada dasarnya interface itu adalah sebuah class yang dideklarasikan dengan key"ord abstract dan semua methodnya bersifat public abstract. nterface ,ersonDao statusnya setara dengan class ,ersonDao di ba"ah ini / public abstract class 4erson:ao{ public abstract void save(4erson p) public abstract void delete(4erson p) public abstract 4erson get>y=d(;ong id) ! Tetapi tetap saja interface dan class adalah dua buah hal yang berbeda. nterface, seperti halnya class, bisa mengeLtends interface lain. nterface yang mengeLtends interface lain akan memiliki semua method yang dipunyai oleh interface orang tuanya.

Colle&tion dan )eneri&s


(emampuan menggunakan collection adalah "ajib dimiliki oleh developer Java. Tanpa kemampuan menggunakan collection, membuat aplikasi yang mengolah data menjadi cukup sulit. $ollection diajarkan dalam kurikulum ilmu komputer dalam kuliah struktur data, karena collection sendiri adalah sebuah struktur data. (ita bisa menyimpan data dengan dalam collection, struktur penyimpanan datanya bisa dipilih dari beberapa jenis collection yang sudah disiapkan oleh Java. Kenerics banyak digunakan dalam library collections, dengan menggunakan generics kita bisa menentukan tipe dari isi collections. (ika akan membahas tentang .ist, Set dan Map, tetapi sebelum itu kita akan membahas bagaimana menentukan dua buah object sama atau berbeda dengan cara mengoverride method e\uals dan hash$ode. !agian terakhir kita akan membahas tentang bagaimana melakukan sorting terhadap collection agar isinya terurut.

to*tring
Setiap class selalu eLtends class Hbject, class Hbject memiliki tujuh buah method, setiap

method mempunyai tujuan tertentu. Method-method tersebut adalah / "ait35 notify35 notify:ll35 ?naliBe35 toString35 e\uals35 hash$ode35

Method toString digunakan oleh Java untuk mendapatkan representasi String dari sebuah object atau class. mplementasi default dari $lass object adalah mencetak nama class diikuti oleh Ealamat memory dari object tersebutG. Mari kita lihat bagaimana implementasi standard dari method toString ini / public class 9oString9est { public static void main(String[] args) { 9oString9est test 7 ne8 9oString9est() System.out.println(*implementasi toString dari class Ab#ect * E *meng.asil0an 3 * E test) ! ! kalau kita compile dan jalankan kode di atas hasilnya / " #avac 9oString9est.#ava " #ava 9oString9est implementasi toString dari class Ab#ect meng.asil0an 3 9oString9est^R5/cMM55 " terlihat bah"a string yang dikembalikan dari method toString tidak deskriptif sama sekali, dengan mengoverride method toString kita bisa mendapatkan string yang lebih deskriptif untuk menggambarkan object tersebut. Misalnya seperti di ba"ah ini / public class 9oString9est { public String toString() { return *ini toString dari class 9oString9est* ! public static void main(String[] args) { 9oString9est test 7 ne8 9oString9est() System.out.println(*implementasi toString dari class Ab#ect * E *meng.asil0an 3 * E test) ! ! +asil eksekusi dari kode di atas akan menghasilkan output seperti di ba"ah ini / " #avac 9oString9est.#ava " #ava 9oString9est implementasi toString dari class Ab#ect meng.asil0an 3 ini toString dari class 9oString9est " method toString banyak digunakan dalam aplikasi Java, salah satunya adalah menampilkan teLt di dalam komponen Jcombo!oL kalau item yang dimasukkan ke dalam Jcombo!oL adalah class yang kita buat sendiri, bukan tipe data primitif atau class "rapper.

e3uals dan hashcode


Method e\uals dan hash$ode berperan sangat penting dalam collection. Method e\uals digunakan untuk membandingkan antara dua buah object apakah sama atau tidak secara logis. Hperator [[ bisa digunakan untuk membandingkan dua buah object, tetapi perbandingan ini

hanya akan menghasilkan true kalau dua buah object apakah berada dalam memory yang sama, atau bisa dikatakan dua buah object ini mempunyai reference yang sama persis. (alau operator [[ mengembalikan nilai true berarti dua buah object ini adalah sama persis baik secara alamat memory dan otomatis sama secara logis. Method e\uals akan mengembalikan true kalau kedua object sama secara logis "alaupun kedua object mempunyai reference berbeda 3tidak berada di memory yang sama5. (ita ambil contoh sebuah String, dua buah object string akan mengembalikan false jika dioperasikan dengan operator [[ "alaupun string yang ada di dalamnya sama. Tetapi method e\uals akan mengembalikan nilai true "alaupun objectnya berada di memory berbeda asalkan nilai stringnya sama. Mari kita lihat bagaimana penjelasan di atas kalau dilihat dalam kode. ,erhatikan kode berikut ini / public class @\uals9est { public static void main(String[] args) { String abc 7 ne8 String(*abc*) String abc% 7 ne8 String(*abc*) boolean e\ualsAperator 7 (abc 77 abc%) System.out.println(*abc 77 abc W * E e\ualsAperator) boolean e\ualsBet.od 7 abc.e\uals(abc%) System.out.println(*abc.e\uals(abc) W * E e\ualsBet.od) ! ! apakah output dari kode di atasZ Menggunakan operator [[ maka hasilnya adalah false karena kedua variabel String diinisialisasi dengan menggunakan ne" String. Sedangkan menggunakan method e\uals hasilnya adalah true karena kedua variabel mempunyai nilai string yang sama. " #avac @\uals9est.#ava " #ava @\uals9est abc 77 abc W /alse abc.e\uals(abc) W true " (alau ingin membandingkan dua buah object apakah sama secara logis, kita akan menggunakan method e\uals, tetapi masalahnya adalah implementasi method e\uals dari class Hbject sama persis dengan operator [[, sehingga harus dioverride agar "alaupun dua buah object yang berbeda tetap dianggap sama asalkan suatu kriteria terpenuhi. Seperti yang terjadi dengan class String dalam contoh di atas, method e\ualsnya dioverride agar mengembalikan true kalau dua buah object dari class String mempunyai nilai string yang sama. Misalnya untuk class $ustomer, dua buah object $ustomer dianggap sama asalkan idnya sama, oleh karena itu method e\uals akan dioverride seperti di ba"ah ini / public class Dustomer { private ;ong id public void set=d(;ong a=d){ t.is.id 7 a=d ! public ;ong get=d() { return t.is.id ! public boolean e\uals(Ab#ect ob#) { i/ (ob# 77 null) { return /alse ! i/ (getDlass() !7 ob#.getDlass()) { return /alse !

/inal Dustomer ot.er 7 (Dustomer) ob# i/ (t.is.id !7 ot.er.id YY (t.is.id 77 null ZZ !t.is.id.e\uals(ot.er.id))) { return /alse ! return true ! !

Terlihat mengoverride method e\uals bukan pekerjaan yang gampang, cukup banyak kode yang harus diketik, nantinya menggunakan 0et!eans proses pembuatan method e\uals bisa digenerate secara otomatis, sehingga meminimalisasi kode yang harus diketik manual. Method hash$ode akan mengembalikan nilai integer unik untuk setiap object yang berbeda. :turanya adalah / Method hash$ode dari sebuah object harus mengembalikan nilai yang sama "alaupun dieksekusi berkali kali selama nilai property dalam object tidak berubah. (alau dua buah object dioperasikan dengan method e\uals mengembalikan nilai true maka method hash$ode dari kedua object harus mengembalikan nilai integer yang sama. Sebaliknya, kalau dua buah object mengembalikan nilai false maka hash$ode untuk kedua object akan mengembalikan nilai integer yang berbeda. (alau dua buah object dioperasikan dengan method e\uals mengembalikan nilai false maka method hash$ode tidak harus mengembalikan nilai yang berbeda. Mengembalikan nilai yang sama pun tidak masalah.

Topik bagaimana menghitung nilai hash$ode yang baik bisa menjadi topik ,hD, tetapi tidak perlu bingung, menggunakan 0et!eans kita bisa mengenerate method hash$ode ini agar mematuhi aturan di atas. $lass $ustomer menggunakan property id sebagai nilai unik, asal nilai idnya berbeda maka dianggap dua buah object $ustomer yang berbeda, oleh karena itu nilai hash$ode akan dihitung dari id ini. 0ah, kode lengkap class $ustomer setelah method hash$ode dioverride adalah seperti di ba"ah ini / public class Dustomer { private ;ong id public void set=d(;ong a=d){ t.is.id 7 a=d ! public ;ong get=d() { return t.is.id ! public boolean e\uals(Ab#ect ob#) { i/ (ob# 77 null) { return /alse ! i/ (getDlass() !7 ob#.getDlass()) { return /alse ! /inal Dustomer ot.er 7 (Dustomer) ob# i/ (t.is.id !7 ot.er.id YY (t.is.id 77 null ZZ !t.is.id.e\uals(ot.er.id))) { return /alse ! return true ! public int .as.Dode() { int .as. 7 .as. 7 R1 L .as. E (t.is.id !7 null W t.is.id..as.Dode() 3 ') return .as. ! !

hash$ode sangat vital ketika kita menggunakan collection yang memanfaatkan nilai hash$ode ini, seperti Has.Set atau Has.Bap. ,erhitungan hash$ode yang salah akan membuat kedua jenis collection ini berantakan. (ita akan kembali lagi ke topik hash$ode ketika membahas kedua collection tersebut di bab berikutnya.

Java Collection 4ramework


Membuat aplikasi yang cukup kompleks tanpa adanya collection yang baik akan sangat repot, banyak hal harus dilakukan hanya untuk membuat collection yang memenuhi kebutuhan kita. Fntungnya dalam JD( terdapat banyak sekali collection yang sudah tersedia, kita hanya perlu mempelajari :, tersebut dan memahami kapan saat terbaik untuk menggunakan collection :, tersebut. Dalam Java collection :, ada beberapa interface kunci yang merupakan dasar dari collection yang ada dalam JD(. nterface-interface itu antara lain / $ollection .ist Iueue Set Map 0avigableSet SortedSet SortedMap 0avigableMap

Dalam buku ini kita akan membahas beberapa interface saja yang sering dibutuhkan dalam aplikasi, antara lain/ .ist, Set, Map dan Iueue. Daftar class yang mengimplementasikan keempat interface di atas antara lain /
Map +ashMap +ashTable TreeMap .inked+ashMap Set +ashSet .inked+ashSet TreeSet .ist :rray.ist @ector .inked.ist Iueue ,riorityIueue

Setiap jenis collection di atas mempunyai empat varian / terurut 3sorted5, tidak terurut 3unsorted5, teratur 3ordered5 dan tidak teratur 3unordered5. $ollection yang terurut 3sorted5 artinya isi dari collection tersebut terurut berdasarkan nilai tertentu dari objectnya, misalnya kalau yang dimasukkan dalam collection adalah object dari $ustomer, kita bisa mengurutkan berdasarkan id atau berdasarkan nilai property yang lain. (ita akan membahas lebih lanjut bagaimana caranya melakukan sorting atau menggunakan sorted collection di bab selanjutnya. $ollection tidak terurut jelas kebalikan dari collection terurut. $ollection teratur 3ordered5 adalah collection yang diatur berdasarkan kapan item tersebut dimasukkan ke dalam collection, item yang dimasukkan pertama akan berada di a"al, sedangkan item yang dimasukkan terakhir akan berada di akhir collection. Sedangkan collection tidak teratur 3unordered5 jelas kebalikan dari collection teratur. 0ah mari kita bahas satu per satu dari keempat collection di atas beserta varianya, dimulai dari .ist.

List
.ist adalah jenis collection yang teratur tetapi tidak terurut. .ist mempunyai indeL yang disusun berdasarkan urutan kapan item dimasukkan ke dalam .ist. si dari .ist bersifat tidak unik, alias dua buah item yang sama bisa dimasukkan berkali kali ke dalam .ist. Method penting dalam .ist antara lain / get3int indeL5D method ini digunakan untuk mengambil isi dari list berdasarkan indeL 3urutan item dimasukkan ke dalam .ist5 indeLHf3Hbject o5D method ini digunakan untuk mengetahui berapa nomor indeL dari object yang ada dalam .ist. add3Hbject o5D digunakan untuk menambahkan object ke dalam .ist add3int indeL, Hbject o5D menambahkan object ke dalam .ist di indeL tertentu

$lass :rray.ist adalah class yang mengimplementasikan interface .ist, bayangkan class :rray.ist ini adalah :rray yang dapat bertambah ukuranya. @ector adalah class yang juga mengimplementasikan .ist, @ector adalah pendahulu dari :rray.ist, kalau tidak ada yang menghalangi anda menggunakan :rray.ist, sebaiknya hindari @ector karena performance :rray.ist lebih bagus dan classnya lebih modern. .inked.ist adalah implementasi dari .ist yang menambahkan method baru untuk menambahkan atau menghapus isi dari .ist dari depan atau dari belakang. $lass ini cocok digunakan untuk membuat tumpukan 3stack5 atau antrian 3\ueue5. Mari kita lihat contoh penggunaan .ist dan :rray.ist dalam kode di ba"ah ini / public class ;ist9est { public static void main(String[] args) { ;istTStringV list 7 ne8 Irray;istTStringV() list.add(*a*) list.add(*b*) list.add(*c*) list.add(*a*) list.add(*?*) System.out.println(*isi dari list 3 *) /or(int i7' iT list.si?e() iEE) { System.out.println(*inde, 0e$* E i E *3* E list.get(i) ) ! ! ! (ode di atas dia"ali dengan deklarasi variabel .ist yang menggunakan generics / .istAStringC, kode ini artinya kita akan membuat variabel dengan tipe .ist dan isinya hanya String saja, tipe data lain tidak bisa dimasukkan ke dalam .ist ini. +asil eksekusi kode di atas adalah seperti di ba"ah ini / " #avac ;ist9est.#ava " #ava ;ist9est isi dari list 3 inde, 0e$'3a inde, 0e$%3b inde, 0e$)3c inde, 0e$13a inde, 0e$53? " secara visual isi dari list di atas bisa digambarkan dalam diagram seperti di ba"ah ini /

inde, item

1 a

& b

$ c

% a

# 2

terlihat bah"a indeL adalah bagian terpenting dari .ist, sedangkan item dalam .ist sendiri bisa dobel, tidak unik. Selain itu item di dalam .ist juga tidak terurut, terlihat dari huruf EaG yang diletakkan setelah huruf EcG.

*et
Set adalah collection yang bersifat unik. Set digunakan kalau anda memerlukan collection yang isinya harus unik. De?nisi unik diimplementasikan dengan mengoverride method e\uals dan hash$ode dari class yang akan dimasukkan ke dalam Set. Semua class "rapper seperti String telah mengoverride method e\uals dan hash$ode sehingga dua buah object String dianggap sama kalau string yang ada di dalamnya sama. Fntuk class yang kita buat sendiri, seperti class

$ustomer, maka method e\uals dan hash$ode harus dioverride dahulu sebelum dimasukkan ke dalam Set. (alau method e\uals dan hash$ode tidak dioverride maka dua buah object dianggap sama kalau keduanya merefer ke object yang sama di dalam memory, tidak seperti yang kita harapkan. $lass implementasi dari interface Set yang paling sering digunakan adalah +ashSet. 0ilai yang dikembalikan oleh hash$ode sangat penting dalam class +ashSet. 0ilai hash$ode digunakan untuk menentukan di mana object tersebut diletakkan dalam EkeranjangG +ashSet. (etika method add di panggil dengan parameter object, +ashSet akan memaggil method hash$ode dari object tersebut untuk menentukan di keranjang mana object akan diletakkan. Setelah ketemu nomer keranjangnya, dicek apakah keranjang tersebut kosong. (alau kosong maka object langsung diletakkkan di keranjang tersebut. (alau keranjang ada isinya, dilakukan pengetesan menggunakan method e\uals, kalau ada object di dalam keranjang ditest menggunakan method e\uals menghasilkan true, maka object lama akan ditimpa dengan object baru yang dimasukkan ke dalam +ashSet menggunakan method add tadi. (ecepatan proses pencarian object di dalam +ashSet tergantung dari bagaimana kita melalukan perhitungan hash$ode. (alau misalnya kita selalu return nilai ) untuk semua object, maka semua object akan diletakkan dalam satu keranjang yang sama, proses pencarian menjadi linier 3H3n55 karena object akan dibandingkan satu per satu menggunakan method e\uals. (alau hash$ode bersifat unik untuk setiap object, maka proses pencarianya sangat cepat yaitu H3)5, +ashSet akan memanggil method hash$ode untuk mendapatkan nilainya. (alau nilai hash$ode tidak selalu unik, +ashSet akan melihat di dalam keranjang tersebut adakah object di dalamnya, kalau ada satu buah maka object itu akan dikembalikan sebagai hasil pencarian, kalau kosong yang dikembalikan adalah null, kalau ada beberapa buah maka untuk setiap object di dalam keranjang ditest menggunakan method e\uals, ketika method e\uals mengembalikan true maka object tersebut adalah hasil pencarianya. Jika dua buah object dipanggil method e\uals menghasilkan nilai true tetapi hash$odenya berbeda 3menyalahi aturan5, maka oleh +ashSet kedua object ini dianggap berbeda karena akan diletakkan di dalam keranjang yang berbeda, asal keranjangnya berbeda maka method e\uals akan diabaikan, tidak pernah dipanggil. Jadi harus ditaati aturan bah"a kalau dua buah object dioperasikan dengan method e\uals mengembalikan true, nilai hash$odenya harus sama. ,erhatikan visualisasi +ashSet yang berisi String di ba"ah ini /

keranjang

&

ab ba

:lgoritma sederhana untuk menghitung hash$ode dari class String adalah menambahkan urutan dari hurufnya, misalnya string EaG nilai hash$odenya ), EbG nilai hash$odenya %, sedangkan string EabG dan EbaG nilai hash$odenya sama yaitu 7. !isa kita lihat juga string EabG dan EbaG diletakkan dalam keranjang yang sama karena hash$odenya sama, tetapi tidak saling timpa, hal ini karena EabG.e\uals3EbaG5 bernilai false. Tujuh paragraf menerangkan tentang Set kok rasanya masih kurang kalau kalau belum melihat kode bagaimana menggunakan Set ini. (ita akan menggunakan class $ustomer yang sudah dioverride method e\uals dan hash$odenya di bab sebelumnya, perhatikan juga bah"a e\uals dan hash$ode dari class $ustomer di atas , kemudian buat class di ba"ah ini di folder yang sama dengan class $ustomer / import #ava.util.Set import #ava.util.Has.Set import #ava.util.=terator

public class DustomerSet9est{ public static void main(String[] args) { SetTDustomerV customers 7 ne8 Has.SetTDustomerV() Dustomer id% 7 ne8 Dustomer() id%.set=d(%l) customers.add(id%) Dustomer id) 7 ne8 Dustomer() id).set=d()l) customers.add(id)) Dustomer c 7 ne8 Dustomer() c.set=d(%l) customers.add(c) CCmereplace id% 0arena mempunyai id yang sama =teratorTDustomerV i 7 customers.get=terator() 8.ile(i..as<e,t()){ Dustomer current 7 i.ne,t() System.out.println(*0eran#ang no$* E current..as.Dode() E * idnya3* E current.get=d()) ! ! ! ,erhatikan juga kode di atas menggunakan terator untuk mengambil nilai dalam Set satu per satu, ada bentuk for each yang diperkenalkan sebagai bagian dari Java 4 .anguage enhancement, bentuk for each ini menyederhanakan kode untuk mengakses item di dalam Set. *or each akan kita bahas di bab tentang java 4 languge enhancement. +asil eksekusi kode di atas adalah seperti di ba"ah ini / " #avac Dustomer.#ava DustomerSet9est.#ava Dustomer.#ava " #ava DustomerSet9est 0eran#ang no$1-1 idnya3) 0eran#ang no$1-) idnya3% " :nda mungkin juga terkejut, ternyata nomor keranjangnya pun tidak terurut dari kecil ke besar. +ashSet adalah collection yang hanya menekankan pada sifat unik saja, sedangkan urutan dan keteraturan tidak dijamin sama sekali. :da jenis collection lain yang bisa menjamin sifat unik sekaligus terurut, yaitu TreeSet, kita akan membahas tentang TreeSet nanti di bab setelah kita bahas konsep sorting.

Ma$
Map adalah bentuk struktur data yang berpasangan antara key-value. (ey bersifat unik karena implementasinya menggunakan Set. (ey dan value adalah object, bisa object apa saja, tipe data primitif tidak bisa dimasukkan ke dalam Map, juga tidak bisa dimasukkan ke semua jenis collection. mplementasi Map memberikan kemampuan untuk mencari value berdasarkan key, setiap kali kita dihadapkan pada permasalahan bagaimana caranya melakukan pencarian berdasarkan value kita bisa menggunakan Map ini. Map bergantung pada method e\uals dan hash$ode untuk menentukan apakah dua buah key sama atau tidak, jadi kalau kita ingin menggunakan object dari class yang kita buat sendiri sebagai key, maka kedua method itu harus dioverride untuk menentukan bagaimana dua buah object dianggap sama atau tidak. +ashMap adalah class yang mengimplementasikan interface Map, sifatnya adalah tidak terurut dan tidak teratur. mplementasi +ashMap adalah yang paling e?sien, implementasi Map lainya yang membutuhkan keterurutan atau keteraturan akan menambahkan komputasi tambahan sehingga kurang e?sien dibanding dengan +ashMap. +ashMap memperbolehkan satu buah key dengan nilai null dan banyak key bukan null yang valuenya adalah null. Method penting yang dimiliki oleh Map antara lain / put3Hbject key, Hbject value5D method yang digunakan untuk meletakkan pasangan key dan value

get3Hbject key5D method digunakan untuk mendapatkan value dari key yang dimasukkan sebagai parameter keySet35D digunakan untuk mendapatkan Set yang berisi semua key, biasanya kita ingin mendapatkan Set dari key ini kalau ingin mengambil nilai dalam Map satu per satu

Mari kita lihat contoh kode penggunaan Map. (ita akan membuat sebuah map dimana key adalah kota dan value adalah kumpulan $ustomer yang tinggal di kota tersebut. Tipe data key adalah String dan tipe data valuenya adalah .ist of $ustomer/ import #ava.util.Bap import #ava.util.Has.Bap import #ava.util.Set import #ava.util.=terator import #ava.util.;ist import #ava.util.Irray;ist public class Bap9est { public static void main(String[] args) { BapTString+;istTDustomerVV customer>yDityBap 7 ne8 Has.BapTString+;istTDustomerVV() ;istTDustomerV #a0artaDust 7 ne8 Irray;istTDustomerV() Dustomer a 7 ne8 Dustomer() a.set=d(%l) #a0artaDust.add(a) Dustomer b 7 ne8 Dustomer() b.set=d()l) #a0artaDust.add(b) customer>yDityBap.put(*#a0arta*+#a0artaDust) ;istTDustomerV surabayaDust 7 ne8 Irray;istTDustomerV() Dustomer c 7 ne8 Dustomer() c.set=d(1l) surabayaDust.add(c) customer>yDityBap.put(*surabaya*+surabayaDust) SetTStringV 0eys 7 customer>yDityBap.0eySet() =teratorTStringV iterator 7 0eys.iterator() 8.ile(iterator..as<e,t()) { String 0ey 7 iterator.ne,t() ;istTDustomerV customers 7 customer>yDityBap.get(0ey) /or(int i 7 ' i T customers.si?e() iEE) { Dustomer cust 7 customers.get(i) System.out.println(*0ota 3 * E 0ey E *+ Dustomer id 3 * E cust.get=d()) ! ! ! ! hasil eksekusi kode di atas adalah / " #avac Bap9est.#ava Dustomer.#ava " #ava Bap9est 0ota 3 #a0arta+ Dustomer id 3 % 0ota 3 #a0arta+ Dustomer id 3 ) 0ota 3 surabaya+ Dustomer id 3 1 " :da satu class lagi yang mengimplement Map interface sekaligus keynya diurutkan berdasarkan logic tertentu, yaitu class TreeSet. (ita akan membahas class TreeSet sekaligus +ashSet setelah membahas bab Sorting di ba"ah ini.

*orting
Sorting adalah cara untuk membuat sebuah collection terurut 3sorted5. :gar collection terurut kita perlu membuat item yang akan dimasukkan ke dalam Set mengimplementasikan interface $omparable. nterface ini digunakan untuk melakukan perbandingan antara dua buah objec, mana yang lebih besar atau lebih kecil ataukah sama persis. nterface $omparable hanya mempunyai satu buah method, yaitu compareTo/ method ini mempunyai sebuah parameter yang bertipe Hbject kalau tidak menggunakan generics, dan bertipe sama dengan class yang mengimplement interface $omparable kalau menggunakan generics. Method compareTo mengembalikan integer, nilai kembalianya positif berarti object yang dipanggil method comparenya lebih besar dari object yang dimasukkan ke parameter, nilai kembalianya negatif berarti sebaliknya dan kalau nilainya nol berarti kedua object sama besar. (ita lihat contoh implementasi interface $omparable di class $ustomer. ,ertama, kita akan mengimplementasikan interface $omparable tanpa menggunakan generics / import #ava.lang.Domparable public class Dustomer implements Domparable{ private ;ong id public void set=d(;ong a=d){ t.is.id 7 a=d ! public ;ong get=d() { return t.is.id ! public int compare9o(Ab#ect o) { Dustomer c 7 (Dustomer) o return get=d().compare9o(c.get=d()) ! public boolean e\uals(Ab#ect ob#) { i/ (ob# 77 null) { return /alse ! i/ (getDlass() !7 ob#.getDlass()) { return /alse ! /inal Dustomer ot.er 7 (Dustomer) ob# i/ (t.is.id !7 ot.er.id YY (t.is.id 77 null ZZ !t.is.id.e\uals(ot.er.id))) { return /alse ! return true ! public int .as.Dode() { int .as. 7 .as. 7 R1 L .as. E (t.is.id !7 null W t.is.id..as.Dode() 3 ') return .as. ! ! (alau menggunakan generics maka method compareTo tipe parameternya adalah $ustomer, bukan Hbject. $ontohnya / import #ava.lang.Domparable public class Dustomer implements DomparableTDustomerV{ private ;ong id public void set=d(;ong a=d){ t.is.id 7 a=d ! public ;ong get=d() { return t.is.id

! public int compare9o(Dustomer c) { return get=d().compare9o(c.get=d()) ! public boolean e\uals(Ab#ect ob#) { i/ (ob# 77 null) { return /alse ! i/ (getDlass() !7 ob#.getDlass()) { return /alse ! /inal Dustomer ot.er 7 (Dustomer) ob# i/ (t.is.id !7 ot.er.id YY (t.is.id 77 null ZZ !t.is.id.e\uals(ot.er.id))) { return /alse ! return true ! public int .as.Dode() { int .as. 7 .as. 7 R1 L .as. E (t.is.id !7 null W t.is.id..as.Dode() 3 ') return .as. ! ! ,erbandingan dalam method compareTo di atas akan menyebabkan $ustomer akan diurutkan berdasarkan idnya dari yang kecil ke besar. (alau ingin diurutkan dari besar ke kecil, maka perbandinganya tinggal dibalik seperti di ba"ah ini / public int compare9o(Dustomer c) { return c.get=d().compare9o(get=d()) ! nterface $omparable bisa digunakan kalau source code dari class $ustomer tersedia dan kita bisa melakukan modi?kasi terhadap class $ustomer. (alau misalnya class yang ingin diurutkan tidak tersedia source codenya, kita bisa membuat class baru kemudian mengeLtends class tersebut sekaligus mengimplementasikan interface $omparable, sehingga kita bisa membuat collection terurut dari class baru ini. 0ah, bagaimana kalau classnya ditandai dengan ?nalZ (ita tidak mungkin mengeLtends class tersebut, ada cara kedua, yaitu dengan membuat class baru yang mengimplementasikan interface $omparator. nterface $omparator mempunyai bentuk generics dan bentuk tanpa generics, seperti halnya interface $omparable, bentuk tanpa generics akan menyebabkan parameter bertipe Hbject sehingga perlu proses casting untuk mengubah menjadi $ustomer, sedangkan bentuk generics tipe data parameternya sudah bertipe $ustomer. mari kita lihat bagaimana cara membuat class yang mengimplementasikan interface $omparator dengan bentuk generics, bentuk non generics saya serahkan kepada anda untuk membuat sendiri/ import #ava.util.Domparator public class DustomerDomparator implements DomparatorTDustomerV{ public int compare(Dustomer c%+ Dustomer c)) { return c%.get=d().compare9o(c).get=d()) ! ! 0ah, setelah $ustomer mengimplementasikan interface $omparable, kita bisa menggunakan collection yang sifatnya terurut, misalnya TreeSet dan TreeMap. (ita ubah sedikit kode contoh penggunaan Set dengan mengganti +ashSet menjadi TreeSet, seperti di ba"ah ini / import #ava.util.Set import #ava.util.9reeSet import #ava.util.=terator public class Dustomer9reeSet9est{

public static void main(String[] args) { SetTDustomerV customers 7 ne8 9reeSetTDustomerV() Dustomer id% 7 ne8 Dustomer() id%.set=d(%l) customers.add(id%) Dustomer id) 7 ne8 Dustomer() id).set=d()l) customers.add(id)) Dustomer c 7 ne8 Dustomer() c.set=d(%l) customers.add(c) CCmereplace id% 0arena mempunyai id yang sama =teratorTDustomerV i 7 customers.get=terator() 8.ile(i..as<e,t()){ Dustomer current 7 i.ne,t() System.out.println(*0eran#ang no$* E current..as.Dode() E * idnya3* E current.get=d()) ! !

kalau kita eksekusi kode di atas maka customer akan diurutkan berdasarkan idnya, seperti di ba"ah ini / " #avac Dustomer9reeSet9est.#ava Dustomer.#ava " #ava Dustomer9reeSet9est 0eran#ang no$1-) idnya3% 0eran#ang no$1-1 idnya3) " TreeSet dan TreeMap menyaratkan item yang dimasukkan mengimplementasikan $omparable, atau kalau itemnya tidak bisa mengimplementasikan $omparable, kita harus menyediakan class yang mengimplementasikan $omparator dan memasukkan object dari class $omparator tersebut di constructor dari TreeSet atau TreeMap, seperti cuplikan kode di ba"ah ini / SetTDustomerV customers 7 ne8 9reeSetTDustomerV(ne8 DustomerDomparator()) BapTDustomerV customerBap 7 ne8 9reeBapTDustomerV(ne8 DustomerDomparator()) (edua collection ini akan menyusun item dalam keadaan terurut menggunakan struktur data tree, kalau item yang dimasukkan lebih kecil dari root maka diletakkan di tree sebelah kiri, kalau lebih besar diletakkan di sebelah kanan. :lgoritma seperti ini menyebabkan proses penambahan item baru ke dalam collection menjadi sedikit lebih lambat daripada +ashSet. Tetapi ketika isi dari TreeSet diambil, keadaanya sudah dalam kondisi terurut, sehingga tidak diperlukan proses pengurutan lagi. Jenis collection yang bersifat terurut hanya tersedia untuk Set dan Map, sedangkan untuk .ist tidak ada. 0ah kalau kita ingin membuat sebuah .ist terurut kita bisa menggunakan class $ollections yang di dalamnya terdapat method yang bisa mengurutkan .ist. (ita akan membahas tentang class $ollections di bab selanjutnya.

Class Collections dan Class Arrays


$lass $ollections berisi method-method utility yang digunakan antara lain untuk/ melakukan sorting, melakukan pencarian, mengacak isi .ist, membalik susunan .ist, mengcopy potongan .ist, mengisi list dengan pola tertentu dan seterusnya. (ita akan membahas satu per satu method di atas. Method sort digunakan untuk mengurutkan .ist berdasarkan logika yang ada dalam method $omparable. tem di dalam .ist harus mengimplementasikan interface $omparable, kalau tidak maka gunakan method sort dengan dua parameter/ .ist dan Hbject dari class yang mengimplementasikan interface $omparator, contoh potongan kodenya seperti di ba"ah ini / import #ava.util.;ist import #ava.util.Irray;ist import #ava.util.Dollections

public class Sort;ist9est { public static void main(String[] args){ ;istTDustomerV customers 7 ne8 Irray;istTDustomerV() Dustomer cust% 7 ne8 Dustomer() cust%.set=d(%'l) customers.add(cust%) Dustomer cust) 7 ne8 Dustomer() cust).set=d()l) customers.add(cust)) Dustomer cust1 7 ne8 Dustomer() cust1.set=d(Rl) customers.add(cust1) System.out.println(*isi dari list sebelum disorting3 *) /or(int i7' iT customers.si?e() iEE) { System.out.println(*inde, 0e$* E i E *3* E customers.get(i) ) ! Dollections.sort(customers) System.out.println(*isi dari list setela. disorting3 *) /or(int i7' iT customers.si?e() iEE) { System.out.println(*inde, 0e$* E i E *3* E customers.get(i) ) ! ! ! (ode di atas memperlihatkan bah"a kita membuat .ist of $ustomer dengan id yang tidak terurut, karena $ustomer mengimplementasikan interface $omparable maka isi dari .ist of $ustomer tersebut bisa disorting menggunakan method sort dari class $ollections. (alau kode di atas docompile dan dieksekusi hasilnya adalah / " #avac Sort;ist9est.#ava Dustomer.#ava " #ava Sort;ist9est isi dari list sebelum disorting3 inde, 0e$'3%' inde, 0e$%3) inde, 0e$)3R isi dari list setela. disorting3 inde, 0e$'3) inde, 0e$%3R inde, 0e$)3%' " (alau misalnya $ustomer tidak mengimplementasikan interface $omparable, maka kita bisa membuat class $ustomer$omparator yang mengimplementasikan interface $omparator sebagai pembanding antara dua buah $ustomer mana yang lebih besar, kode di atas bisa diedit sebagian dengan memanggil method sort yang mempunyai dua buah parameter/ .ist of $ustomer dan instance dari $ustomer$omparator. Dollections.sort(customers+ ne8 DustomerDomparator()) Method binarySearch digunakan untuk melakukan pencarian terhadap isi .ist dengan lebih cepat dibanding dengan method indeLHf dari interface .ist. Method binarySearch baru bisa dipanggil setelah .ist disorting dahulu. Method binarySearch memerlukan dua parameter kalau object dalam .ist mengimplementasikan interface $omparable/ .istnya dan item yang ingin dicari. $ontoh kode penggunaan method binarySearch adalah / import #ava.util.;ist import #ava.util.Irray;ist import #ava.util.Dollections public class >inarySearc.9est { public static void main(String[] args){ ;istTDustomerV customers 7 ne8 Irray;istTDustomerV()

Dustomer cust% 7 ne8 Dustomer() cust%.set=d(%'l) customers.add(cust%) Dustomer cust) 7 ne8 Dustomer() cust).set=d()l) customers.add(cust)) Dustomer cust1 7 ne8 Dustomer() cust1.set=d(Rl) customers.add(cust1) Dollections.sort(customers) int inde, 7 Dollections.binarySearc.(customers+ cust1) System.out.println(*Dustomer dengan id3* E cust1.get=d() E * ditemu0an di inde, 3 * E inde,) ! !

hasil eksekusi kode di atas adalah sebagai berikut / " #avac >inarySearc.9est.#ava Dustomer.#ava " #ava >inarySearc.9est Dustomer dengan id3R ditemu0an di inde, 3 % " (alau item tidak mengimplementasikan interface $omparable maka method binarySearch memerlukan tiga parameter/ .ist, item yang dicari dan object dari class $omparator, seperti dalam kode berikut ini / int inde, 7 Dollections.binarySearc.(customers+ cust1+ ne8 DustomerDomparator()) Fntuk mengacak isi dari sebuah list, ada method shuee. Method shuee ada dua overload, yang pertama hanya mempunyai satu parameter berupa .ist, yang kedua mempunyai dua buah parameter/ .ist dan object dari class -andom. Hbject -andom digunakan untuk menentukan jenis randomisasi yang ingin digunakan untuk mengacak isi dari .ist. Method reverse digunakan untuk membalik isi dari .ist, dimana yang depan menjadi di belakang dan sebaliknya. ,enggunaan method ini perlu hati-hati karena kecepatanya linier, semakin banyak isi dari .ist "aktu eksekusinya membesar secara linier. Method copy digunakan untuk mengcopy isi dari satu .ist ke .ist lain, method ini cukup praktis dibanding harus melakukan copy manual yang memerlukan proses iterasi, jadi hemat kira-kira empat sampai lima baris kode. Method ?ll digunakan untuk mengganti isi dari sebuah list dengan sebuah object yang sama. ,arameter method ?ll ada dua / .ist dan object item yang akan digunakan untuk menimpa semua item yang ada dalam .ist. Method min dan maL digunakan untuk mendapatkan nilai maLimum dan minimum dari sebuah .ist. Method ini menyaratkan semua item di dalam .ist harus mengimplementasikan interface $omparable. Seperti biasa, kalau item di dalam .ist tidak mengimplementasikan interface $omparable maka kita harus menambahkan instance dari class yang mengimplementasikan interface $omparator ke dalam method min dan maL. :da satu jenis method yang cukup berguna, yaitu unmodi?able, jenis method ini ada beberapa, antara lain/ unmodi?able.ist, unmodi?ableMap, unmodi?ableSet dan unmodi?able$ollection. Method jenis ini bagus sekali kalau digunakan untuk melindungi collection agar tidak bisa dimodi?kasi, artinya collectionnya akan bersifat read only. Misalnya di dalam suatu class kita punya property yang bertipe collection, nah kita tidak ingin collection ini dimodi?kasi di luar dari class, sehingga setiap kali method ini digunakan sebagai return type, yang kita return adalah versi read only dari collection tersebut. Sebagai contoh, kita modi?kasi sedikit class $ustomer agar mempunyai property emails yang bertipe .ist of String, seperti di ba"ah ini / import #ava.lang.Domparable import #ava.util.;ist import #ava.util.Irray;ist

import #ava.util.Dollections public class Dustomer implements DomparableTDustomerV{ private ;ong id private ;istTStringV emails public void set=d(;ong a=d){ t.is.id 7 a=d ! public ;ong get=d() { return t.is.id ! public void set@mails(;istTStringV a@mails) { t.is.emails 7 a@mails ! public ;istTStringV get@mails() { return Dollections.unmodi/iable;ist(emails) ! public void add@mail(String email){ i/(t.is.emails 77 null) { t.is.emails 7 ne8 Irray;istTStringV() ! emails.add(email) ! public int compare9o(Dustomer c) { return get=d().compare9o(c.get=d()) ! public boolean e\uals(Ab#ect ob#) { i/ (ob# 77 null) { return /alse ! i/ (getDlass() !7 ob#.getDlass()) { return /alse ! /inal Dustomer ot.er 7 (Dustomer) ob# i/ (t.is.id !7 ot.er.id YY (t.is.id 77 null ZZ !t.is.id.e\uals(ot.er.id))) { return /alse ! return true ! public int .as.Dode() { int .as. 7 .as. 7 R1 L .as. E (t.is.id !7 null W t.is.id..as.Dode() 3 ') return .as. ! ! Dari kode di atas, terlihat bah"a pada saat method getMmails dipanggil, yang dikembalikan adalah versi read only dari emails. Dengan begitu, emails hanya bisa dimodi?kasi dari dalam class $ustomer dengan memanggil method addMmail. ,raktek seperti ini sangat disarankan terutama ketika kita membuat kode yang banyak digunakan orang lain dan tidak ingin collection yang dimanage oleh library tersebut diedit sembarangan. ,engaturan seperti ini biasanya cukup ditekankan kalau aplikasi dibuat oleh banyak sekali orang, sehingga bisa meminimalisasi kesalahan karena kurangnya informasi atau ketidaktahuan anggota tim lain. Dengan membuat collection yang ditandai dengan read only seperti di atas, kita menyampaikan informasi kepada orang lain yang mungkin menggunakan class $ustomer ini bah"a .ist emails tidak bisa diedit dari luar class $ustomer. $lass :rrays berisi method-method utility untuk bekerja dengan array, sama seperti class $ollections yang berisi method-method utility untuk bekerja dengan collection. Method yang ada dalam class :rrays kurang lebih sama dengan method yang ada dalam class $ollections,

seperti/ proses sorting, pencarian, mengisi array dengan nilai tertentu, membuat copy dari array, memeriksa apakah dua buah array sama persis, mendapatkan nilai hash$ode dari array, mendapatkan toString dari array dan merubah array menjadi .ist dengan cepat. Method as.ist digunakan untuk mengubah array menjadi .ist dengan cepat. Tanpa bantuan method ini merubah array menjadi .ist memerlukan langkah-langkah / membuat instance dari .ist, kemudian mengkopy isi array ke dalam .ist dengan iterasi. .angkah-langkah di atas kira-kira memerlukan lima baris kode, tetapi dengan menggunakan method as.ist cukup satu baris kode saja. Tanpa menggunakan method as.ist mengcopy array ke dalam .ist kodenya seperti di ba"ah ini / import #ava.util.;ist import #ava.util.Irray;ist public class DopyIrrayBanual9est { public static void main(String[] args) { String[] names 7 {*me*+*you*+*t.ey*+*us*! ;istTStringV name;ist 7 ne8 Irray;istTStringV() /or(int i 7 ' i T names.lengt. iEE) { name;ist.add(names[i]) System.out.println(*name3* E names[i]) ! ! ! Dengan menggunakan class :rrays kode di atas menjadi sangat pendek, seperti di ba"ah ini / import #ava.util.;ist import #ava.util.Irrays public class DopyIrray9est { public static void main(String[] args) { String[] names 7 {*me*+*you*+*t.ey*+*us*! ;istTStringV name;ist 7 Irrays.as;ist(names) ! ! Method e\uals digunakan untuk menentukan apakah dua buah array isinya sama persis atau tidak, method ini sangat praktis digunakan daripada melakukan iterasi satu per satu isi dari array dan membandingkanya dengan isi array lain. Method toString bisa digunakan untuk membuat sebuah string representasi dari array, string ini sudah diformat sekian rupa sehingga kalau diprint di dalam console akan terlihat bagus. Tanpa menggunakan method toString ini biasanya kita melakukan iterasi untuk mencetak satu persatu isi dari array, dengan adanya method ini tidak perlu lagi melakukan iterasi hanya untuk menampilkan array ke dalam console. Method copyHf digunakan untuk mengcopy sebagian, keseluruhan atau malah membuat array baru dengan isi yang sama tetapi ukurannya lebih panjang dari sebuah array. Sedangkan method copyHf-ange digunakan untuk mengcopy sebagian dari array dengan mende?nisikan a"al dari indeL dan akhir dari indeL yang ingin dicopy. ,erhatikan contoh berikut ini / import #ava.util.Irrays public class Dopy4artialIrray9est { public static void main(String[] args) { String[] names 7 {*me*+*you*+*t.ey*+*us*! CCmembuat array baru dari sebagian isi array names String[] n 7 Irrays.copyA/(names+ )) System.out.println(*setela. dipotong 3 * E Irrays.toString(n)) CCmembuat array baru dari semua isi array names CCse0aligus pan#angnya bertamba. n 7 Irrays.copyA/(names+ -) System.out.println(*setela. ditamba. pan#ang 3 * E Irrays.toString(n)) CCcopy sebagian isi array names dari inde, % sampai inde, 1

n 7 Irrays.copyA/6ange(names+ %+ 1) System.out.println(*setela. dipotong 3 * E Irrays.toString(n)) CCcopy sebagian isinya dan tamba.0an de/ault value untu0 sisanya n 7 Irrays.copyA/6ange(names+ )+ %') System.out.println(*setela. dipotong dan bertamba. pan#ang3 * E Irrays.toString(n)) ! !

$oba tebak hasil eksekusi kode di atas_ :pakah tebakanya sama dengan hasil eksekusinya seperti di ba"ah ini Z " #avac Dopy4artialIrray9est.#ava " #ava Dopy4artialIrray9est setela. dipotong 3 [me+ you] setela. ditamba. pan#ang 3 [me+ you+ t.ey+ us+ null+ null+ null] setela. dipotong 3 [you+ t.ey] setela. dipotong dan bertamba. pan#ang3 [t.ey+ us+ null+ null+ null+ null+ null+ null] " Sisanya, method-metthod seperti / sort dan binarySearch sama persis penggunaanya dengan method yang ada dalam class $ollections.

Class 'entin!
JD( menyertakan banyak sekali class-class yang berguna untuk memudahkan developer membuat aplikasi. !eberapa class sangat penting fungsinya sehingga perlu diperhatikan bagaimana menggunakanya dengan benar.

*tring- *tringBuilder- *tringBu5er


String adalah class yang bersifat immutable, artinya sekali diset nilainya maka tidak bisa lagi diubah. String yang bersifat immutable juga berarti bah"a kalau kita melakukan modi?kasi terhadap object String, pada dasarnya hasil modi?kasi ini adalah object baru. +al ini yang membuat String ini menjadi tidak e?sien digunakan pada saat diperlukan manipulasi String dalam skala yang cukup besar. Mari kita lihat contoh kode yang menunjukkan class String immutable / public class String=mmutable9est { public static void main(String[] args){ String s 7 *ini string immutable * System.out.println(*sebelum operasi concat nilai s 3 * E s) CCappend tida0 meruba. variabel s+ tetapi dibuat ob#ect baru CCdan ob#ect baru ini direturn sedang0an variabel s nilainya tetap s.concat(*concat*) System.out.println(*setela. operasi concat nilai s 3 * E s) String concat 7 s E s.concat(*concat*) E * ob#ect baru* ! ! +asil eksekusi kode di atas adalah / " #avac String=mmutable9est.#ava " #ava String=mmutable9est sebelum operasi concat nilai s 3 ini string immutable setela. operasi concat nilai s 3 ini string immutable " Sebelum dan sesudah operasi concat nilai variabel s tetap, hal ini terjadi karena proses concat dari class String akan membuat object baru kemudian dilakukan concat antara nilai yang sekarang dipunyai oleh variabel s dengan string yang ada dalam parameter, dan object baru ini

direturn. ,roses concat tidak merubah nilai yang dipunyai oleh variabel s, karena class String immutable, sekali nilainya diset tidak bisa diubah lagi. ,erhatikan juga proses string concatenantion dengan menggunakan operator Q di atas, operasi ini jika dilakukan menggunakan String akan menghasilkan banyak sekali object baru, yang pertama adalah object hasil operasi append dari variabel s, kemudian object penggabungan variabel s dengan s.concat dan terakhir hasil penggabungan ketiga string tersebut. (alau proses concatenation atau pengolahan String secara umum dalam skala yang sangat besar, maka akan menyebabkan penggunaan memory yang tidak e?sien. (alau kita dihadapkan dengan masalah tersebut sebaiknya jangan menggunakan class String, selalu gunakan class String!uilder atau String!u^er. $lass String!u^er dibuat untuk tujuan e?siensi, karena String!u^er bukan class immutable seperti class String. String!u^er mempunyai kemampuan untuk digunakan dalam lingkungan multi threading karena sifatnya yang thread safe, tetapi feature ini menyebabkan class String!u^er tidak e?sien dari sisi komputasi $,F, karena thread safe memerlukan pengecekan apakah yang melakukan operasi terhadap class String!u^er ini adalah thread yang sama, kalau threadnya berbeda maka prosesnya disuruh mengantri dan hanya satu thread dalam satu "aktu yang bisa melakukan manipulasi class String!u^er ini. $lass String!uilder mempunyai tujuan yang sama persis dengan class String!u^er, tetapai String!uilder tidak mempunyai fasilitas thread safe, sehingga performanya lebih cepat. (alau kita tidak memerlukan fasilitas thread safe maka String!uilder adalah class yang tepat digunakan untuk manipulasi string. Mari kita rubah kode sebelumnya dengan mengganti class String menjadi String!uilder dan kita lihat perbedaanya / public class String>uilder9est { public static void main(String[] args){ String>uilder s 7 ne8 String>uilder(*ini String>uilder tida0 immutable *) System.out.println(*sebelum operasi concat nilai s 3 * E s) CCappend meruba. variabel s+ CCsetela. proses append nilai variabel s a0an beruba. s.append(*concat*) System.out.println(*setela. operasi concat nilai s 3 * E s) s.append(s.append(*concat*)).append(* ob#ect baru*) ! ! +asil eksekusi kode di atas adalah / " #avac String>uilder9est.#ava " #ava String>uilder9est sebelum operasi concat nilai s 3 ini String>uilder tida0 immutable setela. operasi concat nilai s 3 ini String>uilder tida0 immutable concat " Mulai dari JD( ;, compiler java 3javac5 akan merubah operasi penggabungan String dengan menggunakan operasi append dari class String!uilder secara otomatis. Misalnya kode di ba"ah ini / String s 7 *ini string immutable * String concat 7 s E s.concat(*concat*) E * ob#ect baru* kode di atas kalau dicompile menggunakan JD( ; akan diubah kodenya menjadi seperti di ba"ah ini / String s 7 *ini string immutable * String>uilder builder 7 ne8 String>uilder() String concat 7 builder.append(s).append(s.concat(*concat*)) .append(* ob#ect baru*).toString() Jadi kalau sudah menggunakan JD( ; tidak perlu kha"atir melakukan penggabungan string menggunakan class String dan operator Q, tetapi memang sebaiknya selalu gunakan

String!uilder.append untuk menekankan disiplin penggabungan string yang baik.

Date- Calendar- Date4ormat


!ekerja dengan tanggal bukan pekerjaan yang mudah, terkadang kita perlu melakukan perhitungan berdasarkan tanggal yang cukup rumit, misalnya mendapatkan hari terakhir dari bulan tertentu atau mendapatkan selisih hari antara dua tanggal, atau bahkan bekerja dengan calendar selain Masehi, misalnya penanggalan !udha. Java menyediakan class-class yang bisa digunakan untuk tujuan tersebut, sehingga tidak perlu membuat kode untuk melakukan hal tersebut secara manual. $lass Date adalah representasi dari "aktu di Java, class ini terdapat dua jenis/ java.util.Date dan java.s\l.Date. $lass java.util.Date adalah class yang sering digunakan dalam perhitungan tanggal, sedangkan java.s\l.Date adalah representasi data tanggal di java yang setara dengan tipe data date di dalam database. (alau tidak bekerja dengan database, sebaiknya selalu gunakan java.util.Date, sedangkan java.s\l.Date hanya digunakan ketika kita bekerja dengan database. stilah class Date di dalam bab ini merujuk ke java.util.Date. #aktu dalam perhitungan komputer direpresentasikan sebagai bilangan .ong yang merupakan durasi antara tanggal ) januari )1'& &&/&&/&&& hingga "aktu sekarang dalam mili detik. ,encatatan tanggal ini disimpan dalam ! HS dari ,$. Dari kode java kita bisa mendapatkan "aktu sekarang menggunakan kode / ;ong 8a0tuSe0arang 7 System.current9imeBillis() nilai "aktuSekarang adalah jarak antara tanggal ) januari )1'& &&/&&/&&& hingga kode ini dieksekusi dalam mili detik. (alau ingin mendapatkan representasi yang lebih baik, kita bisa menggunakan class Date untuk mendapatkan "aktu sekarang, seperti di ba"ah ini / :ate d 7 ne8 :ate() int ta.un 7 d.get_ear() int bulan 7 d.getBont.() int tanggal 7 d.get:ate() ;ong 8a0tuSe0arang 7 d.get9ime() variabel d adalah instance dari class Date yang merepresentasikan "aktu sekarang dan mempunyai method-method untuk mendapatkan bagian dari "aktu seperti tahun, bulan, tanggal dan seterusnya. $lass Date juga menyediakan constructor dengan parameter .ong, sehingga nilai dari System.currentTimeMillis35 bisa dimasukkan sebagai parameternya, seperti di ba"ah ini / ;ong 8a0tuSe0arang 7 System.current9imeBillis() :ate d 7 ne8 :ate(8a0tuSe0arang) Semenjak java ).), di dalam JD( ditambahkan class $alendar untuk memanipulasi nilai dari class Date ini, oleh karena itu banyak sekali method di dalam class Date yang sifatnya deprecated, sudah tidak didukung dan sebaiknya tidak digunakan lagi. Misalnya methodmethod seperti getDate, getMonth, getPear dan seterusnya kalau digunakan dan kodenya dicompile maka pada "aktu kompilasi akan muncul "arning bah"a method-method tersebut sudah deprecated. $ontohnya seperti ini / import #ava.util.:ate public class :ate:eprecated9est { public static void main(String[] args) { :ate d 7 ne8 :ate() int ta.un 7 d.get_ear() int bulan 7 d.getBont.() int tanggal 7 d.get:ate() ;ong 8a0tuSe0arang 7 d.get9ime() ! ! (alau kita compile kode di atas, "arning menerangkan bah"a ada kode yang deprecated akan terlihat seperti di ba"ah ini/ " #avac :ate:eprecated9est.#ava

<ote3 :ate:eprecated9est.#ava uses or overrides a deprecated I4=. <ote3 6ecompile 8it. $Jlint3deprecation /or details. " $lass Date digunakan sebagai object untuk menyimpan "aktu saja, hal ini terutama karena class Date mengimplementasikan interface SerialiBable, plus semua fungsi untuk perhitungan sudah ditandai deprecated.Sedangkan class $alendar digunakan layaknya kalkulator untuk proses perhitungan tanggal pada class Date, misalnya kita ingin menambahkan ) hari, menambah ) menit dan seterusnya. $alendar juga menyediakan sistem penanggalan Masehi 3Kregorian$alendar5, penanggalan !udha dengan bahas Thailand dan penanggalan Jepang. Misalnya kita ingin membuat class Date dengan tanggal / ) januari %&&&, kodenya seperti di ba"ah ini / Dalendar calendar 7 Dalendar.get=nstance() CCsecara de/ault penanggalan yang diguna0an adala. Base.i (SregorianDalendar) calendar.set()'''+Dalendar.]I<GI6_+%+'+'+') :ate d 7 calendar.get9ime() (ode di atas menggunakan $alendar.get nstance35 untuk mendapatkan tanggal sekarang, class $alendar yang dikembalikan adalah Kregorian$alendar yang merupakan implementasi penanggalan Masehi. Method set mempunyai beberapa bentuk 3overloading5 untuk mengeset nilai ke dalam calendar, bisa diset satu per satu atau diset hanya bulan-tanggal-tahun atau diset semuanya secara bersamaan seperti dalam contoh di atas. (ita juga bisa langsung membuat instance dari Kregorian$alendar menggunakan constructor seperti di ba"ah ini Dalendar calendar 7 ne8 SregorianDalendar()'''+Dalendar.]I<GI6_+%+'+'+') :ate d 7 calendar.get9ime() $lass $alendar mempunyai method setTime untuk memasukkan object class Date ke dalam calendar, kemudian bisa dilakukan perhitungan dan setelah selesai object date bisa dikeluarkan dari calendar dengan menggunakan method getTime. Fntuk mendapatkan nilai individual dari "aktu, class $alendar menyediakan method get dengan sebuah parameter yang menerangkan bagian apa dari calendar yang ingin diambil. $ontohnya seperti di ba"ah ini / Dalendar calendar 7 Dalendar.get=nstance() int ta.un 7 calendar.get(Dalendar._@I6) int bulan 7 calendar.get(Dalendar.BA<9H) int tanggal 7 calendar.get(Dalendar.:I9@) int .ari 7 calendar.get(Dalendar.:I_(AH(W@@K) ,erlu diperhatikan bah"a nilai bulan yang diambil dari calender dimulai dari & hingga ))__, berbeda dengan tanggal yang tidak ada nilai &, perilaku ini kerap menimbulkan bug di dalam aplikasi karena anggapan umum bulan dimulai dari ) hingga )%. Method add dari class $alendar digunakan untuk menambahkan satuan "aktu ke dalam calendar. ,arameternya ada dua/ satuan "aktu dan berapa banyak nilai yang akan ditambahkan. ,erhatikan contoh di ba"ah ini / Dalendar calendar 7 Dalendar.get=nstance() calendar.add(Dalendar.:I9@+ %) CCmenamba. satu .ari calendar.add(Dalendar.HAG6+ %) CCmenamba. satu #am calendar.add(Dalendar._@I6+ $%) CCmengurangi satu ta.un ,roses penambahan atau pengurangan menggunakan add akan merubah satuan "aktu lebih besar. Misalnya sekarang tanggal 7) januari dan ditambah satu hari, maka hasilnya adalah ) *ebruari. (alau kita tidak ingin satuan "aktu lebih besar ikut berubah karena proses penambahan9pengurangan gunakan method roll, seperti contoh di ba"ah ini/ Dalendar calendar 7 ne8 SregorianDalendar()'''+Dalendar.]I<GI6_+1%+'+'+') calendar.roll(Dalendar.:I9@+ %) CC.asilnya % #anuari )''' bu0an % /ebruari )''' $ontoh di atas, kita menambah satu hari ke tanggal 7) Januari %&&&, karena method yang

digunakan adalah roll dan 7) adalah tanggal terbesar untuk bulan januari maka tanggalnya akan dimulai lagi menjadi ) tetapi bulannya tidak berubah, tetap januari. $lass $alendar juga mempunyai beberapa method lain yang cukup berguna, misalnya method get:ctualMaLimum yang bisa digunakan untuk mengambil nilai maLimum satuan "aktu, kalau parameter dari get:ctualMaLimum ini adalah $alendar.D:PSH*SMH0T+ maka akan direturn nilai tanggal terbesar dari bulan tersebut. (alau $alendarnya mempunyai tanggal ) *ebruari %&&& maka hasik dari get:ctualMaLimum3$alendar.D:PSH*SMH0T+5 adalah %1. $ontohnya seperti di ba"ah ini / public class Dalendar9est { public static void main(String[] args) { Dalendar calendar 7 ne8 SregorianDalendar()'''+Dalendar.H@>6GI6_+%) int ma,Heb 7 calendar.getIctualBa,imum(Dalendar.:I_(AH(BA<9H) System.out.println(ma,Heb) ! ! Date*ormat adalah class yang digunakan untuk memformat tanggal menjadi string. $lass turunan dari Date*ormat yang sering digunakan adalah SimpleDate*ormat. $lass SimpleDate*ormat bisa digunakan untuk mengubah string menjadi tanggal dan sebaliknya dari tanggal menjadi String. $lass ini sebaiknya dibuat setiap kali akan digunakan, hal ini dikarenakan class SimpleDate*ormat tidak thread-safe, artinya kalau diinstansiasi sekali dan digunakan dalam lingkungan multithreading maka hasilnya tidak konsisten. *ormat tanggal di Java menggunakan Date*ormat ada aturanya, ada beberapa huruf yang digunakan sebagai simbol satuan "aktu. Daftar huruf yang digunakan sebagai simbol satuan "aktu adalah /
2uru $atuan waktu ! K y M " # D d * M a + k ( h m s S B f Mra Tahun !ulan Minggu dalam satu tahun Minggu dalam satu bulan +ari dalam satu tahun +ari dalam satu bulan Minggu dalam satu bulan +ari dalam satu minggu ,enanda :M9,M Jam dalam satuan %< jam 3&-%75 Jam dalam satuan %< jam 3)-%<5 Jam dalam satuan )% jam 3&-))5 Jam dalam satuan )% jam 3)-)%5 Menit Detik dalam satu menit Milidetik Daerah "aktu 3timeBone5 Daerah "aktu 3timeBone5 Tipe data Teks Tahun !ulan :ngka :ngka :ngka :ngka :ngka Teks Teks :ngka :ngka :ngka :ngka :ngka :ngka :ngka Tanda daerah "aktu Daerah "aktu berdasar -*$-6%% 3ontoh :D, !$ )11;, 1; )),Jul,July %' 7 %41 %7 < Tuesday, Tue :M, ,M )& %< )) )% 7& 7; )'6 ,ST, KMTQ', ,aci?c Standard Time Q&6&&, -&)&&

!erikut ini adalah contoh format tanggal dan hasilnya kalau dieksekusi /

1ormat tanggal dan waktu Odd9MM9yyyyO Odd9MM9yyyy ++/mm/ssO Odd.MM.yyyy ++/mm/ss BO Odd MMM yyyyO Odd MMMM yyyyO Odd MMM yyyy hh/mm/ss a BO

2asil %)9&79%&&< %)9&79%&&< %7/&)/)1 %).&7.%&&< %7/&)/)1 SKT &) Jan &1 %< *ebruary %&)& %7 Mar %&)& ))/&1/%' ,M SKT

$ontoh kodenya bisa kita lihat di ba"ah ini / import #ava.util.:ate import #ava.te,t.Simple:ateHormat import #ava.te,t.4arse@,ception public class Simple:ateHormat9est { public static void main(String[] args) { :ate no8 7 ne8 :ate() System.out.println(ne8 Simple:ateHormat(*ddCBBCyyyy HH3mm3ss*)./ormat(no8)) String tanggal 7 *)%C%)C%MM' 'N3'M3%'* try { :ate date 7 ne8 Simple:ateHormat(*ddCBBCyyyy HH3mm3ss*).parse(tanggal) System.out.println(ne8 Simple:ateHormat(*dd BBBB yyyy*)./ormat(date)) ! catc.(4arse@,ception e,) { e,.printStac09race() ! ! ! +asil eksekusinya adalah seperti berikut / " #avac Simple:ateHormat9est.#ava " #ava Simple:ateHormat9est %&C')C)'%% '%31)3)& )% :ecember %MM' " Manipulasi tanggal menggunakan $alendar dan memformat tanggal menggunakan SimpleDate*ormat terkadang memerlukan kode yang cukup panjang dan tidak praktis. Masalah kurang handalnya library pengolahan tanggal yang ada dalam JD( sudah banyak diketahui, di JD( ' nanti akan ada library tanggal yang baru di JS--7)&. library ini diturunkan dari library tanggal yang sangat populer dan po"erfull, yaitu Joda Time. Di bab berikutnya kita akan membandingkan bagaimana mengolah data menggunakan $alendar vs menggunakan Joda Time.

Joda &ime
Joda Time adalah library pengolahan tanggal yang ditulis oleh Stephen $olebourne karena sudah cukup frustasi dengan library pengolahan tanggal di dalam JD( yang cukup merepotkan untuk perhitungan tanggal yang rumit. :, untuk pengolahan tanggal bisa dibilang sebagai :, yang paling buruk dalam JD( saat ini. :, tanggal mulai ada semenjak JD( versi ).&, James Kosling mencontek implementasi tanggal dari $, dimana implementasinya masih sederhana dan memiliki banyak kelemahan secara design. Misalnya bulan di dalam class Date dimulai dari & hingga )), jadi kalau kita panggil method getMonth dari class Date untuk bulan Desember maka nilainya adalah )), bukan )%. Joda Time dibuat untuk memperbaiki hal ini. Selain itu Joda Time juga mengenalkan beberapa konsep baru, seperti periode, interval dan implementasi daerah "aktu 3timeBone5 yang lebih baik. *eature chronology juga sangat membantu kalau kita ingin bekerja dengan sistem penanggalan yang tidak umum digunakan, seperti penanggalan islam, budha, julian dan sebagainya. Joda Time bisa digunakan bersamaan dengan class Date dan $alendar dengan baik, kita bisa melakukan konversi dari class-class Joda Time menjadi kedua class tersebut dengan mudah. Jadi Joda Time digunakan sebagai library perhitungan tanggal yang bisa melakukan hal-hal rumit

dengan mudah, kemudian setelah selesai peroses perhitunganya kita bisa mendapatkan hasilnya dalam bentuk class Date. *eature back"ard compatibility inilah salah satu daya tarik dari Joda Time. Sebelum kita mulai belajar tentang konsep dalam Joda Time, kita perlu mendo"nload library Joda Time dari alamat di ba"ah ini / http/99sourceforge.net9projects9joda-time9?les9joda-time9 pada saat buku ini ditulis versi yang terbaru adalah ).;.%, kita hanya perlu satu buah jar saja yaitu joda-time.).;.%.jar. Joda Time memperkenalkan enam konsep "aktu, yaitu / nstant / sebuah instant adalah nilai dalam mili detik dari ) januari )1'& &&/&&/&& hingga sekarang. ,arsial / representasi sebagian dari "aktu, misalnya tanggal saja atau "aktu saja. nterval / interval "aktu dari a"al hingga akhir. Dalam interval terdapat dua buah instant yaitu a"al dan akhir. Durasi / durasi "aktu dalam mili detik, misalnya )&&& mili detik. ,eriode / periode "aktu yang direpresentasikan dalam satuan-satuan "aktu, misalnya ) hari % jam 7 menit dan 7& detik. $hronology / sistem penanggalan yang bisa digunakan sebagai basis perhitungan "aktu.
3lass Immutable nstant, DateTime, DateMidnight .ocalDate, .ocalTime, .ocalDateTime,,artial nterval ,eriod, Minutes, +ours, Days, #eeks, Months, Pears Duration Kregorian$hronology, SH$hronology 3default5, !uddhist$hronology, Julian$hronology, Mthiopic$hronology, $optic$hronology, KJ$hronology Mutable nterval Mutable,eriod 3lass -utable MutableDateTime

$lass-class implementasi dari setiap konsep di atas adalah sebagai berikut /


4onsep nstant ,arsial nterval ,eriode Durasi $hronology

Mari kita bahas satu per satu konsep di atas dengan disertai contoh kode untuk mempermudah pemahaman terhadap konsep-konsep dalam Joda Time. nstant adalah konsep paling sederhana, konsep ini sama dengan class Date, yaitu representasi jumlah mili detik dari tanggal ) januari )1'& &&/&&/&& hingga sekarang. Joda Time mempunyai beberapa class yang digunakan untuk merepresentasikan instant ini, dua class yang sering digunakan adalah class nstant dan class DateTime. $lass nstant berisi satu buah property dalam mili detik, perhatikan contoh berikut ini untuk memahami class nstant / import org.#oda.time.=nstant public class =nstant9est { public static void main(String[] args) { =nstant instant 7 ne8 =nstant(%''') CC % deti0 setela. %M-' CCingat ba.8a instant mutable se.ingga perlu diset lagi setela. CCdiuba. nilainya instant 7 instant.plus(%'') CCditamba. %'' milideti0 instant 7 instant.plus(&'''') CCditamba. satu menit System.out.println(instant) !

! Fntuk mengcompile kode di atas, kita perlu menambahkan jar Joda Time ke dalam classpath. .etakkan joda-time.).;.%.jar ke dalam folder yang sama dengan ?le java dari class di atas, kemudian jalankan command di ba"ah ini untuk mengcompile dan menjalankan kode di atas. Jalankan perintah di ba"ah ini kalau anda bekerja dengan .inuL, FniL dan Mac / " #avac $cp #oda$time$%.&.).#ar =nstant9est.#ava " #ava $cp #oda$time$%.&.).#ar3. =nstant9est %M-'$'%$'%9''3'%3'%.%''` " Sedangkan untuk #indo"s perintahnya sedikit berbeda, hal ini dikarenakan perbedaan pemisah classpath, dimana untuk .inuL9FniL9Mac menggunakan / 3titik dua5 dan "indo"s menggunakan D 3titik koma5 / " #avac $cp #oda$time$%.&.).#ar =nstant9est.#ava " #ava $cp #oda$time$%.&.).#ar . =nstant9est %M-'$'%$'%9''3'%3'%.%''` " $lass DateTime juga merepresentasikan konsep nstant. $lass ini fungsinya menggabungkan fungsi dalam class Date plus class $alender, karena bisa digunakan sebagai representasi "aktu sekaligus mempunyai method-method untuk melakukan manipulasi data "aktu. !erikut ini adalah contoh penggunaan class DateTime / import org.#oda.time.:ate9ime import #ava.util.:ate import #ava.util.Dalendar public class :ate9ime9est { public static void main(String[] args) { :ate9ime date9ime 7 ne8 :ate9ime() CC8a0tu se0arang int date 7 date9ime.get:ayA/Bont.() int mont. 7 date9ime.getBont.A/_ear() CCdimulai dari % .ingga %) int year 7 date9ime.get_ear() :ate9ime plusBont. 7 date9ime.plusBont.s()) :ate9ime plusBinutes 7 date9ime.plusBinutes()) :ate d 7 plusBont..to:ate() CCmenguba. :ate9ime 0e :ate Dalendar c 7 plusBinutes.toSregorianDalendar() CCmenguba. :ate9ime 0e Dalendar System.out.println(date9ime) ! ! ,artial digunakan untuk merepresentasikan "aktu yang terpisah antara tanggal dan jam tanpa daerah "aktu 3timeBone5. Misalnya class .ocalDate hanya mempunyai property tanggal, bulan dan tahun, sedangkan class .ocalTime hanya mempunyai property jam, menit, detik dan mili detik. $lass ini jarang digunakan dan lebih praktis menggunakan class DateTime saja untuk representasi "aktu, class-class tersebut ada hanya untuk tujuan back"ard compatibility dengan versi Joda Time yang lebih lama. $ontoh kodenya seperti di ba"ah ini / import org.#oda.time.;ocal:ate public class 4artial9est { public static void main(String[] args) { ;ocal:ate birt.:ay 7 ne8 ;ocal:ate(%M&R+%+)1) long millis 7 birt.:ay.to:ate9imeItDurrent9ime().getBillis() System.out.println(millis) CCbernilai negati/ 0arena sebelum %M-' birt.:ay 7 birt.:ay.plus_ears()-) CCulta. 0e )int year 7 birt.:ay.get_ear() CCta.un ulta. 0e )! ! nterval adalah representasi jarak antara satu instant dengan intant yang lainya. (onsep interval mempunyai dua buah instant yaitu "aktu mulai dan "aktu selesai. $lass nterval digunakan untuk

merepresentasikan konsep interval ini. Method getStart dari class nterval digunakan untuk mendapatkan "aktu mulai, sedangkan method getMnd digunakan untuk mendapatkan "aktu selesai. (alau ingin mengubah "aktu a"al gunakan method "ithStart dan kalau ingin mengubah "aktu akhir gunakan method "ithMnd. $ontoh penggunaan interval adalah sebeagai berikut ini / import org.#oda.time.:ate9ime import org.#oda.time.=nterval public class =nterval9est { public static void main(String[] args) { :ate9ime no8 7 ne8 :ate9ime() :ate9ime oneBont.;ater 7 no8.plusBont.s(%) =nterval interval 7 ne8 =nterval(no8+ oneBont.;ater) System.out.println(*interval 3 * E interval) System.out.println(*start 3 * E interval.getStart()) System.out.println(*end 3 * E interval.get@nd()) System.out.println(*duration 3 * E interval.to:uration()) CCmeruba. nilai end interval dengan menamba.0an satu #am interval.8it.@nd(interval.get@nd().plusHours(%)) ! ! (alau kita eksekusi kode di atas, hasilnya adalah seperti di ba"ah ini / " #avac $cp #oda$time$%.&.).#ar =nterval9est.#ava " #ava $cp #oda$time$%.&.).#ar3. =nterval9est interval 3 )'%%$')$%&9'131531-.N--C)'%%$'1$%&9'131531-.N-start 3 )'%%$')$%&9'131531-.N--E'N3'' end 3 )'%%$'1$%&9'131531-.N--E'N3'' duration 3 49)5%M)''S " (alau anda bekerja dengan "indo"s, jangan lupa mengganti pemisah classpath dengan simbil D 3titik koma5. (onsep durasi dalam Joda Time merepresentasikan lama "aktu dalam mili detik. Durasi bisa dihitung langsung dengan memasukkan nilai durasi dalam mili detik atau bisa juga dihitung dari sebuah interval. $ontoh kode penggunaan durasi seperti di ba"ah ini / import org.#oda.time.:uration import org.#oda.time.:ate9ime public class :uration9est { public static void main(String[] args) { :uration duration 7 ne8 :uration(%'''') CC %' deti0 System.out.println(*duration 3 * E duration) :ate9ime no8 7 ne8 :ate9ime() :ate9ime oneBont.;ater 7 no8.plusBont.s(%) duration 7 ne8 :uration(no8+ oneBont.;ater) System.out.println(*duration o/ one mont. 3 * E duration) :uration oneHour 7 ne8 :uration(%''' L &' L &') :ate9ime oneHour;ater 7 no8.plus(oneHour) System.out.println(*one .our later 3 * E oneHour;ater) ! ! +asil eksekusi kode di atas adalah seperti berikut ini / " #avac $cp #oda$time$%.&.).#ar :uration9est.#ava " #ava $cp #oda$time$%.&.).#ar3. :uration9est duration 3 49%'S duration o/ one mont. 3 49)5%M)''S one .our later 3 )'%%$')$%&9'535-31'.55RE'N3''

" (alau anda bekerja dengan "indo"s, jangan lupa mengganti pemisah classpath dengan simbil D 3titik koma5. Durasi adalah konsep komputer yang ketat, artinya durasi bisa diukur dalam mili detik dan tidak terikat dengan suatu "aktu tertentu. Sedangkan periode adalah sebuah konsep durasi yang sedikit berbeda karena terikat dengan suatu "aktu tertentu dan lebih condong sebagai intepretasi manusia terhadap "aktu dibanding intepretasi mesin terhadap "aktu. $ontoh periode adalah / ) tahun % bulan 7& hari, nah berapa total lama periode tersebut dalam mili detik tidaklah selalu sama, tergantung dari mana a"al dari periode tersebut. Misalnya ) tahun di tahun %&&& dengan ) tahun di tahun %&&) akan berbeda dalam satuan mili detik karena tahun %&&& adalah tahun kabisat di penanggalan gregorian. Di sisi lain, periode ini lebih praktis dibanding dengan durasi, terutama kalau nilainya lumayan tinggi dan dide?nisikan dalam pecahan "aktu. !erikut ini contoh penggunaan dari konsep periode/ import org.#oda.time.4eriod import org.#oda.time.:ate9ime import org.#oda.time.Hours import org.#oda.time.Binutes public class 4eriod9est { public static void main(String[] args) { 4eriod p 7 ne8 4eriod(%''') CC% deti0 System.out.println(*period 3 * E p) p 7 ne8 4eriod()+1+M+%)R) CC) #am 1 menit M deti0 dan %)R mili deti0 System.out.println(*period 3 * E p) :ate9ime start9ime 7 ne8 :ate9ime()'''+%+%+M+'+'+') CC% #anuari )''' #am M CCmenamba.0an period 0e instant untu0 mendapat0an instant baru :ate9ime end9ime 7 start9ime.plus(p) System.out.println(*end time 3 * E end9ime) CC4eriode nilainya tida0 menentu+ satu .ari belum tentu )5 #am+ CCtergantung apa0a. .ari itu ada daylig.t savings atau tida0. CC>egitupula satu ta.un belum tentu 1&R .ari+ CCtergantung 0abisat atau tida0. CCBenguba. 4eriod 0e durasi .arus ada 8a0tu a8al+ CC0emudian ditamba. dengan period dapat 8a0tu a0.ir dan di.itung durasinya Hours .ours 7 Hours..ours>et8een(start9ime+end9ime) CCmendapat0an durasi dalam #am dengan tipe data int int .ours>et8een 7 .ours.getHours() System.out.println(*.ours duration 3 * E .ours) Binutes minutes 7 Binutes.minutes>et8een(start9ime+ end9ime) System.out.println(*minutes duration 3 * E minutes) ! ! +asil eksekusi kode di atas adalah sebagai berikut / " #avac $cp #oda$time$%.&.).#ar 4eriod9est.#ava " #ava $cp #oda$time$%.&.).#ar3. 4eriod9est period 3 49%S period 3 49)H1BM.%)RS end time 3 )'''$'%$'%9%%3'13'M.%)RE'N3'' .ours duration 3 49)H minutes duration 3 49%)1B " (alau anda bekerja dengan "indo"s, jangan lupa mengganti pemisah classpath dengan simbil D 3titik koma5. $hronology adalah jantung dari Joda Time, semua perhitungan instant, periode dan durasi

didasarkan pada jenis penanggalan yang digunakan. Joda Time secara default menyediakan beberapa sistem penanggalan, antara lain / Kregorian / standard penanggalan masehi yang dimulai pada )4 september )46%, penanggalan ini mende?nisikan bah"a tahun kabisat hanya terjadi pada tahun yang habis dibagi <, tidak habis dibagi )&& dan habis dibagi <&&. Misalnya tahun %&&6 adalah kabisat karena habis dibagi <, tahun %)&& bukan kabisat karena "alaupun habis dibagi < juga habis dibagi )&&. Tahun %&&& adalah kabisat karena habis dibagi <, "alaupun habis dibagi )&& tetapi habis dibagi <&&. Julian / standard penanggalan masehi yang sebelum tanggal )4 september )46%. ,enanggalan ini mende?nisikan bah"a setiap tahun yang habis dibagi < adalah tahun kabisat. SH6;&) / standard penanggalan yang menggunakan sistem Kregorian plus standarisasi format penulisan tanggal. Joda Time secara default menggunakan SH6;&) sebagai default chronology KJ / penanggalan yang menggabungkan Julian dan Kregorian. Sebelum tanggal )4 September )46% sistem penanggalan yang digunakan adalah Julian dan setelahnya adalah Kregorian. ,enanggalan lain yang spesi?k / !uddhist, $optic, Mthiopic

Sampai di sini kita sudah belajar secara umum tentang konsep "aktu dalam Joda Time beserta implementasinya, nah kita akan membahas lagi sedikit tentang bagaimana Joda Time menyederhanakan kode perhitungan tanggal yang dibuat dengan class dari JD(. $ontoh pertama / membuat instant, tambahkan %& hari kemudian print hasilnya ke dalam console dengan format tanggal tertentu. (ode untuk melakukan perhitungan tersebut dengan menggunakan class-class dari JD( adalah seperti berikut ini / import #ava.util.Dalendar import #ava.te,t.Simple:ateHormat public class Dalculate:ate9est { public static void main(String[] args) { Dalendar c 7 Dalendar.get=nstance() c.set()'''+Dalendar.]I<GI6_+%+'+'+') c.add(Dalendar.:I9@+ )') Simple:ateHormat /ormat 7 ne8 Simple:ateHormat(*dd BBB yyyy HH3mm3ss*) System.out.println(*date 3 * E /ormat./ormat(c.get9ime())) ! ! mplementasinya menggunakan Joda Time memerlukan jumlah baris kode setengahnya dari kode di atas / import org.#oda.time.:ate9ime public class Dalculate:ate]oda9est { public static void main(String[] args) { :ate9ime d 7 ne8 :ate9ime()'''+%+%+'+'+'+') System.out.println(*date 3 * E d.plus:ays()').toString(*dd BBB yyyy HH3mm3ss*)) ! ! $ontoh kedua sedikit lebih rumit, misalnya kita ingin mengetahui hasil perhitungan ini / tanggal a"al adalah ) januari %&&&, tambahkan ) bulan <4 hari dari tanggal a"al, kemudian cari tanggal berapa di hari minggu pada minggu tersebut. ,erhitungan ini cukup rumit untuk dibuat implementasinya menggunakan library JD(, tetapi menggunakan Joda Time perhitungan ini sangat sederhana dan hanya memerlukan beberapa baris kode saja. mplementasinya / import org.#oda.time.:ate9ime public class DalculateDomplicated:ate]oda9est {

public static void main(String[] args) { :ate9ime d 7 ne8 :ate9ime()'''+%+%+'+'+'+') System.out.println(*date 3 * E d.plusBont.s(%).plus:ays(5R).dayA/Wee0() .8it.Ba,imumPalue().toString(*dd BBB yyyy HH3mm3ss*)) !

.ibrary Joda Time adalah library yang "ajib ada di setiap project yang kita buat. ,erhitungan tanggal menjadi mudah menggunakan Joda Time.

BigDecimal dan Currency


,enanganan angka pecahan sangat penting untuk aplikasi bisnis, terutama untuk uang, hal ini karena kalau ada kesalahan pembulatan maka akan ada kesalahan perhitungan uangnya. Selisih sedikit saja akan membuat perhutungan accounting atau pajak menjadi tidak seimbang sehingga menyebabkan laporan keuangan tidak benar. !ekerja dengan angka pecahan, kita pasti langsung teringat dengan tipe data Uoat atau double, tergantung presisi dan besarnya data yang digunakan. Tetapi ketika berurusan dengan uang, kedua tipe data ini bisa menyebabkan masalah pelik, terutama kalau ada aturan berapa angka di belakang koma saja yang berpengaruh terhadap perhitungan. Misalnya hanya % buah angka di belakang koma saja yang digunakan, sisanya bisa diabaikan dengan menggunakan pembulatan. Tipe data Uoat dan double tidak bisa diatur berapa angka di belakang koma, sehingga proses pembulatan juga tidak selalu berhasil dengan baik. Mari kita lihat contoh perhitungan bilangan pecahan menggunakan double yang bisa menyebabkan kesalahan angka dibelakang koma. Misalnya kita menjual barang dengan harga -p. ).&&&.&&&,&4 kemudian ada diskon )&V, baru setelah itu dihitung ,,0 4V. Fntuk melihat hasilnya digunakan class 0umber*ormat agar tampilan diformat menggunakan format uang -upiah yang benar. import #ava.te,t.<umberHormat import #ava.util.;ocale public class Sale:ecimal9est { public static void main(String args[]) { double amount 7 %''''''.'R double discount 7 amount L '.%' double total 7 amount $ discount double ta, 7 total L '.'R double ta,ed9otal 7 ta, E total <umberHormat money 7 <umberHormat.getDurrency=nstance( ne8 ;ocale(*in*+*=:*)) System.out.println(*Subtotal 3 *E money./ormat(amount)) System.out.println(*:iscount 3 * E money./ormat(discount)) System.out.println(*9otal 3 * E money./ormat(total)) System.out.println(*9a, 3 * E money./ormat(ta,)) System.out.println(*9a,E9otal3 * E money./ormat(ta,ed9otal)) ! ! +asil eksekusi kode di atas sedikit mengejutkan, perhatikan baik-baik / " #avac Sale:ecimal9est.#ava " #ava Sale:ecimal9est Subtotal 3 6p%.'''.'''+'R :iscount 3 6p%''.'''+'' 9otal 3 6pM''.'''+'5 9a, 3 6p5R.'''+'' 9a,E9otal3 6pM5R.'''+'R " nilai total bukanya -p 1&&.&&&,&4 tetapi malah -p 1&&.&&&,&< ternyata terjadi kesalahan

pembualatan uang pada 0umber*ormat. (alau kita hilangkan proses memformat angkanya seperti di ba"ah ini / import #ava.util.;ocale public class Sale:ecimalGn/ormated9est { public static void main(String args[]) { double amount 7 %''''''.'R double discount 7 amount L '.%' double total 7 amount $ discount double ta, 7 total L '.'R double ta,ed9otal 7 ta, E total System.out.println(*Subtotal 3 *E amount) System.out.println(*:iscount 3 * E discount) System.out.println(*9otal 3 * E total) System.out.println(*9a, 3 * E ta,) System.out.println(*9a,E9otal3 * E ta,ed9otal) ! ! terlihat bah"a sebenarnya angka di belakang koma sedikit berantakan / " #avac Sale:ecimalGn/ormated9est.#ava " #ava Sale:ecimalGn/ormated9est Subtotal 3 %''''''.'R :iscount 3 %'''''.''R 9otal 3 M'''''.'5R 9a, 3 5R'''.''))R''''''R 9a,E9otal3 M5R'''.'5-)R''''% " Dengan menggunakan !igDecimal kita bisa mengontrol bagaimana caranya melakukan pembulatan angka di belakang koma. :turan pembulatan yang digunakan bisa dipilih salah satu dari nilai enum class -oundingMode yang diperkenalkan semenjak Java ;. :turan pembulatan yang tersedia di dalam class -oundingMode antara lain / $M . 0K / pembulatan ke atas DH#0 / pembulatan ke ba"ah mendekati nol, kalau nilainya negatif dibulatkan ke angka lebih besar yang lebih dekat dengan angka nol. *.HH- / pembulatan ke atas mendekati angka negatif tak terhingga. (alau angkanya negatif dibulakan ke angka lebih kecil lagi mendekati negatif tak terhingga. F, / pembulatan yang selalu menjauhi angka nol. (alau nilai positif dibulatkan ke lebih besar, kalau angka negatif dibulatkan ke angka lebih kecil lagi. +:.*SDH#0 / dibulatkan ke angka terdekat, kecuali kalau sama jaraknya antara ke atas dan ke ba"ah, maka dibulatkan ke angka ba"ah mendekati nol. +:.*SF, / dibulatkan ke angka terdekat, kecuali kalau sama jaraknya antara ke atas dan ke ba"ah, maka dibulatkan ke angka atas menjauhi nol. ,embulatan ini adalah sistem pembulatan yang digunakan dalam sistem keuangan. F00M$MSS:-P / tidak perlu dilakukan pembulatan

Selain masalah pembulatan, tipe data double juga mempunyai masalah serius dengan representasinya di dalam memory. Tidak semua angka dibelakang koma bisa direpresentasikan dalam binary, misalnya angka &.&74, kalau angka ini disimpan dalam tipe data double maka hasilnya adalah &.&7<11111111111111;. Masalah representasi data di belakang koma ini tidak muncul di !igDecimal, sehingga bisa dihindari masalah seperti ini. Mari kita lihat contoh masalah ini dalam kode / import #ava.mat..>ig:ecimal import #ava.mat..6oundingBode public class :ouble4roblem9est {

public static void main(String[] args) { double dd 7 .1R >ig:ecimal d 7 ne8 >ig:ecimal(dd) System.out.println(*.1R 7 * E d) CC.asilnya beranta0an 0arena dari double d 7 d.setScale()+ 6oundingBode.HI;H(G4) System.out.println(*.1R 7 * E d) CC.asilnya bagus setela. pembulatan >ig:ecimal dec 7 ne8 >ig:ecimal(*'.1R*) System.out.println(*.1R 7 * E dec) CC.asilnya bagus ! ! hasilnya seperti di ba"ah ini / " #avac :ouble4roblem9est.#ava " #ava :ouble4roblem9est .1R 7 '.15MMMMMMMMMMMMMM---MRR1MR'-5M&N&M%M%R)-1&&&1N%N1RM1-R .1R 7 '.1R .1R 7 '.1R " !igDicimal yang dibuat dari double mempunyai nilai sama persis dengan double, makanya lebih baik kalau nilainya berasal dari String sehingga bisa sesuai yang kita harapkan. 0ah sekarang kita kembali lagi ke contoh pertama dalam bab ini. (ita akan mengimplementasikan perhitungan harga, diskon dan pajak menggunakan !igDecimal dan hasilnya harus cocok, tidak boleh ada selisih angka di belakang koma/ import #ava.mat..>ig:ecimal import #ava.mat..6oundingBode public class >ig:ecimal9est { public static void main(String args[]) { >ig:ecimal amount 7 ne8 >ig:ecimal(*%''''''.'R*) >ig:ecimal discount4ercent 7 ne8 >ig:ecimal(*'.%'*) >ig:ecimal discount 7 amount.multiply(discount4ercent) discount 7 discount.setScale()+ 6oundingBode.HI;H(G4) >ig:ecimal total 7 amount.subtract(discount) total 7 total.setScale()+ 6oundingBode.HI;H(G4) >ig:ecimal ta,4ercent 7 ne8 >ig:ecimal(*'.'R*) >ig:ecimal ta, 7 total.multiply(ta,4ercent) ta, 7 ta,.setScale()+ 6oundingBode.HI;H(G4) >ig:ecimal ta,ed9otal 7 total.add(ta,) ta,ed9otal 7 ta,ed9otal.setScale()+ 6oundingBode.HI;H(G4) System.out.println(*Subtotal 3 * E amount) System.out.println(*:iscount 3 * E discount) System.out.println(*9otal 3 * E total) System.out.println(*9a, 3 * E ta,) System.out.println(*9a,E9otal3 * E ta,ed9otal) ! ! +asil eksekusinya adalah seperti berikut ini / " #avac >ig:ecimal9est.#ava " #ava >ig:ecimal9est Subtotal 3 %''''''.'R :iscount 3 %'''''.'% 9otal 3 M'''''.'5 9a, 3 5R'''.'' 9a,E9otal3 M5R'''.'5 " terlihat bah"a tanpa menggunakan formatter hasil dari perhitungan !igDecimal sudah tepat dan

presisi, tidak ada kesalahan perhitungan sama sekali.

I("
nput Hutput adalah topik yang sangat penting dalam aplikasi apapun, membaca atau menulis ?le merupakan rutin yang sering ada dalam aplikasi. 9H juga meliputi komunikasi dengan aplikasi lain yang ada dalam jaringan melalui komunikasi socket.

4ile
*ile adalah class yang merepresentasikan ?le dan folder yang ada di dalam ?le system, baik yang ada di hardisk lokal atau ada di dalam mesin lain yang diakses dari ?le sharing system. Dengan menggunakan $lass ini kita bisa ini kita bisa melakukan / mengecek sebuah path apakah berupa ?le ataukah folder membuat, merename atau menghapus ?le dan folder mengecek apakah folder atau ?le tersebut ada dalam ?lesystem mengambil daftar isi dari folder.

Mari kita lihat bagaimana class *ile ini beraksi / import #ava.io.Hile import #ava.io.=A@,ception public class Hile9est { public static void main(String[] args) { Hile / 7 ne8 Hile(*ne8/ile.t,t*) i/(!/.e,ists()){ try{ /.create<e8Hile() System.out.println(/.getIbsolute4at.()) ! catc.(=A@,ception e){ e.printStac09race() ! ! Hile /older 7 ne8 Hile(*ne8/older*) i/(!/.e,ists()) { /.m0dir() CC/.m0dirs() CCmembuat /older di dalam /older ! Hile currentHolder 7 ne8 Hile(System.get4roperty(*user.dir*)) Hile[] siblings 7 currentHolder.listHiles() /or(int i7' iTsiblings.lengt. iEE){ Hile sibling 7 siblings[i] i/(sibling.isHile()) { System.out.println(*/ * E sibling.get<ame()) ! else { System.out.println(*d * E sibling.get<ame()) ! ! ! ! (ode di atas akan membuat ?le, kemudian membuat folder dan akhirnya mengambil isi semua ?le dan ?lder dari user.dir 3folder dimana aplikasi java dijalankan5. Masih banyak methodmethod lain yang ada dalam class *ile yang belum kita coba, silahkan lihat javadoc untuk melihat semua method yang dipunyai class *ile ini.

)eader
$lass-class yang mengeLtends class -eader biasa digunakan kalau ingin membaca karakter stream, artinya kalau yang dibaca adalah ?le maka ?le tersebut berisi teLt. :da beberapa ?le yang meneLtends class -eader ini, tapi kita hanya akan membahas class !u^ered-eader untuk membaca ?le teLt. !u^ered-eader akan menyimpan data yang sudah dibaca ke dalam memory, sehingga ketika method read atau read.ine dipanggil dan data sudah ada dalam memory, !u^ered-eader tidak akan membaca lagi dari dalam ?le. Mari kita lihat contoh kodenya / import #ava.io.>u//ered6eader import #ava.io.Hile6eader import #ava.io.=A@,ception public class 6eader9est { public static void main(String[] args) { try{ >u//ered6eader reader 7 ne8 >u//ered6eader(ne8 Hile6eader(*6eader9est.#ava*)) String line 8.ile((line 7 reader.read;ine())!7null) { System.out.println(line E *On*) ! CC#angan lupa untu0 selalu memanggil close setela. reader tida0 diguna0an reader.close() ! catc.(=A@,ception e) { e.printStac09race() ! ! !

'riter
#riter digunakan untuk menulis String atau char=> ke dalam sebuah ?le. (ita akan menggunakan !u^ered#riter sebagai contohnya. import #ava.io.>u//eredWriter import #ava.io.HileWriter import #ava.io.=A@,ception public class Writer9est { public static void main(String[] args) { try{ >u//eredWriter 8riter 7 ne8 >u//eredWriter(ne8 HileWriter(*/ile.t,t*)) 8riter.8rite(*HelloWorld ini /ile te,t sayaOn*) CCmenulis te,t 0e dalam /ile 8riter./lus.() 8riter.8rite(*ini te,t di baris duaOn*) CC#angan lupa untu0 selalu memanggil close CCsetela. reader tida0 diguna0an CCclose #uga se0aligus memanggil /lus. dan menulis data 0e dalam /ile 8riter.close() ! catc.(=A@,ception e) { e.printStac09race() ! ! !

In$ut*tream
nputStream digunakan untuk membaca dari 9H yang berupa byte stream, semua data direpresentasikan dalam byte, jadi baik data berupa teLt maupun binary dapat dibaca menggunakan nputStream. $lass yang mengeLtends nputStream cukup banyak, karena nputStream ini adalah dasar dari H di java. Semua sumber input output rata-rata bisa diakses menggunakan nputStream ini. (ita sayangnya tidak akan membahas panjang lebar mengenai nputStream ini, yang kita bahas hanya sedikit pengenalan bagaimana menggunakan nputStream. ,enggunaan nputStream yang pertama adalah membaca ? le binary, sering kali kita dihadapkan dengan upload ?le dari user ke server, nah proses upload ?le ini mau tidak mau akan melibatkan nputStream intuk membaca ?le yang dikirim ke server. Mari kita lihat struktur kode untuk membaca ?le byte per byte / =nputStream is 7 ne8 Hile=nputStream(*/ile.t,t*) int byte6ead do { byte6ead 7 is.read() CCla0u0an sesuatu dengan datanya ! 8.ile(byte6ead!7$%) Method read dari class nputStream digunakan untuk membaca byte per byte dari sumber data, variabel byte-ead memegang nilai byte yang sedang dibaca, kalau nilai variabel byte-ead adalah -) artinya sudah tidak ada lagi data yang bisa dibaca, alias sudah sampai akhir dari data. Subclass dari nputStream mempunyai bermacam-macam method read, misalnya Data nputStream mempunyai method read!oolean, readHbject, readDouble dan sebagainya. Mari kita lihat contoh sebenarnya dari nputStream, kita akan membuat kode yang bisa memanggil F-. dari internet kemudian membaca halaman dari url tersebut menggunakan nputStream / import #ava.io.=A@,ception import #ava.io.=nputStream import #ava.net.G6; import #ava.net.Bal/ormedG6;@,ception import #ava.net.G6;Donnection public class Grl=nputStream9est { public static void main(String[] args) { try{ G6; url 7 ne8 G6;(*.ttp3CC888.ya.oo.com*) G6;Donnection urlconn 7 url.openDonnection() =nputStream is 7 urlconn.get=nputStream() int byte6ead do{ byte6ead 7 is.read() System.out.print((c.ar)byte6ead) ! 8.ile(byte6ead !7 $%) ! catc.(Bal/ormedG6;@,ception e,) { e,.printStac09race() ! catc.(=A@,ception e,) { e,.printStac09race() ! ! ! output dari kode di atas adalah html yang dibaca dari yahoo.com

!ut$ut*tream
HutputStream tentu saja adalah kebalikan dari nputStream, fungsi HutputStream adalah

menulis data ke sumber data, baik itu data dari ?lesystem ataupun dari koneksi socket. (ita modi?kasi kode di atas untuk menyimpan String ke *ileHutputStream / import #ava.io.=A@,ception import #ava.io.=nputStream import #ava.io.AutputStream import #ava.io.HileAutputStream import #ava.net.G6; import #ava.net.Bal/ormedG6;@,ception import #ava.net.G6;Donnection public class GrlAutputStream9est { public static void main(String[] args) { try{ G6; url 7 ne8 G6;(*.ttp3CC888.ya.oo.com*) G6;Donnection urlconn 7 url.openDonnection() =nputStream is 7 urlconn.get=nputStream() AutputStream os 7 ne8 HileAutputStream(*ya.oo.t,t*) int byte6ead do{ byte6ead 7 is.read() os.8rite(byte6ead) System.out.print((c.ar)byte6ead) ! 8.ile(byte6ead !7 $%) os./lus.() ! catc.(Bal/ormedG6;@,ception e,) { e,.printStac09race() ! catc.(=A@,ception e,) { e,.printStac09race() ! ! ! dalam ?le menggunakan

(ode di atas akan membaca "ebsite yahoo.com kemudian mengambil isinya dan menyimpan teLt html ke dalam ?le yahoo.tLt

ImageI!
mage H adalah class yang berisi utility untuk bekerja dengan gambar. :da beberapa class di dalam java yang merepresentasikan gambar, antara lain con, mage con, mage dan !u^ered mage. con adalah interface yang digunakan untuk menampilkan gambar dalam komponen S"ing, misalnya membuat background atau membuat icon. mage adalah class untuk merepresentasikan sebuah gambar dalam memory java, kita bisa mengambil lebar dan tinggi serta ukuran dari gambar menggunakan class mage ini. mage con adalah implementasi con yang diperoleh dari sebuah mage. Sedangkan !u^ered mage adalah class yang digunakan untuk memanipulasi mage, misalnya melakukan resiBe atau menampilkan gambar yang bisa dicampur dengan bentuk-bentuk lain 3seperti lingkaran atau persegi panjang5 untuk kemudian disimpan menjadi gambar baru atau ditampilkan dalam canvas. mage H memudahkan konversi dari satu class menjadi class lain, nah mari kita lihat bagaimana penggunaanya dalam kode. $ontoh kode pertama adalah membaca ?le gambar dari internet, kemudian disimpan dalam ?le kemudian ditampilkan. import #ava.io.L import #ava.net.L import #ava,.s8ing.L import #ava,.imageio.L public class =mage9est { public static void main(String[] args) {

try { G6; url 7 ne8 G6;( *.ttp3CCi/nubima.orgC8p$contentCuploadsC)'%'C'-C)'%'$'-$)R('115.png*) G6;Donnection urlconn 7 url.openDonnection() =nputStream is 7 urlconn.get=nputStream() AutputStream os 7 ne8 HileAutputStream(*image.png*) int byte6ead do { byte6ead 7 is.read() os.8rite(byte6ead) ! 8.ile (byte6ead !7 $%) os./lus.() os.close() CCmenampil0an image =con icon 7 ne8 =mage=con( =mage=A.read(ne8 Hile(*image.png*))) ]Aption4ane.s.o8Bessage:ialog(null+ *ini gambar*+*menampil0an gambar*+ ]Aption4ane.=<HA6BI9=A<(B@SSIS@+ icon) ! catc. (=A@,ception e,) { e,.printStac09race() ! ! !

Fntuk mengetahui lebih banyak lagi tentang mage H utility, silahkan baca javadoc class ini.

*ocket
Socket adalah satu ujung dari komunikasi dua arah antara dua buah aplikasi yang berjalan di lingkungan jaringan. $lass Socket digunakan untuk merepresentasikan koneksi antara apliksi client dan server. ,ackage java.net menyediakan dua buah class / Socket dan ServerSocket yang mengimplementasikan client dan server. (ita sudah sedikit melihat bagaimana socket beraksi, yaitu pada saat menggunakan F-.$onnection di bab sebelumnya untuk mengambil isi halaman yahoo.com, di dalam class F-.$onnection terdapat implementasi socket client untuk menghubungi yahoo.com dan mengambil halamanya le"at protokol +TT, . Socket adalah jantung dari aplikasi net"ork, setiap kali kita menghubungi aplikasi yang berada di server 9 "orkstation berbeda kita harus menggunakan socket ini, seperti koneksi ke database, koneksi ke server three tier dan sebagainya. (omunikasi socket harus menggunakan protokol tertentu untuk mengatur bagaimana mekanisme komunikasi antara dua buah "orkstation. ,rotokol bisa dianalogikan dalam proses komunikasi dua orang manusia, kalau ingin berkomunikasi kita harus memanggil orang tersebut untuk mendapatkan perhatianya, kemudian menunggu apakah orang ini bersedia berkomunikasi dengan kita atau tidak, setelah keduanya sepakat berkomunikasi maka "ajah dan mata saling berhadapan untuk menandakan bah"a proses komunikasi bisa dilanjutkan, setelah itu percakapan terjadi hingga keduanya sepakat untuk mengakhiri percakapan dan saling memalingkan muka. ,rotokol yang akan kita gunakan dalam contoh kita kali ini adalai T$, 3Transmission $ontrol ,rotocol5 yang sangat terkenal. ,rotokol ini menyediakan mekanisme komunikasi point-to-point yang biasa digunakan dalam arsitektur client-server. nternet yang menggunakan protokol +TT, untuk menampilkan halaman "eb juga menggunakan protokol T$, sebagai mekanisme transfer data antara client 3bro"ser5 dan server 3"ebserver, "ebsite5. $ontoh aplikasi yang akan kita buat sangat sederhana, yaitu aplikasi ping-pong. Server akan berjalan terlebih dahulu, membuka port tertentu dan menunggu client mengirim data ping, setelah ping diterima maka server akan mengirim balik data pong untuk diterima client. (ode server sangat sederhana, langkah-langkah yang harus dilakukan oleh server adalah

sebagai berikut / ). %. 7. <. 4. Membuka ServerSocket !erusaha menerima client membuat reader dan "riter untuk menerima dan mengirim data ke client dalam sebuah loop akan membaca data yang dikirim client (alau ada data yang dikirim client segera membalas dengan mengirim ,ong ke client

(ode untuk Server / import #ava.io.L import #ava.net.L public class 4ing4ongServer { public static void main(String[] args) { try { CC%. bu0a server soc0et ServerSoc0et server 7 ne8 ServerSoc0et(5555) System.out.println(*Server ready. ;istening in port 5555*) CC). berusa.a menerima client Soc0et clientSoc0et 7 server.accept() System.out.println(*Donnection /rom client is e,cepted*) CC1. membuat reader dan 8riter untu0 menerima dan mengirim data 0e client >u//eredWriter out 7 ne8 >u//eredWriter( ne8 AutputStreamWriter(clientSoc0et.getAutputStream())) >u//ered6eader in 7 ne8 >u//ered6eader( ne8 =nputStream6eader(clientSoc0et.get=nputStream())) String input;ine 7 null CC5. dalam sebua. loop a0an membaca data yang di0irim client 8.ile((input;ine 7 in.read;ine())!7null){ System.out.println(*6ecieved * E input;ine E * /rom client*) CCR. Kalau ada data yang di0irim client segera membalas dengan mengirim CC 4ong 0e client out.8rite(*4ongOn*) System.out.println(*Send 4ong to client*) out./lus.() ! ! catc. (=A@,ception e,) { e,.printStac09race() ! ! ! (ode untuk server ini harus dijalankan terlebih dahulu sebelum client dijalankan. $lient akan melakukan beberapa langkah berikut ini ketika berkomunikasi dengan server / ). %. 7. <. 4. Membuat client socket sekaligus menghubungi server Membuat reader dan "riter untuk membaca dan menulis data ke server Dalam sebuah loop, kirim data ke server Dalam loop yang sama berusaha terima data dari server Dalam loop tersebut lakukan ) detik pause agar output bisa terlihat bagus

(ode implementasinya sebagai berikut / import #ava.io.L import #ava.net.L public class 4ing4ongDlient {

public static void main(String[] args) { try { CC%. Bembuat client soc0et se0aligus meng.ubungi server Soc0et clientSoc0et 7 ne8 Soc0et(*local.ost*+ 5555) System.out.println(*client 0one0 to server local.ost35555*) CC). Bembuat reader dan 8riter untu0 membaca dan menulis data 0e server >u//eredWriter out 7 ne8 >u//eredWriter( ne8 AutputStreamWriter(clientSoc0et.getAutputStream())) >u//ered6eader in 7 ne8 >u//ered6eader( ne8 =nputStream6eader(clientSoc0et.get=nputStream())) do { CC1. :alam sebua. loop+ 0irim data 0e server out.8rite(*4ingOn*) System.out.println(*Send ping to server*) out./lus.() CC5. :alam loop yang sama berusa.a terima data dari server String input;ine 7 in.read;ine() System.out.println(*6ecieved * E input;ine E * /rom server*) CCR. :alam loop tersebut la0u0an % deti0 pause agar output bisa bagus 9.read.sleep(%''') ! 8.ile (true) CCla0u0an terus menerus ! catc. (Gn0no8nHost@,ception e,) { e,.printStac09race() ! catc. (=A@,ception e,) { e,.printStac09race() ! catc. (=nterrupted@,ception e,) { e,.printStac09race() ! !

Selanjutnya compile dan jalankan server terlebih dahulu " #avac 4ing4ongServer.#ava " #ava 4ing4ongServer Server ready. ;istening in port 5555 Donnection /rom client is e,cepted 6ecieved 4ing /rom client Send 4ong to client 6ecieved 4ing /rom client . . . Hutput di baris pertama dan kedua akan segera muncul setelah server dijalankan, baris berikutnya akan muncul setelah client berjalan dan komunikasi client-server terjadi. " #avac 4ing4ongDlient.#ava " #ava 4ing4ongDlient client 0one0 to server local.ost35555 Send ping to server 6ecieved 4ong /rom server Send ping to server 6ecieved 4ong /rom server . . Sampai di sini, dasar-dasar java fundamental sudah kita pelajari dengan baik. (alau masih banyak hal-hal yang belum dipahami silahkan baca ulang bab ini atau rujuk ke buku tentang java fundamental yang lebih detail seperti Thinking in Java karya !ruce Mckel.

Java 6 .$date
#eel of Java
Java pertama dibuat dan dikembangkan oleh Sun Microsystems untuk diimplementasikan dalam embeded sistem seperti perangkat elektronik sehari-hari. ,ada saat proses perancangan, java didesain untuk menjadi Eblue collar languageG atau bahasa pemrograman untuk pekerjaan sehari-hari, bukanya bahasa canggih untuk riset ,hd. Fntuk mencapai tujuan tersebut, dibuatlah konsep Efeel-of-javaG, konsep ini berlandaskan kesederhanaan dan kemudahan dibaca. (onsep ini memudahkan programmer dari berbagai macam background merasa mudah belajar bahasa java. Sintaks java dibuat semirip mungkin dengan $ dan $QQ, bahasa paling populer saat itu. !ahkan beberapa konsep HH, dari $QQ yang dirasa menyulitkan dihilangkan dari feature java, misalnya operator overloading dan multiple inheritance. Java juga me"arisi konsep static language dari $9$QQ. Static language me"ajibkan setiap variabel harus dide?nisikan terlebih dahulu sebelum diinisialisasi. (onsep ini memudahkan compiler untuk memeriksa statement java, sehingga error operasi variabel dapat ditemukan pada saat compile. !erbeda dengan dynamic language seperti ruby dan ,+, , semua variabel tidak perlu dide?nisikan dan kita bisa memasukkan tipe data apapun ke dalam variabel tersebut. (alau ada error dalam operasi variabel, error tersebut akan terdeteksi ketika program dijalankan. *eature (esederhanaan dan kemudahan dibaca mempunyai implikasi bahasa Java sangat verbose, kode yang diketik relatif lebih banyak dari bahasa pemrograman lain. +al inilah yang banyak dikeluhkan programmer java, sehinga Sun memutuskan untuk membuat perubahan terhadap bahasa java pada java versi 4. ,erubahan tersebut antara lain/ Mnhanced for loop :utoboLing9FnboLing Static mport @arargs TypeSafe Mnum Kenerics :nnotation ,erubahan di atas semuanya dimaksudkan untuk mengurangi kode program yang harus ditulis programmer tanpa mengurangi semangat kesederhanaan java. Mari kita bahas satu per satu dari yang paling mudah.

$n*an&ed for +oop


4or Loo$ *e"elum Java 6
terasi dalam sintaks bahasa java ada tiga bentuk/ "hile, do-"hile dan for. terasi secara umum digunakan untuk melakukan satu tugas tertentu secara berulang-ulang. Salah satu kegunaan dari iterasi adalah mengambil satu-satu nilai dari sebuah kumpulan data. (umpulan data dalam java bisa dikategorikan tiga/ array, $ollection dan Map. :rray adalah kumpulan data sejenis yang panjangnya tetap, setiap data diletakkan secara berurutan berdasarkan indeL. $ara paling laBim untuk mengambil satu per-satu data dari array adalah menggunakan suatu variabel indeL yang dimulai dari & kemudian diiterasi hingga n-). !erikut ini adalah contoh kodenya / String[] arr 7 {*a*+*b*+*c*! /or(int id,7' id,Tarr.lengt. id,EE){ System.out.println(*current value* E arr[id,]) ! bandingkan kode di atas dengan kode yang sama untuk ,+,/ "arr 7 array(*a*+*b*+*c*!)

/oreac.("val in "arr) ec.o "val ! (ode ,+, mempunyai jumlah kode lebih sedikit dan lebih sederhana. $ollection dalam java mempunyai peran yang sangat penting dalam aplikasi, karena kita bisa mempunyai kumpulan data dengan behaviour berbeda hanya dengan memilih class $ollection yang tepat, tidak perlu membuat algoritma sendiri hanya untuk melakukan sorting data. 0amun untuk mengambil data dari collection kita harus menulis kode yang sedikit lebih rumit dibandingkan dengan array, berikut ini contohnya/ ;ist lists 7 ne8 Irray;ist() lists.add(*a*) lists.add(*b*) =terator iterator 7 lists.iterator() 8.ile(iterator..as<e,t()){ String current 7 (String) iterator.ne,t() System.out.println(*current value 3* E current) ! Terlihat kodenya cukup banyak, karena kita harus membuat variabel bertipe terator hanya untuk mengambil nilai dari $ollection. Map adalah bentuk kumpulan data yang mempunyai pasangan key-value. (ey dalam Map berfungsi sebagai indeL yang mempunyai pasangan @alue. Sebelum Java 4, cara mengakses setiap elemen dalam Map cukup rumit, berikut ini contohnya / Bap maps 7 ne8 Has.Bap() maps.put(*6p*+ *6upia.*) maps.put(*"*+ *GS :ollar*) =terator i 7 maps.0eySet().iterator() 8.ile(i..as<e,t()){ String 0ey 7 (String) i.ne,t() System.out.println(*Key 3 * E 0ey) System.out.println(* value 3* E maps.get(0ey)) ! (ita harus mengambil dahulu daftar (ey dari map, kemudian melakukan iterasi satu-satu terhadap (ey dan dengan menggunakan key tersebut baru bisa diambil pasangan valuenya.

4or Loo$ di Java 6


!entuk penulisan for loop di atas cukup merepotkan dan dibandingkan dengan bahasa lain sudah ketinggalan jaman. Hleh karena itu diperlukan perubahan sintaks penulisan for loop agar proses pengambilan nilai dari kumpulan data menjadi lebih sederhana dan ringkas. *or loop untuk mengambil nilai dari array menjadi seperti berikut ini/ String[] arr 7 {*a*+*b*+*c*! /or(String current 3 arr){ System.out.println(*current value* E current) ! (ode di atas menunjukkan bah"a kita tidak perlu lagi membuat variabel indeL untuk mengambil satu per satu isi dari array. Setiap kali for dilaksanakan, maka elemen yang sedang aktif akan disalin nilainya ke variabel current. !entuk for loop untuk $ollection sama persis dengan :rray di atas. Tidak lagi diperlukan terator untuk mengambil satu per satu elemen dari collection/ DollectionTStringV lists 7 ne8 Irray;istTStringV() lists.add(*a*) lists.add(*b*) /or(String current 3 lists){

System.out.println(*current value 3* E current) ! Sintaks untuk mengakses setiap pasangan key-value juga menjadi lebih ringkas / BapTString+StringV maps 7 ne8 Has.BapTString+StringV() maps.put(*6p*+ *6upia.*) maps.put(*"*+ *GS :ollar*) /or(String 0ey 3 maps.0eySet()){ System.out.println(*Key 3 * E 0ey) System.out.println(* value 3* E maps.get(0ey)) ! ,erbaikan for loop ini pada dasarnya tidak mengubah sintaks java secara drastis, yang terjadi adalah sebelum kode di atas dikompilasi menjadi ?le class, ada satu langkah untuk merubah kode di atas menjadi bentuk yang lama.

Autobo%in!(,nbo%in!
Primiti dan 'ra$$er
Java dibuat pada pertengahan dekade 1&-an, pada "aktu itu memory -:M masih mahal. :rsitek Java memutuskan untuk tetap memasukkan tipe data primitif dengan alasan menghemat memory. Tipe data primitif hanya mempunyai nilai tunggal tanpa mempunyai method, sehingga membutuhkan kapasitas memory yang lebih kecil dibanding dengan object. Tipe data ,rimitif mempunyai class padananya yang disebut dengan #rapper class yang menyediakan method utility untuk melakukan convert dari satu tipe ke tipe yang lain, misalnya mengkonvert data dari tipe int menjadi double. !erikut ini adalah tabel tipe data primitif dan "rappernya/
int double Uoat short char byte boolean long nteger Double *loat Short $haracter !yte !oolean .ong

Dalam banyak kasus terkadang kita perlu melakukan convert dari nilai primitif ke nilai "rappernya atau sebaliknya, berikut ini contohnya / int a 7 %' =nteger b 7 =nteger.valueA/(a) =nteger c 7 ne8 =nteger(a) int d 7 c.intPalue() kode di atas sangat merepotkan dan tidak ada gunanya. :utoboLing9FnboLing memberikan kemudahan dengan menghilangkan ke"ajiban kita untuk menulis kode convert dari primitif ke "rapper atau sebaliknya, dengan inboLing9outoboLing kode di atas akan menjadi / int a 7 %' =nteger b 7 a =nteger c 7 a int d 7 c Seperti halnya enhaced for loop, inboLing9outoboLing dilaksanakan pada level compiler, sebelum kode dirubah menjadi .class, compiler akan merubah kode tersebut ke bentul lamanya. +al ini akan memberikan beberapa konsekuensi, perhatikan kode di ba"ah ini/

=nteger a 7 null int b 7 a kode di baris kedua, ada proses perubahan dari "rapper ke primitif, sebenarnya kode tersebut akan diubah ke bentuk lama sebelum dicompile. 0ilai dari variabel a adalah null, ketika akan dirubah ke bentuk primitif, a akan memanggi method int@alue35 dari class nteger, pemanggilan ini menyebabkan error 0ull,ointerMLception ketika kode di atas dijalankan. (ita harus hati-hati menggunakan fasilitas ini untuk menghindari error 0ull,ointerMLception.

Stati& Import
.tility Class
Sering kita menjumpai jenis class yang disebut Ftility $lass, class ini hanya berisi static method, contohnya adalah class Math dan :ssert. Setiap kali kita akan memanggil method dari class utility ini, kita harus menuliskan nama classnya berulang-ulang. Jika kita bekerja intensive dengan method dalam class Math, kode program kita terlihat tidak rapi, berikut ini contohnya/ :ouble result 7 Bat..po8(Bat..cos(%N')+1) C) Dengan menggunakan static import, kita tidak harus menuliskan nama classnya jika akan mengunakan method atau variabel static. Sintaks penulisan static import / static import #ava.lang.Bat..po8 static import #ava.lang.Bat..cos kita juga bisa menggunakan "ildcard 3Y5 untuk mengimport semua static member dalam class tersebut. static import #ava.lang.Bat..L Setelah static import dide?nisikan, kode untuk memanggil method po" dan cos dari class Math menjadi lebih sederhana, seperti di ba"ah ini/ :ouble result 7 po8(cos(%N')+1) C)

Varar!s
4ungsi Dengan Jumlah Parameter &idak &eta$
:cap kali kita membutuhkan jumlah parameter yang tidak tetap untuk sebuah method tertentu. $ara yang paling laBim dilakukan adalah dengan membuat parameter bertipe array atau collection. $ara ini tidak terlalu rumit, hanya saja kita terkadang harus membuat array atau collection padahal nilai parameternya hanya satu. $ontohnya seperti ini / public void printIll(String[] array){ /or(String curr 3 array){ System.out.println(curr) ! ! (ode untuk memanggil fungsi di atas / String[] arr 7 ne8 String[%] arr['] 7 *a* printIll(arr) @arargs mengijinkan method Java mempunyai jumlah argumen tidak tetap, artinya kita bisa memasukkan jumlah parameter semau kita pada kode pemanggilan method. Mari kita implementasikan kembali method print:ll di atas menggunakan fasilitas varargs/ public void printIll(String... array){ /or(String curr 3 array){

System.out.println(curr) ! !

Sekarang kode untuk memanggil fungsi di atas menjadi lebih sederhana / printIll(*a*) printIll(*a*+*b*+*c*)

-ypeSafe $num
&i$e Data +num
Java tidak mengenal tipe data enum seperti halnya pada $9$QQ, biasanya tipe data enum dide?nisikan sebagai variabel konstant seperti di ba"ah ini / public static /inal ]@<=S(K@;IB=<(;IK=(;IK= 7 ' public static /inal ]@<=S(K@;IB=<(4@6@B4GI< 7 % ,ola ini mempunyai banyak kelemahan karena beberapa alasan, antara lain/ ). Tidak TypeSafe d karena tipenya hanya berupa int, kita bisa saja memasukkan nilai int apapun ketika kita memerlukan data jenis kelamin, atau menambahkan dua jenis kelamin, suatu operasi yang nyaris tidak logis. Tidak mempunyai namespace d (ita harus secara manual memberikan a"alan terhadap variabel enum agar tidak tertukar dengan variabel yang lainya. Mudah -usak d Misalnya suatu saat tanpa sengaja ada yang merubah nilai int dari variabel tersebut, maka integritas data dengan data yang ada di dalam database dengan sendirinya akan ikut berubah. 0ilai yang divetak tidak informatif d Setelah nilai Jenis kelamin dimasukkan ke dalam database, nilai yang dimasukkan hanyalah & atau ). nformasi tentang Jenis kelaminya tidak ada.

%. 7.

<.

Java 4 mendukung TypeSafe enum langsung di sisi sintaksnya. De?nisi enum di atas bisa dengan mudah diganti menjadi / public enum ]enisKelamin{;IK=(;IK=+4@6@B4GI<! #alaupun tampilan enum di atas mirip-mirip dengan enum di $9$QQ, enum di Java 4 mempunyai lebih banyak feature. Mnum di atas adalah class java, yang bisa mempunyai method dan property. Mnum juga merupakan implementasi dari class Hbject, yang $omparable dan SerialiBable. :plikasi berbasis database biasanya mengimplentasikan enum Jenis kelamin dengan mempunyai dua jenis data, data pertama adalah simbol jenis kelamin, biasanya . dan , . Data kedua adalah nama lengkap dari jenis kelamin tersebut, biasanya digunakan sebagai pilihan dalam combo boL. (ita bisa mende?niskan ulang enum Jenis(elamin menjadi seperti berikut ini / public enum ]enisKelamin { ;IK=(;IK=(*;*+*;a0i$la0i*)+ 4@6@B4GI<(*4*+*4erempuan*) private String symbol private String name ]enisKelamin(String symbol+ String name){ t.is.symbol 7 symbol t.is.name 7 name ! public String get<ame() { return name ! ^Averride public String toString() {

! !

return symbol

Mnum juga bisa digunakan dalam clausa s"itch seperti di ba"ah ini / s8itc.(#0){ case ]enisKelamin.;IK=(;IK=3 return *suaranya soprano* case ]enisKelamin.4@6@B4GI<3 return *suaranya tenor* ! Setiap Mnum mempunyai nilai ordinal, nilai tersebut adalah nilai urut enum, urutan pertama mempunyai nilai & dan seterusnya. (ita bisa mendapatkan semua nilai Mnum secara programatik tanpa harus menyebutkan satusatu, contohnya/ ]enisKelamin[] #0s 7 ]enisKelamin.values() /or(]enisKelain #0 3 #0s){ System.out.println(#0) !

)eneri&s
&i$e Data di Dalam Collection
(etika kita akan mengambil elemen dari dalam $ollection, kita memerlukan proses casting ke tipe data sebenarnya. ,roses casting ini diperlukan karena kita tidak bisa mende?niskan tipe data apa yang ada di dalam collection, sehingga semua yang masuk ke dalam collection dianggap bertipe Hbject. Masalah muncul kalau kita tidak tahu-menahu tentang apa isi dari collection tersebut, jika ternyata isi dalam collection tersebut beraneka ragam tipe data, kode kita akan mengalami error $lass$astMLception. $ompiler java tidak dapat mendeteksi potensi kesalahan ini pada saat compile. !erikut ini contohnya / Dollection lists 7 ne8 Irra;ist() lists.add(*a*) lists.add(%'') =terator iterator 7 lists.iterator() /or( iterator..as<e,t() ){ String current 7 (String) iterator.ne,t() ! (ode di atas akan menyebabkan error $lass$astMLception, karena dalam collection lists, kita memasukkan EaG yang bertipe String dan )&& yang bertipe nteger. ,ada saat kita mengambil data dari lists dan melakukan cast ke tipe String terhadap niai )&&, error $lass$astMLception akan terjadi. Kenerics dapat digunakan untuk mende?niskan tipe data apa yang ada di dalam collection, kode di atas dapat dimodi?kasi menjadi seperti di ba"ah ini/ DollectionTStringV lists 7 ne8 Irra;istTStringV() lists.add(*a*) lists.add(%'') /or(String s3 lists){ String current 7 iterator.ne,t() ! pada baris lists.add3)&&5D, compiler akan memberikan keterangan error bah"a nilai yang dmasukkan ke dalam collection lists mempunyai tipe data selain String.

,engecekan tipe data apa yang ada di dalam $ollection sekarang terjadi pada saat kompilasi, bukan pada saat jalanya aplikasi, dengan begitu kesalahan bisa ditemukan lebih cepat. Kenerics bisa digunakan untuk melakukan banyak hal, namun sebagai programmer kita tidak harus memikirkan secara detail tentang penggunaan generics, kita bertindaks sebagai pemakai library, bukan library designer.

Annotations
Metadata
!anyak sekali :, dalam java yang memerlukan kon?gurasi yang terkadang diletakkan dalam ?le terpisah. ,ola ini sangat memberatkan programmer karena ada tambahan ?le lagi yang harus dimantain. :, lainnya mengharuskan kita meng-eLtend class tertentu atau membuat nama method dengan pola tertentu. :nnotation memberikan alternatif cara menambahkan informasi terhadap ?le java. nformasi tambahan ini disebut dengan metadata. Metadata digunakan oleh :, atau DM sebagai informasi tambahan yang digunakan sebagai patokan untuk memperlakukan ?le java tersebut dengan tindakan tertentu. Junit 7.L mengharuskan ?le yang akan ditest memenuhi beberapa aturan, pertama harus mengeLtend class Test$ase, kemudian setiap method yang akan ditest harus dia"ali dengan kata test, berikut ini contohnya/ public class 4erson9est e,tends 9estDase { public 4erson9est(String test<ame) { super(test<ame) ! public void testSet@mails() { /ail(t.is test is not actualy created) ! public void testSet@mails() { /ail(t.is test is not actualy created) ! ! Dengan annotation kita bisa menyederhanakan struktur ?le java di atas, dan menghilangkan keharusan untuk melakukan eLtend terhadap ?le tertentu atau memberikan a"alan terhadap method yang harus ditest, berikut ini test yang sama untuk Junit <.L dengan annotation / public class 4erson9est { public 4erson9est() { ! ^9est public void get@mails() { /ail(t.is test is not actualy created) ! ^9est public void set@mails() { /ail(t.is test is not actualy created) ! ! Terlihat bah"a kita menambahkan annotation 8Test di atas method yang akan ditest. Junit menggunakan informasi 8Test ini sebagai penanda bah"a method yang akan ditest. $ontoh annotation lain yang banyak digunakan adalah 8Deprecated, jika annotation ini diletakkan di atas method, maka akan digunakan oleh java compiler dan DM untuk memberitahukan kepada pemanggil dari method tersebut bah"a method yang dipanggil kemungkinan besar akan dihilangkan pada versi berikutnya. +al ini membantu programmer

menghindari error di masa depan. Menambahkan annotation 8Hverride di atas method yang di-override juga merupakan praktek yang baik. $ompiler akan memeriksa method yang ditandai dengan 8Hverride apakah sudah dengan benar mengoverride method kepunyaan parentnya. $ontohnya, misalkan kita akan berniat mengoverride method e\uals dari class Hbject seperti di ba"ah ini / public boolean e\uals(){ return true ! ternyata kode method e\uals di atas tidak memenuhi struktur method e\uals yang seharusnya mempunyai parameter Hbject. Java compiler tidak akan berkata apa-apa dan tidak akan memperingatkan kita bah"a ada kesalahan dalam proses override tersetbut. ^Averride public boolean e\uals(){ return true ! Dengan menggunakan 8Hverride kita memberitahukan java compiler bah"a kita berniat mengoverride method e\uals, dan jika terdapat kesalahan dalam proses overridenya, compiler akan memberikan peringatan Emethod does not override or implement a method from a supertype G. Masih banyak kasus lain dimana annotation akan memudahkan programmer mengimplentasikan aturan tertentu dari :, yang digunakan. Misalnya hanya dengan menambahkan keterangan 8Stateless terhadap class tertentu, maka kita sudah membuat Stateless session bean. +ibernate versi dahulu me"ajibkan kita untuk membuat ?le hbm.Lml untuk setiap class Mntity, sekarang kita bisa meletakkan informasi mapping hibernate dalam ?le java-nya dengan menggunakan annotation.

Kesimpulan
Java 4 .anguage Mnhancement ditujukan utamanya untuk menyederhanakan kode java tanpa menghilangkan kemudahanya untuk dibaca. ,erubahan sintaks tersebut tidak serta merta merupakan perubahan signi?kan terhadap sintaks java secara radikal, tetapi hanya perubahan kecil dalam compiler, dimana da langkah tambahan untuk merubah sintaks bentuk baru ke dalam bentuk yang lama sebelum ?le java tersebut benar-benar dicompile menjadi ?le class. *eature generics dan annotation ternyata memba"a perubahan yang sangat signi?kan terhadap banyak sekali :, . Dengan menggunakan kedua feature ini :, menjadi lebih mudah digunakan dan lebih sedikit ?le kon?gurasi yang diperlukan untuk menjelaskan beberapa informasi dalam ?le java. ,ada akhirnya bahasa java menjadi lebih mudah digunakan dan lebih ringkas dibandingkan dengan versi sebelumnya.

"A5IA@ 2 @84"8A@0

Instalasi
,roses instalasi 0et!eans sangat sederhana. ,ertama do"nload dahulu installer 0et!eans dari "ebsite netbeans.org http/99netbeans.org9do"nloads9indeL.html +alaman do"nload di netbeans.org terlihat seperti di ba"ah ini /

,ilih paket yang sesuai dengan kebutuhan anda, untuk tujuan buku ini cukup pilih paket java SM yang ukuran do"nloadnya hanya sekitar <4 M!. Setelah do"nload selesai, double click ?le instalasi. Selanjutnya tinggal pilih neLt atau yes dan instalasi selesai.

embuat 'ro.e&t
0et!eans akan menampilkan halaman utama ketika pertama kali dijalankan. +alaman utama 0et!eans menampilkan link-link yang cukup bermanfaat, seperti blog dari 0et!eans evangelist, tutorial dari netbeans.org hingga video demo feature-feature terbaru 0et!eans. Fntuk membuat project pilih menu *ile-C0e" ,roject. sikan nama project dan folder dimana project akan disimpan. Setelah project selesai dibuat, tampilan di 0et!eans seperti berikut ini /

Source ,ackage menampilkan source code ?le java dan ?le-?le kon?gurasi yang nanti diperlukan. Test ,ackage menampilkan semua ?le source code Junit test, .ibraries menampilkan librarylibrary yang diperlukan aplikasi, sedangkan Test .ibraries menampilkan library yang diperlukan hanya untuk Junit test saja. (alau kita buka project 0et!eans di atas di ?le eLplorer, akan terlihat struktur folder project 0et!eans seperti di ba"ah ini /

*older nbproject berisi ?le-?le yang digenerate oleh 0et!eans, sebaiknya ?le-?le di dalam folder ini tidak diubah secara manual, biarkan saja seperti apa adanya. *older build adalah dua folder yang dibuat 0et!eans untuk menyimpan ?le hasil kompilasi java compiler, isinya berupa ?le .class. Sedangkan folder dist berisi ?le jar dari aplikasi yang kita buat beserta library yang diperlukan. Source code aplikasi akan diletakkan dalam folder src. Pang terakhir adalah folder test yang akan digunakan untuk menyimpan ?le test JFnit. *ile build.Lml adalah script ant yang digunakan untuk melakukan berbagai macam hal di 0et!eans. Setiap kali kita melakukan aksi terhadap project, semisal menjalankan aplikasi, 0et!eans akan menjalankan script dalam build.Lml. Jika anda ingin belajar lebih lanjut tentang ant, skill yang amat sangat berguna, silahkan baca tutorial ant dari Mndy Muhardin http/99endy.artivisi.com9do"nloads9"ritings9Tutorial-:nt.pdf (adang kala kita dihadapkan pada masalah dimana struktur project 0et!eans yang rusak karena suatu hal. Jangan panik, cara pemecahanya sangatlah mudah. ,ertama buat project 0et!eans yang baru, kemudian cukup timpa folder src project baru dengan folder src project yang rusak, kemudian tambahkan library yang anda perlukan.

enamba*kan +ibrary
.ibrary pasti diperlukan dalam pembuatan aplikasi java. Semisal komponen Jcalendar untuk menampilkan tanggal yang tidak ada di dalam standard J-M, atau menambahkan library Spring dan +ibernate. .ibrary Jcalendar adalah library F yang bisa didrag and drop ke visual editor, sedangkan library Spring bukan F library. Jcalendar dapat ditambahkan di pallete 0et!eans sehingga bisa didrag and drop ke visual editor. Menambahkan library F ke pallete sangat mudah. Do"nload component Jcalendar dari "ebsite berikut ini / http/99""".toedter.com9do"nload9jcalendar-).7.7.Bip

(emudian eLtract ?le Bip, di dalam folder lib ada ?le jcalendar-).7.7.jar. (emudian lanjutkan langkah menambahkan Jcalendar ke pallete dengan memilih menu berikut dari 0et!eans menu bar / Tools [C ,alette Manager [C S"ing9:#T $omponents Menu ini digunakan untuk menampilkan ,alette Manager. Sebelum memasukkan komponen J$alendar, sebaiknya buat dulu kategori baru untuk menampung komponen J$alendar. Tekan tombol O0e" $ategoryO dan masukkan string OJ$alendarO ke dalam input dialog. Di jendela ,alette Manager, tekan tombol Oadd from J:-O, kemudiaan pilih ?le jcalendar).7.%jar yang tadi telah disiapkan. (lik neLt. Setelah itu akan muncul dialog seperti di ba"ah ini.

Setelah proses penambahan Jcalendar selesai, anda bisa melihat komponen-komponen Jcalendar dalam pallete, di bab-bab berikutnya akan dibahas bagaimana menggunakan library ini untuk mengambil input tanggal dari user. Menambahkan library non F ke dalam project langkahnya lebih mudah. Dari project tab, klik kanan node .ibraries, kemudian akan tampil menu seperti di ba"ah ini /

Fntuk menambahlkan library yang disediakan oleh 0et!eans pilih :dd .ibary, kemudian pilih library yang akan ditambahkan, misalnya Spring ata +ibernate. :dd ,roject digunakan untuk menambahkan project lain sebagai library. :dd Jar9folder digunakan untuk menambahkan library jar yang tidak disediakan oleh 0et!eans, misalkan library jcalendar. ,roperties digunakan untuk menampilkan semua library yang telah ditambahkan, bisa juga digunakan untuk menambahkan atau menghapus semua jenis library. :da kalanya library yang diperlukan oleh project 0et!eans tidak dapat ditemukan sehingga membuat project menjadi tidak valid, seperti tampilan di gambar berikut ini. +al ini terjadi kalau tidak sengaja menghapus ?le jar atau mendo"nload project 0et!eans dari internet

sehingga jar yang dibutuhkan tidak ditemukan. $ara mengatasinya tidak susah, buka menu properties di atas, kemudian remove jar yang hilang, ditandai dengan tanda seru, kemudian tambahkan jar yang sesuai.

,raktek yang paling baik dalam mengelola library adalah dengan meletakkan semua jar yang dibutuhkan didalam folder project. !uat sebuah folder di dalam project 0et!eans dan beri nama lib, kemudian letakkan semua jar eLternal yang dibutuhak di dalam folder ini. 0et!eans mampu mengenali folder di dalam project 0et!eans dengan relative path, sehingga kalau project 0et!eans dipindah-pindah ke folder berbeda atau dicopy dari satu komputer ke komputer lain atau dicommit ke code repository seperti subversion, struktur project tidak rusak dan tidak terjadi masalah library hilang seperti gambar di atas.

en!!unakan $ditor
0et!eans mempunyai editor yang sangat bagus, hal ini penting karena sebagian besar "aktu coding kita habiskan menggunakan editor. Mditor 0et!eans mempunyai feature yang sangat lengkap sehingga sangat membantu programmer meningkatkan produkti?tasnya. Tampilan editor 0et!eans seperti di ba"ah ini /

!agian atas adalah nama ?le, kemudian di ba"ahnya ada editor toolbar yang bisa digunakan untuk melakukan berbagai macam aksi terhadap jendela editor. *eature pertama yang paling dicari user adalah code completion atau autocomplete. *eature ini dapat dipanggil dengan short cut :.TQS,:$M. (etik beberapa huruf pertama dari apapun yang anda ingin ketik, kemudian tekan :.TQS,:$M, misalnya ketik Str kemudian tekan :.TQS,:$M. Menu autocomplete akan menampilkan kemungkinan yang dimaksud dengan Str, tampilanya seperti di ba"ah ini /

Di bagian ba"ah terdapat daftar class yang dia"ali dengan Str, kemudian dibagian atas terdapat javadoc dari class yang sedang terpilih. +al ini sangat bermanfaat jika sedang bekerja dengan library yang masih belum familiar. Jika 0et!eans anda belum menampilkan javadoc, anda bisa mendo"nload javadoc dari link berikut ini / http/99java.sun.com9javase9do"nloads9indeL.jspTdocs (emudian menambahkan ke setting 0et!eans secara manual. !uka menu Tools [C Java ,latform, akan tampil dialog seperti di ba"ah ini. ,indah ke tab Java Doc kemudian tambahkan ?le Bip yang sudah dido"nload dari link di atas.

*eature berikutnya yang sangat berguna adalah fasilitas navigasi di dalam source code. *eature ini sangat berguna untuk menuju ke deklarasi dari class ataupun variabel. :rahkan pointer mouse ke atas deklarasi class atau variabel kemudian tekan $T-. Q $lick secara bersamaan. Jika source code dari sebuah class tersedia, maka class yang dimaksud akan ditampilkan. Misalnya anda ingin melihat source code class String, tetapi ternyata source code tersebut tidak tersedia di instalasi netbeans. :nda bisa menambahkan secara manual dengan mendo"nload source code JD( dari link berikut ini / http/99do"nload.java.net9openjdk9jdk;9 MLtract ?le tar.gB kemudian buka menu Tools [C Java ,latform yang akan membuka dialog seperti di atas. !uka tab source code dan tambahkan folder dimana anda mengekstract ?le hasil do"nload link di atas berada. Jika ingin menambahkan source code ke jar selain JD( langkah-langkahnya sedikit lebih panjang. .angkah pertama adalah membuat library, pilih menu Tools -C .ibrary kemudian tekan tombol 0e" .ibrary, beri nama librarynya, misalkan Jcalendar. (emudian tambahkan jar di tab $lasspath, source code di tab Sources dan javadoc di tab Javadoc seperti gambar di ba"ah ini

*eature berikutnya yang cukup membantu dalam menulis kode adalah auto?L. ,erhatikan gambar di ba"ah ini, setiap kali ada error dalam kode yang sedang ditulis di editor, akan ada icon ber"arna merah dengan tanda seru di sebelah kiri nomor baris di mana error terjadi. Jika 0et!eans tahu bagaimana memperbaiki kode yang error ini maka akan ada icon tambahan berupa lampu bolham "arna kuning. (lik lampu bolham akan keluar menu untuk memilih alternatif memperbaiki error, misalnya menambahkan import untuk class atau membuat statement try9catch.

Sebagai contoh, lihat gambar di di atas, ada statement untuk membuat instance dari J$alendar, ketika lampu bolham diklik akan ada menu untuk mengimport class Jcalendar, ketika menu tersebut diklik maka akan ada tambahan statement import class J$alendar. Shortcut untuk memanggil menu auto?L adalah :.T Q M0TM- di baris yang sama dimana icon lampu bolham muncul. con lampu bolham juga bisa dimunculkan "alau tanpa error, caranya dengan mengeblok beberapa baris kode, lampu bolham kuning akan keluar di baris terakhir kode yang diblok. (lik atau tekan :.T Q M0TM- di baris munculnya bolham kuning, maka akan tampil berbagai macam alternatif kode yang akan melingkupi baris yang diblok. Misalnya pilih menu paling atas, maka statement for akan diletakkan mulai dari baris %& hingga setelah baris %). Silahkan coba-coba menggunakan pilihan yang ada untuk mengetahui kode apa yang akan ditambahkan ketika menu-menu tersebut dipilih.

0et!eans Mditor menyediakan feature untuk mengenerate kode-kode yang sering diperlukan, tekan :.T Q 0SM-T atau klik kanan di Mditor kemudian pilih menu nsert $ode. Menu akan muncul dengan beberapa pilihan seperti di gambar di ba"ah ini.

Mari kita bahas satu persatu menu yang ada di atas. Ketter and Setter digunakan untuk

mengenerate method yang akan mengencapsulasi property id dan total. Tekan menunya kemudian akan muncul dialog seperti gambar di ba"ah ini, pilih checkboLnya dan tekan generate. Method get d, set d, getTotal dan setTotal akan digenerate oleh netbeans.

$onstructor digunakan untuk mengenerate constructor dari class ,enjualan. Misalnya kita pilih % buah property id dan total sebagai parameter constructor, maka akan digenerate kode seperti di ba"ah ini / public 4en#ualan(String id+ >ig:ecimal total) { t.is.id 7 id t.is.total 7 total ! e\uals dan hash$ode digunakan untuk mengenerate method yang akan mengoverride kedua method tersebut dari class Hbject. (egunaan fungsi e\uals adalah membandingkan antara dua buah object apakah secara ElogicG sama dengan object lainya. Fntuk menentukan dua buah object dari class ,enjualan apakah sama atau tidak digunakan property id, asal dua buah object tersebut mempunyai id yang sama maka dianggap sama. (onsep e\uals dan hash$ode sudah dijelaskan di bagian Java *undamental, jadi tidak dibahas lagi secara mendetail di sini. ,embahasan hanya terbatas bagaimana caranya membuat method e\uals dan hash$ode yang baik dan bug free. Menulis sendiri e\uals maupun hash$ode tidak dilarang, tapi sebaiknya dihindari, gunakan fasilitas generate e\uals dan hash$ode dari DM. +asil generate e\uals dan hash$ode dari 0et!eans sebagai berikut / ^Averride public boolean e\uals(Ab#ect ob#) { i/ (ob# 77 null) { return /alse ! i/ (getDlass() !7 ob#.getDlass()) { return /alse ! /inal 4en#ualan ot.er 7 (4en#ualan) ob# i/ ((t.is.id 77 null) W (ot.er.id !7 null) 3 !t.is.id.e\uals(ot.er.id)) { return /alse ! return true ! ^Averride public int .as.Dode() { int .as. 7 1 .as. 7 )1 L .as. E (t.is.id !7 null W t.is.id..as.Dode() 3 ') return .as. ! (alau anda melihat di 0et!eans yang anda gunakan tidak ada generate toString, tidak perlu panik, karena memang feature ini baru ada di 0et!eans ;.1. *ungsinya untuk mengenerate method toString agar lebih mudah untuk mencetak nilai suatu object di console atau untuk tujuan logging. (ode hasil generate toString seperti berikut / ^Averride public String toString() {

return *4en#ualan{* E *id7* E id E *total7* E total E Q!Q

*eature lain yang cukup membantu mempercepat coding adalah code tamplate. .ihat gambar di ba"ah ini, gambar tersebut adalah jendela yang menampilkan semua code template yang tersedia secara default dari 0et!eans. $ara menampilkan jendela tersebut dengan memilih menu Tools -C Hption. $ode template sangat membantu mempercepat code dengan membuat shortcut dari kode yang ingin diketik. Misalnya ketik sout kemudian tekan tab, maka akan muncul kode System.out.println35, atau ketik psvm kemudian tab, akan muncul kode deklarasi method main. :nda bisa menambahkan code template untuk mengenerate kode yang anda inginkan atau sering digunakan.

!erikut ini daftar feature dan shortcut lain di editor netbeans yang sering digunakan Menampilkan nomor baris @ie" [C Sho" .ine 0umbers $T-. Q e menghapus baris yang sedang aktif atau semua baris yang sedang dipilih $T-. Q k menebak kata yang pernah muncul berikutnya. !erbeda dengan code completion 3$T-. Q S,:$M5 karena menebak kata ini tidak menampilkan conteLt menu tapi langsung menampilkan kata yang ditebak, sehingga lebih cepat. (alau kata yang ditebak salah, tekan $T-. Q k sekali lagi untuk menampilkan tebakan berikutnya. $T-. Q 9 membuat baris yang sedang aktif atau baris yang sedang dipilih menjadi tidak aktif 3komentar5 $T-. Q T:! berpindah dari satu ?le ke ?le yang lain

$T-. Q i memperbaiki import dengan mengimport class yang belum diimport dan menghapus import yang tidak digunakan $T-. Q o mencari class yang ada dalam project $T-. Q f mencari string dalam class 9 ?le yang sedang aktif di editor $T-. Q S+ *T Q f mencari string dalam semua ?le yang ada dalam project $T-. Q b membuka deklarasi variabel atau class $T-. Q S+ *T Q ,anah ke !a"ah mengkopi satu baris atau satu blok baris ke ba"ah tanpa harus memencet $T-. Q c trus $T-. Q v :.T Q S+ *T Q ,anah ke !a"ah memindahkan satu baris atau satu blok baris ke ba"ah $T-. Q o melakukan pencarian terhadap nama class dan membukanya di editor. !isa menggunakan huruf besar dari setiap kata class untuk pencarian. Misalnya nama classnya *ile nputStream cukup mengetikkan * , di dialog pencarian. $T-. Q S+ *T Q o Mencari ?le di dalam project. !erbeda dengan $T-. Q o yang hanya mencari class saja, perintah ini akan menampilkan semua ?le baik ?le java maupun ?le-?le yang lain. $T-. Q \ menuju ke baris terakhir yang diedit. Tekan $T-. Q \ beberapa kali untuk menuju ke baris-baris yang diedit sebelumnya $T-. Q ) berpindah ke tab project, $T-. Q & berpindah ke tab editor, $T-. Q < berpindah ke tab output.

Masih banyak lagi feature Mditor 0et!eans yang belum dibahas di sini. Shortcut di atas hanya secuil feature yang sering digunakan. (alau ingin melihat secara lengkap shortcut di dalam editor silahkan buka menu Tools [C Hption kemudian buka tab (eymap. !ahkan jika anda terbiasa dengan DM lain semisal eclipse, anda bisa mengganti pro?le shortcut menjadi eclipse. Sekarang anda bisa menggunakan 0et!eans dengan shortcut Mclipse.

en!!unakan Visual Desi!ner


0et!eans dilengkapi dengan @isual editor untuk :#T9S"ing, anda bisa membuat F aplikasi desktop dengan melakukan click and drug. Modul visual editor 0et!eans disebut dengan Matisse. Modul ini dilengkapi sebuah sistem layout yang disebut *ree *orm .ayout. Sistem layout ini khusus dibuat untuk ditulis menggunakan DM, tidak dikode manual dengan tangan. !eberapa netbeaners mengaku pada a"alnya kesulitan menggunakan visual designer 0et!eans karena terbiasa dengan @isual !asic atau Delphi. ,erbedaan utamanya terletak di sistem layouting di 0et!eans yang lebih Ueksibel. (alau sebuah panel diubah ukuranya maka anggota component di dalam panel akan ikut di-arrange sehingga tampilanya menyesuaikan dengan lebar 9 tinggi panel. *eature ini tidak ada di @! yang menggunakan null layout, berapapun ukuran dari panelnya component di dalamnya tidak ikut di-arrage, alias di situ situ saja letaknya. (arena sistem layout inilah visual editor 0et!eans terasa sedikit lebih susah penggunaanya, karena componen akan di-snap agar bisa saling terkait dan saling menyesuaikan kalau ukuran panelnya dirubah. (alau anda tidak suka dengan keadaan ini, anda bisa merubah layout panel ke null layout dan anda akan mendapatkan ErasaG yang sama dengan @! editor.

embuat Visual Component


.angkah pertama menggunakan visual designer adalah membuat visual component yang merupakan child dari $ontainer, misalnya Jframe. (lik kanan di project kemudian pilih ne" ?le dan pilih S"ing KF *orm di list sebelah kiri dan pilih Jframe *orm di sebelah kanan .

(lik tombol neLt dan beri nama class kemudian klik ?nish. :nda akan diba"a ke jendela visual designer 0et!eans. Tampilanya seperti gambar di ba"ah ini. Sebelah kiri adalah tab project, sebelah tengah tab disigner. Sebelah kanan atas adalah pallete dan sebelah kanan ba"ah adalah properties. Sebelah kiri ba"ah ada satu tab namanya inspector, kalau tab ini belum terlihat pilih menu "indo"s [C 0avigator [C nspector untuk menampilkanya. !erpindah dari visual editor dan editor bisa dilakukan dengan mengklik tombol source atau tombol design di bagian atas editor. Di bagian yang sama pula terdapat icon dengan lambang ber"arna hijau yang digunakan untuk menampilkan previe". Sebelah kanan icon previe" terdapat tombol-tombol untuk mengatur aligment component, apakah rata kiri, rata kanan, atas ba"ah atau di tengah-tengah.

/eker.a den!an .endela pallet


Jendela pallet menampilkan komponen-komponen yang bisa digunakan dalam aplikasi java desktop. ,allet dapat ditambah dan dihapus, di bagian sebelumnya sudah dibahas bagaimana menambahkan component baru ke dalam pallet.

/eker.a den!an .endela properties


Jendela ,roperties terdiri dari empat bagian, properties, binding, events dan code. !agian properties berisi property dari component yang sedang dipilih di visual editor. !agian binding memperlihatkan binding antara satu component dengan component lain, proses binding menggunakan frame"ork !eans!inding. !agian event memperlihatkan event apa saja yang diimplementasikan untuk component tersebut, biasanya bagian ini digunakan untuk menghapus event yang tidak digunakan, kenapaZ (arena kode yang digenerate netbeans untuk handle event tidak dapat diedit9dihapus dari editor. !agian code digunakan untuk menyelipkan kode di area yang tidak bisa diedit dari tab editor. Seperti kode yang ingin diselipkan setelah komponen diinstansiasi, karena proses instansiasi component ada dalam method init$omponents yang tidak dapat diedit dari editor, maka kode yang ingin diselipkan bisa dilalukan dari bagian code ini.

/eker.a den!an .endela Inspe&tor


Jendela inspector termasuk dalam jendela yang gunanya untuk bernavigasi. Jendela inspector digunakan untuk bernavigasi dari satu component ke component yang lain, terkadang ada kesulitan untuk memilih komponent, misalnya karena ada di dalam tab component yang berlapis, sehingga untuk memilih component tersebut memerlukan sedikit "aktu lebih banyak.

Debu!!in!
*eature debugging di sebuah DM sangat penting untuk membantu developer mencari masalah atau mengetahui keadaan internal dari aplikasi ketika sedang dijalankan. Dengan fasilitas debugging, aplikasi dapat di pause di tempat tertentu kemudian diperiksa keadaan internalnya, misalnya nilai dari suatu variabel, atau Uo" eksekusi. Mari kita praktekkan proses debugging di 0et!eans. !uat sebuah class, namakan Main.java, kemudian tambahkan kode berikut ini di dalam class Main public class Bain { public static void main(String[] args) { int total 7 ' /or(int i7' iT%'' iEE){ i/(iXR 77 '){ totalE7i ! ! System.out.println(total) ! ! !reak point adalah sebuah tempat di dalam kode program dimana proses debugging akan berhenti. $ara membuat break point sangat gampang, klik bagian kiri editor dimana ada tampilan nomor baris, sehingga muncul kotak ber"arna merah seperti gambar di ba"ah ini/

Setelah breakpoint berhasil dibuat, klik kanan di editor kemudian pilih menu Debug *ile. Mksekusi kode akan berhenti di tempat breakpoint berada dan ditandai dengan panah ber"arna hijau seperti di gambar di ba"ah ini. Di bagian ba"ah 0et!eans terdapat panel variables, di panel ini terdapat semua variables yang terlihat dari break point, ada variabel i, total dan args. (olom di sebelahnya memperlihatkan nilai variabel pada "aktu program berhenti di break point. Fntuk melihat jalanya aplikasi baris per baris, tekan *6 berkali-kali sambil amati perubahan nilai variabel. #atch adalah sebuah statement yang akan dievaluasi dalam proses debugging. #atch bisa mengevaluasi statement, misalnya dalam setiap eksekusi kode, kita ingin melihat apa hasil dari statement / i V 4. $aranya klik kanan di editor dan pilih ne" "atch kemudian ketikkan statement i V 4 di dialog yang muncul. #atch akan ditampilkan di panel yang sama dengan variabel. #atch ditandai dengan icon berlian dan variabel ditandai dengan icon belah ketupat ber"arana hijau.

Di sebelah kiri terdapat panel debugging yang memperlihatkan stack trace, atau urutan pemanggilan fungsi dari Main class hingga breakpoint. $ontoh di atas kita bisa lihat ada icon kotak "arna kuning dengan tulisan Main.main, artinya method main pada class Main sedang dieksekusi pada saat eksekusi kode berhenti di breakpoint. (alau aplikasinya cukup kompleks dan mempunyai banyak class, panel debugger akan memperlihatkan stack trace yang lengkap dari pertama kali kode dieksekusi hingga berhenti di breakpoint. Sangat berguna untuk urutan eksekusi kode dalam stack trace, dengan informasi ini kita bisa mengetahui bagaimana kode terangkai dan bagaimana kaitan antar class pada "aktu eksekusi. $lass apa memanggil class apa dan method apa yang dieksekusi. *6 adalah shortcut untuk step over, artinya eksekusi satu baris ini dilakukan semua kemudian meloncat ke baris berikutnya. (adangkala dalam satu baris eksekusi terdapat beberapa method yang dieksekusi dalam satu rangkaian. (alau ingin melihat eksekusi kode ke dalam method tersebut tekan *' 3step into5, anda akan diba"a ke method yang sedang dieksekusi. (alau mau keluar dari method yang sedang dieksekusi ke method pemanggilnya tekan $T-. Q *' 3step out5.

"A5IA@ 3 AK080 DA4A K8 DA4A"A08

Akses Data"ase dengan JDBC


en!enal JD/C
Java Database $onnectivity adalah :, yang digunakan Java untuk melakukan koneksi dengan aplikasi lain atau dengan berbagai macam database. JD!$ memungkinkan kita untuk membuat aplikasi Java yang melakukan tiga hal/ konek ke sumber data, mengirimkan \uery dan statement ke database, menerima dan mengolah resultset yang diperoleh dari database. JD!$ mempunyai empat komponen / ). JD!$ :, JD!$ :, menyediakan metode akses yang sederhana ke sumber data relational 3-D!MS5 menggunakan pemrograman Java. dengan menggunakan JD!$ :, , kita bisa membuat program yang dapat mengeksekusi SI., menerima hasil -esultSet, dan mengubah data dalam database. JD!$ :, juga mempunyai kemampuan untuk berinteraksi dengan lingkungan terdistribusi dari jenis sumber data yang berbeda-beda. JD!$ :, adalah bagian dari Java ,latform yang disertakan dalam library JD( maupun J-M. JD!$ :, sekarang ini sudah mencapai versi <.& yang disertakan dalan JD( ;.&. JD!$ :, <.& dibagi dalam dua package yaitu / java.s\l dan javaL.s\l. %. JD!$ Driver Manager $lass DriverManager dari JD!$ bertugas untuk mende?sikan object-object yang dapat digunakan untuk melakukan koneksi ke sebuah sumber data. Secara tradisional DriverManager telah menjadi tulang punggung arsitektur JD!$. 7. JD!$ Test Suite JD!$ Test Suite membantu kita untuk mencara driver mana yang cocok digunakan untuk melakukan sebuah koneksi ke sumber data tertentu. Tes yang dilakukan tidak memerlukan resource besar ataupun tes yang komprehensif, namun cukup tes-tes sederhana yang memastikan ?tur-?tur penting JD!$ dapat berjalan dengan lancar. <. JD!$-HD!$ !ridge !rige ini menyediakan fasilitas JD!$ untuk melakukan koneksi ke sumber data menggunakan HD!$ 3Hpen Data!ase $onnectivity5 driver. Sebagai catatan, anda perlu meload driver HD!$ di setiap komputer client untuk dapat menggunakan bridge ini. Sebagai konsekuensinya, cara ini hanya cocok dilakukan di lingkungan intranet dimana isu instalasi tidak menjadi masalah. Dengan keempat komponen yang dipunyainya, JD!$ menjadi tools yang dapat diandalkan untuk melakukan koneksi, mengambil data dan merubah data dari berbagai macam sumber data. Modul ini hanya akan membahas dua komponen pertama dari keempat komponen yang dipunyai oleh JD!$, yaitu JD!$ :, dan DriverManager. Sumber data yang digunakan adalah -elational Database.

Database Driver
JD!$ memerlukan database driver untuk melakukan koneksi ke suatu sumber data. Database driver ini bersifat spesi?k untuk setiap jenis sumber data. Database driver biasanya dibuat oleh pihak pembuat sumber datanya, namun tidak jarang juga komunitas atau pihak ketiga menyediakan database driver untuk sebuah sumber data tertentu. ,erlu dipahami sekali lagi bah"a database driver bersifat spesi?k untuk setiap jenis sumber data. Misalnya, Database Driver MyS\l hanya bisa digunakan untuk melakukan koneksi ke database MyS\l dan begitu juga database driver untuk ,ostgre SI. juga hanya bisa digunakan untuk melakukan koneksi ke database ,ostgre SI.. Database driver untuk setiap D!MS pada umumnya dapat dido"nload dari "ebsite pembuat

D!MS tersebut. !eberapa vendor D!MS menyebut Database driver ini dengan sebutan Java $onnector 3J9$onnector5. Database driver biasanya dibungkus dalam ?le yang berekstensi jar. Setiap database driver harus mengimplement interface java.s\l.Driver.

embuat Koneksi
Melakukan koneksi ke database melibatkan dua langkah/ Meload driver dan membuat koneksi itu sendiri. $ara meload driver sangat mudah, pertama letakkan ?le jar database driver ke dalam classpath. (emudian load driver dengan menambahkan kode berikut ini/ Dlass./or<ame(*com.mys\l.#dbc.:river*) 0ama class database driver untuk setiap D!MS berbeda, anda bisa menemukan nama class tersebut dalam dokumentasi driver database yang anda gunakan. Dalam contoh ini, nama class database driver dari MyS\l adalah com.mys\l.jdbc.Driver. Memanggil method $lass.for0ame secara otomatis membuat instance dari database driver, class DriverManager secara otomatis juga dipanggil untuk mengelola class database driver ini. Jadi anda tidak perlu menggunakan statement ne" untuk membuat instance dari class database driver tersebut. .angkah berikutnya adalah membuat koneksi ke database menggunakan database driver yang sudah diload tadi. $lass DriverManager bekerja sama dengan interface Driver untuk mengelola driver-driver yang diload oleh aplikasi, jadi dalam satu sesi anda bisa meload beberapa database driver yang berbeda. (etika kita benar-benar melakukan koneksi, JD!$ Test Suite akan melakukan serangkaian tes untuk menentukan driver mana yang akan digunakan. ,arameter yang digunakan untuk menentukan driver yang sesuai adalah F-.. :plikasi yang akan melakukan koneksi ke database menyediakan F-. pengenal dari server databse tersebut. Sebagai contoh adalah F-. yang digunakan untuk melakukan koneksi ke MyS\l / #dbc3mys\l3CC[.ost]3[port]C[sc.ema] contoh konkritnya / #dbc3mys\l3CClocal.ost311'&Clati.an Setiap vendor D!MS akan menyertakan cara untuk menentukan F-. ini di dalam dokumentasi. :nda tinggal membaca dokumentasi tersebut tanpa harus kha"atir tidak menemukan informasi yang anda perlukan. Method DriverManager.get$onnection bertugas untuk membuat koneksi/ Donnection conn 7 :riverBanager.getDonnection( *#dbc3mys\l3CClocal.ost311'&Clati.an*) Dalam kebanyakan kasus anda juga harus memasukkan parameter username dan pass"ord untuk dapat melakukan koneksi ke dalam database. Method get$onnection menerima Fsername sebagai parameter kedua dan pas"ord sebagai parameter ketiga, sehingga kode di atas dapat dirubah menjadi / Donnection conn 7 :riverBanager.getDonnection( *#dbc3mys\l3CClocal.ost311'&Clati.an*+ *root*+**) Jika salah satu dari driver yang diload berhasil digunakan untuk melakukan koneksi dengan F-. tersebut, maka koneksi ke database berhasil dilaksanakan. $lass $onnection akan memegang informasi koneksi ke database yang dide?nisikan oleh F-. tersebut. Setelah sukses melakukan koneksi ke database, kita dapat mengambil data dari database menggunakan perintah \uery ataupun melakukan perubahan terhadap database. bagian berikut ini akan menerangkan bagaimana cara mengambil dan memanipulasi data dari database.

enyiapkan -able
Dalam contoh berikutnya akan digunakan table TS,M-SH0, table ini terdiri dari tiga buah kolom / id, name dan pass"ord. d adalah primary key dengan tipe integer dan nilainya increment berdasarkan urutan insert. ,rimary key dengan tipe integer sangat bagus untuk performance karena mudah diindeL dan indeL bisa sangat e?sien, selain itu id akan digunakan sebagai foreign key di table-table yang lain, sehingga sangat penting untuk menggunakan tipe data integer karena database bisa sangat e?sien membandingkan integer dalam proses joint. (olom name harus uni\ue tapi bukan primary key karena ukuranya yang cukup besar. (alau name ini sering digunakan dalam "hare statement sebaiknya dibuatkan indeL intuk mempercepat proses \uery. Dengan menggunakan mys\l, berikut ini DD. dari table TS,M-SH0 / create table 9(4@6SA< ( id integer auto(increment primary 0ey+ anamea varc.ar(%'') uni\ue not null+ pass8ord varc.ar()'') not null ) engine7=nno:> ,erhatikan bagian akhir dari DD. di atas, ada attribute engine[ nnoD! yang memerintahkan mys\l menggunakan nnoD! database engine. nnoD! adalah database engine di mys\l yang mendukung transcation 3commit dan rollback5, constraint foreign key dan constraint lainya. Sedangkan My S:M tidak mendukung transaction dan constraint. Dari sisi performance My S:M masih lebih cepat dibanding nnoD!, jadi gunakan kedua engine ini pada kasus yang tepat. Jika diperlukan konsistensi data maka gunakan nnoD!, jika kecepatan adalah segalanya maka My S:M lebih tepat digunakan.

en!ambil dan

emanipulasi Data dari Database

,roses pengambilan data dari database memerlukan suatu class untuk menampung data yang berhasil diambil, class tersebut harus mengimplement interface -esultSet. Hbject yang bertipe -esultSet dapat mempunyai level fungsionalitas yang berbeda, hal ini tergantung dari tipe dari result set. .evel fungsionalitas dari setiap tipe result set dibedakan berdasarkan dua area/ Dengan cara bagaimana result set itu dapat dimanipulasi !agaimana result set itu menangani perubahan data yang dilakukan oleh proses lain secara bersamaan 3concurrent5. TP,MS*H-#:-DSH0.P / result set tersebut tidak bisa berjalan mundur, reslut set hanya bisa berjalan maju dari baris pertama hingga baris terakhir. result set hanya menggambarkan keadaan data ketika \uery dijalankan atau ketika data diterima oleh resul set. Jika setelah itu ada perubahan data dalam database, result set tidak akan diupdate alias tidak ada perubahan dalam result set tipe ini. TP,MSS$-H..S 0SM0S T @M / result set dapat berjalan maju mundur. result set dapat berjalan maju dari ro" pertama hingga terakhir atau bergerak bebas berdasarkan posisi relatif atau absolute. TP,MSS$-H..SSM0S T @M / result set dapat berjalan maju mundur. result set dapat berjalan maju dari ro" pertama hingga terakhir atau bergerak bebas berdasarkan posisi relatif atau absolute.

JD!$ menyediakan tiga tipe result set untuk tujuan berbeda/ ).

%.

7.

nstance dari object bertipe -esultSet diperlukan untuk menampung hasil kembalian data dari database. Sebelum kita bisa memperoleh instance dari -esultSet, kita harus membuat instance dari class Statement. $lass Statement mempunyai method eLecuteIuery yang digunakan untuk menjalankan perintah \uery dalam database kemudian mengembalikan data hasil eksekusi \uery ke dalam object -esultSet. !erikut ini adalah contoh kode untuk membuat instance class Statement, kemudian menjalankan

\uery untuk mengambil data dari database yang hasilnya dipegang oleh -esultSet / Statement statement 7 conn.createStatement( 6esultSet.9_4@(SD6A;;(S@<S=9=P@+ 6esultSet.DA<DG6(6@I:(A<;_) 6esulSet rs 7 statement.e,ecutebuery(*select L /rom 9(4@6SA<*) -esultSet akan meletakkan kursornya 3posisi pembacaan baris5 di sebuah posisi sebelum baris pertama. Fntuk menggerakkan kursor maju, mundur, ke suatu posisi relatif atau ke suatu posisi absolute tertentu, gunakan method-method dari -esultSet/ neLt35 -- mengarahkan kursor maju satu baris. previous35 -- mengarahkan kursor mundur satu baris. ?rst35 -- mengarahkan kursor ke baris pertama. last35 -- mengarahkan kursor ke baris terakhir. before*irst35 -- mengarahkan kursor ke sebelum baris pertama. after.ast35 -- mengarahkan kursor ke setelah baris terakhir. relative3int ro"s5 -- mengarahkan kursor relatif dari posisinya yang sekarang. Set nilai ro"s dengan nilai positif untuk maju, dan nilai negatif untuk mundur. absolute3int ro"0umber5 d mengarahkan kursor ke posisi tertentu sesuai dengan nilai ro"0umber, dan tentu saja nilainya harus positif.

nterface -esultSet menyediakan method getter untuk mengakses nilai dari setiap kolom dalam baris yang sedang aktif. ,arameter fungsi getter bisa menerima nilai indeL dari kolom ataupun nama kolomnya. 0amun begitu, penggunaan nilai indeL lebih e?sien dibanding menggunakan nama kolom. 0ilai indeL dimulai dengan satu hingga banyaknya kolom. ,enggunaan nama kolom adalah case insensitive, artinya huruf kecil atau huruf besar tidak menjadi masalah. getString digunakan untuk mengambil kolom dengan tiper data char, varchar atau tipe data string lainya. get nt digunakan untuk mengambil kolom dengan tipe data integer. !erikut ini dalah contoh program lengkap dari melakukan koneksi hingga mengambil data dari database. Dlass./or<ame(*com.mys\l.#dbc.:river*) Donnection conn 7 :riverBanager.getDonnection( *#dbc3mys\l3CClocal.ost311'&Clati.an*+*root*+**) Statement statement 7 conn.createStatement(6esultSet.9_4@(SD6A;;(S@<S=9=P@+ 6esultSet.DA<DG6(6@I:(A<;_) 6esulSet rs 7 statement.e,ecutebuery(*select L /rom 9(4@6SA<*) 8.ile(rs.ne,t()){ System.out.println(rs.get=nt(*id*)) System.out.println(rs.getString(*name*)) ! Method eLecuteIuery hanya dapat menjalankan perintah SI. select, gunakan method eLecuteFpdate untuk menjalankan perintah insert, update dan delete. +asil dari eksekusi insert, update dan delete tidak mengembalikan result set, tetapi mengembalikan sebuah nilai integer yang merepresentasikan status hasil eksekusi method eLecuteFpdate. !erikut ini contoh insert, update dan delete / result 7 statement.e,ecuteGpdate( *update 9(4@6SA< set name 7QrobyQ 8.ere name7QandyQ*) result 7 statement.e,ecuteGpdate(*delete 9(4@6SA< 8.ere name7QandyQ*) Statement sangat Ueksible namun eksekusi \uery-nya sangat lambat jika dibandingkan dengan ,reparedStatement. +al ini dikarenakan setiap kali melakukan eksekusi \uery menggunakan statement, database akan melalui berbagai macam langkah eksekusi \uery, antara lain /

). %. 7. <.

melakukan parsing terhadap \uery membuat eLecution plan memasukkan parameter ke dalam \uery mengeksekusi \uery tersebut.

,reparedStatement hanya akan melakukan langkah ) dan % ketika pertama kali menyiapkan ,reparedStatement, eksekusi berikutnya hanya menjalankan langkah 7 dan <. Dengan menggunakan sedikit test kecil, kecepatan eksekusi ,reparedStatement bisa mencapai puluhan kali lebih cepat dibanding Statement. Selain lebih cepat, ,reparedStatement juga aman dari serangan hacker yang disebut dengan s\l injection. S\l njection adalah serangan hacker dengan memanfaatkan proses pembentukan \uery yang melibatkan penggabungan string seperti yang terjadi dalam Statement. ,erhatikan \uery berikut ini yang digunakan dalam proses login String name 7 *Indy* String pas8ord 7 *p8d%)1* Statement statement 7 conn.createStatement(6esultSet.9_4@(SD6A;;(S@<S=9=P@+ 6esultSet.DA<DG6(6@I:(A<;_) 6esulSet rs 7 statement.e,ecutebuery(*select L /rom 9(4@6SA< 8.ere name 7Q* E name E *Q and pass8ord7Q E pass8ord E *Q*) Fsername dan pass"ord diambil dari form login, bagaimana jika yang login adalah seorang hacker dan mencoba memasukkan string berikut ini ke dalam username String name 7 *.ac0erQ or %7% $$* String pass8ord 7 *pass8ord bypass* Dengan memasukkan username berbentuk \uery statement seperti di atas, mari kita lihat \uery yang dihasilkan dari proses penggabungan string di atas / select L /rom 9(4@6SA< 8.ere name 7Q.ac0erQ or %7% $$ and pass8ord7Qpass8ord bypassQ Dengan menambahkan \uery Oor )[)O maka statement "here akan selalu bernilai true dan string O--O digunakan untuk membuat \uery di belakangnya hanya sekedar komentar dan tidak ikut dieksekusi. :rtinya, hanya dengan mengetahui username tanpa mengetahui pass"ord, hacker dapat mengeksekusi \uery di atas dengan sukses. Selain itu, statement juga rentan terkena error kalau ada karakter khusus dalam string yang digabung-gabung dalam \uery. Misalnya ada seorang user yang namanya EMartin HJnealG, tanda J di dalam string nama akan membuat statement gagal dieksekusi karena \uery yang tidak valid. !egitu juga dengan karakter-karakter buruk lainnya seperti J R O g c. Menggunakan statement sangat mudah dan U eksible, namun sangat tidak e?sien, rentan serangan hacker dalam bentuk s\l injection, dan rentan mengalami s\l error karena ada bad character dalam string parameter. ,reparedStatement mena"arkan keunggulan dari sisi e?siensi, keamanan dan tahan terhadap input yang mengandung bad character. (unjugi blog ifnu.artivisi.com9Zp['' untuk mengetahui bagaimana cara menghilangkan bad character jika anda menggunakan statement dan tidak bisa berpindah ke ,reparedStatement.

en!!unakan 'reparedStatement
Memanggil method eLecuteFpdate berulang-ulang, misalnya melakukan insert ratusan atau ribuan baris, sangat tidak e?sien. +al ini disebabkan karena D!MS harus memproses setiap \uery yang dikirimkan dalam beberapa langkah/ memparsing \uery, mengcompile \uery dan kemudian baru mengeksekusi \uery tersebut. ,reparedStatement mena"arkan solusi yang lebih baik dalam menangani keadaan tersebut. ,reparedStatement menyaratkan \uery yang akan dieksekusi dide?nisikan terlebih dahulu ketika ,reparedStatement dibuat. (emudian \uery tersebut dikirimkan ke dalam database untuk dicompile terlebih dahulu sebelum digunakan. (onsekuensinya, ,reparedStatement bukan hanya mempunyai \uery, tetapi mempunyai \uery yang sudah dicompile. (etika ,reparedStatement

dijalankan, D!MS tidak perlu melakukan kompilasi ulang terhadap \uery yang dijalankan ,reparedStatement. +al inilah yang menyebabkan ,reparedStatement jauh lebih e?sien dibandingkan menggunakan method Statement.eLecuteFpdate. !erikut ini contoh pembuatan ,reparedStatement menggunakan class $onnection yang telah dibuat sebelumnya / 4reparedStatement ps 7 conn.prepareStatement( *update 9(4@6SA< set pass8ord 7 W 8.ere name 7 W*) ,erhatikan tanda Z yang ada dalam \uery di atas, tanda Z disebut sebagai parameter. (ita bisa memberikan nilai yang berbeda ke dalam parameter dalam setiap pemanggilan ,reparedStatement. Method setString, set*loat, set nt dan beberapa method lain digunakan untuk memasukkan nilai dari setiap parameter. Method tersebut mempunyai dua parameter, parameter pertama adalah int yang digunakan untuk menentukan parameter ,reparedStatement mana yang akan diberi nilai. ,arameter kedua adalah nilai yang akan dimasukkan ke dalam ,reparedStatement, tipe data dari parameter kedua tergantung dari method yang digunakan. !erdasarkan kode di atas, berikut ini contoh penggunaan method ,reparedStatement.setString / ps.setString(%+*p8dbaru*) ps.setString()+*ri?al*) (ode di atas memberikan contoh bagaimana memasukkan nilai ke dalam parameter ,reparedStatement. !aris pertama memasukkan String EandyG ke dalam parameter pertama dan baris kedua memasukkan String EriBalG ke parameter kedua. Sehingga pemanggilan \uery oleh ,reparedStatement berdasarkan kode di atas sama dengan \uery statement di ba"ah ini / *update 9(4@6SA< set p8d 7 Qp8dbaruQ 8.ere name 7 Qri?alQ* !erikut ini contoh lengkap penggunaan ,reparedStatement untuk melakukan update dan insert data / 4reparedStatement p=nsert 7 conn.prepareStatement( *insert into 9(4@6SA<(name+pass8ord) values(W+W)*) p=nsert.setString(%+*dian*) p=nsert.setString()+*p8ddian*) p=nsert.e,ecuteGpdate() 4reparedStatement pGpdate 7 conn.prepareStatement( *update 9(4@6SA< set pass8ord7W 8.ere name7W*) pGpdate.setString(%+*p8dandri*) pGpdate.setString()+*andri*) pGpdate.e,ecuteGpdate() Dalam contoh di atas, insert dan update data hanya dilaksanakan sekali saja, hal ini tidak memberikan gambaran yang tepat untuk melihat keunggulan ,reparedStatement dibandingkan Statement.eLecuteFpdate. S\l njection dapat dihindari dengan menggunakan ,reparedStatement karena apapun yang dimasukkan hacker akan dianggap sebagai parameter dan tidak dianggap sebagai bagian dari \uery. Mari kita implementasikan lagi contoh \uery login sebelumnya yang menggunakan Statement menjadi menggunakan ,reparedStatement. String name 7 *Indy* String pas8ord 7 *p8d%)1* 4reparedStatement loginStatement 7 conn.prepareStatement(*select L /rom 9(4@6SA< 8.ere name 7 W and pass8ord 7 W*) loginStatement.setString(%+name) loginStatement.setString()+pass8ord) #alaupun hacker memasukkan username dan pass"ord seperti berikut ini / String name 7 *.ac0erQ or %7% $$* String pass8ord 7 *pass8ord bypass* (edua teLt itu tidak dianggap sebagai bagian dari \uery tapi hanya sebagai parameter saja. ,reparedStatement akan berusaha mencari username EhackerJ or )[) --G di dalam database

dan pasti akan gagal, \uery untuk membandingkan pass"ord juga tetap dieksekusi "alaupun ada string O--O di dalam username. ,esan moralnya adalah gunakan selalu ,reparedStatement dan hindari sebisa mungkin untuk menggunakan Statement.

/at&* $%e&ution
Misalnya kita ingin meng-insert seratus baris data dalam sebuah loop, kita bisa menggunakan fasilitas batch eLecution dari ,reparedStatement. batch eLecution mengumpulkan semua eksekusi program yang akan dilaksanakan, setelah semuanya terkumpul batch eLecution kemudian mengirimkan kumpulan eksekusi program secara bersamaan ke D!MS dalam satu kesatuan. Metode ini sangat e?sien karena mengurangi overhead yang diperlukan program untuk berkomunikasi dengan D!MS. Dalam contoh di ba"ah ini kita akan menggunakan batch eLecution untuk melakukan insert data sebanyak seratus kali. 4reparedStatement p=nsert 7 conn.prepareStatement( *insert into 9(4@6SA<(name+pass8ord) values(W+W)*) /or(int i7' iT%'' iEE){ p=nsert.setString(%+*user 0e * E i) p=nsert.setString()+*p8d 0e * E i) p=nsert.add>atc.() ! p=nsert.e,ecute>atc.() Setiap kali iterasi, method setString dipanggil untuk mengisikan sebuah string ke dalam ,reparedStatement, kemudian method add!atch dipanggil untuk mengumpulkan batch dalam satu "adah. Setelah iterasi selesai, method eLecute!atch dipanggil untuk melaksanakan semua keseratus instruksi insert secara berurut dengan sekali saja melaksanakan koneksi ke database.

enan!ani -ransa&tion
Dukungan transaction oleh JD!$ tergantung dengan Databasenya, karena ada database yang mendukung transaction dan ada pula database yang tidak mendukung transaction. MySI. mendukung transaction jika kita menggunakan nnoD! sebagai sistem tablenya, kalau kita menggunakan My S:M maka transaction tidak didukung. Transaction merupakan konsep penting dari database. Transaction memastikan perubahan data dilaksanakan dengan kaidah :$ D 3:tomicity, $onsistency, solation, Durability5. (aidah ini memastikan semua proses perubahan data berjalan secara benar, jika ada yang salah maka semua perubahan dalam satu kesatuan logika harus dibatalkan 3rollback5. Mari kita evaluasi kode di atas agar menggunakan transaction, sehingga jika satu proses insert gagal, maka semua insert yang dilaksanakan sebelumnya akan dibatalkan / try{ connection.setIutoDommit(/alse) 4reparedStatement p=nsert 7 conn.prepareStatement( *insert into 9(4@6SA<(name+pass8ord) values(W+W)*) /or(int i7' iT%'' iEE){ p=nsert.setString(%+*user 0e * E i) p=nsert.setString()+*p8d 0e * E i) p=nsert.add>atc.() ! p=nsert.e,ecute>atc.() connection.commit() connection.setIutoDommit(true) ! catc. (Sb;@,ception e,) { try{

connection.rollbac0() !catc.(Sb;@,ception e){ !

endapatkan ID yan! Di!enerate "tomatis


MySI. mempunyai feature auto-increment untuk mengenerate primery key secara otomatis. Fntuk mendapatkan D yang baru saja digenerate ada teknik khusus, tidak bisa menggunakan cara dengan mengambil id yang paling besar dari table TS,M-SH0. $ara ini akan sangat berbahaya kalau aplikasi digunakan oleh banyak user, misalnya setelah user : menginsert satu baris kemudian select id terbesar, ada kemungkinan user ! juga menginsert data sehingga id yang didapatkan user : dari select id terbesar bukan id yang baru saja digenerate user :, melainkan id yang digenerate user !. !erikut ini contoh kode untuk mengambil id yang baru saja digenerate oleh database / 4reparedStatement p=nsert 7 conn.prepareStatement( *insert into 9(4@6SA<(name+pass8ord)*+ Statement.6@9G6<(S@<@6I9@:(K@_S) p=nsert.setString(%+*dian*) p=nsert.setString()+*p8ddian*) p=nsert.e,ecuteGpdate() 6esultSet rs 7 p=nsert.getSeneratedKeys() rs.ne,t() ;ong id 7 rs.get;ong(%) ,reparedStatement harus digunakan untuk mengambil key yang digenerate MySI. secara otomatis. ,ara "aktu membuat prepared statement, ada tambahan satu parameter yaitu Statement.-MTF-0SKM0M-:TMDS(MPS. ,arameter tersebut digunakan untuk memberitahu ,reparedStatement bah"a proses insert akan mengenerate primary id secara otomatis. Setelah p nser.eLecuteFpdate35D dilaksanakan, dengan menggunakan prepared statement yang sama eksekusi method getKenerated(eys35D, method ini akan mereturn -esultSet yang isinya cuma satu baris dan satu column. Di baris berikut nya dipanggil rs.neLt35 untuk meloncat ke baris pertama dan rs.get.ong3)5 untuk mengambil id-nya.

JD/C0"D/C /rid!e
HD!$ atau Hpen Database $onnectivity adalah standard pengaksesan relational database atau data source lain dengan memanfaatkan middle layer untuk menjembatani aplikasi dengan datasource tersebut. HD!$ dikembangkan bersama oleh SI. :ccess group yang terdiri dari perusahaan-perusahaan besar seperti Microsoft dan !M. Sebelum dikembangkan HD!$, setiap koneksi ke database berbeda-beda menggunakan cara yang berbeda-beda pula, hal ini menyulitkan pengembang untuk membuat kode yang portable antar database. Dengan menggunakan HD!$, aplikasi bisa mengakses database dangan cara yang seragam dan hanya perlu menyediakan driver yang sesuai dengan database tersebut. (onsep ini diambil oleh JD!$ dimana :, untuk mengakses database seragam, hanya perlu menyediakan driver sesuai untuk setiap database. Sayangnya beberapa jenis database tidak menyediakan JD!$ driver, seperti MS-:ccess. Fntuk bisa connect ke MS-:ccess bisa memanfaatkan JD!$-HD!$ driver bridge yang disediakan Sun. Setiap instalasi MS-:ccess %&&7 akan disertakan database sample 0orth"ind.mdb, letakkanya ada di =Hhce nstallation>RHhce))RS:M,.MS, berikutnya siapkan beberapa langkah untuk membuat HD!$ con?guration. :gar bisa menggunakan JD!$-HD!$ bridge, anda perlu membuat DS0 3Data Source 0ame5 yang digunakan untuk mensetting driver HD!$ dan databasenya. !erikut langkah-langkah membuat DS0 / !uka $ontrol ,anel C :dministrative Tool C Data Sources 3HD!$5

(lik tab System DS0. (emudian klik tombol :dd Dari daftar driver HD!$, pilih Microsoft :ccess Driver 3Y.mdb5, HD!$JT7%.D.., dan tekan tombol ?nish. Sekarang bisa dilihat ada informasi DS0 seperti berikut ini / <ame3 <ort.8ind :escription3 :S< /or t.e <ort.8ind.mdb Select :atabase3 <ort.8ind.mdb Tekan tombol H(. DS0 E0orth"indG sekarang sudah siap digunakan

Setelah DS0 siap, langkah berikutnya adalah membuat connection ke DS0 menggunakan JD!$HD!$ bridge. Dlass./or<ame(*sun.#dbc.odbc.]dbcAdbc:river*) Donnection conn 7 :riverBanager.getDonnection(*#dbc3odbc3<ort.8ind*) JD!$-HD!$ driver class sun.jdbc.odbc.JdbcHdbcDriver sudah tersedia di dalam JD(, terutama di "indo"s. Sedangkan di HS] atau .inuL masih harus diteliti lagi apakah class ini tersdia atau tidak. Setelah koneksi berhasil dibuat, sisanya sama saja dengan menggunakan JD!$ driver biasa. ,roses pembuatan \uery dengan statement atau preparedstatement, transaction dan seterusnya sama.

eman!!il #un&tion dan Stored'ro&edure


Stored procedure dan *unction tidak bisa dipisahkan dari database, keduanya digunakan untuk mengeksekusi \uery di database. Menulis \uery di JD!$ atau S, tergantung dari style pemrograman, bisa juga karena merek database tertentu mempunyai feature yang bisa digunakan dalam S, tetapi tidak tersedia di JD!$. S, juga sangat cepat, beberapa -D!MS bisa mencompile S, menjadi native code sehingga kecepatan eksekusinya meningkat. S, juga bisa mengurangi komunikasi net"ork jika ada proses yang melibatkan \uery, loop, condition checking terhadap data yang cukup besar dan tidak melibatkan interaksi user. MySI. semenjak versi 4 sudah mendukung Stored,rocedure, informasi yang lengkat tentang stored procedure di mys\l 4 bisa dibaca di sini/ .ttp3CCdev.mys\l.comCtec.$resourcesCarticlesCmys\l$storedprocedures.pd/ Sebelum bisa memanggil stored procedure dari JD!$, pertama kali jelas harus dibuat dulu stored procedurenya. Membuat stored procedure di mys\l tidak terlalu susah, buka mys\l client console dan jalankan perintah berikut ini/ mys\lV create procedure get(persons () select L /rom 9(4@6SA< Setelah procedure selesai dibuat, coba jalankan dengan menggunakan perintah ini / mys\lV call get(persons() (alau perintah di atas bisa dijalankan dengan baik, pertanda bah"a stored procedurenya berhasil digunakan. Memanggil stored procedure dari JD!$ tidak susah, prosesnya sama dengan menggunakan ,reparedStatement. !erikut ini kode untuk memanggil stored procedure getSusers di atas Dlass./or<ame(*com.mys\l.#dbc.:river*) Donnection c 7 :riverBanager.getDonnection( *#dbc3mys\l3CClocal.ost311'&Clati.an*+ *root*+ **) DallableStatement callableStatement 7 c.prepareDall(*{call get(persons!*) 6esultSet rs 7 callableStatement.e,ecutebuery() 8.ile(rs.ne,t()){ System.out.println(rs.get=nt(*id*) E *+* E rs.getString(*name*) E *+* E rs.getString(*pass8ord*))

! Stored procedure juga bisa mempunyai parameter. !erikut ini cara membuat dan memanggil stored procedure di mys\l 4 yang mempunyai parameter. mys\lV create procedure get(person(by(id (=< user(id int) select L /rom 9(4@6SA< 8.ere id7user(id Memanggil stored procedure mys\lV call get(person(by(id(R''') Memanggil stored procedure dengan parameter berupa variabel di mys\l 4 client console mys\lV set ^person(id 7 R''' mys\lV call get(person(by(id(^person(id) Memanggil stored procedure dengan parameter dari JD!$ DallableStatement callableStatement 7 c.prepareDall(*{call get(person(by(id(W)!*) callableStatement.set=nt(%+ R''') 6esultSet rs 7 callableStatement.e,ecutebuery() 8.ile(rs.ne,t()){ System.out.println(rs.get=nt(*id*) E *+* E rs.getString(*username*) E *+* Ers.getString(*pass8ord*)) ! ,emanggilan Stored procedure dapat dikombinasikan dengan Iuery biasa dalam satu skope transaction. :rtikel lengkap tentang JD!$ bisa dilihat di "ebsite sun / http/99java.sun.com9developer9onlineTraining9Database9JD!$%& ntro9JD!$%&.html

Model- Dao dan *ervice Pattern


:kses terhadap database merupakan bagian yang sangat penting dari aplikasi database. ,enggunaan pattern yang sesuai dapat memberikan manfaat sangat besar. ,attern yang sering digunakan dalam akses database adalah D:H 3Data :ccess Hbject5 dan Service9*acade pattern. (edua pattern ini digunakan untuk menerapkan Eseparation of concernG atau pemisahan kode proram berdasarkan fungsi kode program. Semua kode untuk akses data harus dipisahkan dengan kode untuk pengaturan user inteface. +al ini memungkinkan kode akses data yang dibuat untuk aplikasi desktop, dengan mudah digunakan untuk aplikasi "eb. ,enerapan konsep separation of concern secara disiplin, dapat menghasilkan kode program yang dapat dites secara otomatis menggunakan JFnit atau D!Fnit. Fnit testing merupakan paramater utama dalam menentukan apakah kode program yang kita hasilkan mempunyai mutu yang tinggi atau tidak. $overage unit testing yang tinggi mencerminkan kode program yang berkualitas tinggi pula. Dao pattern berisi semua kode untuk mengakses data, seperti \uery. Semua kode yang sepesi?k terhadap implementasi akses data berhenti di sini, lapisan lebih atas tidak boleh tahu bagaimana akses data diterapkan, apakah menggunakan JD!$ murni atau +ibernate atau J,:. .apisan lainya hanya perlu tahu fungsionalitas dari suatu method di dalam D:H class, tidak perlu tahu bagimana method tersebut diimplementasikan. $lass D:H akan mempunyai method seperti save, delete, get!y d atau get:ll. ,raktek yang laBim digunakan adalah satu buah Mntity9Table akan mempunyai satu buah class D:H. !agian ini akan menerangkan bagaimana melakukan akses database menggunakan +ibernate serta menerangkan teori H-M dibalik +ibernate. ,embahasan dilanjutkan bagaimana menggunakan Spring untuk memanage +ibernate dan mengimplementasikan Declarative Transaction. !agian selanjutnya membahas feature +ibernate secara mendetail.

$ntity Class (

odel

Di dalam D:H layer ini, biasanya juga diterapkan konsep H-M. Setiap table dibuatkan Mntity class yang merepresentasikan table. +al ini memudahkan maintenance kode karena abstraksi dan logic aplikasi diterapkan di dalam kode. +anya dengan melihat kode dan nama-nama class atau property, developer bisa melihat logic dibaliknya. Ditambah dengan javadoc dan komentar yang ekstensif, H-M bisa memudahkan maintenance code sangat signi?kan. $ontoh-contoh di atas menggunakan table TS,M-SH0, dalam konsep H-M, table ini akan dimap dengan Mntity class ,erson. Setiap property dalam class ,erson merepresentasikan kolom dalam table TS,M-SH0. !uat class ,erson di dalam package com.googlecode.projecttemplate.pos.model. :gar kode yang kita buat terstruktur dengan rapi, class-class yang mempunyai fungsi yang sama akan dikelompokkan ke dalam package yang sama pula, misalnya class ,erson ini diletakkan dalam package model, kemudian class-class D:H diletakkan dalam package dao, class-class service diletakkan dalam package service dan class-class F diletakkan dalam package ui. public class 4erson { private ;ong id private String name private String pass8ord public ;ong get=d() { return id ! public void set=d(;ong id) { t.is.id 7 id ! public String get<ame() {

return name ! public void set<ame(String name) { t.is.name 7 name ! public String get4ass8ord() { return pass8ord ! public void set4ass8ord(String pass8ord) { t.is.pass8ord 7 pass8ord !

Setelah data mele"ati D:H layer, tidak ada lagi class-class dari package javaL.s\l seperti -esultSet. Setiap \uery yang dieksekusi untuk mendapatkan data dari table TS,M-SH0 di map ke dalam class ,erson, sehingga di dalam kode yang menggunakan D:H, tidak perlu lagi menghapal nama-nama kolom dari table, cukup menggunakan kelas ,erson.

DA" 'attern
D:H layer hanya melakukan \uery sederhana, sebaiknya tidak menempatkan kode bisnis di dalam layer D:H, karena satu D:H hanya ditujukan untuk melakukan manipulasi terhadap satu table saja. ,roses transaksi juga tidak terjadi dalam layer D:H tetapi di layer lebih atasnya yaitu Service layer. ,erhatikan juga semua D:H method men-thro"s SI.MLception, sehingga kalau ada error di dalam method dao, SI.MLception dilempar ke layer service dan layer service bisa merollback transaction. Di ba"ah ini adalah contoh ,ersonDaoJDbc menggunakan JD!$ untuk table TS,M-SH0 / public class 4erson:ao]dbc { private Donnection connection private 4reparedStatement insertStatement private 4reparedStatement updateStatement private 4reparedStatement deleteStatement private 4reparedStatement get>y=dStatement private 4reparedStatement getIllStatement private /inal String insertbuery 7 *insert into 9(4@6SA<(name+pass8ord) * E * values(W+W)* private /inal String updatebuery 7 *update 9(4@6SA< set name7W+ * E * pass8ord7W 8.ere id7W* private /inal String deletebuery 7 *delete /rom 9(4@6SA< 8.ere id7W* private /inal String get>y=dbuery 7 *select L /rom 9(4@6SA< 8.ere id 7W* private /inal String getIllbuery 7 *select L /rom 9(4@6SA<* public void setDonnection(Donnection connection) t.ro8s Sb;@,ception{ t.is.connection 7 connection insertStatement 7 t.is.connection.prepareStatement(insertbuery+ Statement.6@9G6<(S@<@6I9@:(K@_S) updateStatement 7 t.is.connection.prepareStatement(updatebuery) deleteStatement 7 t.is.connection.prepareStatement(deletebuery) get>y=dStatement 7 t.is.connection.prepareStatement(get>y=dbuery) getIllStatement 7 t.is.connection.prepareStatement(getIllbuery) ! public 4erson save(4erson person) t.ro8s Sb;@,ception{ i/ (person.get=d() 77 null) { insertStatement.setString(%+ person.get<ame()) insertStatement.setString()+ person.get4ass8ord())

int id 7 insertStatement.e,ecuteGpdate() person.set=d(id) ! else { updateStatement.setString(%+ person.get<ame()) updateStatement.setString()+ person.get4ass8ord()) updateStatement.set=nt(1+ person.get=d()) updateStatement.e,ecuteGpdate() ! return person ! public 4erson delete(4erson person) t.ro8s Sb;@,ception{ deleteStatement.set=nt(%+ person.get=d()) deleteStatement.e,ecuteGpdate() return person ! public 4erson get>y=d(;ong id) t.ro8s Sb;@,ception{ get>y=dStatement.set;ong(%+ id) 6esultSet rs 7 get>y=dStatement.e,ecutebuery() CCproses mapping dari relational 0e ob#ect i/ (rs.ne,t()) { 4erson person 7 ne8 4erson() person.set=d(rs.get;ong(*id*)) person.set<ame(rs.getString(*name*)) person.set4ass8ord(rs.getString(*pass8ord*)) return person ! return null ! public ;istT4ersonV getIll() t.ro8s Sb;@,ception{ ;istT4ersonV persons 7 ne8 Irray;istT4ersonV() 6esultSet rs 7 getIllStatement.e,ecutebuery() 8.ile(rs.ne,t()){ 4erson person 7 ne8 4erson() person.set=d(rs.get;ong(*id*)) person.set<ame(rs.getString(*name*)) person.set4ass8ord(rs.getString(*pass8ord*)) persons.add(person) ! return persons ! !

Servi&e 'attern
Service pattern digunakan utamanya untuk menyederhanakan class-class D:H yang ada, misalnya kita mempunyai 4& buah table maka laBimnya akan ada 4& buah class D:H. $lass D:H tersebut perlu disederhanakan, caranya adalah dengan mengelompokkan class-class D:H dalam satu modul aplikasi ke class Service. Misalnya D:H yang berhubungan dengan user management ke dalam class FserService. Transaction diatur dalam class Service, praktek yang laBim digunakan adalah satu method dalam class service adalah satu scope transaction. Jadi ketika method dalam service mulai dieksekusi transaction akan dimulai 3begin5, ketika method akan berakhir, transaction akan dicommit, jika terjadi eLception pada saat method dilaksanakan dilakukan rollback data untuk mengembalikan

keadaan seperti sebelumnya. !erikut ini adalah contoh class Service / public class Service]dbc { private 4erson:ao]dbc person:ao private Donnection connection public void set:ataSource(:ataSource dataSource){ try { connection 7 dataSource.getDonnection() person:ao 7 ne8 4erson:ao]dbc() person:ao.setDonnection(connection) ! catc. (Sb;@,ception e,) { e,.printStac09race() ! ! public 4erson save(4erson person){ try { connection.setIutoDommit(/alse) person:ao.save(person) connection.commit() connection.setIutoDommit(true) ! catc. (Sb;@,ception e,) { try{ connection.rollbac0() !catc.(Sb;@,ception e){ e.printStac09race() ! ! return person ! public 4erson delete(4erson person){ try { connection.setIutoDommit(/alse) person:ao.save(person) connection.commit() connection.setIutoDommit(true) ! catc. (Sb;@,ception e,) { try{ connection.rollbac0() !catc.(Sb;@,ception e){ e.printStac09race() ! ! return person ! public 4erson get4erson(;ong id){ try { return person:ao.get>y=d(id) ! catc. (Sb;@,ception e,) { e.printStac09race() ! return null !

public ;istT4ersonV get4ersons(){ try{ return person:ao.getIll() ! catc. (Sb;@,ception e,) { e.printStac09race() ! return ne8 Irray;istT4ersonV() !

Setelah class D:H dan service berhasil dibuat, mari kita lihat bagaimana cara menggunakannya / public class Bain]dbc { public static void main(String[] args) { Bys\l:ataSource dataSource 7 ne8 Bys\l:ataSource() dataSource.setGser(*root*) dataSource.set4ass8ord(**) dataSource.set:atabase<ame(*lati.an*) dataSource.setServer<ame(*local.ost*) dataSource.set4ort<umber(11'&) Service]dbc service 7 ne8 Service]dbc() service.set:ataSource(dataSource) 4erson person 7 ne8 4erson() person.set<ame(*administrator*) person.set4ass8ord(*p8d*) service.save(person) System.out.println(*id 3 * E person.get=d()) System.out.println(*name3 * E person.get<ame()) try { dataSource.getDonnection().close() ! catc. (Sb;@,ception e,) { e,.printStac09race() ! ! !

Seperti terlihat dalam kode di atas, abstraksi HH, jadi terlihat dengan jelas, kode menjadi rapi dan mudah dibaca dengan hilangnya try-catch untuk menhandle SI.MLception. ,emisahan layer seperti ini juga sangat strategis dalam pembagian tugas antar developer. Misalnya dalam satu team terdapat developer senior dan junior, keduanya bisa mengerjakan bagian yang berbeda tanpa harus menunggu bagian lain selesai. Developer senior mengerjakan bagian backend ke database, kemudian membuat kerangka kode D:H dan Service ini, di tahap a"al project, kode D:H dan Service masih kosong menunggu re\uirement di approve oleh client. Dengan menggunakan kerangka kode ini, Developer junior yang bertugas untuk membuat F sudah bisa langsung menggunakan kode D:H dan Service. Setelah proses re\uirement selesai, Developer senior bisa mulai mem?nalisasi kode D:H dan Service, developer junior tidak perlu merubah kodenya sama sekali karena perubahan di sisi D:H dan Service tidak berpengaruh sama sekali di kode F . Semakin besar ukuran tim dalam project, semakin penting pemisahan layer kode ini untuk mendukung kerja tim agar tidak saling menunggu anggota tim lain menyelesaikan tugasnya, selama kerangka kodenya sudah dibuat, anggota tim lain sudah bisa mulai mengerjakan tugasnya. Setelah mengenal JD!$, kita akan membahas cara mengakses database yang lebih baik dengan

manggunakan +ibernate. Dengan menggunakan +ibernate kode program yang akan dibuat akan lebih ringkas dan terlihat konsep HH, dibanding dengan JD!$ murni. +ibernate adalah frame"ork H-M untuk memetakan tabel dalam database dan class dalam konsep HH, . Dengan menggunakan +ibernate kode program kita akan lebih rapi dan terlihat HH, .

!)M- /i"ernate dan *$ring


:kses database menggunakan kode JD!$ murni memerlukan kode yang cukup panjang, bisa dilihat dari class D:H dan class Service di bagian sebelumnya. Selain itu SI.MLception juga ada di mana-mana, penggunaan transaction juga masih manual dengan memanggil kode begin, rollback dan commit. !agian ini akan membahas konsep akses database menggunakan HH, menggunakan konsep H-M dan frame"ork hibernate. Selain itu akan dibahas juga penggunaan Spring untuk menangani transaction dengan menerapkan konsep declarative transaction menggantikan programatic transaction yang digunakan di bagian sebelumnya. (alau masih a"am dengan semua istilah di atas, jangan kha"atir. :kan kita bahas satu per satu konsep H-M, +ibernate, declarative transaction vs programatic transaction dan spring di bagianbagian selanjutnya.

"b.e&t 1elational

appin!

Hbject -elational Mapping 3H-M5 adalah sebuah frame"ork yang dapat menjembatani perbedaan sistem basis data yang bersifat relational dengan paradigma pengembangan aplikasi yang berorientasi objek. Setiap objek yang akan memetakan menjadi tabel-tabel pada basis data relasional dibungkus oleh suatu interface dengan menerapkan konsep design pattern. +al tersebut bertujuan untuk memudahkan lapisan aplikasi 3controller5 mengakses data tersebut. ,b-ect .elational (appin% merupakan teknik otomasi dan transparansi dari ob-ect persistence ke dalam tabel pada basis data, menggunakan metadata yang mendeskripsikan pemetaan antara objek dan basis data. H-M berperan dalam lapisan model dalam konsep M@$. Model adalah sebuah lapisan yang paling dekat dengan sumber data, baik itu berasal dari basis data, webservice, maupun /le s stem. ,b-ect .elational (appin% 3H-M5 juga mengatasi perbedaan sistem basis data yang bersifat relational dengan paradigma pengembangan aplikasi yang berorientasi objek. Selain itu, H-M juga menjembatani dialek SI. yang digunakan, sehingga apapun produk -D!MS yang digunakan tidak berpengaruh terhadap kode program. H-M merupakan solusi yang mengatasi perbedaan aspek-aspek ketidaksesuaian antara konsep pemrograman berorientasi objek dengan konsep basis data relasional.

Hibernate
,roject hibernate dimulai pada tahun %&&) oleh Kavin (ing, project ini mulai mendapat tanggapan serius setelah Kavin (ing dipekerjakan oleh Jboss dan Jboss mulai mengerahkan pasukan lebih banyak lagi untuk mengelola +ibernate secara serius. (eberhasilan +ibernate sangat fenomenal, bahkan di satu titik +ibernate justru lebih terkenal dibanding konsep H-M itu sendiri. +ibernate Q Spring benar-benar menohok MJ! %.) secara telak, sehingga dalam rilis versi berikutnya, MJ! 7.&, diperkenalkan konsep J,: yang mengambil ilham dari +ibernate. Sekarang ini +ibernate, bersama i!atis, sudah menjadi pemimpin pasar di backend frame"ork untuk mengkabstraksi JD!$. Semenjak versi 7.4 hibernate dilengkapi dengan +ibernate :nnotation dan juga +ibernate secara resmi menjadi salah satu implementasi J,:. Sedangkan J,: sendiri pada dasarnya hanya :, yang "ujud nyatanya adalah sekumpulan interface seperti halnya JD!$. mplementasi J,: yang dikenal selain +ibernate adalah Toplink. :nnotation dengan +ibernate bisa diimplementasikan dengan tiga cara/ menggunaka J,: annotation, menggunakan murni +ibernate :nnotation atau mencampur antara keduanya. !agaimana membedakan hibernate annotation dan J,: annotationZ $ukup dilihat import dari annotationya, jika diimport dari javaL.persistence berarti J,: annotation, kalau diimport dari org.hibernate.mapping berarti +ibernate annotation.

*eature dari +ibernate annotation lebih lengkap dibanding J,: annotation. ,endekatan yang digunakan dalam buku ini adalah secara default menggunakan J,: :nnotation, jika ada feature mapping yang tidak ada di dalam J,: annotation, maka baru digunakan +ibernate annotation. :nda tidak perlu bingung harus menggunakan yang mana, karena pada dasarnya implementasi di belakang annotation ini ya +ibernate itu sendiri, jadi menggunakan cara yang manapun hasilnya sama saja. Secara teknis tidak ada bedanya, hanya masalah pilihan saja. ,roject +ibernate mempunyai pengaruh yang sangat besar, selain mempengaruhi MJ! dengan dilahirkanya J,:, +ibernate project juga menghasilkan +ibernate @alidation yang merupakan cikal bakal !eans @alidation yang akhirnya masuk JS-. Selain itu ada project +ibernate Search yang bertujuan untuk membuat full teLt indeLing dari table-table yang dikelola +ibernate, sehingga bisa dilakukan full teLt search terhadap table tersebut, sangat po"erfull. ,roject berikutnya adalah +ibernate Shards, project ini bertujuan untuk memberikan kemampuan pemisahan table dalam bebebrapa instance database, alias distributed database.

"b.e&t persisten&e
Dalam pengembangan sistem, pengertian persistence adalah objek yang dihasilkan dari suatu sistem yang dapat disimpan dalam "aktu lama bahkan bersifat permanen. ,b-ect 0ersistence bisa disimpan dalam bentuk basis data relasional, /le s stem dalam harddisk, /le ]M., 1eb Service, ,+2(S 3,b-ect +ata 2ase (ana%ement S stem4" dan .D:, . 0amun ,b-ect 0ersistence yang paling banyak digunakan dalam pengembangan perangkat lunak adalah basis data relasional. !asis data relasional mudah dibuat dan diakses. Dengan ob-ect persistence, data yang terkandung pada objek tersebut dapat dengan mudah disimpan dan diakses. ,b-ect persistence bersifat abstrak, dapat menyembunyikan rincian mekanisme bagaimana suatu data disimpan dan diakses, seingga tidak terlihat oleh objek lainnya. Hbject persistence yang dimaksud dalam buku ini dibatasi hanya ke -D!MS.

"b.e&t0relational mismat&*
,b-ect-relational mismatch adalah ketidaksesuaian antara basis data yang menggunakan konsep relasional dengan pengembangan aplikasi yang menggunakan konsep berorientasi objek. (etidaksesuaian tersebut meliputi aspek/

(ranularity
,emecahan entit pada atribut-atribut yang lebih kompleks. Misalnya class ,erson mempunyai atribut address dengan tipe data :ddress. Sedangkan pada basis data relasional tidak memungkinkan pada tabel ,M-SH0 ada kolom address dengan tipe data address, yang mungkin dilakukan adalah memecah address menjadi streetSaddress, citySaddress, Bip$odeSaddress.

*u"ty$es
,embeda antara superclass dan subclass. ,ada pemrograman berbasis objek dikenal istilah inheritance 3pe"arisan5 dari class parent kepada class child. Sedangkan pada basis data relasional tidak dikenal proses pe"arisan antar tabel.

Identity
Terdapat perbedaan fungsi antara lambang sama dengan 3[5 dan method e5uals34" pada objek tetapi merujuk nilai yang sama pada primar ke basis data relasional.

Association
+ubungan dua entitas pada objek dikenal dengan re!erences sedangkan pada relasional dikenal dengan !orei%n ke . :sosiasi antar entity terdiri dari/ one-to-one" one-to-man , dan man -to-man .

7avigasi data
,roses pencarian pada basis data menggunakan -oin table sedangkan pada objek memanggil suatu method %etter. 0avigasi dibagi dua macam berdasarkan arahnya, antara lain/ directional dan bidirectional.

Impelementasi "1 Ketidaksesuaian

untuk

en!atasi

asala*

Mntity class merupakan class yang merepresentasikan setiap tabel pada basis data. Mntity berfungsi sebagai jembatan penghubung antar lapisan dalam aplikasi. Dengan pola ini proses perpindahan data menjadi sederhana dan terintegrasi. Mntity dibuat berdasarkan FM. class diagram yang telah dirancang. Mntity berisi class 6ava2ean yang setiap propertinya akan merepresentasikan atribut-atribut pada tabel. ,roses pemetaan 7ntit menjadi tabel terjadi ketidaksesuaian antara tabel yang berasal dari basis data relasional dan class -ava2eans yang berorientasi objek. (etidaksesuaian tersebut dapat di atasi dengan menggunakan konsep H-M sehingga setiap tabel bisa merepresentasikan class DTH dan diakses sebagai objek. Fraian berikut menjelaskan implementasi konsep H-M untuk mengatasi ketidaksesuaian yang meliputi tiga aspek yaitu aspek identitas, asosiasi, dan navigasi.

Identitas
Terdapat perbedaan pengenal identitas antara objek dan tabel. ,ada objek identitas dibedakan menjadi nilai dan alamat memorinya. Sehingga terdapat dua notasi yang melambangkan kesamaan suatu identitas pada objek Java, yaitu lambang samadengan (==5 dan method equals(). $ontoh / a == b, berarti variabel a dan b memegang alamat re!erence yang sama pada memori. 3a.equals(b)), secara lojik mempunyai nilai yang sama. ,ada basis data relasional, identitas dari suatu tabel disebut dengan primar ke . Dengan demikian, sering kali terjadi objek yang secara lojik sama 3 a.equals(b)5 dan me"akili satu baris dalam tabel basis data, tetapi objek tersebut tidak berada pada satu lokasi alamat memori yang sama. H-M mengatasi ketidaksesuaian tersebut dengan menambah properti identit pada setiap entity. Dengan demikian pengujian apakah class a sama dengan class b bisa ditulis seperti berikut/ a.getId().equals(b.getId()).

Asosiasi
(ebanyakan entitas pada basis data mempunyai keterhubungan dengan entitas yang lainnya. Mlemen yang menghubungkan kedua tabel tersebut ditandai dengan !orei%n ke . ,ada objek, elemen penghubung dua objek ditandai dengan sebuah re!erence ob-ect. 0amun permasalannya adalah pada re!erence ob-ect yang menghubungkannya bergantung pada arah asosiasinya 3direction o! relationship5. :pabila asosiasi antara dua objek terjadi pada dua arah, maka harus dide?nisikan dua kali pada setiap classnya. :kan tetapi !orei%n ke pada tabel relasional, tidak mengenal arah dari asosiasinya, karena asosiasi antara dua tabel dihubungkan dengan table -oin atau pro-ection. :sosiasi antara dua entitas terdiri dari one-to-one" one-to-man , dan man -to-man .

7avigasi data
Masalah navigasi data adalah problem bagaimana mengakses suatu objek dari objek lain. Menurut arahnya, navigasi terbagi menjadi dua macam, yaitu/ unidirectional dan bidirectional. ,ada premrograman berbasis objek, proses akses properti objek dari objek lain bisa langsung menggunakan method %etter. :pabila arah navigasinya unidirectional, maka tidak terdapat properti objek tersebut di object la"anya. Sehingga dari satu arah relasi bisa terlihat, tapi di sisi lain relasi tidak terlihat. Sedangkan pada basis data relasional, konsep arah navigasi tidak mempengaruhi proses akses data. Misalnya sebuah table mempunyai relasi one-to-man kemudian !orei%n ke berada pada tabel la"anya, akan tetapi arah navigasi dari asosiasi yang menghubungkannya tidak

berpengaruh. Selama ada !orei%n ke yang menghubungkan kedua tabel, proses \uery yang melibatkan kedua tabel bisa dijalankan. Teorinya cukup dua halaman setengah saja, bahasan berikutnya lebih banyak praktek dan membuat kode.

appin! Seder*ana
+ibernate mapping dapat dilakukan dengan dua cara / menggunakan Lml atau menggunakan annotation. (arena sekarang Java 4 dan Java ; sudah laBim di gunakan maka hanya akan dibahas mapping hibernate menggunakan annotation saja. (alau si bos masih memaksa menggunakan Lml silahkan mulai organisasi teman-teman satu project untuk mengadakan pemogokan kerja /D. ,emaksaan menggunakan ]M. adalah melanggar hak asasi programmer untuk menggunakan teknologi terbaru dan tools terbaik yang tersedia. ,ersiapan yang harus dilakukan sebelum memulai membuat mapping sederhana adalah menambahkan library +ibernate J,: ke dalam project Java. Di dalam library +ibernate J,: terdapat Di bab sebelumnya yang membahas JD!$ sudah ada class ,erson yang dimapping dengan table TS,M-SH0, nah class tersebut akan diubah dan didekorasi dengan hibernate annotation sehingga proses mapping bisa terjadi secara otomatis. Setelah ditambahkan hibernate annotation, class ,erson akan terlihat seperti ini / ^@ntity ^9able(name7*9(4@6SA<*) public class 4erson implements Seriali?able { ^=d ^SeneratedPalue(strategy7Seneration9ype.IG9A) ^Dolumn(name7*=:*) private ;ong id ^Dolumn(name7*name*+uni\ue7true+lengt.7%'') private String name ^Dolumn(name7*4ISSWA6:*+uni\ue7true+lengt.7)'') private String pass8ord public String get<ame() { return name ! public void set<ame(String name) { t.is.name 7 name ! public String get4ass8ord() { return pass8ord ! public void set4ass8ord(String pass8ord) { t.is.pass8ord 7 pass8ord ! public ;ong get=d() { return id ! public void set=d(;ong id) { t.is.id 7 id ! ! Mari kita bahas satu-satu a keong 385 yang ada di dalam class ,erson ini. 8Mntity digunakan untuk mendeklarasikan bah"a class ,erson adalah Mntity class. 8Mntity hanya bisa dipasangkan dengan deklarasi class saja.

8Table digunakan untuk meletakkan de?nisi dan kon?gurasi dari table yang akan dimapping dengan class Mntity. Di dalam 8Table terdapat attribute name yang digunakan untuk mende?nisikan nama table yang akan dimapping dengan class ,erson yaitu TS,M-SH0. 8 d digunakan untuk menandakan sebuah property sebagai primary key. (onsekuensinya adalah nilai property harus uni\ue dan tidak boleh null. 8 d harus ada di salah satu property Mntity class, kalau tidak ada hibernate akan teriak-teriak bah"a syarat entity tidak dipenuhi. !agaimana jika ingin punya table yang tidak mempunyai primary key tapi ingin dijadikan MntityZ Tidak bisa. Setiap Mntity akan dimapping ke table dan tablenya harus mempunyai primary key, kalau tidak ada primary key table tersebut tidak bisa dimapping ke Mntity class, bisanya dimapping ke 8$omponent, apa itu 8$omponentZ :kan dibahas di bagian, bagian berikutnya, sabar ya. 8Kenerated@alue digunakan berpasangan dengan 8 d untuk menandakan primary digenerate secara otomatis oleh database. Di MySI. 8Kenerated@alue akan diterjemahkan dengan menandai kolom D sebagai autoSincrement. 8Kenerated@alue mempunyai dua attribute. :ttribute pertama adalah strategy, yang digunakan untuk menentukan bagaimana primary key akan digenerate. :ttribute kedua adalah generator, nilai attribute ini berupa nama generator untuk id-nya, bisa juga diisi dengan nama Se\uence kalau menggunakan -D!MS yang mendukung se\uece, seperti Hracle. Topik ini akan dibahas panjang lebar di bab +ibernate Mapping. 8$olumn digunakan untuk mengatur struktur kolom. !erikut ini attribute apa saja yang mungkin digunakan dalam 8$olumn / name / nama kolom, nama kolom default sama dengan nama property uni\ue / menambahkan uni\ue constraint agar tidak ada % baris yang sama nullable / mengijinkan nilai column bisa diisi null atau tidak insertable / apakah kolom ini diikutkan dalam \uery insert apa tidak updatable / apakah kolom ini diikutkan dalam \uery update apa tidak columnDe?nition / override s\l DD. untuk kolom ini, tidak disarankan untuk digunakan karena tidak portable untuk semua database. Setiap \uery DD. untuk database berbeda akan mempunyai s\l yang berbeda pula. Table / mende?nisikan table target, default adalah table yang ada di 8Mntity length / panjang data dari kolom ini precision / menyimpan berapa panjang angka pecahan di belakang koma dari angka desimal scale / menyimpan panjang digit angka desimal

,roses mapping di atas sangat sederhana dan belum mencakup semua mapping feature di hibernate secara lengkap. Fntuk sementara proses mapping dibatasi hanya untuk mapping sederhana, kemudian dilanjutkan ke kon?gurasi hibernate hingga setting spring H-M. Setelah mengatahui feel dari hibernate, baru akan dibahas mapping yang lebih advance lagi.

Konfi!urasi Hibernate
Setelah selesai membuat Mntity class dan annotation mapping, langkah berikutnya adalah membuat kon?gurasi hibernate / hibernate.cfg.Lml Membuat hibernate.cfg.Lml dengan 0et!eans sangat mudah, pilih menu *ile -C 0e", kemudian di dalam jendela pilih +ibernate di sebelah kiri dan +ibernate $on?guration #iBard di sebelah kanan. Jendela berikutnya meminta untuk memilih connection ke database yang akan digunakan. Jika belum ada silahkan pilih 0e" Database $onnection untuk membuat koneksi ke database yang baru. +ibernate.cfg.Lml harus berada dalam classpath ketika aplikasi di jalankan, cara paling gampang yaitu dengan menyimpan hibernate.cfg.Lml di dalam src folder. (lik H(, berikutnya jendela visual editor untuk hibernate.cfg.Lml akan muncul seperti gambar di ba"ah ini /

Pang visual-visual sudah kuno dan gak macho, jadi kita buka jendela ]M. kemudian edit hibernate.cfg.Lml menjadi seperti berikut ini /
TW,ml version7*%.'* encoding7*G9H$N*WV T!:AD9_4@ .ibernate$con/iguration 4G>;=D *$CCHibernateCHibernate Don/iguration :9: 1.'CC@<* *.ttp3CC.ibernate.source/orge.netC.ibernate$con/iguration$1.'.dtd*V T.ibernate$con/igurationV Tsession$/actoryV Tproperty name7*.ibernate.dialect*Vorg..ibernate.dialect.BySb;=nno:>:ialectTCpropertyV Tproperty name7*.ibernate.connection.driver(class*Vcom.mys\l.#dbc.:riverTCpropertyV Tproperty name7*.ibernate.connection.url*V#dbc3mys\l3CClocal.ost311'&CposTCpropertyV Tproperty name7*.ibernate.connection.username*VrootTCpropertyV Tproperty name7*.ibernate..bm)ddl.auto*VcreateTCpropertyV Tproperty name7*.ibernate.s.o8(s\l*VtrueTCpropertyV Tproperty name7*.ibernate./ormat(s\l*VtrueTCpropertyV Tmapping class7*com.googlecode.pro#ecttemplate.pos.model.4erson*CV TCsession$/actoryV TC.ibernate$con/igurationV

Sekarang kita bahas satu persatu kon?gurasi di atas. +ibernate.cfg.Lml dimulai dengan tag Ahibernate-con?gurationC kemudian diikuti dengan tag Asession-factoryC di dalam tag session-factory terdapat tag-tag property dan tag-tag mapping. Tag property mende?nisikan hal-hal umum dalam kon?gurasi +ibernate, sedangkan tag mapping digunakan untuk mendaftar semua class Mntity. hibernate.dialect digunakan untuk mende?nisikan database apa beserta dialect khusus dari datababase tersebut. Misalnya MySI. nnoD!Dialect atau HracleDialect. Dengan menggunakan hibernate, kalau mau ganti database tinggal mengganti dialect ini maka aplikasi akan jalan dengan sangat lancar, tidak perlu melakukan perubahan signi?kan. hibernate.connection.driverSclass mende?nisikan driver yang dipakai untuk database. hibernate.connection.url berisi JD!$ url connection ke database server. hibernate.connection.username dan hibernate.connection.pass"ord username dan pass"ord ke database server. berisi informasi

hibernate.hbm%ddl.auto digunakan untuk memerintahkan hibernate mengenerate table-

table yang akan dimapping secara otomatis. si dari kon?gurasi ada beberapa, antara lain/ create semua table yang sudah ada akan didrop dan dibuat table-table baru. update table yang lama tidak didrop hanya dirubah seperlunya saja dengan menggunakan alter table. validate table yang ada tidak diotak-atik, hanya kalau antara mapping dan table yang sudah ada tidak sinkron, maka hibernate akan mengeluarkan error. create-drop setiap kali hibernate ditutup semua table akan didrop dan dibikin ulang ketika hibernate dibuka kembali.

hibernate.sho"Ss\l digunakan untuk memerintahkan hibernate menampilkan \uery yang digenerate oleh +ibernate dalam jendela Hutput ketika aplikasi berjalan. hibernate.formatSs\l s\l yang ditunjukkan dalam Hutput diformat agar tampilanya bagus dan mudah dibaca

Sekarang hanya ada satu tag mapping yang isinya class ,erson yang sudah kita buat sebelumnya, jika ada lebih dari satu class Mntity dalam project, buat lagi tag mapping untuk mendaftar semua class Mntity.

en.alankan Hibernate
Setelah class Mntity dan hibernate.cfg.Lml sudah selesai dibuat, saatnya untuk menjalankan +ibernate dan mencoba menyimpan atau menampilkan data dari database. !uat class baru, namakan saja Main+ibernate, kemudian ketik kode di ba"ah ini / public class BainHibernate { public static void main(String[] args) { SessionHactory sessionHactory 7 Don/iguration().buildSessionHactory() 4erson p 7 ne8 4erson() p.set<ame(*dian*) p.set4ass8ord(*p8ddian*) Session session 7 sessionHactory.openSession() try { session.begin9ransaction() session.save(p) session.get9ransaction().commit() ! catc. (Hibernate@,ception .ibernate@,ception) { session.get9ransaction().rollbac0() ! session.close() session 7 sessionHactory.openSession() buery \uery 7 session.createbuery(*/rom 4erson*) ;istT4ersonV persons 7 \uery.list() /or (4erson person 3 persons) { System.out.println(*id 3 * E person.get=d()) System.out.println(*name 3 * E person.get<ame()) System.out.println(*pass8ord 3 * E person.get4ass8ord()) ! session.close() sessionHactory.close()

Sebelum bisa menjalankan kode di atas, anda harus menambahkan library +ibernate J,: ke project, kemudian klik kanan ?le, pilih -un. Setelah proses run selesai, table TS,M-SH0 akan dibuat di database dan satu baris data akan diinsert. Silahkan cek database untuk mengetahui apakah kode sukses dieksekusi atau tidak. 0ah terlihat bah"a kode sangat rapi, untuk proses insert tidak perlu membuat \uery insert, table digenerate secara otomatis, \uery menjadi pendek dan abstraksi HH, dari aplikasinya memudahkan kode dimengerti 9 dibaca orang lain.

Class0&lass 'entin! dalam Hibernate


Session*actory adalah jantung dari +ibernate. Session*actory hanya dibuat satu kali dan cuma satu object untuk setiap aplikasi. ,ada "aktu aplikasi start, Session*actory akan dibuat dan akan ditutup tepat pada "aktu aplikasi diakhiri. Dalam JD!$ posisi Session*actiry ini setara dengan $onnection. Session adalah class yang dibuat sebelum proses eksekusi perintah-perintah yang berurusan dengan database. Session mempunyai daur hidup yang sangat pendek, seperti terlihat dalam kode di atas, setelah proses insert dilaksanakan maka session segera ditutup, proses \uery di ba"ahnya menggunakan object session yang berbeda. Session harus diperlakukan seperti ini, jangan sampai dalam satu aplikasi hanya membuka satu session kemudian digunakan di semua bagian aplikasi. (enapa tidak boleh seperti ituZ (arena kalau proses ke database yang dilakukan oleh session gagal, maka object session ini menjadi tidak synchroniBed dengan database, untuk menghindari hal seperti ini sebaiknya object session segera ditutup ketika satu atomic activity selesai dijalankan. Session mempunyai reference ke class Transaction yang mengatur proses transaction. Session mempunyai kemampuan untuk memulai, mengcommit dan merolback transaction. (emungkinan besar kode aplikasi kita hanya akan berisi class Session saja, sedangkan Session*actory hanya ada dalam kon?gurasi saja. Iuery adalah class yang mengimplementasikan \uery spesi?k hibernate yaitu +ibernate Iuery .anguage. +I. ini nantinya akan diterjemahkan ke \uery yang spesi?k ke database sesuai dengan settingan hibernate.dialect.

en!!unakan Hibernate den!an Sprin! "1


Spring adalah Dependency njection 3D 5 atau nversion of $ontrol 3 o$5. Tugas utama Spring adalah memanage object-object yang dibutuhkan dalam aplikasi. Misalnya Session*actory dan Session adalah object-object yang diperlukan untuk bekerja dengan +ibernate, Spring dapat membantu memanage object-object ini sehingga kode infransturktur 3boiler code5 dapat dikurangi secara signi?kan karena dihandle oleh Spring. (ode infrasturktur 3boiler plate code5 contohnya adalah membuka dan menutup Sesssion, menangani transaction seperti transaction begin, commit dan rollback. Spring akan mengambil alih tanggung ja"ab untuk memanage kode infrastruktur ini dari tangan developer, hal ini sangat strategis karena developer seringkali lupa untuk menulis kode infrastruktur yang dapat mengakibatkan memory leak atau merusak konsistensi data. ,eranan utama Spring dalam aplikasi desktop cukup besar, salah satu tugas utama Spring adalah memanage +ibernate agar developer tidak perlu secara manual harus membuat kode untuk membuka menutup session 3transparent Session management5 dan menangani transaction 3declarative transaction5. Transaction yang ditangani secara manual dengan kode disebut gaya pemrograman ,rogramatic Transaction, sedangkan gaya pemrograman yang menyerahkan penanganan transaction ke frame"ork disebut Declarative Transaction. !agaimana perbandigan kedua gaya ini akan dibahas lebih lanjut di bagian berikutnya. Spring mempunyai feature :spect Hriented ,rogramming 3:H,5 yang menjadi tulang punggung dibalik implementasi declarative transaction dan transparent Session management.

:H, memungkinkan Spring menyisipkan kode untuk memulai transaction kemudian membuka session pada saat sebuah method dalam service akan dieksekusi, kemudian disisipkan pula kode untuk merollback dan menutup session ketika method dalam service muncul eLception, dan setelah method selesai dilaksanakan Spring menyisipkan kode untuk mengcommit transaction plus menutup session. Semua proses penyisipan kode ini dilakukan secara runtime dan transparan terhadap developer. Sehingga developer cukup berkonsentrasi untuk mengimplementasikan bussiness logic tanpa harus kha"atir lupa mengcommit transaction atau menutup Session.

/i"ernate DA! menggunakan *$ring


.angkah berikutnya setelah mapping Mntity ,erson dan hibernate con?guration selesai dibuat adalah membuat D:H dan Service. (edua pattern ini mengikuti pattern yang sudah diterangkan dalam bagian JD!$, tidak perlu diterangkan secara panjang lebar tentang teori dan kegunaanya. +ibernate D:H dengan bantuan Spring menjadi sangat rapih karena tidak memerlukan kode untuk memanage Session, proses pembukaan dan penutupan session dilakukan oleh Spring secara transparan. Sebelum proses pembuatan D:H dimulai, persiapkan dulu project dengan menambahkan library Spring *rame"ork versi %.4.;. (alau anda menggunakan 0et!eans versi ;.6 dan ke ba"ah, silahkan do"nload dahulu Spring *rame"ork dari http/99""".springsource.org9do"nload, Spring library yang diba"a 0et!eans ;.1 mempunyai versi %.4.; dan versi 7.&, versi Spring ini tidak mempunyai beberapa class yang diperlukan dalam buku ini. !uat calss ,ersonDao di package com.googlecode.projecttemplate.pos.dao kemudian ketik kode berikut ini / ^Domponent public class 4erson:ao { ^Iuto8ired private SessionHactory sessionHactory public 4erson save(4erson person){ sessionHactory.getDurrentSession().saveArGpdate(person) ! public 4erson delete(4erson person){ sessionHactory.getDurrentSession().delete(person) ! public ;ong count(){ return (;ong) sessionHactory.getDurrentSession() .createbuery(*select count(L) /rom 4erson p*) .uni\ue6esult() ! public 4erson get>y=d(;ong id){ return (4erson) sessionHactory.getDurrentSession() .createbuery(*/rom 4erson p 8.ere p.id73id*) .set4arameter(*id*+ id) .uni\ue6esult() ! public ;istT4ersonV getIll(){ return sessionHactory.getDurrentSession() .createbuery(*/rom 4erson p*) .list() ! public ;istT4ersonV getIll(int start+ int num){ return sessionHactory.getDurrentSession() .createbuery(*/rom 4erson p*) .setHirst6esult(start) .setHetc.Si?e(num) .list() ! !

(ode di atas memperlihatkan annotation dari Spring, yaitu 8$omponent, annotation ini digunakan untuk menandai suatu class akan dimanage oleh Spring, istilahnya adalah Spring !ean. :rtinya class D:H ini proses pembuatan object-nya akan dilakukan oleh Spring. Hbject dari D:H akan dibuat satu dan hanya satu saja, pattern ini disebut Singleton. ,attern Singleton menyaratkan bah"a sebuah class hanya mempunyai satu instance 9 object. Semua class yang masuk dalam kategory Spring !ean dapat diinject ke Spring !ean lain dengan menggunakan annotation 8:uto"ired. :nnotation kedua dari Spring adalah 8:uto"ired, annotation ini digunakan untuk menandai sebuah property harus diinject oleh Spring dan diambil dari kumpulan Spring !ean. Seperti dalam contoh D:H ini, Spring akan berusaha mencari instance dari Session*actory di dalam koleksi Spring !ean. (alau ketemu, instence akan diletakkan dalam property tersebut, kalau tidak ketemu Spring akan mengeluarkan eLception. Di chapter sebelumnya, pada bagian JD!$ kode untuk membuat D:H, Service dan connection kita harus rangkai sendiri. D:H diinstansiasi, Service juga diinstantiasi, kemudian proses pembuatan koneksi juga dilakukan di dalam kode Java. 0ah proses merangkai kode ini bisa dilakukan dengan elegan menggunakan feature Dependency njection dari Spring. Setiap class yang ditandai dengan 8$omponent akan diinsatansiasi oleh spring, kemudian semua dependency dari class 8$omponent yang ditandai dengan 8:uto"ired diambil 3dirangkai5 dari kumpulan Spring !ean. 0anti akan kita lihat lebih banyak lagi penggunaan Spring !ean di topik yang lebih advance.

(eneric DA!
!entuk D:H cukup repetitif, terutama fungsi-fungsi dasar seperti save, delete, get!y d dan get:ll. ,roses pembuatan D:H bisa dipersingkat dengan membuat generic D:H, kemudian semua D:H akan eLtends generic D:H ini dan menambahkan generic classnya. Tidak perlu banyak dijelaskan lagi, langsung saja kita lihat bentuknya public class >ase:aoHibernateT9V { ^SuppressWarnings(*unc.ec0ed*) protected Dlass domainDlass ^Iuto8ired protected SessionHactory sessionHactory ^SuppressWarnings(*unc.ec0ed*) public >ase:aoHibernate() { t.is.domainDlass 7 (Dlass) ((4arameteri?ed9ype) getDlass().getSenericSuperclass()) .getIctual9ypeIrguments()['] ! public 9 save(9 domain) { sessionHactory.getDurrentSession().saveArGpdate(domain) ! ^SuppressWarnings(*unc.ec0ed*) public 9 get>y=d(;ong id) { return (9) sessionHactory.getDurrentSession().get(domainDlass+ id) ! public 9 delete(9 domain) { sessionHactory.getDurrentSession().delete(domain) ! ^SuppressWarnings(*unc.ec0ed*) public ;ong count() { ;ist list 7 sessionHactory.getDurrentSession().createbuery( *select count(L) /rom * E domainDlass.get<ame() E * ,*).list() ;ong count 7 (;ong) list.get(') return count ! ^SuppressWarnings(*unc.ec0ed*)

public ;istT9V getIll() { return sessionHactory.getDurrentSession().createbuery(*/rom * E domainDlass.get<ame()) .list() ! ^SuppressWarnings(*unc.ec0ed*) public ;istT9V getIll(int start+ int num) { return sessionHactory.getDurrentSession().createbuery(*/rom * E domainDlass.get<ame()) .setHirst6esult(start).setBa,6esults(num) .list() !

0ah setelah generic D:H di atas udah jadi, ,ersonDao yang sebelumnya harus menulis satu-satu kodenya tinggal eLtends !aseDao+ibernate di atas dan mengganti T dengan class ,erson. Seperti di ba"ah ini / ^Domponent public class 4erson:ao e,tends >ase:aoHibernateT4ersonV{ ! -ingkas sekali bukanZ Dari sekian puluh baris hanya menjadi empat baris saja. *ungsi-fungsi D:H yang ada di dalam !aseDao+ibernate di atas sangat terbatas untuk fungsi-fungsi dasar dari operasi data, besar kemungkinan akan dibutuhkan fungsi-fungsi yang jauh lebih kompleks, fungsifungsi yang kompleks dan spesi?k ini harus dibuat manual.

*$ring *ervice
Setelah menyelesaikan D:H, langkah berikutnya adalah membuat Spring Service. !erbeda dengan D:H yang merupakan class, Spring Service sebaiknya dibuatkan interface, kemudian diimplementasikan oleh class. Misalnya untuk contoh Mntity ,erson, buat ,ersonService yang merupakan interface dan ,ersonService mpl yang merupakan class implementasi dari ,ersonService. Di bagian selanjutnya akan diterangkan lebih lanjut tentang magic yang ada dalam Spring Service ini dan kenapa sebaiknya Spring Service dibuatkan interface dan implementasinya. Sama halnya dengan Service yang sudah dibuat di bab JD!$, Spring Service ini tugasnya untuk menangani transaksi dan tempat untuk menulis bussiniss process logic. Di contoh ,ersonService logic bussinesss processnya masih sangat sederhana, sehingga terlihat cuma sebagai kepanjangan tangan D:H. Di kasus yang sebenarnya, dalam satu method di dalam Spring Service biasanya terdapat banyak sekali kode untuk melakukan banyak hal, mengupdate beberapa table sekaligus. Service dapat memanfaatkan kode yang sudah ada di dalam D:H, dan sebaiknya di dalam Service tidak menulis kode yang langsung mengakses Session*actory, semua kode yang mengakses Session*actory sebaiknya diletakkan di dalam D:H. +al ini dimaksudkan untuk mengelola kode dengan rapi dan disiplin. Transaction management dengan menggunakan Spring Service berbeda dengan service yang kita buat di bab JD!$. Spring Service tidak perlu memanage transaksi secara manual, dengan memulai transaksi, commit dan rollback. Transaction Management di Spring Service dilaksanakan secara transparan, artinya kita sebagai programmer Spring tidak perlu tahu detail bagaimana Spring Service menangani transaction, kita hanya perlu tahu bah"a method-method dalam Spring Service yang ditandai 8Transactional akan memulai transaction ketika masuk ke method, mencommit sesaat setelah keluar dari method dan merollback transaction kalau ada eLception ketika method tersebut dieksekusi. Teknik penanganan transaction secara transparan ini disebut sebagai Declaraitive Transaction, sedangkan penanganan transaction secara manual seperti di JD!$ Service, disebut sebagai ,rogramatic Transaction. Di ekosistem Java, hanya MJ! dan Spring saja yang mempunyai feature Declarative Transaction. Spring Service mempunyai karakteristik yang mirip dengan Stateless Session !ean dari MJ!, yaitu method-methodnya transactional.

!erikut ini contoh ,ersonService di package com.googlecode.projecttemplate.pos.service dan class ,ersonService mpl di package com.googlecode.projecttemplate.pos.service.impl public inter/ace 4ersonService { void save(4erson person) void delete(4erson person) ;ong count() 4erson get4erson(;ong id) ;istT4ersonV get4ersons() ;istT4ersonV get4ersons(int start+ int num) ! Setiap method dari ,ersonService di atas diimplemetasikan oleh class ,ersonService mpl ^Service(*personService*) ^9ransactional(readAnly7true) public class 4ersonService=mpl implements 4ersonService{ ^Iuto8ired private 4erson:ao person:ao ^9ransactional(readAnly7/alse) public void save(4erson person) { person:ao.save(person) ! ^9ransactional(readAnly7/alse) public void delete(4erson person) { person:ao.delete(person) ! public ;ong count() { return person:ao.count() ! public 4erson get4erson(;ong id) { return person:ao.get>y=d(id) ! public ;istT4ersonV get4ersons() { return person:ao.getIll() ! public ;istT4ersonV get4ersons(int start+ int num) { return person:ao.getIll(start+ num) ! ! Dalam class ,ersonService mpl di atas, terdapat beberapa annotation dari Spring. :nnotation pertama adalah 8Service yang digunakan untuk menandai bah"a class ini adalah Spring Service, terdapat satu parameter yaitu EpersonServiceG yang merupakan nama dari Spring Service ini. 8Service mempunyai fungsi yang sama dengan 8$omponent dalam class D:H, yaitu menandai bah"a class ini nantinya akan diinstansiasi oleh Spring dan instansiasi-nya disebut sebagai Spring !ean. 8Transactional digunakan untuk menandai method-method dalam Spring Service merupakan satu area transaksi. ,arameter readHnly menandai apakah method tersebut dapat melakukan operasi insert9update9delete dalam database. 8Transactional dapat digunakan untuk mendandai class sehingga semua method dalam class tersebut secara default menggunakan kon?gurasi tersebut, kemudian setiap method dapat juga ditandai 8Transactional yang mengoveride 8Transactional yang diletakkan di class. Semua method yang melakukan proses manipulasi data harus ditandai dengan 8Transactional3readHnly[false5 atau cukup 8Transactional sebagai bentuk pendeknya. (alau

tidak ditandai dengan 8Transactional maka Spring akan mengeluarkan error bah"a transaksi dalam method tersebut bersifat readonly dan tidak diperkenankan untuk melakukan manipulasi data dalam database.

Declarative &ransaction vs Programatic &ransaction


Setelah melihat implementasi Spring Service dan JD!$ Service di bab-bab sebelumnya, kita jadi tahu ternyata ada dua jenis variasi Trasaction Management. $ara yang pertama adalah ,rogramatic Transaction, dimana proses penanganan transaksi dilakukan secara manual, programmer harus menulis kode untuk memulai transaksi, kemudian mencommit transaksi dan kalau ada eLception melakukan rollback. $ontoh lengkapnya bisa dilihat pada bab yang membahas JD!$ di bagian Service ,attern. ,rogramatic Transaction sangat mudah dipahami karena konsepnya ada di setiap bahasa pemrograman. (ode yang ditulis untuk melakukan ,enanganan transaksi secara manual ini disebut dengan boiler plate code atau kode infrastruktur, kode jenis ini tidak berkontribusi sama sekali terhadap bussiness proses aplikasi. Dengan kata lain, kodenya harus ditulis tapi nilai tambahnya kosong. Semenjak a"al, teknologi di ekosistem Java berusaha membuat teknologi agar proses penanganan transaksi tidak lagi dilakukan secara manual, sehingga munculah jenis kedua proses pengangan transaksi, yaitu Declarative Transaction. *rame"ork yang mempunyai feature Declarative Transaction mengambil alih proses penanganan transaksi dari kode yang ditulis manual oleh programmer ke frame"ork itu sendiri. ,rogrammer cukup mendeklarasikan bah"a method ini adalah transactional, dengan kata lain setiap method yang dideklarasikan sebagai transactional tersebut akan dieksekusi, frame"ork akan memulai transaction, ketika eksekusi methodnya akan berakhir frame"ork akan melakukan commit, dan jika terdapat eLception di tengah-tengah method maka frame"ork akan merollback tranksaksi. Dengan begitu, programmer dapat berkonsentrasi di proses bisnis aplikasi tanpa harus direpotkan dengan boiler plate code untuk menangani transaksi. MJ! dan Spring adalah frame"ork yang mempunyai feature Declarative Transaction. MJ! le"at feature $ontainer Managed Tranasction 3$MT5 membuat semua method dalam Stateless Session !ean 3S.S!5, Statefull Session !ean 3S.S!5 dan Message Driven !ean 3MD!5 bersifat transactional. Dalam Spring, method dalam Spring Service yang ditandai dengan 8Transactional bersifat transactional. Spring menggunakan :H, untuk mengimplementasikan Declarative Transaction. .ihat gambar di ba"ah ini, di kotak paling kiri adalah kode program yang memanggil service. Spring Service yang dipanggil sebenernya adalah :H, ,roLy, bukan ,ersonService mpl. :H, ,roLy adalah class yang dibuat on-the-Uy pada "aktu aplikasi berjalan, didalam class ini disisipkan Transaction :dvisor untuk menangani transaction begin, commit dan rollback. Jadi sebenernya kode untuk transaction begin,commit dan rollback ada dalam :H, ,roLy ini tanpa perlu ditulis manual, alias dibuat oleh Spring. $ustom :dvisor bisa ditambahkan dalam Spring Service, biasanya digunakan untuk proses logging agar kode log tidak bercampur dengan kode bussiness process. ,ada akhirnya kode dalam ,ersonService mpl akan dieksekusi, kemudian return dari eksekusi kode tersebut dikembalikan ke pemanggilnya. Di bagian berikutnya kita akan membahas bagaimana cara membuat aplikasi

Spring Transaction Management 3http/99static.springsource.org9spring9docs97.&.7.-M.M:SM9spring-frame"orkreference9html9transaction.html5

Sprin! Confi!uration dan Sprin! Appli&ation Conte%t


Setelah Mntity, hibernate con?guration, D:H dan Spring Service selesai dibuat, langkah berikutnya adalah membuat Spring con?guration, atau biasa disebut dengan Spring :pplication $onteLt $on?guration. !entuknya sama dengan hibernate con?guration yaitu ?le ]M.. Di dalam Spring :pplication $onteLt ini akan dide?nisikan class-class yang dimanage oleh spring, sering disebut dengan Spring !ean. :pa sih sebenarnya Spring !ean ituZ Spring !ean pada dasarnya hanya object biasa, tetapi punya keistime"aan karena berada dalam Spring :pplication $onteLt, sehingga object ini bisa digunakan dalam proses Deppendency njection. $ontoh kongkritnya bisa dilihat dari class D:H, class ini membutuhkan Session*actory agar bisa digunakan, kata lain class D:H dipenden 3tergantung5 terhadap Session*actory, nah proses memasukkan 3inject5 Session*actory ke dalam D:H dilakukan menggunakan annotation 8:uto"ired. Mekanisme ini bisa dilakukan jika Session*actory dide?nisikan dalam Spring :pplication $onteLt $on?guration, D:H juga ditandai dengan 8$omponent dan dikon?gurasi agar 8$omponent ini bisa dikenali oleh Spring :pplication $onteLt. (on?gurasi Spring :pplication $onteLt dapat di buat dengan mudah menggunakan 0et!eans, pilih menu *ile -C 0e" *ile kemudian pilih node Hthers dan akhirnya pilih Spring ]M. $on?guration *ile seperti di dialog berikut ini /

(lik 0eLt dan lanjutkan ke halaman berikutnya, di halaman ini terdapat dialog untuk memilih Spring namespace apa saja yang akan disertakan dalam kon?gurasi, pilih 7 buah namespage/ conteLt, tL dan p. .anjutkan ke halaman berikutnya dengan menekan neLt, di halaman ini anda akan diminta untuk memberikan nama ?le kon?gurasi, beri nama ?le-nya application$onteLt.Lml setelah itu tekan *inish. Setelah application$onteLt.Lml selesai dibuat, modi?kasi ?lenya menjadi seperti ini / TW,ml version7*%.'* encoding7*G9H$N*WV Tbeans ,mlns7*.ttp3CC888.spring/rame8or0.orgCsc.emaCbeans* ,mlns3,si7*.ttp3CC888.81.orgC)''%CJB;Sc.ema$instance* ,mlns3conte,t7*.ttp3CC888.spring/rame8or0.orgCsc.emaCconte,t* ,mlns3t,7*.ttp3CC888.spring/rame8or0.orgCsc.emaCt,* ,mlns3p7*.ttp3CC888.spring/rame8or0.orgCsc.emaCp* ,si3sc.ema;ocation7*.ttp3CC888.spring/rame8or0.orgCsc.emaCbeans .ttp3CC888.spring/rame8or0.orgCsc.emaCbeansCspring$beans$).R.,sd .ttp3CC888.spring/rame8or0.orgCsc.emaCconte,t .ttp3CC888.spring/rame8or0.orgCsc.emaCconte,tCspring$conte,t$).R.,sd .ttp3CC888.spring/rame8or0.orgCsc.emaCt, .ttp3CC888.spring/rame8or0.orgCsc.emaCt,Cspring$t,$).R.,sd*V Tconte,t3component$scan base$pac0age7*com.googlecode.pro#ecttemplate.pos*CV Tconte,t3annotation$con/igCV Tt,3annotation$drivenCV Tconte,t3property$place.older location7*classpat.3#dbc.properties*CV Tbean id7*dataSource* class7*org.spring/rame8or0.#dbc.datasource.:riverBanager:ataSource*

p3driverDlass<ame7*"{#dbc.driver!* p3url7*"{#dbc.url!* p3username7*"{#dbc.username!* p3pass8ord7*"{#dbc.pass8ord!*CV Tbean id7*sessionHactory* class7*org.spring/rame8or0.orm..ibernate1.annotation.InnotationSessionHactory>ea n* p3dataSource$re/7*dataSource* p3con/ig;ocation7*classpat.3.ibernate.c/g.,ml*CV Tbean id7*transactionBanager* class7*org.spring/rame8or0.orm..ibernate1.Hibernate9ransactionBanager* p3sessionHactory$re/7*sessionHactory*CV TCbeansV (alau anda menggunakan 0et!eans versi ;.1, kemungkinan besar ? le di atas akan menggunakan Spring 7.&, perbedaan dalam kon?gurasi hanya ada di Lmlns saja. !uku ini menggunakan Spring %.4.; sehingga anda perlu mengganti Lmlns yang berakhiran 7.&.Lsd menjadi %.4.Lsd seperti dalam kon?gurasi di atas. Mari kita bahas satu persatu kon?gurasi di atas. conte5t&component-scan digunakan untuk mende?nisikan base-package dimana classclass yang dianotasi 8$omponent, 8-epository dan 8Service berada, di contoh-contoh sebelumnya class yang dimaksud adalah D:H dan Service. (alau hanya ingin memasukkan package yang ada class D:H dan servicenya bisa menggunakan tanda koma 3,5 untuk memisahkan package-nya, seperti contoh di ba"ah ini Tconte,t3component$scan base$pac0age 7 *com.googlecode.pro#ecttemplate.pos.dao+com.googlecode.pro#ecttemplate.pos.servi ce.impl*CV conte5t&annotation-con6g digunakan untuk memberitahu Spring bah"a dalam project ini akan digunakan annotation untuk mengkon?gurasi. t5&annotation-driven digunakan untuk memberitahu Spring bah"a Declarative Transaction akan menggunakan annotation 8Transactional kon?gurasi

conte5t&property-placeholder digunakan untuk mendaftarkan ? le-?le property yang akan digunakan untuk menyimpan kon?gurasi, misalnya dalam hal ini adalah kon?gurasi koneksi ke database. Semua poperty yang ada bisa diakses dalam application conteLt ini menggunakan sintaks NWnamaSpropertyX. Misalnya dalam :pplication $onteLt ini terdapat NWjdbc.driverX, kon?gurasi ini menghendaki ada property jdbc.driver di dalam ? le jdbc.properties. :"alan classpath/ menerangkan bah"a ?le jdbc.properties akan berada dalam classpath. Jika ada ?le properties lain yang digunakan, pisahkan daftar ?le-nya dengan tanda koma 3,5.

:gar kon?gurasi ini berjalan, maka perlu dibuat ?le jdbc.properties di dalam folder src atau di dalam Adefault-packageC. .angkahnya/ pilih menu *ile -C 0e" *ile, kemudian pilih Hther dan akhirnya pilih ,roperties *ile, beri nama jdbc.properties. .alu isikan kode berikut ini / #dbc.driver7com.mys\l.#dbc.:river #dbc.url7#dbc3mys\l3CClocal.ost311'&Cpos #dbc.username7root #dbc.pass8ord7 nilai jdbc.pass"ord sengaja dikosongkan karena user root tidak mempunyai pass"ord. bean digunakan untuk membuat Spring !ean, alias meminta spring untuk menginstansiasi class yang ada dalam attribute class. $ontoh dalam kon?gurasi di atas, akan dibuat Spring !ean dengan id datasource yang diinstansiasi dari class org.springframe"ork.jdbc.datasource.DriverManagerDataSource. (emudian di property

driver$lass0ame dari class tersebut diisikan nilai dari jdbc.driver, dan seterusnya. (alau kon?gurasi di atas ditulis dalam kode Java, maka padananya adalah sebagiai berikut :riverBanager:ataSource datasource 7 ne8 :riverBanager:ataSource() datasource.set:riverDlass<ame(*com.mys\l.#dbc.driver*) datasource.setGrl(*#dbc3mys\l3CClocal.ost311'&Cpos*) datasource.setGsername(*root*) datasource.set4ass8ord(**) Setiap kali ada tag AbeanC di Spring :pplication $onteLt, anda harus membayangkan bah"a sebenarnya yang dilakukan oleh Spring adalah menginstansiasi sebuah class, kemudian menset property yang dibutuhkan oleh object yang baru saja diinstansiasi. 0ah proses instansiasi plus menset property yang dibutuhkan oleh object inilah inti dari Spring, sangat sederhana kanZ #alaupun konsepnya sangat sederhana, namun efeknya sangat po"erfull. Sekarang kalau misalnya ingin mengganti class dari datasource ke :pache $ommons D!$, , maka kita tidak perlu mengganti kode Java, cukup mengganti kon?gurasi Spring maka kita sudah mempunyai $onnection ,ooling. Dengan cara inilah Spring me"ujudkan konsep modular, komponen dalam aplikasi bisa diganti, disubstitusi atau dibongkar pasang hanya dengan mengganti kon?gurasi di dalam Spring :pplication $onteLt ini, luar biasa. bean berikutnya yang dibuat adalah session*actory. ,roperty yang diset untuk session*actory ini ada datasource yang diambil dari bean datasource, kemudian property con?g.ocation digunakan untuk mende?nisikan ?le hibernate.cfg.Lml. ,re?L classpath/ digunakan untuk memberitahu Spring bah"a ?le hibernate.cfg.Lml akan berada di dalam classpath. bean terakhir adalah transactionManager. !ean ini digunakan oleh Spring untuk memenage transaction dari +ibernate. ,arameter yang diperlukan adalah bean session*actory.

Setelah selesai membuat Spring :pplication $onteLt, kode sudah siap dijalankan. !uat sebuah class, namakan MainSpring kemudian ketik kode berikut ini untuk mencoba menggunakan kode yang sudah dibuat/ public class BainSpring { public static void main(String[] args) { IpplicationDonte,t appDonte,t 7 ne8 Dlass4at.JmlIpplicationDonte,t(*applicationDonte,t.,ml*) 4ersonService personService 7 (4ersonService) appDonte,t.get>ean(*personService*) 4erson person 7 ne8 4erson() person.set<ame(*i/nu*) person.set4ass8ord(*p8di/nu*) personService.save(person) ;istT4ersonV persons 7 personService.get4ersons() /or (4erson p 3 persons) { System.out.println(*name3* E p.get<ame() E *+ pass8ord3*Ep.get4ass8ord()) ! ! !

Sebelum menjalankan class di atas, tambahkan library Spring *rame"ork %.4.;.SM$&) ke dalam project, klik kanan ?le kemudian pilih run. $lass ini akan menginstansiasi :pplication$onteLt yang diambil dari ?le kon?gurasi application$onteLt.Lml, kemudian dari :pplication$onteLt tersebut kita ingin mendapatkan service bean, caranya dengan memanggil method get!ean dan menggunakan string personService sebagai parameternya. Setelah service diambil dari :pplication$onteLt, kita bisa menggunakanya untuk menyimpan object ,erson yang baru saja dibuat menggunakan method save atau mengambil semua ,erson dari table TS,M-SH0 menggunakan method get,ersons.

.tility class untuk mengenerate ta"le dan initial data


.ihat lagi ?le con?gurasi hibernate.cfg.Lml, di dalam ?le tersebut ada property Session*actory hibernate.hbm%ddl.auto yang nilainya create-drop, property ini memberitahu Session*actory untuk mendrop table yang sudah ada kemudian membuat table yang baru. Terkadang kita ingin menggenerate table dari a"al karena ada perubahan struktur table, terkadang kita juga tidak ingin mendrop table-table yang sudah dibuat, nah berulang-ulang kali kita harus mengganti nilai hibernate.hbm%ddl.auto dari create-drop menjadi none agar tablenya tidak digenerate ulang. (adang kala cukup menyebalkan kalau sudah menyiapkan data untuk mengetest aplikasi tapi lupa mengganti nilai hibernate.hbm%ddl.auto menjadi none, sehingga pada "aktu aplikasi dijalankan semua table dicreate ulang. Fntuk menghindari kesalahan di atas, kita bisa secara permanen mengeset nilai hibernate.hbm%ddl.auto menjadi none, kemudian membuat satu class utility KenerateTables untuk mengenerate table. Setiap kali ingin mengenerate table, cukup jalankan class ini. Di dalam class KenerateTables bisa juga diletakkan kode-kode untuk membuat initial data, misalnya data user atau data master. !uat class KenerateTables di dalam package com.googlecode.projecttemplate.pos.util kemudian ketikkan kode seperti berikut ini. public class Senerate9ables { public static void main(String[] args) t.ro8s Sb;@,ception { IbstractIpplicationDonte,t appDonte,t 7 ne8 Dlass4at.JmlIpplicationDonte,t(*classpat.3applicationDonte,t.,ml*) :ataSource dataSource 7 (:ataSource) appDonte,t.get>ean(*dataSource*) Don/iguration c/g 7 ne8 InnotationDon/iguration().con/igure(*.ibernate.c/g.,ml*) Donnection conn 7 dataSource.getDonnection() ne8 Sc.ema@,port(c/g+ conn).create(true+ true) 4ersonService personService 7 (4ersonService) appDonte,t.get>ean(*personService*) 4erson person 7 ne8 4erson() person.set<ame(*i/nu*) person.set4ass8ord(*p8di/nu*) personService.save(person) System.e,it(') !

Sampai di sini, struktur utama dari project sudah tersedia, ada class Mntity, D:H dan Service kemudian ada ?le kon?gurasi hibernate.cfg.Lml, application$onteLt.Lml dan jdbc.properties. (ode untuk menjalankan project juga sudah dibuat. !agian selanjutnya akan membahas +ibernate secara lebih mendalam, dia"ali dengan pembahasan tentang +ibernate Mapping, kemudian dilanjutkan dengan +I..

Hibernate

appin!

+ibernate, seperti halnya semua frame"ork H9- mapping, membutuhkan metadata yang digunakan sebagai informasi pemetaan dari class ke table database. Sebelum Java 4 metadata yang digunakan adalah ?le hbm.Lml, masalah utama dengan hbm.Lml adalah kesalahan mapping akan terlihat kalau aplikasi dijalankan, sedangkan DM yang ada saat itu belum cukup canggih untuk bisa melihat kesalahan mapping yang terjadi di dalam hbm.Lml, kon?gurasi yang terpisah dalam ?le berbeda seperti ini juga menimbulkan masalah penurunan produkti?tas, karena programmer harus bolak-balik melihat kode Java dan kode Lml. Setelah Java 4 memperkenalkan annotation, +ibernate mengeluarkan +ibernate :nnotation sebagai

alternatif hbm.Lml. :nnotation juga memudahkan DM seperti 0et!eans untuk membuat feature autocomplete dan pemeriksaan kesalahan. Melihat kesuksesan +ibernate yang luar biasa, J$, akhirnya memutuskan untuk membuat teknologi standard H-M, yang kemudian diberi nama J,: 3Java ,ersistence :, 5. Seperti halnya semua standard di dalam Java, J,: ini pada dasarnya hanya kumpulan interface dan annotation, setiap vendor bisa membuat implementasi dari J,: ini. -eference implementation 3- 5 dari J,: adalah Top.ink Mssentials, semua vendor lain yang ingin membuat implementasi J,: bisa meneliti behaviour Toplink Mssentials sebagai patokan. +ibernate juga mempunyai implementasi J,: yang disebut +ibernate MntityManager. Dalam buku ini kita akan menggunakan +ibernate plus J,: annotation untuk basic mapping, serta beberapa annotation dari +ibernate :nnotation. J,: annotation ditandai dengan package import javaL.persistence sedangkan +ibernate :nnotation ditandai dengan package org.hibernate.annitations. (enapa masih harus menggunakan +ibernate :nnotationZ (arena pada dasarnya J,: itu hanya mempunyai feature mapping yang umum dipakai H-M, ada feature tertentu yang hanya ada di +ibernate :nnotation, sehingga kita masih harus mencampur antara J,: dan +ibernate :nnotation. Selain annotation yang berbeda, J,: dan +ibernate juga mempunyai class-class yang berbeda. Jika di +ibernate ada Session*actory maka di J,: ada MntityManager*actory, di +ibernate ada Session di J,: ada MntityManager, dan seterusnya. Tidak perlu merasa bingung atau bimbang, J,: dan +ibernate mempunyai tujuan yang sama, tidak ada perbedaan essensial antara keduanya, anda bisa memilih salah satu tanpa merasa bah"a yang lain jauh lebih baik atau sebaliknya.

+ntity dan Basic ma$$ing


!ab sebelumnya sudah memperlihatkan basic mapping, kita akan bahas sekali lagi tentang basic mapping dalam bab ini, kalau anda merasa sudah cukup mengerti tentang basic mapping, silahkan lanjut ke bagian berikutnya. !asic mapping adalah kumpulan annotation untuk memapping sebuah class 9 Mntity ke table dalam database. Sebuah Mntity minimum harus mempunyai dua buah annotation, yaitu 8Mntity dan 8 d, kedua annotation ini "ajib ada di dalam Mntity. J,: annotation menggunakan konsep $on?guration by MLception dimana ada aturan bah"a annotation lain yang tidak disebutkan akan diperlakukan secara default. !agaimana konsep ini diterapkan dalam proses mappingZ Mari kita lihat contoh berikut ini / ^@ntity public class 4erson implements Seriali?able { ^=d private ;ong id private String name private String pass8ord CCgetter setter ! Mapping class ,erson di atas berbeda dengan mapping class ,erson yang ada di bab sebelumnya, semua annotation lain selain 8Mntity dan 8 d dihilangkan, sehingga +ibernate akan menggunakan nilai default untuk mappingnya ke dalam table. 0ilai defaultnya antara lain / nama tablenya akan sama dengan nama class, yaitu ,erson nama kolom akan sama dengan nama property panjang varchar untuk tipe String adalah %44 primary key yang ditandai dengan 8 d tidak digenerate, dengan kata lain kita harus set nilainya sebelum menyimpan dalam database.

8Table digunakan untuk mende?nisikan table yang akan dimapping dengan Mntity, selain nama dari table yang dide?nisikan dalam attribute name, 8Table bisa menerima catalog dan schema. :ttribute yang tidak kalah pentingnya adalah uni\ue$onstraints yang digunakan untuk mende?nisikan uni\ue constraints dari table tersebut. Misalnya di table TS,M-SH0 kolom nama harus uni\ue, maka 8Table di Mntity person bisa diganti seperti di ba"ah ini / ^9able(name7*9(4@6SA<*+uni\ueDonstraints7{^Gni\ueDonstraint(column<ames7*<IB@*)!)

kalau kombinasi kolom 0:MM dan ,:SS#H-D mempunyai nilai uni\ue, 8Table diganti seperti di ba"ah ini ^9able(name7*9(4@6SA<*+uni\ueDonstraints7{^Gni\ueDonstraint(column<ames7{*<IB@*+ *4ISSWA6:*!)!) Tipe data Date memerlukan informasi apakah data yang disimpan hanya tanggal, hanya "aktu atau tanggal dan "aktu, 8Temporal digunakan untuk kebutuhan ini, 8Temporal bisa berisi TemporalType.D:TM, TemporalType.T MMST:M, atau TemporalType.T MM. . Misalnya di class ,erson kita tambahkan satu kolom lagi untuk menampung informasi tanggal lahir, karena tanggal lahir hanya perlu informasi tanggal saja, maka mappingnya seperti ini / ^9emporal(9emporal9ype.:I9@) ^Dolumn(name7*>=69H(:I9@*) private :ate birt.:ate Terkadang kita perlu tipe data enum untuk menampung informasi berupa nilai pilihan yang terbatas, misalnya jenis kelamin, atau status perka"inan. +ibernate mendukung tipe data enum untuk digunakan dalam entity, annotation yang digunakan adalah 8Mnumerated. (ita bisa memilih untuk menyimpan string dari enum atau menyimpan urutanya, jika ingin menyimpan string dari enum gunakan MnumType.ST- 0K, sedangkan MnumType.H-D 0:. digukanan kalau ingin menyimpan urutan enumnya. Jika anda masih a"am tentang enum, silahkan membaca lagi bab sebelumnya yang membahas tentang tipe data enum. Sebagai contoh, buat enum MaritalStatus di package model seperti berikut ini public enum BaritalStatus { S=<S;@+BI66=@:+:=PA6D@: ! (emudian mapping class ,erson ditambah kode berikut ini / ^@numerated(@num9ype.S96=<S) ^Dolumn(name7*S9I9GS*+lengt.7)') private BaritalStatus status +ibernate juga bisa menampung data binary seperti foto pro?le user ke dalam database, tipe data yang digunakan adalah byte array 3byte=>5, kemudian annotation 8.ob 3.arge object5 digunakan untuk menandai peroperty ini. $ontohnya seperti berikut ini ^;ob ^Dolumn(name7*4=D9G6@*) private byte[] picture 8.ob juga digunakan untuk menandai kolom denga tipe data String yang mempunyai ukuran sangat panjang. MySI. varchar hanya sanggup menampung %44 huruf, jadi kalau punya kolom yang ingin mempunyai panjang lebih dari %44 harus menggunakan tipe data TeLt. +ibernate akan membuat kolom bertipe teLt kalau ada property String ditandai dengan 8.ob ^;ob ^Dolumn(name7*6@BI6K*) private String remar0 Semua annotation di atas sudah cukup mengcover sebagian besar basic mapping di +ibernate. !agian berikutnya kita akan membahas annotation 8Kenerated@alue yang digunakan berbarengan dengan 8 d.

Id (eneration
8Kenerated@alue adalah annotation yang digunakan berbarengan dengan 8 d, annotation 8Kenerated@alue menandai bah"a primary key akan digenerate oleh database.0ilai attribute startegy menentukan bagaimana caranta primary key akan digenerate oleh database, nilai attribute strategy antara lain/ KenerationType.:FTH proses generate id tergantung database yang digunakan, berdasarkan databasenya hibernate akan memilih proses generate menggunakan T:!.M, SMIFM0$M atau DM0T TP. ,ilihan :FTH ini yang paling aman dan portable ke semua database.

KenerationType.T:!.M proses generate id menggunakan satu buah table yang menyimpan nilai terakhir yang digunakan. Sebelum insert data, ambil satu baris dalam table se\uence kemudian baca nilai terakhir dan tambahkan satu, setelah proses insert berhasil update nilai terbesarnya dengan nilai terakhir yang baru saja digunakan untuk insert. (on?gurasi lengkapnya seperti di ba"ah ini /

G5enerated2alue=strategyH5eneration4y/e.4A"L8, generatorHIP860+@JIDI> G4a,le5enerator=na#eHIP860+@JIDI, ta,leHI4J6:@@I@5J@:&"86I, / (olu#n@a#eHIna#eI,value(olu#n@a#eHI(+:@4I, / (olu#n2alueHIP860+@JIDI>


(on?gurasi di atas menggunakan sebuah table dengan nama TS-F00 0KS0FM!M- yang mempunyai kolom 0:MM dan $HF0T seperti contoh di ba"ah ini. Setiap kali insert ke table TS,M-SH0 nilai count dari ,M-SH0S D akan bertambah satu secara otomatis untuk mencatat id terakhir yang digunakan.
0:MM ,M-SH0S D ,M0JF:.:0S D $HF0T )%7 44&

KenerationType.SMIFM0$M proses generate id berdasarkan se\uence, oracle tidak mempunyai feature autoSincrement, untuk mengenerate id oracle menggunakan se\uence. Sebuah se\uence dapat digunakan oleh beberapa table yang berbeda. Misalnya untuk beberapa entity digunakan se\uence yang sama, maka bisa dideklarasikan dengan menyebutkan nama se\uence-nya secara eLplisit seperti di ba"ah ini /

G5enerated2alue=strategyH5eneration4y/e.08A:8@(8,generatorHI08AJ04+68I>
Se\uence SMISSTH-M bisa digunakan di entity ,erson atau di entity yang lain. SMIFM0$M mendukung preallocation untuk mengalokasikan sekian buah angka setiap kali increment. SMIFM0$M adalah metode yang paling tidak portable dan hanya oracle, db% dan posgres yang mendukung SMIFM0$M. ,erformance SMIFM0$M yang paling bagus karena dapat mengatasi masalah pemanggilan SMIFM0$M secara bersamaan. $ontoh SMIFM0$M generation yang menggunakan preallocation seperti berikut /

G5enerated2alue=strategyH5eneration4y/e.08A:8@(8, generatorHI8&PJ08AI> G0e?uen%e5enerator=na#eHI8&PJ08AI, se?uen%e@a#eHI8&PJ08AI, allo%ation0iBeH.33>

KenerationType. DM0T TP menggunakan identity sebagai proses generate id, nilai id akan terus bertambah, uni\ue dan nilainya hanya bisa digunakan dalam table tersebut. MySI. mendukung pilihan ini dengan feature autoSincrement.

,roses generate id tidak hanya tergantung dengan database, hibernate memungkinkan programmer menentukan generate id dari aplikasi Java, tidak dari database. Misalnya aplikasi yang akan dibuat memerlukan sinkronisasi data dari cabang ke pusat, jika setiap cabang tablenya menggunakan D bertipe DM0T TP, kemungkinan table TS,M-SH0 antara cabang satu dengan cabang yang lain akan mempunyai D yang sama, sehingga diperlukan proses generate id yang uni\ue untuk semua cabang. Java mempunyai class FF D yang akan mengenerate string yang dipastikan uni\ue setiap kali digenerate. !erikut ini kon?gurasi 8Kenerated@alue yang menggunakan FF D string / ^SeneratedPalue(generator7*system$uuid*) ^SenericSenerator(name7*system$uuid*+strategy7*uuid*) ,embahasan mengenai 8 d masih panjang, salah satu topik advance adalah menggunakan composite primary key, dimana primary key dari sebuah table terdiri dari dua kolom atau lebih. ,enggunaan composite primary key tidak disarankan, karena akan membuat proses mapping relationship dengan entity lain menjadi lebih rumit. Topik ini tidak akan dicover dalam buku ini, anda bisa melihat ke hibernate reference untuk mengetahui bagaimana cara menggunakan composite primary key.

Class Diagram
!agian berikutnya akan membahas lebih banyak tentang entity relationship mapping, sebelum mulai membahas topik relationship mapping, kita bahas dulu class Diagram contoh yang akan digunakan di bagian selanjutnya. FM. class diagram pertama memperlihatkan ; class yang berhubungan dengan user management. Salah satu class-nya adalah class ,erson yang sudah digunakan dalam contohcontoh di bagian sebelumnya. $lass ,erson mempunyai beberapa relationship, salah satunya adalah Hne-to-Hne relationshipe ke class $ustomer. $lass ,erson juga mempunyai relasi Manyto-Many dengan -ole, class -ole mempunyai Many-to-Many relationship dengan class Menu. $lass $ustomer mempunyai inheritance Member$ustomer, jadi dari struktur ini akan digunakan sebagai contoh untuk membahas inheritance mapping. $lass $ustomer juga mempunyai property dengan tipe :ddress, dimana :ddress ini bukan merupakan entity, hanya class yang bisa di-embed di class lain. $lass $ustomer juga mempunyai hubungan $ollectionHfMlement dengan tipe .istAStringC untuk menampung data email yang dimiliki customer, dimana setiap customer bisa mempunyai banyak email . $ollectionHfMlement akan dibuatkan satu table tersendiri untuk menampung email-email setiap customer.

$lass Diagram kedua merepresentasikan data yang digunakan dalam Transaksi, yaitu produk, pembelian dan penjualan. ,roduk mempunyai relasi dengan SalesDetail dan $ustomerDetail berupa relasi Hne-to-Many. Sales dan SalesDetail mempunyai hubungan Many-to-Hne yang disebut sebagai Master-Detail, dimana tanpa ada data Master-nya 3Sales5 data Detail 3SalesDetail5 menjadi tidak berguna, sehingga setiap kali data Master-nya dihapus, data Detailnya juga harus ikut dihapus. Dengan kata lain, daur hidup data Detail tergantung daur hidup Masternya.

Setelah memahami studi kasus yang akan digunakan dalam bagian-bagian berikutnya, mari kita bahas satu per satu relationship yang ada dalam +ibernate.

!ne0&o0!ne
-elationship ini memapping dua buah entity sepasang, artinya satu entity dimapping tepat ke satu entity yang lain. $ontohnya adalah relationship antara ,erson dan $ustomer. Setiap $ustomer dibuatkan data personya, relasi ini memungkinkan customer untuk bisa login ke system, misalnya untuk mengecek berapa banyak poin yang dimiliki oleh $ustomer yang tipenya Member$ustomer. -elationship Hne-to-Hne menggunakan annotation 8HneToHne, kemudian diikuti dengan 8Join$olumn untuk mende?nisikan *oreign (ey. Di sisi la"anya juga menggunakan :nnotation 8HneToHne tanpa diikuti 8Join$olumn tetapi cukup dide?nisikan saja attribute mapped!y yang isinya nama property. Mari kita lihat mapping untuk class ,erson dan class $ustomer / ^@ntity ^9able(name7*9(DGS9AB@6*) public class Dustomer { ^=d ^SeneratedPalue ^Dolumn(name7*=:*) private ;ong id ^Dolumn(name7*H=6S9(<IB@*+nullable7/alse+lengt.7%'') private String /irst<ame ^Dolumn(name7*S@DA<:(<IB@*+lengt.7%R') private String second<ame private Iddress address ^DollectionA/@lements(target@lement7String.class) ^=nde,Dolumn(name7*emails(inde,*) private ;istTStringV emails ^Dolumn(name7*4HA<@*+nullable7/alse+lengt.7%R) private String p.one ^Ane9oAne ^]oinDolumn(name7*4@6SA<(=:*) private 4erson person

CCgetter dan setter di sini

,roses mapping Hne-to-Hne dimulai de class $ustomer ini dengan menggunakan 8HneToHne dan 8Join$olumn. 0ama dari 8Join$olumn akan diterjemahkan menjadi foreign key ketika +ibernate mengenerate table dari mapping ini. ^@ntity ^9able(name7*9(4@6SA<*+uni\ueDonstraints7{^Gni\ueDonstraint(column<ames7{*<IB@*! )!) public class 4erson implements Seriali?able { ^Ane9oAne(mapped>y 7 *person*) private Dustomer customer ^=d ^SeneratedPalue(strategy7Seneration9ype.IG9A) ^Dolumn(name7*=:*) private =nteger id ^Dolumn(name7*<IB@*+uni\ue7true+lengt.7%'') private String name ^Dolumn(name7*4ISSWA6:*+uni\ue7true+lengt.7)'') private String pass8ord ^9emporal(9emporal9ype.:I9@) ^Dolumn(name7*>=69H(:I9@*) private :ate birt.:ate ^@numerated(@num9ype.S96=<S) ^Dolumn(name7*S9I9GS*+lengt.7)') private BaritalStatus status ^;ob ^Dolumn(name7*4=D9G6@*) private byte[] picture ^;ob ^Dolumn(name7*6@BI6K*) private String remar0 ^Bany9oBany(mapped>y7*persons*) private SetT6oleV roles ! CCgetter setter di sini

Sedangkan di sisi ,erson mapping dilakukan cukup dengan menambahkan 8HneToHne dan mensetting attribute mapped!y dengan nama property person yang ada dalam class $ustomer.

!ne0&o0Many dan Master0Detail


-elasi Hne-to-Many menggunakan annotation 8HneToMany, 8ManyToHne dan 8Join$olumn, -elasi antara Sales dan SalesDetail adalah HneToMany plus Master-Detail. Mari kita lihat kode untuk class Sales dan SalesDetail ^@ntity ^9able(name7*9(SI;@S*) public class Sales {

^=d ^SeneratedPalue ^Dolumn(name7*=:*) private ;ong id ^9emporal(9emporal9ype.9=B@S9IB4) ^Dolumn(name7*SI;@S(:I9@*+nullable7/alse) private :ate sales:ate ^Ane9oBany(mapped>y7*sales*+cascade7Dascade9ype.I;;) ^Dascade(org..ibernate.annotations.Dascade9ype.:@;@9@(A64HI<) private ;istTSales:etailV sales:etails ^Dolumn(name7*9A9I;(SI;@S*+precision7%N+scale7'+nullable7/alse) private >ig:ecimal totalSales ! CCgetter setter di sini

:nnotation yang ada dalam class Sales adalah 8HneToMany dan 8$ascade. Seperti yang diterangkan dalam bagian sebelumnya, daur hidup class Detail tergantung dari Master-nya, sehingga dalam mapping 8HneToMany ditambahkan attribute cascade yang nilainya adalah $ascadeType.:... (on?gurasi ini menyebabkan SalesDetail akan disimpan kalau Sales disimpan, tidak perlu kode untuk menginsert SalesDetail satu per satu, cukup simpan Sales-nya maka semua SalesDeatail yang ada akan ikut disimpan 3insert5. !egitu juga kalau class Sales dihapus, maka semua SalesDetail-nya juga akan dihapus secara otomatis tanpa harus menghapus satu per satu. :nnotation 8$ascade diperlukan untuk proses edit class Sales. Misalnya pembeli pada "aktu di kasir memba"a empat item barang, kemudian kasir sudah menginput keempat sales tersebut dan menyimpan transaksi, maka satu baris data Sales dan empat baris data SalesDetail disimpan dalam database. (emudian customer tersebut membatalkan salah satu itemnya karena ada kerusakan ?sik, kemudian menambahkan satu item lain untuk menggantikanya. (asir akan menghapus satu item dari SalesDetail, menambahkan satu item ke dalam SalesDetail kemudian menyimpan transaksi yang baru saja diedit tersebut. Dengan attribute cascade all di dalam 8HneToMany dan annitation 8$ascade di atas, hibernate akan memeriksa satu per satu SalesDetail apa yang ada dalam .istASalesDetailC dan SalesDetail apa yang ada dalam database. (emungkinan hasil perbandingan antara SalesDetail dalam .ist dan SalesDetail yang ada dalam database ada tiga jenis/ ). %. 7. Data SalesDetail yang ada di dalam .ist dan di dalam database, maka nilainya di database diupdate. Data SalesDetail yang ada dalam .ist tetapi belum ada dalam Database, maka data yang di dalam .ist diinsert. Data SalesDetail yang tidak ada dalam .ist tetapi ada dalam database, maka data yang ada dalam database dihapus.

,oin pertama dan kedua sudah bisa dilaksanakan dengan menggunakan mapping 8HneToMany dan attribute cascade all. ,oin ketiga dapat dilakukan dengan menggunakan annotation 8$ascade. Mapping di sisi class SalesDetail menggunakan annotation 8ManyToHne dan 8Join$olumn untuk mende?nisikan nama kolom *oreign (ey. (ode class SalesDetail seperti di ba"ah ini / ^@ntity ^9able(name7*9(SI;@S(:@9I=;*) public class Sales:etail { ^=d ^SeneratedPalue ^Dolumn(name7*=:*) private ;ong id

^Bany9oAne ^]oinDolumn(name7*46A:GD9(=:*+nullable7/alse) private 4roduct product ^Dolumn(name7*bGI<9=9_*+nullable7/alse) private =nteger \uantity ^Dolumn(name7*46=D@*+nullable7/alse+precision7%N+scale7') private >ig:ecimal price ^Dolumn(name7*SG>9A9I;*+nullable7/alse+precision7%N+scale7') private >ig:ecimal subtotal ^Bany9oAne ^]oinDolumn(name7*SI;@S(=:*+nullable7/alse) private Sales sales CCgetter setter di sini !

Many0to0Many
-elationship Many-to-Many terjadi antara class -ole dengan class Menu, dimana setiap -ole bisa mempunyai banyak Menu dan sebaliknya. Setiap mapping Many-to-Many akan menghasilkan sebuah table baru. :nnotation yang digunakan dalam relationship Many-to-Many adalah 8ManyToMany di kedua class. Salah satu class akan mempunyai mapping tambahan yaitu 8JoinTable. $lass yang mempunyai 8JoinTable ini disebut dengan class pengendali relationship. Mari kita lihat kode class -ole di ba"ah ini / ^@ntity ^9able(name7*9(6A;@*) public class 6ole { ^=d ^SeneratedPalue ^Dolumn(name7*=:*) private ;ong id ^Dolumn(name7*<IB@*+lengt.7R'+uni\ue7true) private String name ^Bany9oBany ^]oin9able(name7*9(6A;@(4@6SA<*+ #oinDolumns7{^]oinDolumn(name7*6A;@(=:*)!+ inverse]oinDolumns7{^]oinDolumn(name7*4@6SA<(=:*)!) private SetT4ersonV persons ^Bany9oBany ^]oin9able(name7*9(6A;@(B@<G*+ #oinDolumns7{^]oinDolumn(name7*6A;@(=:*)!+ inverse]oinDolumns7{^]oinDolumn(name7*B@<G(=:*)!) private SetTBenuV menus CCgetter setter di sini ! ,erhatikan class -ole di atas, dalam relationship Many-to-Many dengan class Menu, class -ole bertindak sebagai class ,engendali karena mempunyai mapping 8JoinTable. ,roses perangkaian relasi ini akan terjadi ketika class -ole ini disimpan, dengan syarat class Menu

disimpan terlebih dahulu atau sudah berada dalam database. (alau urutan ini dibalik, class -ole disimpan terlebih dahulu sebelum class Menu, maka akan muncul error yang memberitahu bah"a class Menu belum disimpan dalam database. !erikut ini kode dari class Menu / ^@ntity ^9able(name7*9(B@<G*) public class Benu { ^=d ^SeneratedPalue ^Dolumn(name7*B@<G(=:*) private ;ong id private String name ^Bany9oBany(mapped>y7*menus*) private SetT6oleV roles CCgetter setter di sini !

Com$onent
Mapping component ini terjadi kalau sebuah class yang bukan entity melainkan embedable class berada dalam class lain yang tipenya Mntity. $lass component ditandai dengan 8Mmbeddable, class ini tidak akan dibuatkan table, tetapi semua property yang ada dalam class ini akan dibuatkan table di dalam class Mntity-nya. (onsep component ini mirip dengan konsep :bstract Data type, dimana sebuah class Mntity bisa mempunyai property dengan tipe class selain class fundamental Java 3String, Date, !igDecimal, nteger dst5. Tujuan utamanya adalah untuk menyederhanakan kode kalau class component ini digunakan dalam Mntity secara berulang-ulang. Misalnya kita buat class :ddress yang menjadi property class $ustomer, ada kemungkinan class :ddress akan digunakan dalam Mntity lain sehingga dibuatkan class :ddress agar tidak perlu mengetik semua property dalam class :ddress. !erikut ini kode untuk class :ddress / ^@mbeddable public class Iddress { ^Dolumn(name7*I::6@SS%*+lengt.7%N'+nullable7/alse) private String address% ^Dolumn(name7*I::6@SS)*+lengt.7%N') private String address) ^Dolumn(name7*D=9_*+lengt.7R'+nullable7/alse) private String city ^Dolumn(name7*46AP=<D@*+lengt.7R'+nullable7/alse) private String province ^Dolumn(name7*4AS9(DA:@*+lengt.7R') private String postDode ^Dolumn(name7*DAG<96_*+lengt.7R'+nullable7/alse) private String country ! CCgetter setter di sini

,erhatikan bah"a dalam class $ustomer tidak diperlukan annotation apapun untuk memapping class :ddress dalam class $ustomer. 0et!eans biasanya memberi tanda garis ba"ah merah di deklarasi variabel address yang menerangkan bah"a basic attribute harus menggunakan tipe primitive, "rapper atau array. Tidak perlu kha"atir mengenai tanda error ini, karena ketika dicompile atau dijalankan tidak ada masalah sama sekali.

Collection! +lement
$ollectionHfMlement digunakan untuk menyimpan nilai property yang jumlahnya lebih dari satu. Dalam contoh kali ini, misalnya setiap customer bisa mempunyai lebih dari satu buah email. Mmail-email ini akan disimpan ke dalam table berbeda. Tipe data dari collectionHfMlement bisa berupa tipe data basic seperti String atau class, jika tipe datanya class maka class tersebut tidak bisa digunakan dalam hibernate \uery selayaknya Mntity. $ollectionHfMlement bisa digabungkan dengan 8 ndeL$olumn untuk membuat indeL urutan, misalnya email-email tersebut diurutkan berdasarkan prioritasnya. $ontoh mapping-nya seperti di ba"ah ini diambil dari class $ustomer/ ^DollectionA/@lements(target@lement7String.class) ^=nde,Dolumn(name7*emails(inde,*) private ;istTStringV emails

Inheritance
Dalam HH, inheritance adalah suatu konsep yang sangat penting, tetapi konsep inheritance ini tidak ada dalam -elational Database, masalah perbedaan konsep ini sering disebut dengan Hbject--elational mpedance. H-M, dalam hal ini +ibernate, mengatasi Hbject--elational mpedance dengan tiga strategi / ). Hne Table ,er $lass, strategi ini akan membuat table sebanyak class-nya. Misalnya dalam contoh ada class $ustomer yang merupakan parent class Member$ustomer, dengan menggunakan Hne Table ,er $lass, maka akan dibuat masing-masing satu table untuk kedua class ini. $ontoh mappingnya / ^@ntity ^9able(name7*9(DGS9AB@6*) ^=n.eritance(strategy7=n.eritance9ype.9I>;@(4@6(D;ISS) public class Dustomer implements Seriali?able{ !

dan di sisi Member$ustomer adalah / ^@ntity ^9able(name7*9(B@B>@6(DGS9AB@6*) public class BemberDustomer e,tends Dustomer implements Seriali?able{ ! Strategi ini punya banyak kelemahan, misalnya jika ingin mendapatkan semua customer dengan \uery Efrom $ustomer cG maka data dari table TS$FSTHMM- dan table TSMMM!M-S$FSTHMM- harus disatukan, karena sebenernya Member$ustomer adalah $ustomer juga. +ibernate mengimplementasikan masalah penggabungan table ini dengan mengenerate union all \uery antara table TS$FSTHMM- dan TSMMM!M-S$FSTHMM-. Strategi ini tidak mendukung auto generate id dengan tipe DM0T TP atau :FTH karena id harus disharing antara dua table tersebut, sehingga hanya menyisakan SMIFM0$M dan T:!.M untuk strategi generate id. +al ini menyebabkan -D!MS yang tidak mendukung SMIFM0$M seperti MySI. harus menggunakan strategi T:!.M agar bisa menggunakan T:!.MS,M-S$.:S. %. Single table, Strategi ini akan menyimpan seluruh class dari parentnya hingga subclass ke dalam satu table saja. :ntar class dibedakan menggunakan satu kolom yang disebut dengan Discriminator. Setiap class mempunyai nilai berbeda dalam colom discriminator ini. :nnotation 8Discriminator$olumn digunakan untuk mendi?nisikan nama kolom diskriminator dan 8Discriminator@alue digunakan untuk mende?nisikan nilainya untuk setiap class. Jika kedua annotation ini tidak diset, maka digunakan kolom DTP,M dan nilainya diambil dari mana class Mntity

$ontoh mappingnya adalah sebagai berikut / ^@ntity ^9able(name7*9(DGS9AB@6*) ^=n.eritance(strategy7=n.eritance9ype.S=<S;@(9I>;@) ^:iscriminatorDolumn( name7*DGS9AB@6(9_4@*+ discriminator9ype7:iscriminator9ype.S96=<S+ lengt.7&) ^:iscriminatorPalue(*DGS9*) public class Dustomer implements Seriali?able{ ! Mapping di class turunanya adalah sebagai berikut / ^@ntity ^9able(name7*9(B@B>@6(DGS9AB@6*) ^:iscriminatorPalue(*BDGS9*) public class BemberDustomer e,tends Dustomer implements Seriali?able{ Mapping ini cocok digunakan jika satu class mempunyai banyak turunan tetapi kolom di turunanya cuma berbeda sedikit. (alau kolom di turunanya mempunyai banyak perbedaan maka nantinya akan ada banyak kolom kosong bernilai null. Selain itu kolom yang dipunyai oleh turunan harus bisa diisi dengan nilai null, hal ini dikarenakan untuk entity dengan tipe $ustomer nilai di kolom yang hanya dipunyai oleh Member$ustomer akan bernilai null. 7. Joined subclasss, strategi ini akan menyimpan kolom yang sama di satu table dan membuat satu table lagi untuk menyimpan property yang hanya dipunyai subclass. Strategi ini dianggap paling bagus, merupakan gabungan antara table per class dan single table. Dalam contoh kita, semua property dalam class $ustomer akan disimpan di dalam table TS$FSTHMM-, baik itu dari entity $ustomer maupun Member$ustomer. Table TSMMM!M-S$FSTHMM- sekarang hanya mempunyai property-property yang dipunyai Member$ustomer tetapi tidak dipunyai $ustomer. Setiap kali data $ustomer diambil dari database, +ibernate akan menggenerate \uery untuk mengambil dari table TS$FSTHMM-. Jika yang diambil adalah Member$ustomer maka \uery yang digenerate hibernate akan mengambil data dari TS$FSTHMM- yang dijoint dengan TSMMM!M-S$FSTHMM-. Mappingnya adalah sebagai berikut ini / ^@ntity ^9able(name7*9(DGS9AB@6*) ^=n.eritance(strategy7=n.eritance9ype.]A=<@:) public class Dustomer implements Seriali?able{ ! Mappingnya di subclassnya / ^@ntity ^9able(name7*9(B@B>@6(DGS9AB@6*) ^4rimaryKey]oinDolumn(name7*DGS9AB@6(=:*) public class BemberDustomer e,tends Dustomer implements Seriali?able{ ! Mapping inheritance class bukan pekerjaan gampang, perlu pemahaman cukup jelas mengenai bagaimana pengaruh inheritance di Mappingnya maupun di +I.nya. Secara umum mapping inheritance sering dihindari selama masih ada alternatif solusi yang sama baiknya, tetapi kalau sudah tidak ada pilihan lain ya tidak ada masalah menggunakan inheritance mapping.

Data"ase Inde,
Database indeL adalah feature yang sangat penting dalam peristence database. Setiap kolom yang digunakan dalam klausa "here sebaiknya dibuatkan indeLnya, bahkan kalau perlu dibuat kombinasi indeL yang sama persis dengan klausa "here-nya. Misalnya di dalam D:H class ,erson ada \uery untuk mengambil data berdasarkan nama-usernya, maka kolom name dalam table

TS,M-SH0 perlu diindeL agar \uery tersebut berjalan dengan cepat. ,roses indeLing biasanya dilakukan untuk tujuan optimisasi, indeLing adalah solusi pertama yang mengatasi sebagian besar masalah performa \uery yang lambat. Setiap -D!MS administration tools mempunyai kemampuan untuk mempro?le \uery yang sedang berjalan. (alau ada \uery yang lambat ditunjukkan oleh hasil pemeriksaan, cara terbaik mengatasinya adalah melihat klausa "here-nya, kemudian pastikan ada indeL yang dengan kombinasi sama dengan klausa "her tersebut. (emudian kalau ada join di dalam slo" \uery tersebut, pastikan de?nisi kolom join-nya sama persis, baik tipe data mapun panjang kolom-nya. (emudian indeL juga kolom yang digunakan sebagai join tersebut. ndeLing bisa dilakukan kasus per kasus seperti dalam penjelasan di atas, dengan mencari slo" \uery. ndeLing bisa juga dilakukan di depan ketika aplikasi akan dibuat kalau sudah tahu bah"a ukuran datanya akan sangat besar dan potensial mengakibatkan slo" \uery. Mapping hibernate untuk membuat database indeL adalah sebagai berikut / ^@ntity ^9able(name7*9(4@6SA<*+uni\ueDonstraints7{^Gni\ueDonstraint(column<ames7{*<IB@*! )!) ^org..ibernate.annotations.9able( applies9o7*9(4@6SA<*+ inde,es7{ ^=nde,(column<ames7{*<IB@*!) ! ) public class 4erson implements Seriali?able { ! :nnotation yang digunakan adalah 8org.hibernate.annotations.Table, annotation adalah komplement dari 8javaL.persistenve.Table yang sudah ada di atasnya. Di dalamnya ada attribute appliesTo yang isinya adalah nama table yang akan diideL. ndeLes digunakan untuk mendaftarkan semua indeL yang akan dibuat dalam table TS,M-SH0, dalam hal ini kita hanya akan membuat satu buah indeL saya yang isinya cuma satu kolom, yaitu kolom 0:MM.

H2+
Iuery adalah bagian terpenting dari aplikasi yang mengakses database, inti dari aplikasi berada di kode yang mengandung \uery ini. +ibernate mempunyai \uery yang disebut +I., di dalam +I. semua object yang digunakan berasal dari class mapping, tidak ada lagi \uery ke table langsung. +I. pada akhirnya akan diubah menjadi \uery yang sesuai dengan -DMS yang digunakan, teknik ini mememungkinkan +ibernate mempunyai feature portability antar -DMS. +ibernate yang sudah matang secara teknologi menjamin semua \uery yang dibuat merupakan \uery yang optimal untuk setiap -D!MS, tuning preformance biasanya tidak dilakikan terhadap \uery yang digenerate hibernate melainkan dilakukan dengan memastikan bah"a struktur table yang dibuat sudah optimum. +I. bersifat case-insensitive kecuali untuk nama Mntity dan propertynya, semua key"ord dalam +I. bisa ditulis dalam huruf kecil ataupun huruf besar. Mari kita mulai dengan beberapa contoh +I. untuk mendapatkan gambaran konkrit bagaimana bentuk +I.. $ontoh paling sederhana adalah melakukan select terhadap Mntity ,erson, seperti yang ada dalam contoh D:H di bagian sebelumnya / /rom 4erson p Seperti terlihat di atas, tidak diperlukan statement select. Iuery di atas akan mengembalikan .istA,ersonC, kita bisa juga melakukan select satu per satu terhadap property class ,erson seperti di ba"ah ini / select p.id+ p.name+ p.pass8ord /rom 4erson p Iuery di atas akan mengembalikan tiga property yaitu id, name dan pass"ord dari class ,erson, hasil \uerynya adalah .istAHbject=>C bukanya .istA,ersonC seperti di contoh

sebelumnya. +al ini dikarenakan \uery di atas memilih satu per satu property class ,erson. Hbject=> akan mempunyai panjang tiga, indeL nol berisi id dengan tipe .ong, indeL satu berisi name dengan tipe String dan indeL dua berisi pass"ord dengan tipe String. Dalam contoh \uery di atas, dapat dilihat juga adanya feature alias untuk mempermudah merefer entity apa yang sedang digunkan. Misalnya dalam contoh di atas p digunakan sebagai alias dari Mntity ,erson.

Pro#ection
,rojection digunakan untuk mengambil nilai-nilai tertentu dari sebuah entity. ,rojection menggunakan klausa select untuk mendaftarkan property apa saja yang akan dikembalikan oleh +I. tersebut. $ontoh kedua di atas menunjukkan bagaimana menggunakan feature projection dalam +I..

Condition
+I. mempunyai feature condition layaknya SI. Iuery, operator kondisi yang digunakan pun tidak berbeda dengan SI. Iuery. $ondition dalam +I. menggunakan klausa "here seperti halnya dalam SI. Iuery, nama-nama yang ada dalam klausa "here adalah property dari Mntity. !erikut ini contoh-contoh penggunaan klausa "here / /rom 4erson 8.ere name7Qi/nuQ /rom 4erson 8.ere picture is not null /rom 4erson 8.ere id 7 ) Dalam klausa "here bisa digunakan property chaining untuk mengakses property dari entity, misalnya seperti contoh di ba"ah ini /rom 4erson p 8.ere p.customer./irst<ame 7 Qi/nuQ Iuery di atas akan mencari ,erson yang juga $ustomer dengan nama depan JifnuJ, \uery di atas kalau diimplementasikan dengan SI. Iuery memerlukan join antara table TS,M-SH0 dan table TS$FSTHMM-. ,roperty chaining adalah salah satu feature +I. yang sangat po"erfull karena mengurangi baris kode \uery secara signi?kan tanpa harus menulis klausa join, cukup menggunakan tanda titik untuk mengakses property dari sebuah entity. Hperator, fungsi dan symbol yang boleh ada dalam klausa "here adalah sebagai berikut / Hperator matematika Q, -, Y, 9 Hperator perandingan [, C[, A[, C, A, AC, _[, dan like Hperator logika menggunakan and, or, dan not Tanda 3 5, digunaka untuk menandai pengelompokan kondisi

in, not on, bet"een, is null, is not null, is empty, is not empty, member of, dan not member of, berikut ini contoh-contoh penggunaanya / /rom 4erson p 8.ere p.name in (Qi/nuQ+QdianQ) /rom 4erson p 8.ere p.name bet8een QIQ and Q]Q /rom 4erson p 8.ere p.customer is null /rom Dustomer c 8.ere c.emails is empty /rom Dustomer c 8.ere Qi/nubima^gmail.comQ member o/ c.emails Serta bentuk negasinya /rom 4erson p 8.ere p.name not in (Qi/nuQ+QdianQ) /rom 4erson p 8.ere p.name not bet8een QIQ and Q]Q /rom 4erson p 8.ere p.customer is not null /rom Dustomer c 8.ere c.emails is not empty /rom Dustomer c 8.ere Qi/nubima^gmail.comQ not member o/ c.emails

!entuk case sederhana/ case ... "hen ... then ... else ... end !entuk case pencarian / case "hen ... then ... else ... end

,enggabungan String ... aa .... atau concat3...,...5 /rom Dustomer c 8.ere c./irst<ame ZZ c.last<ame 7 Qi/nu bimaQ /rom Dustomer c 8.ere concat(c./irst<ame+ c.last<ame) 7 Qi/nu bimaQ currentSdate35, currentStime35, currentStimestamp35 /rom 4erson p 8.ere p.birt.:ate 7 current(date() second3...5, minute3...5, hour3...5, day3...5, month3...5 dan year3...5 /rom 4erson p 8.ere year(p.birt:ate) 7 %MN& fungsi-fungsi untuk manipulasi string dan perhitungan matematis / substring35, trim35, lo"er35, upper35, length35, locate35, abs35, s\rt35, bitSlength35, mod35 /rom 4erson p 8.ere substring(p.name+'+%)7QiQ coalesce35 dan nullif35 str35 untuk menconvert nilai numerik atau temporal menjadi menjadi nilai string cast3... as ...5 dimana argumen kedua adalah nama tipe data +ibernate, dan eLtract3 ... from ...5 jika kedua fungsi cast dan eLtract didukung oleh -D!MS yang digunakan fungsi indeL35 yang dapat dioperasikan terhadap collection yang mempunyai indeL hasil dari operasi join

fungsi-fungsi dalam +I. yang digunakan untuk operasi collection, seperti/ siBe35, minelement35, maLelement35, minindeL35, maLindeL35, plus fungsi elements35 dan indices35 yang dapat dikuanti?kasi menggunakan key"ord / some, all, eLists, any dan in. /rom Dustomer c 8.ere c.emails.si?e 7 % /rom Dustomer c 8.ere si?e(c.emails) 7 % /rom Dustomer c 8.ere ma,element(c.emails) V % /rom Dustomer c 8.ere minelement(c.emails) 7 % /rom Dustomer c 8.ere e,ist elements(c.emails) select m /rom Benu m+ 6ole r 8.ere m in elements(r.menus) select m /rom Benu m+ 6ole r 8.ere all elements(r.menus) V %' fungsi skalar SI. seperti sign35, trunc35, rtrim35 dan sin35 \uery parameter seperti dalam ,reparedStatement JD!$ / Z named parameter, misalnya / /id, /name, /birtdate. (edua style parameter di atas akan dibahas di bab berikutnya SI. literal seperti / JifnuJ, )', ;.;;MQ%, J)16;-&7-&) )&/&&/&&.&J $onstant Java yang ditandai dengan public static ?nal, misalnya $olor.!.FM

Parameter Binding
Di bagian sebelumnya telah disinggung dua gaya untuk memasukkan parameter ke dalam +I., cara pertama menggunakan symbol Z Sebagai penanda letak parameter seperti di dalam ,reparedStatement, contohnya seperti berikut ini/ sessionHactory.getDurrentSession() .createbuery(*/rom 4erson p 8.ere p.name 7 W or p.customer./irst<ame7W*) .set4arameter(%+*i/nu*) .set4arameter()+*i/nu*) $ara kedua adalah menggunakan named parameter, dimana parameternya tidak menggunakan indeL posisi, tapi menggunakan sebuah nama dia"ali dengan tanda /, cara ini jauh lebih baik dan gampang dibaca dibanding cara pertama. Mari kita lihat \uery di atas jika diimplementasikan menggunakan named parameter / sessionHactory.getDurrentSession() .createbuery(/rom 4erson p 8.ere p.name 7 3name or * E * p.customer./irst<ame73/name*) .set4arameter(*name*+*i/nu*)

.set4arameter(*/name*+*i/nu*)

!rder By
.ayaknya SI., +I. juga mendukung sorting hasil \uery menggunakan klausa order by, cara penggunaan order by di +I. sama dengan di SI.. $ontohnya seperti berikut ini / /rom 4erson p order by p.name asc

Agregat
+I. juga mendukung fungsi-fungsi agretat, klausa group by dan klausa having seperti dalam SI. Iuery. !erikut ini contoh penggunaanya / select pd.product.name+ sum(pd.subtotal) /rom 4urc.ase:etail pd group by pd.product.name .aving sum(pd.subtotal) V %''''''

*u"3uery
+I. mendukung sub\uery di dalam \uery, feature ini hanya tersedia untuk -D!MS yang juga mendukung sub\uery. $ara penggunaanya sama dengan sub\uery dalam SI. Iuery, yaitu dengan meletakkan sub\uery di dalam tanda kurung buka-tutup 35 . !erikut ini contoh penggunaan sub\uery dalam +I. /rom 4erson p 8.ere p.name in (select c./irst<ame /rom Dustomer c)

Join
Join dalam +I. bisa digunakan secara implisit maupun eLplisit. $ara implisit terjadi kalau kita menulis +I. dengan mengakses property dari entity dimana property tersebut tipenya juga merupakan entity atau element lain yang dimpping ke table berbeda. Misalnya kita ingin mengambil property nama pertama 3?rst0ame5 customer dari Mntity ,erson, contonya / select p.customer./irst<ame /rom 4erson p select p /rom 4erson p 8.ere p.customer./irst<ame li0e Qi/nuXQ Join cara kedua dilakukan secara eLplisit dengan menggunakan key"ord join, seperti contoh di ba"ah ini / select p /rom 4urc.ase p #oin p.purc.ase:etail pd 8.ere pd.subtotal V %''''''

Masalah La8yInitiali8ation+,ce$tion- 79: *elect, La8y etch dan +ager etch


Masalah paling sering dihadapi programmer ketika menggunakan Spring-+ibernate adalah .aBy nitialiBationMLception 3. M5, error ini terjadi ketika kode berusaha mengakses property yang belum diinisialisasi. Secara default, +ibernate :nnotation menggunakan J,: annotation seperti yang dibahas dalam buku ini akan menginisialisasi single property seperti customer dalam class ,erson atau product dalam class ,urchaseDetail. Tetapi property dengan tipe collection seperti purchaseDetail dalam $lass ,urchase tidak diinisialisasi. . M terjadi karena setiap kali method dalam Service selesai dieksekusi maka Session yang digunakan dalam method service tersebut akan ditutup, sehingga ketika kode kita berusaha mengakses property yang belum diinisialisasi maka error . M akan muncul. :da beberapa cara untuk mengatasi . M, cara pertama adalah dengan mengeset mapping dari ,urchase ke purchaseDetail dengan *etchType.M:KM-, seperti contoh di ba"ah ini / ^Ane9oBany(mapped>y7*purc.ase*+cascade7Dascade9ype.I;;+ /etc.7Hetc.9ype.@IS@6) ^Dascade(org..ibernate.annotations.Dascade9ype.:@;@9@(A64HI<) private ;istT4urc.ase:etailV purc.ase:etail Mapping di atas akan secara otomatis menginisialisasi purchaseDetails setiap kali entity ,urchase di-select. Solusi ini malah akan menimbulkan masalah yang disebut dengan N8* Select" hal ini terjadi karena untuk setiap baris dalam table TS,F-$+:SM, +ibernate akan melakukan satu \uery untuk mendapatkan semua baris dalam TS,F-$+:SMSDMT: ., sehingga satu \uery / /rom 4urc.ase p yang menghasilkan 0 buah baris TS,F-$+:SM akan dilakukan \uery ke -D!MS sebanyak 0Q)

kali. (esimpulanya adalah solusi eager fetch ini tidak boleh digunakan secara sembarangan, bahkan disarankan untuk tidak menggunakan eager fetch sama sekali karena akan menyebabkan pemborosan resource. Solusi kedua adalah dengan menggunakan klausa left join fetch ketika ingin mendapatkan nilai ,urchase plus purchaseDetail seperti dalam \uery berikut ini / /rom 4urc.ase p le/t #oin /etc. p.purc.ase:etail pd +I. di atas akan diterjemahkan oleh +ibernate dengan melakukan join antara TS,F-$+:SM dan TS,F-$+:SMSDMT: . sehingga masalah 0Q) select dan masalah . M terpecahkan dengan baik. !est ,ractice untuk mengatasi masalah ini adalah dengan selalu menggunakan left join fetch untuk semua property yang merupakan entity agar tidak terkena masalah . M dan 0 Q ) Select.

&rans ormation
Terkadang kita dihadapkan pada suatu kebutuhan untuk mengambil nilai-nilai tertentu saja dari suatu table, tetapi tidak ingin mendapatkan nilai .istAHbject=>C dari hasil \uery-nya, karena abstraksi kode menjadi susah dibaca kalau menggunakan tipe data .istAHbject=>C, kebutuhan seperti ini biasanya sering ditemui di dalam report. +ibernate mempunyai feature yang disebut Transformation yang dapat digunakan untuk mentransformasi hasil select \uery ke dalam class tertentu. Mari kita lihat contoh penggunaan feature Transformation ini untuk membuat laporan penjualan harian berdasarkan produk. ,ertama, buat sebuah class dengan struktur seperti di baah ini / public class :ailySales6eport { private String product<ame private ;ong \uantity private >ig:ecimal sub9otal public String get4roduct<ame() { return product<ame ! public void set4roduct<ame(String product<ame) { t.is.product<ame 7 product<ame ! public ;ong getbuantity() { return \uantity ! public void setbuantity(;ong \uantity) { t.is.\uantity 7 \uantity ! public >ig:ecimal getSub9otal() { return sub9otal ! public void setSub9otal(>ig:ecimal sub9otal) { t.is.sub9otal 7 sub9otal ! ! (emudian kode dalam D:H untuk mengambil nilai DailySales-eport dari \uery dengan feature Transformation adalah sebagai berikut ini / sessionHactory.getDurrentSession() .createbuery(*select p.name as product<ame+ sum(pd.\uantity) as \uantity+ * E * sum(pd.subtotal) as sub9otal /rom 4urc.ase:etail pd * E * group by pd.product.name * E * 8.ere pd.purc.ase.purc.ase:ate 7 current(date*) .set6esult9rans/ormer(9rans/ormers.alias9o>ean(:ailySales6eport.class)) .list() (ode di atas menggunakan alias to bean transformer yang menyaratkan kode +I.

menggunakan nama alias yang sama dengan property yang ada dalam class DialySales-eport, misalnya p.name diberi alias product0ame yang sama persis dengan property DialySales-eport.product0ame dan seterusnya.

Hibernate Ca&*e
:plikasi yang mempunyai load tinggi sering kali berhadapan dengan performa yang buruk karena akses ke database yang sangat tinggi. +ibernate mempunyai feature cache yang dapat mempertahankan performa aplikasi dikala akses ke database sangat tinggi. $ache dibuat untuk tujuan ini, meningkatkan performa aplikasi dalam keadaan load yang sangat tinggi. ,erforma cache sendiri bisa ratusan hingga ribuan kali lebih cepat dibanding database akses karena datanya yang terletak di dalam memory, sedangkan -D!MS biasanya meletakkan data di dalam +ard disk. +ibernate mempunyai feature cache yang terdiri dari dua level/ *irst level cache dan second level cache. $ache di hibernate berfungsi untuk mengurangi hit ke database sehingga resource bisa lebih e?sien. $ara kerja cache adalah dengan menyimpan data dalam memory, dalam hal ini sebagai object Java. Selama object masih terus disimpan oleh cache, +ibernate tidak akan mengambil nilai data itu dari database tetapi dari cache ini. $ache pada teorinya adalah sebuah Map 9 $ollection untu menyimpan object-object berupa data. +ibernate pertama kali akan berusaha mencari data di cache, jika tidak diperoleh maka hibernate memutuskan untuk meng\uery data dari -D!MS.

4irst level cache


*irst level cache digunakan untuk menyimpan resource yang digunakan selama satu scope transaksi atau bisa juga diartikan dalam satu Thread. $ache ini built in di dalam +ibernate dan tidak perlu kon?gurasi tambahan untuk menghidupkanya. Dalam buku ini, satu scope transaksi adalah ketika method dalam Spring service mulai dieksekusi hingga method tersebut selesai dieksekusi. *irst .evel cache berada dalam +ibernate Session, selama Session masih belum ditutup data akan disimpan dalam Session, sehingga \uery ke data yang sama selama session masih belum ditutup tidak akan diambil dari dalam Database, tetapi diambil dari *irst level cache di dalam Session ini. Selain itu Session tidak boleh digunakan atau dishare untuk thread berbeda, setiap kali transaksi selesai atau setiap kali thread selesai maka session harus diclose, hal ini mengakibatkan ?rst level cache dala Session tersebut juga dibuang. ,erhatikan kode yang berada dalam suatu method class D:H berikut ini / /or(int7' iT%'' iEE){ sessionHactory.getDurrentSession() .createbuery(*/rom 4erson*) .list() ! Terlihat bah"a \uery Ofrom ,ersonO dieksekusi seratus kali dalam kode Java, tetapi kalau dilihat outputnya, +ibernate hanya akan mengeksekusi \uery sekali saja pada saat pertama kali. +ibernate tidak akan mengeksekusi SI. untuk \uery berikutnya, tetapi menggunakan nilai yang sama yang diambil dari *irst level cache.

*econd level cache


Sifat *irst level cache yang hanya hidup dalam satu scope transaksi yang sangat pendek, terkadang tidak sesuai dengan kebutuhan optimisasi data yang sering dibaca oleh aplikasi dalam proses berbeda. Second level cache memenuhi kebutuhan ini dengan melakukan cache daam satu scope aplikasi, dimana cache akan berada dalam Session*actory, sehingga cache akan bisa terus dipertahankan selama session*actory tersebut tidak diclose, yang artinya aplikasi dimatikan. Session*actory akan dibuat ketika distart aplikasinya dan diclose ketika aplikasi ditutup. ,erlu di"aspadai dalam penggunaan second level cache ini, karena cache tidak akan diupdate kalau proses update data dilakukan darii proses lain tanpa menggunakan Session*actory yang sama, misalnya ada satu proses di background yang akan melakukan perubahan data atau

peruahan data dilakukan manual langsung ke database dari -D!MS admin tool. #alaupun bisa saja dibuat sebuah kon?gurasi yang secara periodik akan mengupdate cache. Second level cache mempunyai beberapa setrategi, antara lain / read-only, non strict read"rite, read-"rite, dan transactional. Mari kita bahas satu per satu mode di atas. -ead-Hnly digunakan kalau data yang dicache tidak pernah dirubah sama sekali, misalnya entity Menu, kalau ada perubahan di Mntity menu maka apalikasi harus direstart agar cachenya direfresh. Strategi ini mempunyai kinerja paling bagus dan aman digunakan dalam lingkungan cluster. -ead-#rite digunakan kalau data yang dicache akan diupdate. Strategi ini tidak boleh digunakan jika transaction isolation level yang digunakan adalah SerialiBable. Jika digunakan dalam lingkungan cluster, harus dipastikan bah"a cache provider mendunkung locking terhadap cache data. 0onstrict -ead-#rite digunakan jika data hanya sesekali diupdate dan dipastikan bah"a tidak akan pernah ada proses mengupdate data ini secara simultan dari dua buah mesin berbeda dalam satu cluster. Transactional menyediakan dukungan penuh terhadap transactional cache dalam lingkunan cluster. $ache dengan feature ini harus digunakan bersama denga JT: provider yang mendukung clustering. Sebelum memulai menggunakan Second level cache, yang pertama harus dilakukan adalah memilih cache provider yang sesuai, karena tidak ada satupun cache provider yang mendukung semua strategi, pilih cache provider yang sesuai dengan kebutuhan aplikasi. :da beberapa cache provoder yang didukung oleh +ibernate, setiap cache provider mempunyai feature dan kemampuan yang berbeda-beda, silahkan pilih cache provider yang sesuai dengan kebutuhan aplikasi. !erikut ini cache provider yang didukung oleh +ibernate
0ama Mh$ache HS$ache S"arm$ache Jboss Tree$ache -ead-Hnly Pes Pes Pes Pes 0on strict read "rite Pes Pes Pes 0o -ead #rite Pes Pes 0o 0o Transactional 0o 0o 0o Pes

Sebagai contoh, kita akan menggunakan Mh$ache sebagai cache provider. !erikut ini kon?gurasi yang harus ditambahkan dalam hibernate.cfg.Lml / Tproperty name7*cac.e.provider(class*V org..ibernate.cac.e.@.Dac.e4rovider TCpropertyV Tproperty name7*cac.e.use(second(level(cac.e*VtrueTCpropertyV Selanjutnya buat sebuah Lml kon?gurasi dengan isi sebagai berikut / TW,ml version7*%.'* encoding7*G9H$N*WV Te.cac.eV Tdis0Store pat.7*#ava.io.tmpdir*CV Tde/aultDac.e ma,@lements=nBemory7*%''''* eternal7*/alse* time9o=dleSeconds7*%)'* time9o;iveSeconds7*%)'* over/lo89o:is07*true* CV Tcac.e name7*com.googlecode.pro#ecttemplate.model.Benu* eternal7*true* over/lo89o:is07*/alse* CV

Tcac.e name7*com.googlecode.pro#ecttemplate.model.4erson* ma,@lements=nBemory7*%'''* eternal7*/alse* time9o=dleSeconds7*M''* time9o;iveSeconds7*%N''* over/lo89o:is07*true* CV TCe.cac.eV (on?gurasi di atas memperlihatkan bah"a entity yang dicache adalah Menu dan ,erson, kemudian ada beberapa kon?gurasi lain yang diset, mari kita bahas satu per satu / diskStore kon?gurasi ini digunakan untuk meletakkan cache di disk kalau memory tidak mencukupi. Disk Store berguna kalau database dan aplikasi diletakkan dalam server berbeda, sehingga akses data dari local hardisk lebih cepat daripada akses database yang berada di hardisk server lain default$ache digunakan untuk mende?nisikan attribute default dari ehcache. :ttribute yang ada dalam default$ache akan dioverride oleh attribute yang sama dalam tag cache cache tag digunakan untuk mende?nisikan Mntity apa saja yang akan dicache dalam +ibernate, attribute name berisi nama class dari Mntitynya. maLMlements nMemory digunakan untuk mende?nisikan berapa maLimum jumlah object entity yang akan disimpan dalam cache. eternal true digunakan untuk menandai bah"a cache ini akan hidup selamanya, tidak diganti atau diupdate selama aplikasi berjalan. ,erhatikan bah"a untuk menu nilai eternal adalah true, karena selama aplikasi berjalan menu tidak kan berubah sama sekali, sedangkan untuk ,erson nilai eternal adalah false, artinya ada kemungkinan nilai ,ersin ini bisa berubah dan cache harus mengupdate nilainya jika ada perubahan. overUo"ToDisk true menandakan bah"a cache untuk ,erson bisa disimpan dalam hardisk jika memory sudah tidak mencukupi. Sedangkan cache untuk Menu mempunyai nilai false, artinya semua cache untuk menu akan disimpan dalam memory dan tidak ada yang disimpan dalam hardisk. timeTo.iveSeconds digunakan untuk mende?nisikan berapa lama cache hidup sebelum berusaha diupdate dari database. Setelah time to live dile"ati maka cache akan diremove dan re\uest berikutnya yang memerlukan cache tersebut akan diambil lagi dari database. timeTo dleSeconds digunakan untuk menandai berapa lama cache tidak digunakan sebelum deremove. (alau data tersebut sudah mencapai "aktu di timeTi dleSeconds tanpa sekalipun diakses, maka data akan diremove dari cache. +al ini dimaksudkan untuk menghindari cache diisi oleh data yang jarang digunakan, sehingga ukuranya akan semakin membengkak.

Tidak perlu ada kon?gurasi untuk memberitahu hibernate tentang adanya ?le ehcache.Lml ini, library ehcache akan secara otomatis mencari ?le ini, ehcache.Lml harus berada dalam classpath agar dapat ditemukan. ,erubahan lain yang perlu dilakukan adalah disisi mappingnya, di dalam class Menu dan ,erson perlu ditambahkan annotation 8$ache dan mendeklarasikan strategi apa yang digunakan. ^@ntity ^9able(name7*9(B@<G*) ^Dac.e(usage7Dac.eDoncurrencyStrategy.6@I:(A<;_) public class Benu impelements Seriali?able{ ! Seperti yang kita bahas sebelumnya, entity Menu akan menggunakan strategi read-only karena sifatnya yang tidak akan berubah selama aplikasi berjalan, jika menu akan berubah maka aplikasi harus direstart. ^@ntity

^9able(name7*9(4@6SA<*+uni\ueDonstraints7{^Gni\ueDonstraint(column<ames7{*<IB@*! )!) ^Dac.e(usage7Dac.eDoncurrencyStrategy.6@I:(W6=9@) public class 4erson implements Seriali?able { ! Mntity ,erson menggunakan strategi read-"rite karena ada kemungkinan nilai-nilai entity ini berubah dengan adanya penambahan atau edit data person. Second level cache paling tepat digunakan untuk data yang sering dibaca tetapi jarang ditulis seperti table-table catalog atau table master. Seperti dalam caontoh di atas adalah Mntity Menu dan Mntity ,erson. ,erlu diketahui juga bah"a cache ini hidupnya di dalam Session*actory, sehingga akan memberikan efek jika digunakan dalam arsitektur Three Tier, dimana hanya ada satu Session*actory yang berada di thier application server. Jika aplikasinya menggunakan arsitektur client server dimana setiap client akan langsung terhubung dengan database dan setiap client mempunyai Session*actory sendiri-sendiri, maka second level cache menjadi tidak relevan dan sebaiknya tidak digunakan dalam arsitektur client-server.

*wing
Java #oundation Class
Java *oundation $lass 3J*$5 merupakan sekumpulan class-class Java yang digunakan untuk mengembangkan perangkat lunak berbasis KF 3Kraphical Fser nterface5. Selain itu, J*$ juga mempunyai class-class yang digunakan untuk menambahkan fungsi dan kemampuan interaksi yang variatif dari pemrograman Java. Dari de?nisi ini, J*$ tidak hanya berisi class-class KF saja tetapi juga class-class lain yang dapat meningkatkan kemampuan pemrograman Java baik dari segi fungsionalitasnya maupun dari segi kemampuan interaksi pemrograman Java yang sangat kaya.

#eature J#C
*itur-?tur yang dipunyai oleh J*$ *itur (omponen S"ing .ook and *eel 3.a*5 Deskripsi Memuat semua class-class yang dibutuhkan untuk membuat aplikasi berbasis KF , dari tombol, table, tab, menu, toolbar dan sebagainya Memberikan kemampuan kepada program Java yang dikembangkan menggunakan library S"ing untuk memilih tema tampilan. Misalnya sebuah program yang sama dapat mempunyai tampilan "indo"s .a* atau Java .a*, atau .a* lain yang dikembangkan oleh komunitas seperti JKoodies. *aslititas untuk mengembangkan aplikasi bagi penyandang cacat, misalnya dukungan untuk membuat huruf braile, kemampuan mengambil input dari layar sentuh dan sebagainya. !erisi kumpulan class-class yang dapat digunakan untuk memanipulasi object-object % dimensi, sperti garis, kotak, lingkaran, kurva dan lain sebagainya. Selain itu Java %D :, juga memberikan kemampuan program yang ditulis menggunakan Java untuk mencetak output ke alat pencetak seperti printer. Menyediakan kemampuan drag-and-drop antara program Java dan program lain yang ditulis spesi?k untuk suatu platform sistem operasi tertentu. Membantu pengembang perangkat lunak untuk membangun aplikasi yang dapat mendukung semua bahasa dan huruf yang ada di dunia.

:ccessibility :,

Java %D :,

Drag-and-drop

nternationaliBation 3i)6n5

Modul ini akan berkonsentrasi untuk membahas komponen S"ing. ,emilihan komponen dan library S"ing yang tepat dapat mempengaruhi kualitas program yang kita buat secara signi?kan. +al ini dikarenakan, dalam dunia Java Standard Mdition, lebih spesi?k lagi aplikasi Java yang dibangun menggunakan S"ing, belum ada frame"ork yang benar-benar komprehensif membimbing pengembang untuk membuat aplikasi yang berkualitas. ,ada umumnya aplikasi yang dikembangkan dengan S"ing mempunyai kode yang sangat JkotorJ, dimana kode yang berisi pengendalian terhadap event komponen S"ing bercampur aduk dengan kode yang berisi aturan bisnis dan kode yang berisi manipulasi terhadap data.

Swin! 'a&ka!e
S"ing :, sangat bagus dan lengkap, Java ;.& menyertakan setidaknya tujuh belas 3)'5 buah package yang berisi class-class S"ing yang siap digunakan.
javax.accessibility javax.swing javax.swing.border javax.swing.colorchooser javax.swing.event javax.swing.filechooser javax.swing.plaf javax.swing.plaf.basic javax.swing.plaf.metal javax.swing.plaf.multi javax.swing.plaf.synth javax.swing.text javax.swing.text.html javax.swing.text.rtf javax.swing.table javax.swing.tree javax.swing.undo

Ftungnya kita tidak akan menggunakan semua class-class dalam package S"ing, hanya sebagian kecil saja dari class-class tersebut yang nantinya akan benar-benar kita gunakan. Sehingga kita bisa berkonsentrasi untuk memahami beberapa komponen penting saja. Dalam modul ini nanti kita hanya akan menggunakan beberapa class komponen S"ing yang penting saja. !eberapa kelas ini sudah cukup sebagai bahan pemembuat perangkat lunak berkualitas. (omunitas Java juga menyediakan banyak sekali library S"ing, antara lain dari S"ingL dan JKoodies yang mengembangkan library standard S"ing dengan menambahkan berbagai macam feature menarik. Sedangkan komunitas dari javadesktop.org mengembangkan banyak sekali library S"ing untuk keperluan khusus. 0yaris semua komponen yang kita perlukan baik komponen umum hingga komponen untuk tujuan khusus banyak tersedia di internet, kita tinggal mencari dan menggunakan. ,raktek yang baik dalam memilih komponen apa yang tepat adalah dengan mencari dahulu informasi di internet. +al ini sangat bermanfaat untuk mengurangi "aktu kita mengembangkan komponen, sehingga kita bisa lebih banyak berkonsentrasi untuk mengembangkan sisi bisnis dan usability dari soft"are yang kita kembangkan. Sebaik apapun softe"are yang kita buat tapi tidak memberikan nilai tambah terhadap masalah yang dihadapi adalah kesia-siaan belaka. !anyak sekali soft"are yang dianggap gagal memberikan nilai tambah terhadap masalah yang dihadapi hanya karena tampilan KF -nya sangat susah dipahami dan tidak intuitif.

Swin! HelloWorld
Menggunakan contoh langsung adalah cara yang tepat untuk memulai proses belajar. $ara ini memberikan gambaran kongkrit tentang subject yang akan dipelajari, sehingga proses belajar lebih cepat diserap. Fntuk tujuan ini, kita akan membuat sebuah program kecil yang menampilkan kata E+ello#orldG menggunakan komponen S"ing. !erikut ini adalah langkahlangkah yang harus anda lakukan untuk membuat program E+ello#orldG berbasis komponen S"ing/ ). %. 7. <. nstall Java Development (it 3JD(5 Membuat program +ello#orld itu sendiri Melakukan kompilasi program +ello#orld Menjalankan program +ello#orld

Install Java Develo$ment Kit


Pang perlu kita lakukan dalam langkah ini hanyalah mendo"nload JD( dari "ebsite java.sun.com. kemudian jalankan program instalasinya dan ikuti perintah-perintah dalam langkah-langkah instalasi tersebut. Setelah proses instalasi selesai, kita siap untuk membuat program Java.

Mem"uat $rogram /ello'orld

,rogram Java dengan tampilan seperti di atas dapat dibuat dengan dua cara. $ara yang pertama adalah dengan menggunakan teLt editor dan mengetik kode program. $ara yang kedua adalah dengan menggunakan 0etbeans Matisse KF !uilder. .akukan langkah-langkah berikut ini untuk membuat program di atas menggunakan teLt editor/ ). !uka teLt editor kesayangan anda. %. (etikkan kode program di ba"ah ini dan simpan dengan nama ?le +ello#orld.java / public class HelloWorld { public void display(){ ]Hrame.set:e/ault;oo0IndHeel:ecorated(true) ];abel label 7 ne8 ];abel(*HelloWorld*) ]Hrame /rame 7 ne8 ]Hrame() /rame.getDontent4ane().add(label) /rame.setPisible(true) /rame.pac0() /rame.set:e/aultDloseAperation(]Hrame.@J=9(A<(D;AS@) ! public static void main(String[] str){ HelloWorld .ello 7 ne8 HelloWorld() .ello.display() ! !

Melakukan kom$ilasi $rogram /ello'orld


(ompilasi program tersebut dengan cara menjalankan program javac 3Java compiler5. Jika anda bekerja di lingkungan "indo"s buka command prompt, kemudian ketik program berikut ini / c3Olati.anV #avac HelloWorld.#ava Jika anda bekerja di lingkungan K0F9linuL, buka console dan ketikkan perintah berikut ini / s.ell" #avac HelloWorld.#ava

Men#alankan $rogram /ello'orld


,roses kompilasi akan menghasilkan ?le yang berekstensi .class, ?le inilah yang akan kita eksekusi. Jika anda bekerja di lingkungan "indo"s lakukan perintah berikut ini/ c3Olati.anV #ava HelloWorld Jika anda bekerka di lingkungan K0F9.inuL jalankan perintah berikut ini/ s.ell" #ava HelloWorld

embuat Swin! HelloWorld den!an 3et/eans


0etbeans ;.) dilengkapi dengan KF builder yang dikenal dengan Matisse. Dalam modul ini selanjutnya, Matisse akan digunakan untuk menyebut 0etbeans KF !uilder. Tools ini sangat po"erful dan produktif dalam membuat komponen KF . .angkah-langkah yang harus anda lakukan untuk membuat S"ing +ello#orld dengan Matisse adalah sebagai berikut/ ). !uat project baru dalam 0etbeans, caranya pilih menu / Hile V <e8 4ro#ect

%.

.angkah berikutnya anda harus menentukan kategori project yang akan anda buat, caranya pilih / Seneral V ]ava Ipplication :nda akan diba"a ke dialog untuk menentukan nama project dan folder dimana anda meletakkan project tersebut, pilih folder sesuai keinginan anda.

7.

(lik kanan di project yang baru anda buat, popup menu akan muncul, kemudian pilihlah menu / <e8 V ]Hrame Horm... (emudian masukkan nama class J*rame yang akan dibuat, misalnya +ello#orld.java, klik ?nish.

<.

Tampilan 0etbeans akan berganti dengan tampilan KF builder, dimana di sisi kanan akan terlihat S"ing ,allet. (lik item .abel di S"ing ,allet kemudian klik di atas J*rame, sebuah J.abel akan dibuat.

Jendela Design dan ,allete 0etbeans Matisse 4. Fntuk memenuhi tujuan kita membuat S"ing +ello#orld, kita akan memasukkan string E+ello#orldG ke dalam J.abel yang baru saja kita buat. $aranya, dobel klik di atas J.abel tersebut, kursor muncul bersama teLt ?eld dan ketikkan E+ello"orldG. (lik kanan di ?le HelloWorld.#ava pada jendela eLplorer di sebelah kiri, pilih menu 7un 1ile... untuk mengcompile dan menjalankan class HelloWorld.#ava atau tekan tombol S+ *T Q *;.

;.

Matisse mempunyai sistem .ayouting yang sangat Ueksible, sistem layout yang digunakan oleh Matisse adalah Kroup.ayout. Dalam chapter berikutnya kita akan belajar bagaimana menggunakan Kroup.ayout ini dengan benar dan memanfaatkan keunggulanya dalam menata component KF dengan sangat rapi. S"ing hello"orld ini hanya sebagian kecil saja dari pekerjaan yang harus dilakukan dalam membangun aplikasi desktop berbasis Java. Selanjutnya kita akan membahas penggunaan J.abel, J!utton, J$heck!oL, JTeLt*ield dan J-adio!utton untuk membuat aplikasi KF sederhana dengan menggunakan Matisse.

Kom$onen *wing
S"ing toolkit menyediakan banyak sekali komponen untuk membangun aplikasi KF desktop. S"ing toolkit juga menyediakan class-class untuk menangani interaksi antara aplikasi dan user menggunakan standard input seperti keyboard dan mouse. (omponen-komponen yang disediakan S"ing mencakup semua KF toolkit yang laBim digunakan dalam apilasi desktop, seperti / JTabel, J.ist, JTree, J!utton, J.abel dan masih banyak komponen-komponen lainnya yang sudah teruji dan siap pakai. Selain komponen KF , S"ing juga menyediakan fasilitas untuk proses undo, komponen untuk mengolah teLt, internationaliBation, (omponen KF yang mendukung penyandang cacat 3accessibility support5 dan fasilitas drag-and-drop. .ook and *eel merupakan fasilitas yang unik dalam S"ing. Dengan fasilitas .ook and *eel ini kita bisa dengan mudah merubah tampilan dari program kita sesuai dengan keinginan dan tujuan kita. Misalnya, agar program terlihat fancy atau agar program terlihat konsisten dalam segala keadaan. S"ing juga menyediakan library Java %D untuk pengolahan data secara visual, seperti mengolah gambar, object %D, bahkan animasi. S"ing.abs.org menyediakan libary S"ing ,ainter yang merupakan pengembangan dari Java %D, S"ing ,ainter ini memungkinkan aplikasi S"ing mempunyai tampilan yang indah dan terlihat profesional. Java ;.& menambahkan banyak sekali ? tur-?tur baru ke dalam package S"ing, termasuk dukungan untuk library HpenK. menggunakan JHK., Tray con dan #eb Service. Dengan adanya dukungan ini S"ing menjadi lebih po"eful dan mempunyai masa depan yang cerah.

Struktur Komponen Swin!


Secara arsitektur, S"ing dibangun di atas arsitektur :#T 3:bstract #indo"s Toolkit5. :#T adalah KF toolkit yang dikembangkan oleh Sun engineer sebelum S"ing muncul. (elemahan utama :#T adalah Ueksibilitas tampilan KF , seperti painting method yang masih sangat primitif. S"ing dimaksudkan untuk memperbaiki kekurangan dari :#T tanpa harus membuang teknologi yang sudah dibuat dan membuat KF toolkit baru dari nol. (omponen :#T diletakkan dalam satu package yaitu java.a"t, didalamnya terdapat komponenkomponen KF dasar, salah satunya adalah $omponent. $lass $omponent adalah moyang dari sebagian besar komponen :#T maupun S"ing. $heck!oL, .abel, !utton dan beberapa komponen :#T lainnya adalah turunan langsung dari class $omponent. 0amun dalam kenyataanya arsitektur demikian tidak memberikan Ueksibilitas yang cukup memadai untuk membuat berbagai macam komponen baru yang dibutuhkan dalam desktop application. S"ing muncul dengan memba"a teknologi :#T yang telah ditambahkan dengan banyak kemampuan. 0yaris semua komponen KF dari S"ing merupakan turunan class $ontainer dan class $ontainer adalah turunan dari class $omponent.

/eker.a den!an J+abel, J-e%t#ield dan J/utton


!ekerja dengan komponen S"ing menggunakan Matisse sangat menyenangkan dan mudah. Kroup.ayout yang sangat Ueksibel memungkinkan kita untuk membuat aplikasi dengan tampilan seperti yang kita harapkan. .abel, teLt?eld dan tombol adalah komponen-komponen dasar yang selalu ada dalam setiap aplikasi berbasis desktop. (etiga komponen ini mempunyai fungsi yang sangat sederhana, teLt?eld menyimpan data berbentuk teLt 3string5 yang relatif pendek , label banyak digunakan untuk memberikan keterangan penjelas terhadap komponen lain dan tombol digunakan user untuk menjalankan satu instruksi tertentu.

!erikut ini adalah contoh aplikasi sederhana yang melakukan penjumlahan dua buah bilangan.

$ontoh program menggunakan J.abel, JTeLt*ield dan J!utton Fntuk membuat aplikasi ini menggunakan Matisse, lakukan langkah-langkah berikut ini/ ). !uat project baru di 0etbeans 3kalau sudah membuat project, tidak perlu membuat lagi5 dengan cara memilih menu / Hile V <e8 4ro#ect (emudian ikuti petunjuk yang diberikan dialog. %. !uat class J*rame baru, caranya dengan memilih menu / Hile V <e8 Hile (emudian akan muncul dialog seperti di ba"ah ini /

Jendela dialog ne" ?le 7. ,ilih kategori / ]ava SG= Horms V ]Hrame Horm Seperti terlihat di dialog 0e" *ile dialog di atas, kemudian beri nama ,enjumlahan.java <. !uat tampilan form seperti gambar ba"ah ini, caranya dengan klik Jendela ,allete di sebalah kanan untuk memilih komponen apa yang akan dibuat, kemudian klik di jendela Design untuk menempatkan komponen yang sudah dipilih tadi ke dalam form. +asilnya terlihat seperti pada gambar di ba"ah ini/

Jendela design 0etbens Matisse 4. Kanti nama setiap komponen agar mudah dikenali. (lik kanan di atas setiap komponen yang ada dalam Jendela Design di atas, kemudian pilih menu / Kli0 0anan V D.ange Pariable <ame ... Kanti nama komponen-komponen tersebut 3sesuai urutan dari kiri ke kanan, atas ke ba"ah5 menjadi / lbl(eterangan, tLt:, lbl,lus, tLt!, btn+itung, lbl+asil. ;. Menambahkan variabel untuk menampung nilai yang akan dijumlahkan. (lik tombol Source untuk membuka jendela yang menampilkan kode sumber dari program di atas kemudian tambahkan kode di ba"ah ini tepat di ba"ah de?nisi dari class ,enjumlahan/ private String str 7 *Hasilnya adala. 3 * private int a+ b Menangani penekanan tombol btn+itung. (lik kanan di atas komponen btn+itung kemudian pilih menu / @vents V Iction V action4er/ormed :nda akan diba"a ke jendela Source, dan akan menemukan kode program seperti di ba"ah ini / private void btnHitungIction4er/ormed(#ava.a8t.event.Iction@vent evt) { CC 9A:A add your .andling code .ere3 ! Fbah kode program di atas menjadi / private void btnHitungIction4er/ormed(#ava.a8t.event.Iction@vent evt) { CC 9A:A add your .andling code .ere3 a 7 =nteger.parse=nt(t,tI.get9e,t()) b 7 =nteger.parse=nt(t,t>.get9e,t()) int .asil 7 a E b lblHasil.set9e,t(str E .asil) ! 6. $ompile dan jalankan program. Tekan tombol ,enjumlahan.java kemudian pilih menu -un *ile. S+ *T Q *;, atau klik kanan ?le

'.

$atatan / Method nteger.parse nt digunakan untuk merubah String menjadi nteger. Method btn+itung:ction,erformed akan dipanggil setiap kali kita memencet tombol btn+itung.

Sekarang anda bisa melihat bah"a bekerja dengan J.abel, JTeLt*ield dan J!utton sangat sederhana. Fntuk latihan, silahkan rubah fungsi yang digunakan dalam program di atas, misalnya perkalian dua bilangan atau pengurangan dua bilangan.

/eker.a den!an JC*e&k/o% dan J1adio/utton


J$heck!oL dan J-adio!utton hanya bisa mempunyai dua buah kemungkinan nilai, benar atau salah. (edua komponen ini digunakan untuk merepresentasikan data yang berupa pilihan. J$heck!oL digunakan jika pilihanya berupa multiple selection, sedangkan J-adio!utton digunakan jika pilihanya berupa single selection. J-adio!utton digunakan misalnya untuk merepresentasikan pilihan jenis kelamin. J$heck!oL digunakan misalnya untuk merepresentasikan pilihan hobby. !uttonKroup diperlukan untuk mengumpulkan J-adio!utton yang mempunyai grup pilihan yang sama. Misalnya grup pilihan jenis kelamin digunakan untuk mengumpulkan J-adio!utton yang merepresentasikan pilihan laki-laki dan J-adio!utton yang merepresentasikan pilihan perempuan dalam satu group. Jika J-adio!utton tidak diletakkan dalam satu group, maka pilihan laki-laki dan pilihan perempuan bisa dipilih bersamaan. Status dari J-adio!utton dan J$heck!oL dapat diketahui dengan melihat nilai kembalian dari method isSelected, jika dipilih maka nilai kembalian method isSelected adalah benar, dan false jika sebaliknya. Setiap J-adio!utton dan J$heck!oL mempunyai teLt yang menerangkan pilihan yang di"akilinya. Method getTeLt dan setTeLt digunakan untuk memanipulasi teLt. Di ba"ah ini adalah contoh program yang menggunakan J$heck!oL dan J-adio!utton.

$ontoh aplikasi menggunakan J$heck!oL dan J-adio!utton Di bagian atas aplikasi ini, terdapat dua J-adio!utton untuk merepresentasikan pilihan tipe "arna, transparan atau ber"arna. Di ba"ahnya terdapat pilihan "arna yang dapat dipilih lebih dari satu buah menggunakan J$heck!oL. Fntuk membuat program di atas ikuti langkah-langkah berikut ini/ ). !uat class baru bertipe J*rame *orm, kemudian beri nama ,ilihan.java %. !uat tampilan di atas menggunakan Matisse. komponen yang harus dibuat adalah / Dua object J-adio!utton / radio!er"arna dan radioTransparan. Satu object !uttonKroup / groupTipe#arna. Mmpat object J$heck!oL / chk+ijau, chk!iru, chkMerah, chk(uning. Satu object JTeLt:rea / tLt#arna. Satu object JScroll,ane / scroll#arna

Fntuk melihat semua komponen yang ada dalam Jendela Design, gunakan Jendela nspector di sisi kiri ba"ah. 7. Masukkan object radio!er"arna dan radioTransparan ke dalam object groupTipe#arna. $aranya dengan / a5 Memilih komponen radio!er"arna di Jendela Design b5 (lik tab code di Jendela ,roperties c5 ,ilih properti / ,ost-$reation $ode d5 Masukkan kode berikut ini kedalam dialog yang muncul / group9ipeWarna.add(radio>er8arna) .akukan langkah yang sama terhadap object radioTransparan. <. Menangani event ketika J-adio!utton diklik. $aranya dengan / a5 Memilih komponen radio!er"arna di Jendela Design b5 (lik kanan komponen radio!er"arna, kemudian pilih menu/ @vent V Iction V action4er/ormed c5 :nda akan diba"a ke dalam Jendela $ode, dan menemukan kode berikut ini / private void radio>er8arnaIction4er/ormed(#ava.a8t.event.Iction@vent evt) { CC 9A:A add your .andling code .ere3 ! Fbahlah kode di atas menjadi / private void radio>er8arnaIction4er/ormed(#ava.a8t.event.Iction@vent evt) { CC 9A:A add your .andling code .ere3 i/(radio>er8arna.isSelected()){ lbl9ipeWarna.set9e,t(*9ipe 8arna 3 * E radio>er8arna.get9e,t()) ! ! .akukan langkah yang sama terhadap radioTransparan. 4. !uat sebuah private method untuk menangani event pemilihan terhadap J$heck!oL. Method tampilkan#arna ini nantinya akan dipanggil setiap kali salah satu dari J$heck!oL dipilih. yang dilakukan oleh metod tampilkan#arna adalah mengecek status setiap J$heck!oL, apakah sedang dipilih atau tidak. Jika sedang dipilih maka teLt dari J$heck!oL tersebut akan ditampilkan dalam tLt#arna. $lass String!u^er digunakan untuk menampung nilai teLt dari J$heck!oL yang statusnya terpilih. private void tampil0anWarna(){ String>u//er 8arna 7 ne8 String>u//er() i/(c.0>iru.isSelected()){ 8arna.append(c.0>iru.get9e,t() E * *) ! i/(c.0Hi#au.isSelected()){ 8arna.append(c.0Hi#au.get9e,t() E * *) ! i/(c.0Kuning.isSelected()){ 8arna.append(c.0Kuning.get9e,t() E * *) ! i/(c.0Bera..isSelected()){ 8arna.append(c.0Bera..get9e,t() E * *) ! t,tWarna.set9e,t(8arna.toString()) !

;. Menangani event pemilihan J$heck!oL. $aranya sebagai berikut / a5 ,ilih komponen chk+ijau di Jendela Design. b5 (lik kanan komponen chk+ijau untuk memunculkan conteLt 3popup5 menu. c5 ,ilih menu / @vent V Iction V action4er/ormed d5 :nda akan diba"a ke Jendela $ode, kemudian dalam method chk+ijau:ction,erformed tersebut panggil method tampilkan#arna. seperti di ba"ah ini / private void c.0Hi#auIction4er/ormed(#ava.a8t.event.Iction@vent evt) { CC 9A:A add your .andling code .ere3 tampil0anWarna() ! .akukan hal ini untuk semua J$heck!oL. '. $ompile dan jalankan program dengan menekan tombol S+ *T Q *;. $ara lain dalam menampilkan pilihan adalah dengan menggunakan J.ist dan J$ombo!oL. (edua komponen ini mempunyai Ueksibilitas yang lebih tinggi dan lebih mudah digunakan jika object yang dimasukkan dalam pilihan lebih kompleks. J.ist dan J$ombo!oL bisa mempunyai $omponentMditor agar pilihan yang ditampilkan tidak hanya berupa teLt, bisa berupa "arna atau icon. !agian berikutnya akan membahas bagaimana bekerja menggunakan J.ist dan J$ombo!oL.

/eker.a den!an J+ist dan JCombo/o%


J$ombo!oL memerlukan tempat yang minimalis dibandingkan dengan J-adio!utton, selain itu J$ombo!oL mempunyai bentuk $ombo!oL yang dapat diedit, sehingga memungkinkan user untuk memilih pilihan yang tidak ada dalam item J$ombo!oL.

$ontoh J$ombo!oL J.ist memungkinkan multiple selection dengan menekan tombol / S+ *T Q .eft $lick atau $T-. Q .eft $lick. (emampuan ini membantu user jika harus melakukan multiple selection. J$ombo!oL dan J.ist sangat Ueksibel, kita dapat menambah dan menghapus item di dalamnya dengan sangat mudah. Sehingga cocok digunakan untuk merepresentasikan pilihan yang item pilihannya bersifat dinamis. :plikasi di ba"ah ini adalah contoh penggunaan J$ombo!oL dan J.ist.

$ontoh program menggunakan J$ombo!oL dan J.ist

!agian pertama program ini terdapat sebuah J$ombo!oL dan J.abel, setiap kali item di dalam J$ombo!oL dipilih, J.abel di sebelahnya akan menampilkan item yang dipilih tersebut. !agian kedua program ini terdapat sebuah J.ist dan JTeLt:rea. Setiap kali item-item di dalam J.ist dipilih, JTeLt:rea akan menampilkan item-item yang dipilih tersebut dipisahkan dengan koma 3,5. kuti langkah-langkah berikut ini untuk membuat program di atas/ ). !uatlah class J*rame *orm baru dan beri nama .ist:nd$ombo.java. %. !uat tampilan program di atas menggunakan Matisse, kemudian tambahkan komponenkomponen/ a5 Mmpat buah J.abel / lbl,ekerjaan, lbl,ilihan,ekerjaan, lbl+obby, lbl,ilihan+obby. b5 Satu buah J$ombo!oL / cmb,ekerjaan c5 Satu buah J.ist / lst+obby d5 Satu buah JteLt:rea / tLt,ilihan+obby 7. Merubah isi J$ombo!oL. Fntuk merubah isi dari J$ombo!oL dan J.ist kita akan menggunakan Jendela ,roperties, Jendela ini letaknya di sebelah kanan ba"ah, di ba"ah Jendela ,allete dan akan muncul hanya jika jendela Design yang dipilih.

Jendela ,roperties ,ilih komponen J$ombo!oL di Jendela Design, Jendela ,roperties akan menampilkan properties dari J$ombo!oL. ,ada bagian model di dalam Jendela ,roperties masukkan item ,elajar, Mahasis"a, ,rogrammer, Technical #riter dan Tester. Setiap item dipisahkan dengan koma 3,5. <. Merubah isi J.ist. ,ilih J.ist di Jendela Design maka Jendela ,roperties untuk J.ist akan muncul. Di bagian model isikan item / Membaca, Hlahraga, Trekking, $oding, Menonton *ilm, !ersepeda dan Mengajar. Setiap item dipisahkan dengan koma 3,5. 4. Menangani pemilihan J$ombo!oL. (lik kanan J$ombo!oL di Jendela Design, kemudian pilih menu / @vents V Iction V action4er/ormed Jendela $ode akan terbuka, tambahkan code seperti di ba"ah ini / private void cmb4e0er#aanIction4er/ormed(#ava.a8t.event.Iction@vent evt) { lbl4ili.an4e0er#aan.set9e,t(*4e0er#aan anda 3 * E cmb4e0er#aan.getSelected=tem()) ! method getSelected tem dari J$ombo!oL digunakan untuk memperoleh item yang sedang di pilih dalam J$ombo!oL. ;. Menangani event pemilihan dari J.ist. Mvent yang digunakan untuk menangani pemilihan item dari J.ist berbeda dengan J$ombo!oL. J.ist akan mengaktifkan .istSelection event ketika user memilih item dalam J.ist. Fntuk menangani event ini, lakukan langkah-langkah berikut /

a5 (lik kanan pada J.ist di dalam Jendela Design, kemudian pilih menu / @vents V ;istSelection V valueD.anged b5 Dalam jendela kode yang ketik kode seperti berikut ini / private void lstHobbyPalueD.anged(#ava,.s8ing.event.;istSelection@vent evt) { Ab#ect[] selected=tems 7 lstHobby.getSelectedPalues() i/(selected=tems 77 null ZZ selected=tems.lengt. 77 '){ t,t4ili.anHobby.set9e,t(**) !else{ String>u//er strPalues 7 ne8 String>u//er() /or(Ab#ect item 3 selected=tems){ strPalues.append(item.toString() E *+ *) ! t,t4ili.anHobby.set9e,t( strPalues.substring('+ strPalues.lengt.() $ ))) ! ! $atatan / Method getSelected@alues dari J.ist mengembalikan item-item yang terpilih.

/eker.a den!an

enu, 'opup

enu dan -oolbar

Menu, ,opup menu dan Toolbar digunakan untuk melakukan navigasi dalam aplikasi. dengan ketiga komponen itu navigasi dalam aplikasi menjadi lebih Ueksibel dan mudah digunakan oleh user. Menu dan Toolbar pada umumnya diletakkan di bagian atas dari aplikasi agar mudah ditemukan oleh user. Sedangkan ,opup Menu bisa muncul di mana saja sesuai dengan konteks aplikasi. JMenu!ar adalah class yang digunakan untuk menampung JMenu. JMenu dapat menampung satu atau lebih JMenu tem. JMenu tem merupakan bagian terluar dari struktur menu yang tidak bisa mempunyai child. JSeparatordigunakan untuk memisahkan antara satu menu item dan menu item yang lain. Jika didalam menu terdapat sub menu, gunakan JMenu untuk menampung sub menu tersebut. Selain JMenu tem, JMenu juga dapat menerima class J$heck!oLMenu tem dan J-adio!uttonMenu tem. J,opupMenu mempunyai banyak kesamaan dibandingkan dengan JMenu!ar. ,erbedaan utamanya adalah / JMenu!ar hanya bisa berada di atas sebuah jendela J*rame. Sedangkan J,opupMenu bisa muncul di mana saja sesuai dengan konteks dari aplikasi. ,erbedaan lainnya terletak di dalam penggunaan umum keduanya. JMenu!ar berisikan menu9instruksi yang bersifat umum dan berlaku untuk semua keadaan dalam aplikasi. Sedangkan J,opupMenu akan mempunyai menu9instruksi yang berbeda-beda berdasarkan dari konteks aplikasi. Hleh karena itu J,opupMenu terkadang disebut juga sebagai konteks menu. Toolbar memberikan cara yang lebih praktis dibandingkan menu, bahkan bisa dikatakan bah"a toolbar adalah cara cepat untuk mengakses menu. Hleh karena itu, setiap item dalam toolbarbiasanya juga tersedia dalam menu. ,ada umumnya toolbar di"akili hanya dengan gambar9icon yang melambangkan perintah dari toolbarnya. Di internet banyak tersedia toolbar icon gratis yang dapat kita gunakan. !erbeda dengan JMenu!ar dan J,opupMenu yang hanya bisa menerima menu item, JTool!ar dapat menampung J!utton atau control lainya. Seperti contohnya / J$heck!oL, J-adio!utton, Jtoggle!utton dan lainya. 0ormalnya, JTool!ar akan diisi dengan J!utton yang dihilangkan teLt-nya dan diganti dengan icon. (ita juga perlu merubah dekorasi J!utton agar tampilannya terlihat cantik dan menarik.

$ontoh program dengan Menu, ,opup Menu dan Toolbar Fntuk membuat program seperti di atas, ada beberapa tahap yang perlu dilakukan. Tahap pertama adalah membuat Menu, yang kedua adalah membuat ,opup Menu dan yang ketiga adalah membuat Toolbar.

Mem"uat Menu
!ekerja dengan Menu dalam Java melibatkan enam komponen S"ing, antara lain / ). %. 7. <. 4. ;. ]Benu>ar / $lass yang menampung semua menu, hanya bisa menampung ]Benu sebagai child. ]Benu / $lass yang mempunyai child menu item. !iasanya ]Benu ini yang jadi child langsung dengan ]Benu>ar ]Benu=tem / Fjung dari menu, di sinilah object Iction diletakkan, sehingga ketika kita memilih ]Benu=tem ada action tertentu yang dijalankan aplikasi. ]D.ec0>o,Benu=tem / Fjung dari menu, namun bentuknya lebih mirip ]D.ec0>o,. ]6adio>uttonBenu=tem / Fjung dari menu, namun bentuknya lebih mirip ]>utton. ]Separator / pemisah antar ]Benu=tem atau antar ]Benu

Setiap komponen menu mempunyai fungsi dan kegunaan masing-masing. Jika kita perhatikan, menu dalam aplikasi umumnya mempunyai shortcut untuk mengakses menu tanpa menggunakan bantuan mouse. Misalnya menu *ile biasanya dapat diakses menggunakan tombol :.T Q *, menu *ormat dapat diakses dengan :.T Q H. *asilitas shortcut menu ini disebut sebagai (eyboard Mnemonic. *ile mempunyai mnemonic *, *ormat mempunyai mnemonic o, dan seterusnya. ,ada umumnya tampilan mnemonic dari sebuah menu di"akili dengan huruf yang bergaris ba"ah. Matisse mempunyai fasilitas yang sangat H( untuk bekerja dengan Menu, fasilitas drag-anddropnya membantu banyak pekerjaan membangun aplikasi barbasis KF secara signi?kan. Dalam program di atas kita akan membuat struktur menu sebagai berikut/

Struktur menu dari aplikasi kuti langkah-langkah berikut ini untuk membuat struktur menu seperti di atas/ ). !uat sebuah class J*rame dan beri nama ToolbarMenu.java

%.

Menambahkan JMenu!ar ke dalam J*rame. ,ilih komponen Menu !ar dari Jendela ,allete kemudian klik J*rame di Jendela Design. Sebuah class JMenu!ar akan ditambahkan di dalam J*rame. Kanti namanya menjadi menu!ar. Menambahkan JMenu ke dalam JMenu!ar. (lik kanan JMenu!ar yang baru saja kita buat di Jendela nspector, kemudian pilih menu / Idd V ]Benu Kanti nama JMenu tersebut menjadi menu*ile. (emudian alihkan perhatian anda ke Jendela ,roperties

7.

Jendela ,roperties dari class JMenu si properti teLt dengan string E*ileG. (emudian set isi properti mnemonic dengan string EfG, hal ini akan menyebabkan tampilanya menu*ile menjadi *ile dan user dapat menekan tombol :.T Q * untuk mengaktifkan menu menu*ile. <. Menambahkan JMenu tem. .angkah berikutnya adalah menambahkan JMenu tem ke dalam JMenu menu*ile yang telah dibuat di langkah sebelumnya. caranya, klik kanan di JMenu menu*ile di Jendela nspector, kemudian pilih menu / Idd V ]Benu=tem Tambahkan berturut-turut menu0e", menuHpen dan menuSave. ,ilih JMenu tem dari Jendela nspector, kemudian untuk masing-masing JMenu tem set teLt dan mnemonic yang sesuai dari Jendela ,roperties. 4. Menambahkan JSeparator. Dalam struktur menu yang bagus, menu yang mempunyai fungsi serupa diletakkan dalam urutan berderdekatan dan dipisahkan dengan separator 3pemisah5. .angkah menambahkan JSeparatortidak berbeda dengan langkah menambahkan JMenu tem, klik kanan di JMenu menu*ile kemudian pilih menu/ Idd V ]Separator Menambahkan JMenu. !erikutnya kita akan menambahkan JMenu baru ke dalam JMenu menu*ile. JMenu yang baru ini akan bertindak sebagai sub menu. $aranya juga sama / klik kanan di JMenu menu*ile kemudian pilih menu / Idd V ]Benu !eri nama menuSetting, set teLt dan mnemonic yang sesuai pada Jendela ,roperties. '. Menambahkan J$heck!oLMenu tem. ,erilaku J$heck!oLMenu tem tidak berbeda jauh dengan J$heck!oL biasa, bedanya hanyalah J$heck!oLMenu tem berada dalam struktur menu. $ara menambahkan J$heck!oLMenu tem sama dengan komponen lain / klik kanan JMenu menuSetting kemudian pilih menu / Idd V ]D.ec0>o,Benu=tem !eri nama chk.ine0umber, set teLt dan mnemonic yang sesuai pada Jendela ,roperties. J$heck!oLMenu tem sedikit sepesial dibandingkan dengan JMenu tem, karena J$heck!oLMenu tem memiliki properties selected. ,roperties selected ini digunakan untuk menentukan apakah J$heck!oLMenu tem dalam keadaan terpilih atau tidak.

;.

6.

Menambahkan J-adio!uttonMenu tem. Dalam contoh ini kita akan mempunyai dua buah J-adio!uttonMenu tem, radio!inary dan radioTeLt. (eduanya dibuat dengan langkah yang sama dengan komponen lain, klik kanan di JMenu menuSetting, kemudian pilih menu / Idd V ]6adio>uttonBenu=tem Set teLt dan mnemonic yang sesuai dari Jendela ,roperties.

1.

Menambahkan !uttonKroup. Seperti halnya J-adio!utton, J-adio!uttonMenu tem juga memerlukan !uttonKroup agar hanya satu buah J-adio!uttonMenu tem yang bisa dipilih. $ara menambahkan !uttonKroup sangat mudah, klik item !uttonKroup dari Jendela ,allete kemudian klik Jendela Design, maka otomatis !uttonKroup akan ditambahkan. Kanti namanya menjadi groupHpenMethod. Dalam Jendela nspector, !uttonKroup yang baru dibuat tadi akan berada dalam kategori Hther $omponents, seperti terlihat dalam gambar di ba"ah ini /

!uttonKroup berada dalam kategori Hther $omponents )&. Menambahkan J-adio!uttonMenu tem ke dalam !uttonKroup. ,ilih masing-masing J-adio!uttonMenu tem dari Jendela nspector, kemudian perahatikan Jendela ,roperties dari J-adio!uttonMenu tem tersebut, pada bagian group!utton pilih item groupHpenMethod, seperti terlihat dalam gambar di ba"ah ini /

,roperties dari J-adio!uttonMenu tem )). $ompile dan jalankan class ToolbarMenu.java. (lik kanan class ToolbarMenu dari Jendela Design kemudaian pilih menu -un *ile atau tekan tombol S+ *T Q *;. !ekerja dengan Menu menggunakan Matisse sangatlah menyenangkan dan produktif. +al ini berbeda sekali jika harus mengetik satu demi satu kode untuk menyusun struktur menu seperti contoh program di atas. Membuat ,opup Menu menggunakan Matisse juga sama mudahnya. +anya saja kita harus menentukan dimana dan dengan cara apa popup menu itu muncul, apakah dengan penekanan tombol tertentu dari keyboard atau ketika tombol mouse ditekan.

Mem"uat Po$u$ Menu


,opup menu pada dasarnya tidak jauh berbeda dibandingkan dengan menu biasa, hanya saja popup menu dapat muncul di mana saja, tidak hanya di bagian atas J*rame seperti halnya JMenu!ar. Selain itu kita harus menentukan kapan popup muncul, pada umumnya popup akan muncul ketika user melakukan klik kanan terhadap suatu komponen S"ing. Misalnya, ketika suatu table di klik kanan terdapat popup yang muncul, dan sebagainya. ,opup menu terutama digunakan sebagai EconteLt sensitive menuG, dimana menu yang ditampilkan oleh popup menu tergantung konteks dari aplikasi, semisal / komponen apa yang dikenai aksi klik kanan, bagaimana keadaan data dalam komponen tersebut dan sebagainya. :plikasi yang memerlukan interaksi yang sangat intens dengan user sebaiknya menggunakan popup menu untuk memudahkan user mengakses action tertentu. +al ini jauh lebih praktis dibanding user harus mengakses menu dalam JMenu!ar di bagian atas J*rame. ,opup menu dalam contoh program di atas akan muncul ketika user melakukan klik kanan terhadap J*rame. menu yang ditampilkanya pun hanya ada tiga buah/ cut, copy dan paste. kuti langkah-langkah beritkut ini untuk membuat ,opup menu / ). !uka class ToolbarMenu.java, yang telah dibuat dalam langkah sebelumnya dalam Jendela Design. %. (lik Jendela ,allete dan pilih J,opupMenu, kemudian klik Jendela Design. Secara otomatis J,opupMenu akan ditambahkan dalam class ToolbarMenu.java. Kanti nama variabel JpopupMenu yang baru saja dibuat menjadi popFpMenu. J,opupMenu tidak terlihat dalam Jendela Design, namun anda bisa mengkasesnya melalui Jendela nspector. 7. Menambahkan JMenu tem. Seperti halnya JMenu!ar, J,opupMenu dapat memiliki child berupa JMenu, JMenu tem, J$heck!oLMenu tem, J-adio!uttonMenu tem dan JSeparator. Menambahkan JMenu tem ke dalam J,opupMenu sangat sederhana, caranya / klik kanan pada J,opupMenu di Jendela Design, kemudian pilih menu / Idd V ]Benuitem Kanti nama objectnya menjadi menu$ut, beralihlah ke Jendela ,roperties kemudian set teLt dan mnemonic yang sesuai. .akukan langkah ini untuk JMenu tem yang lain, menu$opy dan menu,aste. <. Memunculkan J,opupMenu. (etika tombol kanan mouse di klik di atas J*rame, J,opupMenu akan tampil. :gar behavior tersebut berjalan, kita perlu menangani event mouse$lick terhadap J*rame. $aranya / a5 (lik kanan J*rame di Jendela Design, kemudian pilih menu / @vents V Bouse V mouseDlic0ed b5 Di dalam jendela source yang terbuka masukkan kode berikut ini / private void /ormBouseDlic0ed(#ava.a8t.event.Bouse@vent evt) { i/(evt.get>utton() 77 Bouse@vent.>G99A<1){ popGpBenu.s.o8((Domponent)evt.getSource()+ evt.getJ()+evt.get_()) ! ! (ondisi if di atas digunakan apakah tombol yang diklik mouse adalah tombol sebelah kanan, jika nilai kembalian method get!utton sama dengan nilai !FTTH07 maka benar tombol kanan yang ditekan. Method sho" digunakan untuk memunculkan popup menu, parameter pertama diisi dengan $omponent dimana nantinya popup menu akan ditampilkan, sedangkan parameter kedua dan ketiga diisi dengan letak koordinat popup menu akan ditampilkan. 4. Simpan ?le ToolbarMenu.java, compile dan jalankan. (emudian coba munculkan popup menu dengan mengklik kanan J*rame.

,opup menu sangat berguna jika aplikasi yang kita kembangkan membutuhkan interaksi yang intensif dengan user. ,opup menu menyediakan cara mudah untuk mengakses menu9action yang sesuai dengan konteks dari aplikasi.

Mem"uat &ool"ar
Toolbar memberikan dimensi lain dalam mengakses menu dbandingkan menu ataupun popup menu. ,ada umumnya Toolbar merupakan cara singkat untuk mengakses menu. Menu yang di"akili toolbar adalah menu yang bersifat umum dan tidak terikat pada konteks tertentu. (egunaan lain dari toolbar adalah mempercantik tampilan aplikasi, karena toolbar biasanya adalah tombol yang didekorasi dengan icon yang menarik. Selain itu toolbar juga memberikan kesempatan kepada user untuk mengkustomisasi tampilan dari aplikasi. (arena layout toolbar sangat Ueksibel, user bisa memindah-mindahkan letak toolbar di dalam aplikasi, di atas, di ba"ah atau di samping, atau bahkan mengambang 3Uoating5 di atas jendela yang sedang aktif. Dalam contoh program di atas kita akan membuat sebuah JTool!ar dengan dua buah J!utton yang telah didekorasi dengan icon cantik. con yang digunakan banyak tersedia di internet, format ?le yang dipilih adalah .png, karena format ?le ini paling bagus dalam menangani transparasi komponen. Sebelum mulai membuat JTool!ar, kita perlu mempersiapkan terlebih dahulu icon yang akan digunakan sebagai dekorasi J!utton. kuti langkah-langkah berikut ini / ). !uatlah sebuah Java package baru untuk menampung semua icon yang akan digunakan. caranya klik kanan di jendela ,rojects bagian nama project, pilih menu / <e8 V ]ava 4ac0age !eri nama images untuk Java package yang baru saja kita buka. %. Memasukkan con ke dalam package. Fntuk memasukkan image ke dalam package kita perlu tahu dimana project disimpan, misalkan project disimpan dalam folder / c3O#avas8ing !uka ?le eLplorer, kemudian navigasi ke folder c3O#avas8ingOsrcOimages $opy semua icon yang diperlukan ke dalam folder di atas. 7. !uild project. .angkah ini diperlukan untuk mengcompile semua ?le .java menjadi ?le .class. Selain itu proses ini juga akan mengkopi ?le selain ?le .java 3termasuk ?le icon5 ke dalam folder buildRclasses. Jika proses ini tidak dilaksanakan, maka ketika program dijalankan, ?le icon tidak akan ditemukan dan program menjadi error .

Setelah proses persiapan selesai, lakukan langkah-langkah berikut ini untuk membuat Toolbar / ). !uka class ToolbarMenu.java yang sudah dibuat di langkah sebelumnya. %. !uat sebuah object JTool!ar, caranya / klik item JTool!ar dari Jendela ,allete, kemudian klik J*rame di Jendela Design. Secara otomatis sebuah object JTool!ar akan dimasukkan ke dalam J*rame. Kanti namanya menjadi tool!ar. 7. Menambahkan J!utton dalam JTool!ar. (lik item J!utton dalam Jendela ,allete kemudian klik komponen JTool!ar yang baru saja kita buat tadi. J!utton baru akan diletakkan di atas JTool!ar, ganti nama J!utton tersebut menjadi btn0e". .etakkan lagi satu buah J!utton di atas JTool!ar dan beri nama btnMaLimiBe. <. Mendekorasi Tampilan J!utton. :gar tampilan J!utton terlihat cantik, kita perlu mengeset beberapa nilai dari properti J!utton, seperti terlihat pada gambar di ba"ah ini /

Jendela ,roperties J!utton a5 TeLt, hapus nilai teLtnya. b5 !order, pilih bordernya menjadi empty border dan set nilai bordernya menjadi =4,4,4,4>. Tujuan pemberian empty border ini agar tombol berukuran lebih besar dibandingkan dengan icon yang akan digunakan nanti, dan setiap mouse mele"ati J!utton, ada efek transisi yang cantik. Fntuk mengedit border dari J!utton, Matisse menyediakan Jendela !order untuk memilih border yang kita inginkan untuk Jbutton. !order yang dipilih bisa single border, atau composite border yang terdiri dari beberapa border.

Jendela !order Mditor dari J!utton c5 Hpa\ue, uncheck nilai opa\ue. !ertujuan agar tombolnya ber"arna transparan, sehingga mempunyai "arna background yang sama dengan background JTool!ar. d5 con, ganti iconya dengan icon yang telah disiapkan. Fntuk memasukkan icon ke dalam J!utton, tekan tombol di samping pilihan con di dalam Jendela ,roperties, kemudian akan muncul Dialog con Mditor seperti di ba"ah ini / Jendela icon editor ,ilih radio button $lasspath, kemudian tekan tombol Select *ile dan pilih salah satu icon yang telah disiapkan. Tekan H(. .akukan langkah-langkah yang sama terhadap J!utton yang lain. 4. $ompile dan jalankan class ToolbarMenu untuk melihat hasilnya.

embuat Dialo! dan J#ileC*ooser


Dialog memerankan peran yang penting dalam aplikasi berbasis desktop. nteraksi antara user dengan aplikasi terkadang tidak berjalan dengan baik karena user memberikan aksi yang tidak valid kepada aplikasi. (etika hal tersebut terjadi, aplikasi harus memberitahukan kepada user apa yang telah terjadi dan bagaimana seharusnya user memperbaikinya. Model interaksi seperti ini tepat dilaksanakan menggunakan dialog. Skenario lain adalah ketika aplikasi memerlukan input dari user agar aplikasi bisa terus melaksanakan tugasnya, misalnya meminta kon?rmasi apakah user yakin akan melaksanakan sebuah aksi penting terhadap aplikasi seperti delete, update atau add data. Dialog juga memberikan pembatasan kepada user, sebelum dialog selesai diproses, user tidak akan bisa berinteraksi dengan bagian aplikasi lainya. Dialog mencegah hal ini terjadi dengan memastikan bah"a jendela yang bisa diaktifkan hanyalah jendela dialog, sedangkan jendela aplikasi yang lain tidak dapat diaktifkan selama jendela dialog masih aktif. :plikasi sangat sering menggunakan dialog untuk berinteraksi dengan user, tetapi jenis interaksinya selalu seragam dan berulang-ulang. S"ing menyediakan dialog yang didesign untuk keperluan yang sering muncul dalam aplikasi, seperti JHption,ane dan J*ile$hooser. S"ing juga menyediakan class JDialog jika kita ingin membuat dialog custom sesuai keinginan kita.

Mem"uat $re0defined dialog dengan J!$tionPane


JHption,ane menyediakan beberapa dialog yang siap pakai dan sering digunakan dalam aplikasi. JHption,ane sangat memudahkan kita dalam meminta user suatu input tertentu atau memberitahu user apa yang terjadi dalam aplikasi. JHption,ane mempunyai banyak static method untuk menampilkan popup dialog dengan mudah. Terdapat empat method utama yang dapat kita gunakan sebagai landasan membuat dialog. (eempat method tersebut secara rinci digambarkan dalam table berikut ini/
Method sho"$on?rmDialog sho" nputDialog sho"MessageDialog sho"HptionDialog Deskripsi Meminta kon?rmasi daru user, seperti yes9no9cancel Meminta input dari user, baik berupa input teLt menggunakan JTeLt*ield maupun pilihan menggunakan J$ombo!oL Memberitahukan user tentang apa yang baru saja terjadi Kabungan dari ketiga jenis dialog di atas

S"ing juga menyediakan method sho" nternal]]] yang digunakan jika kita bekerja dengan J nternal*rame. ,arameter dari keempat method tersebut mengikuti pola yang konsisten. Terurut dari kiri ke kanan, berikut ini parameter-parameter yang bisa diterima oleh method-method dalam class JHption,ane/ ). parent$omponent /Mende?sikan komponen yang akan menjadi parent dari dialog boL ini. *rame dari parent component tersebut akan menjadi frame dari dialog dan dialog akan ditampilkan di tengah-tengah parent component. Jika nilai dari parent$omponent diset null, maka dialog akan menggunakan frame default dan dialog akan diletakkan ditengahtengah layar monitor 3tergantung .`*5. %. message / ,esan yang deskriptif menerangkan perihal dialog yang muncul. ,ada umumnya message berupa pesan String yang akan diletakkan dalam dialog, namun jenis object lain juga diijinkan digunakan sebagai message. Hbject-object yang diijinkan akan diperlakukan berbeda, object-object tersebut antara lain a5 Hbject=> / Setiap object akan ditampilkan dalam dialog berurut dari atas ke ba"ah. :turan ini berlaku rekursif untuk semua object didalam array. b5 $omponent / Jika object yang dimasukkan sebagai message bertipe $omponent, maka $omponent tersebut akan ditampilkan ditengah-tengah dialog. c5 con / con akan dimasukkan ke dalam sebuah J.abel kemudian ditampilkan di sebelah kiri dari dialog.

d5 others / Hbject lainya akan ditampilkan dalam dialog dengan mengambil nilai kembalian dari method toString dari setiap object. 7. messageType /Mende?sikan jenis dari pesan. ,ada umumnya memberikan custom icon untuk setiap jenis pesan. Setiap .`* manager akan memperlakukan setiap jenis pesan dengan berbeda, namun perbedaanya tidak akan terlalu mencolok. ,ilihan yang mungkin dan icon yang me"akilinya adalah/ a5 M--H-SMMSS:KM b5 0*H-M:T H0SMMSS:KM c5 #:-0 0KSMMSS:KM d5 ,.: 0SMMSS:KM 3tanpa icon5 <. optionType / Mende?sikan tombol-tombol yang akan ditampilkan di bagian ba"ah dari dialog. a5 DM*:F.TSH,T H0 b5 PMSS0HSH,T H0 c5 PMSS0HS$:0$M.SH,T H0 d5 H(S$:0$M.SH,T H0 0amun kita tidak dibatasi untuk hanya menggunakan empat jenis set tombol di atas, kita dapat mende?sikan tombol-tombol yang akan muncul sesuai kebutuhan. 4. Hptions / Deskripsi yang lebih detail dari set tombol yang digunakan dialog. 0ilai yang laBim adalah sebuah array String berisi teLt yang akan ditampilkan di setiap tombol. 0amun Hbject lain juga dapat diterima, antara lain/ a5 $omponent $omponent akan diletakkan dalam baris tombol secara langsung. b5 con Sebuah J!utton akan dibuat dan didekorasi dengan icon ini. c5 other Hbject dengan tipe selainnya akan dirubah ke dalam bentuk String dengan mengambil nilai kembalian dari method toString dari object tersebut.

;.

con / con yang digunakan untuk mendekorasi dialog. Jika icon ini dide?nisikan maka akan menimpa icon default yang dide?nisikan oleh messageType. nitial@alue / 0ilai default dari pilihan yang mungkin ada dalam dialog.

'. Title / Judul dari dialog yang diletakkan di bagian paling atas dari dialog. 6. Fntuk lebih jelasnya, berikut ini beberapa contoh kode penggunaan JHption,ane beserta hasil tampilanya / ]Aption4ane.s.o8Bessage:ialog(null+ *Simple plain dialog*+*4lain dialog*+ ]Aption4ane.4;I=<(B@SSIS@)

Tampilan dialog sederhana ]Aption4ane.s.o8Bessage:ialog(null+ *_our action 8as succeed+ E you can proceed to ne,t assigment*+ *=n/ormation dialog*+ ]Aption4ane.=<HA6BI9=A<(B@SSIS@)

Tampilan dialog dengan tipe dialog nformation ]Aption4ane.s.o8Bessage:ialog(null+ *_ou neet to be sure to do t.is action!*+ *:ialog 4eringatan*+ ]Aption4ane.WI6<=<S(B@SSIS@)

Dialog dengan tipe #arning ]Aption4ane.s.o8Bessage:ialog(null+ *Somet.ing goes 8rong and generate error message*+ *@rror :ialog*+ ]Aption4ane.@66A6(B@SSIS@)

Dialog dengan tipe Mrror ]Aption4ane.s.o8Don/irm:ialog(null+ *D.oose yes or no*+*Don/irmation :ialog*+ ]Aption4ane._@S(<A(A49=A<+

]option4ane.WI6<=<S(B@SSIS@)

Hption dialog dengan tipe nformation dan pilihan PMSS0H ]Aption4ane.s.o8Don/irm:ialog(null+ *D.oose yes+ no or cancel*+*Don/irmation :ialog*+ ]Aption4ane._@S(<A(DI<D@;(A49=A<+ ]Aption4ane.4;I=<(B@SSIS@)

HptionDialog dengan tipe ,lain dan pilihan PMSS0HS$:0$M. ]Aption4ane.s.o8=nput:ialog(null+ *=nput your name .ere*+*=nput :ialog*+ ]Aption4ane.=<HA6BI9=A<(B@SSIS@)

nputDialog dengan tipe message nformation String[] options 7 {*Ipple*+*Bango*+*Srape*+*Suava*! ]Aption4ane.s.o8=nput:ialog(null+ *D.oose t.is one Aption*+*=nput dialog*+ ]Aption4ane.WI6<=<S(B@SSIS@+null+options+*Ipple*)

nputDialog dialog dengan tipe #arning, Hptions berupa array of String dan initial@alue [ J:ppleJ

Mem"uat J4ileChooser
J*ile$hooser digunakan untuk bernavigasi dalam ?le system, kemudian memilih satu atau lebih ?le atau folder dari list ?le dan folder. J*ile$hooser pada dasarnya adalah pengembangan dari dialog yang dapat digunakan untuk memilih ?le. J*ile$hooser dapat digunakan sebagai dialog untuk menyimpan ?le atau untuk membuka ?le. J*ile$hooser hanya memberikan fasilitas untuk memilih ?le atau folder, sedangkan mekanisme untuk menyimpan atau membuka ?le dilakukan sendiri menggunakan library 9H. :plikasi berikut ini adalah contoh penggunaan J*ile$hooser untuk membuka dan menyimpan ?le.

$ontoh program menggunakan J*ile$hooser Tampilan J*ile$hooser ketika tombol open ditekan adalah seperti di ba"ah ini /

Tampilan J*ile$hooser Fntuk membuat aplikasi di atas lakukan langkah-langkah berikut ini / ). %. !uat class J*rame *orm baru, beri nama $hooser.java Masukkan dua buah JTeLt*ield / tLtHpen dan tLtSave, dua buah Jbutton / btnHpen dan btn save, sebuah J.abel / lblStatus. Sesuaikan penataan komponen sesuai dengan gambar di atas.

7. Tambahkan sebuah object J*ile$hooser sebagai ?eld dari class $hooser, beri nama chooser. public class D.ooser{ ]HileD.ooser c.ooser 7 ne8 ]/ileD.ooser() CC0ode lain di sini ! <. *ile0ameMLtention*ilter digunakan sebagai ?le ?lter dalam J*ile$hooser. Metode ?lteringnya adalah mencocokkan ekstensi ? le dalam ? le system dengan ekstensi yang ada dalam *ile0ameMLtention*ilter. $ontoh kode di ba"ah ini akan menyebabkan J*ile$hooser mempunyai pilihan EJ,MK *ileG, dan jika pilihan tersebut dipilih, maka ?le dengan ekstensi EjpgG, EjpegG,GJ,KG atauEJ,MKG saja yang akan ditampilkan oleh J*ile$hooser. Hile<ame@,tensionHilter ]4@SHilter 7 ne8 Hile<ame@,tensionHilter( *]4@S Hile*+*#pg*+*#peg*+]4S+]4@S) c.ooser.addD.oosableHileHilter(]4@SHilter) Set direktori yang akan dituju oleh J*ile$hooser. Fntuk mengetahui dimana direktori aktif aplikasi, kita bisa menggunakan system property Euser.dirG. (ode berikut ini akan menyebabkan J*ile$hooser dibuka pada direktori aktif aplikasi / String dir 7 System.get4roperty(*user.dir*) c.ooser.setDurrent:irectory(ne8 Hile(dir)) Menghandle event penekanan tombol btnSave. (etika tombol btnSave ditekan, chooser akan menampilkan dialog save ?le, kemudian mengambil nama ?le yang dipilih dan menampilkannya dalam tLtSave, serta menampilkanya dalam lblStatus. !erikut ini kodenya / private void btnSaveIction4er/ormed(Iction@vent evt) { int ret 7 c.ooser.s.o8Save:ialog(t.is) i/(ret 77 ]HileD.ooser.I446AP@(A49=A<){ Hile / 7 c.ooser.getSelectedHile() lblStatus.set9e,t(*Status 3 saving /ile* E /.getIbsolute4at.())

4.

;.

! ! '.

t,tSave.set9e,t(/.getIbsolute4at.())

Menghandle penekanan tombol btnHpen. (ode untuk menangani penekanan tombol btnHpen mirip dengan kode untuk menangani penenakan tombol btnSave, perbedaanya adalah btnHpen akan menampilkan dialog open ?le, berikit ini kodenya / private void btn>ro8seIction4er/ormed(Iction@vent evt){ int ret 7 c.ooser.s.o8Apen:ialog(t.is) i/(ret 77 ]HileD.ooser.I446AP@(A49=A<){ Hile / 7 c.ooser.getSelectedHile() lblStatus.set9e,t(*Status 3 opening /ile* E /.getIbsolute4at.()) t,tApen.set9e,t(/.getIbsolute4at.()) ! ! $ompile dan jalankan aplikasinya dengan menekan tombol S+ *T Q *;

6.

!ekerja dengan JHption,ane dan dengan J*ile$hooser sangat sederhana. (eduanya menggunakan modal dialog untuk mengambil input dari user. Modal dialog akan mencegah user mengakses bagian aplikasi lain sebelum dialog ditutup, atau dalam hal ini memutuskan pilihan apa yang diambil oleh user. Masih banyak lagi komponen S"ing yang disediakan oleh JD(, anda tinggal melanjutkan membaca dari referensi yang diberikan modul ini pada bagian akhir untuk melanjutkan pembelajaran anda tentang Java desktop.

Konse$ M%C
M@$ adalah arsitektur aplikasi yang memisahkan kode-kode aplikasi dalam tiga lapisan, Model, @ie" dan $ontrol. M@$ termasuk dalam arsitektural design pattern yang menghendaki organisasi kode yang terstruktur dan tidak bercampur aduk. (etika aplikasi sudah sangat besar dan menangani struktur data yang kompleks, harus ada pemisahan yang jelas antara domain model, komponen vie" dan kontroler yang mengatur penampilan model dalam vie". :rsitektur M@$ ini memungkinkan adanya perubahan dalam domain model tanpa harus mengubah code untuk menampilkan domain model tersebut. +al ini sangat bermanfaat ketika aplikasi mempunyai domain model dan vie" komponen sangat besar dan kompleks.

Diagram interaksi antar komponen dalam arsitektur M@$ 3#ikipedia.org5 Model adalah representasi dari object yang sedang diolah oleh aplikasi, dalam Java, model ini biasanya direpresesentasikan sebagai Java !ean. Java !ean adalah class Java biasa atau ,HJH 3,lain Hld Java Hbject5. Syarat sebuah ,HJH dianggap sebagai Java !ean adalah / ). Mempunyai constructor default, constructor yang tidak mempunyai parameter. %. Semua ?eld-?eld yang bisa diakses dilengkapi dengan getter dan setter method. .ebih jelasnya lihat kode dari class ,erson di ba"ah ini / public class 4erson { private ;ong id private String name private String email public ;ong get=d() { return id ! public void set=d(;ong id) { t.is.id 7 id ! public String get<ame() { return name ! public void set<ame(String name) { t.is.name 7 name ! public String get@mail() { return email ! public void set@mail(String a@mail) { t.is.email 7 a@mail ! ! (ode di atas adalah representasi Model dalam Java untuk Mntity ,erson. !eberapa orang terkadang salah mengartikan model ini sebagai data akses domain. Dimana data dari sumber

data, misalnya database, diambil dan diolah. ,ada hakekatnya Model adalah representasi data dari object sebenarnya, bukan kumpulan kode untuk mengakses data dari database. ,endekatan terbaik adalah memisahkan kode untuk melakukan akses sumber data ke dalam lapisan tersendiri, lapisan ini biasanya disebut sebagai service. Service diimplementasikan dalam bentuk class-class yang disebut sebagai manager, misalnya SI.Manager, ,rintManager, -eportManager, ]M.Manager, #ebServiceManager dan seterusnya. Dengan begitu kode akan menjadi lebih rapi dan terstruktur. Manfaat paling terasa adalah kemudahan pencarian kesalahan dan penambahan modul-modul baru tidak harus merombak seluruh struktur aplikasi. @ie" adalah komponen komponen S"ing, seperti ja"ab untuk menangkap tombol keyboard, barcode untuk merepresentasikan Model dalam bentuk visual. Semisal / JTable, J.ist, J$ombo!oL dan sebagainya. @ie" juga bertanggung interaksi user terhadap sistem, semisal / klik mouse, penekanan scanning dan sebagainya.

$ontroller sebenarnya hanya sekumpulan kode-kode untuk mensinkronisasi keadaan Model dan @ie". Jika ada perubahan data dari Model, $ontroller harus mengupdate tampilan @ie". Dan sebaliknya jika user memberikan event terhadap @ie", $ontroller harus mengupdate Model sesuai dengan hasil interaksi user terhadap @ie".

odel dalam Komponen Swin!


Sebagaian besar komponen S"ing mempunyai model. J!utton mempunyai model yaitu !uttonModel yang memegang JstateJ dari J!utton d apa keyboard mnemonicnya, apakah J!utton tersebut sedang dipilih atau tidak dan seterusnya. :da pula komponen S"ing yang mempunyai lebih dari satu model. J.ist mempunyai .istModel yang memegang isi dari J.ist dan .istSelectionModel untuk mencatat item J.ist yang sedang dipilih. ,ada banyak kasus normal kita tidak perlu pusing memikirkan model ini. Semisal kita tidak perlu memikirkan model dari J!utton karena pada kasus umum kita tidak perlu memodi?kasi model dari J!utton. .alu, kenapa model komponen S"ing dibuatZ :lasan utamanya adalah Ueksibilitas untuk menentukan bagaimana data disimpan dan diambil dari komponen S"ing. Misalnya kita mempunyai aplikasi spreadsheet yang menggunakan komponen JTable, karakteristik utama spreadsheet adalah banyak cell yang kosong, dengan begitu kita bisa memilih model data yang sesuai dengan karakteristik tersebut. $ontoh lainnya adalah JTable yang digunakan untuk menampilkan data dari database dengan jumlah baris luar biasa banyak. (ita bisa mengatur agar tampilan JTable dibuat halaman-perhalaman dalam menampilkan baris data, tidak semua data ditampilkan dalam satu halaman, hal ini ditujukan untuk e?siensi dan mempertahankan agar aplikasi tetap responsif "alau bekerja dengan data yang besar. Model dalam komponen S"ing juga mempunyai keuntungan lain, yaitu tidak perlu ada dua data terpisah, untuk struktur data aplikasi dan untuk komponen S"ing. (egunaan Model yang cukup penting juga adalah adanya konsep event-listener, dimana jika terjadi event perubahan data dalam model, semua listener yang terdaftar dalam model tersebut akan diberitahu dan tindakan yang tepat dapat diambil untuk menangani event yang muncul. Sebagai contoh, untuk menambahkan item dalam J.ist kita bisa memanggil method add tem dari J. st. ,enambahan item dalam J.ist ini akan mengakibatkan .istModel memicu event dalam J.ist dan listener lainnya. (omponen S"ingidalam hal ini J.istiakan diupdate tampilanya untuk mereUeksikan perubahan item dalam .istModel. #alaupun terkadang banyak yang menyebut arsetektur komponen S"ing sebagai M@$, tetapi pada dasarnya arsitektur komponen S"ing tidak sepenuhnya M@$. (omponen S"ing secara umum dibuat agar @ie" dan $ontroller diletakkan dalam satu tempat 3class5 yaitu class F yang disediakan oleh .ook-and-*eel. :rsitektur komponen S"ing lebih tepat disebut sebagai E:rsitektur dengan Model yang terpisahG. Selanjutnya kita akan membahas beberapa model yang seringkali harus kita kustomisasi sesuai dengan kebutuhan. Sedangkan model yang nyaris tidak pernah kita rubahi!uttonModeli tidak dibahas dalam bagian ini.

&a"leModel
TableModel adalah class model yang paling sering dikustomisasi. (arakteristik data dari JTable yang berbentuk koleksi data dua dimensi membutuhkan perhatian khusus agar e?sien digunakan dalam aplikasi. Jika kita tidak hati-hati, maka aplikasi kita bisa menjadi sangat lambat dan tidak e?sien. TableModel adalah interface yang digunakan oleh JTable untuk mende?nisikan ciri-ciri dari data tabular yang akan ditampilkan oleh JTable. Misalnya / jumlah kolom, nama kolom, class dari object dalam kolom, jumlah baris dan nilai setiap cell. Dengan adanya data-data ini JTable dapat secara e?sien menentukan bagaimana menampilkan data tersebut. !erikut ini adalah kode untuk menampilkan koleksi object ,erson. $lass :rray.istA,ersonC adalah implementasi dari generics, konsep dalam Java yang digunakan untuk mende?nisikan isi dari koleksi. :rray.istA,ersonC artinya adalah membuat sebuah object koleksi :rray.ist yang harus diisi oleh object ,erson dan tidak bisa diisi oleh object lainya, misalnya String. public class 4erson9ableBodel e,tends Ibstract9ableBodel{ private ;istT4ersonV persons public 4erson9ableBodel(;istT4ersonV persons) { t.is.persons 7 persons ! public int get6o8Dount() { return persons.si?e() ! public int getDolumnDount() { return 1 ! public Ab#ect getPalueIt(int ro8=nde,+ int column=nde,) { 4erson p 7 persons.get(ro8=nde,) s8itc.(column=nde,){ case ' 3 return p.get=d() case % 3 return p.get<ame() case ) 3 return p.get@mail() de/ault 3 return ** ! ! ^Averride public String getDolumn<ame(int column) { s8itc.(column){ case ' 3 return *=:* case % 3 return *<IB@* case ) 3 return *@BI=;* de/ault 3 return ** ! ! ! Pang perlu diperhatikan bah"a dalam :bstracTableModel, method is$ellMditable selalu mengembalikan nilai false, artinya semua cell tidak dapat diedit. (emudian method set@alue:t adalah method kosong belaka, artinya jika kita memanggil method ini tidak akan terjadi apa-apa. $lass kedua adalah DefaultTableModel yang telah mengimplementasi semua method abstract dari interface TableModel. -epresentasi data DefaultTableModel menggunakan dua jenis data tabular, yaitu array dua dimensi, Hbject=>=>, dan @ector dari @ector, @ectorA@ectorAHbjectCC. Jika kita mempunyai struktur data selain kedua jenis tersebut kita harus melakukan konversi data ke dalam salah satu bentuk struktur data tersebut. $ara yang lebih cerdas adalah mende?nisikan sendiri class yang mengimplement interface TableModel seperti class $ustomerTableModel di atas. Setelah TableModel selesai dide?nisikan kita tinggal memanggil method setTableModel dari

object JTable, atau membuat object JTable baru menggunakan constructor yang menerima argumen TableModel. $ontohnya seperti potongan kode di ba"ah ini / ]9able table 7 ne8 ]9able(ne8 :e/ault9ableBodel()) ]9able table% 7 ne8 ]9able() table%.setBodel(ne8 :e/ault9ableBodel())

ListModel
J.ist adalah komponen S"ing yang mempunyai dua model sekaligus, .istModel dan .istSelectionModel. .istModel digunakan untuk mende?nisikan item9element yang dikandung oleh J.ist. Sedangkan .istSelectionModel digunakan untuk mende?nisikan bagaimana representasi data jika terjadi proses pemilihan di J.ist. Seperti halnya TableModel, .istModel mempunyai dua class yang mengimplement .istModel, :bstract.istModel dan Default.istModel. (ita bisa menggunakan salah satu dari tiga tipe tersebut untuk membuat object .istModel. $ara pertama dengan membuat class baru yang mengimplement .istModel. $ara kedua dengan membuat class baru yang meneLtends :bstract.istModel dan cara ketiga dengan langsung menggunakan Default.istModel. Struktur data J.ist tidak terlalu rumit seperti JTable, dan pada umumnya, cukup hanya dengan menggunakan Default.istModel sudah memenuhi sebagaian besar kebutuhan penggunaan J.ist. !erikut ini contoh bagaimana membuat .istModel untuk data customer, contoh ini menggunakan cara kedua untuk membuat obejct .istModel, yaitu dengan cara membuat class baru yang mengeLtends :bstract.istModel / public class Dustomer;istBodel e,tends Ibstract;istBodel{ private Irray;istT4ersonV customer 7 ne8 Irray;istT4ersonV() public Dustomer;istBodel(;istT4ersonV cust){ customers.addIll(cust) ! public Ab#ect getPalueIt(int inde,) { return customers.get(inde,) ! public int getSi?e() { return customers.si?e() ! ! mplementasi .istModel sangat mudah dan tidak serumit TableModel, namun implementasi dari .istSelectionModel sangat rumit, karena kita harus mengimplementasi dua puluh buah method. .ebih baik menggunakan implementasi standard dari .istSelectionModel yaitu Default.istSelectionModel.

1enderer
-enderer dan Mditor adalah @ie" dari pattern M@$. -enderer digunakan untuk menampilkan data di komponen S"ing. !eberapa komponen S"ing mengijinkan programmer untuk mende?nisikan -enderer yang akan digunakan. Jika renderernya menggunakan default renderer yang disedikan oleh S"ing, maka String yang ditampilkan dalam komponen adalah hasil return method toString object tersebut. Misalnya entity -ole akan ditampilkan dalam sebuah comboboL, maka string yang tampil akan berasal dari method toString class -ole, kalau method toString-nya masih ba"aan dari class Hbject dan tidak dioverride oleh class -ole, return dari String adalah nama class-nya diappend oleh alamat memory dimana object role itu berada. Misalnya com.googlecode.projecttemplate.pos.model.-ole84<fc11<<, hal seperti ini bisa dihindari dengan mengoverride method toString dari role, misalnya / ^Averride public String toString() { return *6ole{* E *name7* E name E Q!Q

! Misalnya kita perlu menampilkan class -ole dalam beberapa comboboL yang berbeda tetapi string yang ditampilkan berbeda pula , misalnya di satu combo boL akan ditampilkan id-nya di combo boL yang lain ingin ditampilkan name-nya. Masalah ini tidak bisa diselesaikan dengan hanya mengoverride method toString, kita harus membuat renderer baru untuk menampilkan id role atau menampilkan nama role. -enderer untuk combo boL dibuat dengan mengimplementasikan .ist$ell-enderer, tetapi membuat renderer langsung dengan mengimplementasikan .ist$ell-enderer tidaklah mudah. $ara terbaik adalah mengeLtends renderer yang sudah ada yoitu Default.ist$ell-enderer kemudian mengoverride method untuk menampilkan String di dalam Jcombo!oL, contohnya seperti berikut ini / public class 6ole=dDombo>o,6enderer e,tends :e/ault;istDell6enderer{ ^Averride public Domponent get;istDell6endererDomponent(];ist list+ Ab#ect value+ int inde,+boolean isSelected+ boolean cellHasHocus) { ];abel renderer 7 (];abel) super.get;istDell6endererDomponent( list+ value+ inde,+ isSelected+ cellHasHocus) i/(value instanceo/ 6ole){ 6ole r 7 (6ole) value renderer.set9e,t(String.valueA/(r.get=d())) ! return renderer ! ! $lass -ole d$ombo!oL-enderer meneLtends Default.ist$ell-enderer kemudian hanya mengoverride satu buah method yaitu get.ist$ell-enderer$omponent. Method tersebut sudah ada implementasinya, kita hanya ingin mengubah cara renderer ini menampilkan String di dalam combo boL saja, oleh karena itu method yang sudah diimplementasikan oleh Default.ist$ell-enderer dieksekusi dengan menggunakan key"ord super. (emudian parameter value akan berisi object yang dimasukkan ke dalam comboboL, value ditest menggunakan key"ord instanceof untuk memastikan bah"a value tersebut adalah -ole. Setelah itu set teLt dari Jlabel menggunakan nilai id dari -ole. Setelah -enderer selesai dibuat, mari kita buat kode untuk memasang renderer tersebut ke dalam Jcombo!oL ]Dombo>o, combo 7 ne8 ]Dombo>o,() combo.set6enderer(ne8 6ole=dDombo>o,6enderer())

$ditor
Mditor digunakan oleh beberapa komponent untuk menentukan komponen apa yang digunakan untuk mengedit data dalam component . Sebagian besar component menggunakan component yang sama untuk -enderer dan Mditor sehingga komponent tersebut akan terlihat sama ketika berada dalam mode normal atau mode edit. Salah satu component yang menggunakan Mditor dan -enderer berbeda adalah Jtable. ,erpindahan mode dari standard ke edit dalam Jtable terjadi jika user melakukan double click terhadap cell-cell dalam Jtable. Dalam mode normal Jtable menggunakan Jlabel untuk menampilkan datanya, tetapi akan menggunakan JteLt*ield untuk data String dan 0umber ketika berada dalam mode Mdit dan menggunakan Jcheck!oL untuk data dengan tipe !oolean. Fntuk data lain Jtable tetap akan menggunakan JteLt*ield. Jika kita ingin misalnya menambahkan Jcalendar untuk tipe data Date, maka kita harus membuat custom Mditor dan memasangkanya ke Jtable untuk tipe data Date, setelah itu harus dipastikan bah"a method get$olumn$lass mengembalikan class Date. Sebagai contoh, kita akan membuat Jtable untuk ,erson, di property birthDate akan digunakan Mditor yang khusus untuk tipe Date menggunakan component dari Jcalendar. .angkah pertama adalah membuat class Jdate$hooser$ellMditor seperti di ba"ah ini /

public class ]:ateD.ooserDell@ditor e,tends IbstractDell@ditor implements 9ableDell@ditor { private static /inal long serialPersionG=: 7 M%-NN%R-R))%-RR&'M; private ]:ateD.ooser dateD.ooser 7 ne8 ]:ateD.ooser() public Domponent get9ableDell@ditorDomponent(]9able table+ Ab#ect value+ boolean isSelected+ int ro8+ int column) { :ate date 7 null i/ (value instanceo/ :ate) { date 7 (:ate) value ! dateD.ooser.set:ate(date) return dateD.ooser ! public Ab#ect getDell@ditorPalue() { return dateD.ooser.get:ate() ! ! Setelah itu buat TableModel yang mengoverride get$olumn$lass agar mengembalikan class Date untuk column birthDate public class 4erson9ableBodel e,tends Ibstract9ableBodel{ private static /inal long serialPersionG=: 7 %; private ;istT4ersonV persons public 4erson9ableBodel(;istT4ersonV persons) { t.is.persons 7 persons ! public int get6o8Dount() {return persons.si?e() ! public int getDolumnDount() {return 1 ! public Ab#ect getPalueIt(int ro8=nde,+ int column=nde,) { 4erson p 7 persons.get(ro8=nde,) s8itc.(column=nde,){ case '3 return p.get=d() case %3 return p.get<ame() case )3 return p.get>irt.:ate() de/ault3 return ** ! ! ^Averride public DlassTWV getDolumnDlass(int column=nde,) { s8itc.(column=nde,){ case '3 return ;ong.class case %3 return String.class case )3 return :ate.class de/ault3 return Ab#ect.class ! ! ^Averride public boolean isDell@ditable(int ro8=nde,+ int column=nde,) { i/(column=nde, 77 % ZZ column=nde, 77)){ return true ! return /alse ! ! .angkah terakhir adalah mendaftarkan Mditor ke dalam Jtable ]table table 7 ne8 ]table()

table.set:e/ault@ditor(:ate.class+ ne8 ]dateD.ooserDell@ditor()) +asilnya nanti akan terlihat seperti ini /

"A5IA@ ! APLIKA0I P+0

A$likasi P!*
:plikasi ,HS digunakan oleh toko-toko atau retail kecil untuk mencatat transaksi. Jenis aplikasi ini cocok diimplementasikan dengan menggunakan Java Desktop karena karakteristiknya yang harus berinteraksi dengan hard"are seperti printer, scanner dan terkadang cash dra"er. *eature yang akan diimplementasikan dalam contoh buku ini meliputi :dministrasi ,engguna hinnga ke :ccess $ontrol .ist 3:$.5, ,roduk, ,embelian !arang dan ,enjualan. *eature advance seperti accounting dan stock tidak diimplementasikan untuk membertahankan contoh aplikasi yang sederhana. Struktur data yang digunakan dalam aplikasi ,HS ini sama persis dengan FM. yang dibuat untuk contoh Mapping di bab +ibernate, untuk mengingat kembali struktur data tersebut, mari kita lihat class diagram di ba"ah ini /

$lass diagram pertama adalah data pengguna, role dan menu yang digunakan untuk menyimpan data login user sekaligus mende?nisikan :$. untuk user tersebut. !iasanya ada beberapa role dalam aplikasi ,HS, seperti (asir, :dministrator dan Super Fser. Modul kedua adalah data Transaksi untuk mencatat pembelian dan penjualan.

Dilihat dari sisi jenis datanya, data-data di atas dibagi menjadi dua jenis/ Master dan Transaksi. Data Master adalah data-data yang dipersiapkan sebelum data Transaksi bisa dibuat, Data master ini relatif statis dan berubah sedikit-demi sedikit selama aplikasi berjalan, sedangkan data Transaksi selalu berubah ketika ada proses pembelian atau penjualan barang. Data pengguna, produk dan menu tergolong dalam jenis data Master, sedangkan pembelian dan penjualan tergolong dalam jenis data Transaksi. Dari sisi tampilan aplikasi, biasanya dibedakan antara screen untuk data master dan data transaksi, tampilan screen untuk data Master biasanya cukup sederhana, sedangkan untuk data transaksi dibuat sebaik mungkin agar proses input data cepat dan akurat. Di bagian berikutnya kita akan membuat screen untuk masing-masing data tersebut.

Data

aster

Screen pertama yang akan kita buat adalah screen untuk input data ,erson 3pengguna5 yang tergolong data Master. Screen untuk data Master akan terlihat sama untuk data-data lainya, sehingga cukup kita bahas satu saja di buku ini, screen-screen lain bisa dilihat di kode yang menyertai buku ini.

Di bagian paling atas terdapat tombol-tombol operasi data seperti / Tambah, Mdit, +apus, Simpan, !atal dan (eluar. (emudian di sebelah kiri ada teLt?eld untuk melakukan pencarian terhadap data ,engguna yang ditampilkan dalam table di ba"ahnya. Sebelah kanan adalah form untuk memanipulasi data ,engguna. $ara menggunakan screen id dimulai dari membuka menu untuk menampilkan screen, kemudian user bisa menekan tombol tambah, berikutnya melengkapi semua data di form sebelah kanan, termasuk memilih foto yang akan ditampilkan. Setelah semua form selesai diisi, tombol simpan ditekan untuk menyimpan data ke dalam database. Data pengguna yang baru saja disimpan akan ditampilkan di dalam table yang ada di sebelah kiri, setiap kali baris dalam table dipilih, maka detail informasi ,engguna akan ditampilkan di sebelah kanan, tombol Mdit

dan +apus menjadi bisa diklik. (alau tombol Mdit ditekan, maka form sebelah kanan menjadi bisa diubah-ubah isinya. Setelah selesai melakukan edit terhadap data ,engguna, tombol save ditklik untuk menyimpan data ke dalam database. Tombol Delete digunakan untuk menghapus data ,engguna dari database, tombol ini hanya menjadi bisa diklik kalau ada data pengguna dalam table yang dipilih. ,roses penghapusan data tidak selalu bisa dilakukan kalau data ,engguna ini masih digunakan di tempat lain, misalnya data -ole masih menyimpan data ,engguna yang akan dihapus, maka proses penghapusan akan gagal. +al ini terjadi karena ada constraint foreign key data ,engguna di dalam data relasi antara -ole-,engguna. 0ah setelah mengetahui bagaimana cara menggunakan screen ,engguna di atas, mari kita bahas bagaimana cara membuat screen di atas.

Mendesign *creen
.angkah pertama adalah buat class ,erson,anel dengan tipe J nternal*rame. .angkahlangkahnya adalah sebagai berikut / ). ,ilih menu untuk membuat ?le baru Hile V <e8 Hile

(emudian akan muncul jendela untuk memilih jenis ?le apa yang akan dibuat, pilih S8ing SG= Horms V ]internalHrame Horm

!eri nama ,erson,anel dan com.googlecode.projecttemplate.pos.ui.security

letakkan

di

package

!uat satu per satu komponen untuk menampilkan data person seperti dalam gambar di atas menggunakan komponen-komponen yang bisa didrag-n-drop dari jendela pallete %. 7. (emudian beri nama untuk satu per satu untuk setiap tombol di atas / btn:dd, btnMdit, btnDelete, btnSave, btn$ancel dan btn(eluar (omponen Jdate$hooser diambil dari library Jcalendar, di bab sebelumnya sudah dijelaskan bagaimana caranya mendo"nload library ini dan meletakkanya dalam pallete. Silahkan merujuk ke !agian % / 0etbeans bab Menambahkan .ibrary Fntuk mengedit komponen Jtable agar mempunyai % buah kolom tanpa baris sama sekali, silahkan pilih Jtable tersebut kemudian klik pada baris Model di jendela ,roperties, akan muncul jendela untuk mengedit tampilan dari Jtable seperti di ba"ah ini /

<.

Setelah selesai mempersiapkan screen ,erson,anel, langkah berikutnya adalah membuat frame utama yang akan berisi menu dan Jdesktop,ane yang nantinya akan digunakan sebagai container dari semua Jinternal*rame yang ada dalam aplikasi. kuti langkah-langkah berikut ini untuk membuat frame utama / ). %. 7. Membuat class dengan tipe Jframe, pilih menu *ile C 0e" untuk membuat ?le baru dan pilih ?le dengan tipe S"ing KF *orms C Jframe form !eri nama Main*rame letakkan di package com.googlecode.projecttemplate.pos.ui kemudian tekan tombol *inish. .angkah berikutnya adalah menambahkan Menu!ar untuk menampilkan menu-menu aplikasi. (lik item Menu !ar dari ,allet dan drag n drop ke atas Main*rame. Kanti nama variabelnya menjadi mnu!ar. Selanjutkan tambahkan Jmenu dengan melakukan klik kanan di Menu pilih item :dd Menu. Kanti teLtnya menjadi EMaster DataG dan ganti variablemnya menjadi mnuMasterData !erikutnya adalah menambahkan Jmenu tem ke dalam mnuMasterData. (lik kanan di mnuMasterData kemudian pilih :dd *rom ,allete C Menu tem. Kanti teLtnya menjadi E,enggunaG dan ganti nama variabelnya menjadi mnu,engguna. +asil langkah-langkah di atas bisa dilihat di gambar di ba"ah ini

<. 4.

;.

'.

Setelah menu selesai dibuat, langkah terakhir adalah meletakkan Jdesktop,ane ke dalam Main*rame sebagai tempat dimana nanti J ternal*rame seperti ,erson,anel akan ditampilkan. ,ilih item Jdesktop,ane dari ,allete kemudian drag n drop di atas Main*rame beri nama variabelnya desktop,ane, sesuaikan ukuranya agar memenuhi seluruh halaman Main*rame.

Setelah ,erson,anel dan Main*rame selesai didesign, sekarang "aktunya menggabungkan keduanya agar kalau mnu,anel diklik ,erson,anel akan ditampilkan dalam desktop,ane. (lik kanan mnu,erson kemudian pilih menu Mvent C :ction C action,erformed, tampilan Source akan dibuka untuk class Main*rame, silahkan tambahkan kode berikut ini di dalam jendela Source public 4erson4anel person4anel private void mnu4ersonIction4er/ormed(#ava.a8t.event.Iction@vent evt) { try { i/ (person4anel 77 null) { person4anel 7 ne8 4erson4anel() des0top4ane.add(person4anel) ! else { person4anel.toHront() ! person4anel.setPisible(true) person4anel.setSelected(true) person4anel.setSi?e(des0top4ane.getSi?e()) ! catc. (4ropertyPeto@,ception e,) { log.error(*error 0eti0a menampil0an person panel*+ e,) ! ! ,erhatikan kode public ,erson,anel person,anelD adalah variabel dari ,erson,anel yang digunakan untuk menampung ,erson,anel yang sedang aktif. Setiap kali ,erson,anel ditutup dengan menekan tombol ] atau tombol (eluar maka variabel ini harus diset menjadi null, hal ini dimaksudkan agar hanya satu jendela ,erson,anel saja yang aktif. (alau pengecekan ini tidak dilakukan maka jendela ,erson,anel akan ditampilkan berkali-kali kalau menu mnu,erson ditekan. Di dalam blok catch terdapat object log yang digunakan untuk menyimpan 9 menampilkan log aplikasi. $lass object log ini berasal dari libary .og<j yang bisa dido"nload dari log<j.apache.org, kemudian tambahkan log<j jar ke dalam library project. (alau anda masih bungung untuk mensetup log<j, anda bisa menghapus kode log di dalam statement catch di atas dan ganti dengan eL.printStackTrace35. (alau anda berhasil mendo"nload log<j jar dan menambahkan ke dalam library project, lanjutkan dengan meneklarasikan object log tepat di ba"ah statement class Main*rame sebagai berikut ini / private static /inal ;ogger log 7 ;ogger.get;ogger(BainHrame.class) (ita ingin agar setiap kali user menjalankan aplikasi, jendela aplikasi ini nantinya akan ditambilkan memenuhi layar, kode berikut ini diletakkan di dalam constructor Main*rame untuk memaLimiBe tampilan Main*rame public BainHrame() { initDomponents() set@,tendedState(]Hrame.BIJ=B=`@:(>A9H) ! Setiap kali 0et!eans membuat class Jframe baru, maka secara otomatis 0et!eans juga membuat method main di dalam class Jframe tersebut. Sampai dengan langkah ini anda bisa mencoba menjalankan class Jframe dengan mengklik kanan Main*rame dan memilih menu -un *ile. $oba tekan menu ,engguna dan pastikan ,erson,anel tampil di dalam Desktop,ane.

Mem"uat class Main dan Inisialisasi *$ring A$$lication Conte,t


Sampai di langkah di bab ini kita sudah membuat kode backend untuk melakukan koneksi ke database, membuat Mntity, membuat Dao, membuat Service dan mempersiapkan F aplikasi.

.angkah berikutnya adalah membuat sebuah class yang merupakan class utama yang menggabungkan kode backend dan kode F . !uat class baru dan beri nama Main, letakkan di dalam package com.googlecode.projecttemplate.pos . $lass Main ini nantinya akan menginisialisasi Spring dan +ibernate, kemudian menyimpan service dari Spring untuk digunakan dalam aplikasi. Setelah inisialisasi Spring selesai, baru kemudian Main*rame akan diinisialisasi dan ditampilkan. 0anti kita juga akan membahas bagaimana caranya membuat splash screen agar proses inisialisasi Spring terlihat oleh user, dan user tidak merasa bingung selama inisialisasi Spring karena tampilan Main*rame belum terlihat. !erikut ini adalah isi dari class Main / public class Bain { private static SecurityService securityService private static BainHrame /rame public static SecurityService getSecurityService() { return securityService ! public static BainHrame getHrame() { return /rame ! public static void main(String[] args) { #ava.a8t.@ventbueue.invo0e;ater(ne8 6unnable() { public void run() { IpplicationDonte,t applicationDonte,t 7 ne8 Dlass4at.JmlIpplicationDonte,t(*applicationDonte,t.,ml*) securityService 7 (SecurityService) applicationDonte,t.get>ean(*securityService*) /rame 7 ne8 BainHrame() /rame.setPisible(true) ! !) ! ! ,erhatikan kode di atas, di dalam class ini ada object securityService yang berisi method-method yang digunakan untuk melakukan berbagai operasi database terhadap Mntity ,erson, Menu dan -ole. Hbject ini ditandai dengan static dan dibuatkan method getternya, tujuan penggunaan static ini adalah agar object securityService bisa dengan mudah diakses oleh object lain dari aplikasi ,HS yang membutuhkan object securityService. (ita nanti akan melihat lebih banyak bagaimana cara menggunakan object securityService ini di dalam ,erson,anel. (ode di atas juga berisi kode MventIueue.invoke.ater, method ini digunakan untuk mengkeksekusi kode aplikasi di dalam thread baru. Tujuan utamanya adalah agar Thread utama aplikasi yang disebut sebagai Mvent Dispatcher Thread 3MDT5 tetap bebas mendengarkan aksi dari user terhadap F aplikasi. ,raktek penggunaan thread baru untuk aplikasi dan membebaskan MD, mendengarkan egent dari user sangat penting agar aplikasi bisa berjalan dengan halus dan tidak terasa ada lag antara aksi yang dilakukan user dengan response dari aplikasinya. +ingga bab ini kita belum membuat interface SecurityService dan class SecurityService mp, berikut ini adalah class-class yang diperlukan untuk membuat SecurityService/ $lass MenuDao dan -oleDao yang diletakkan com.googlecode.projecttemplate.pos.dao ^6epository public class Benu:ao e,tends >ase:aoHibernateTBenuV{ ! ^6epository public class 6ole:ao e,tends >ase:aoHibernateT6oleV{ dalam package

! (arena kita sudah membuat class !aseDao+ibernate maka membuat MenuDao dan -oleDao menjadi sangat ringkas. nterface SecurityService yang com.googlecode.projecttemplate.pos.service public inter/ace SecurityService { public public public public public public public public public public public public ! Dan terakhir class SecurityService mpl packagecom.googlecode.projecttemplate.pos.service.impl yang interface SecurityService ^Service(*securityService*) ^9ransactional(readAnly7true) public class SecurityService=mpl implements SecurityService{ ^Iuto8ired private 4erson:ao person:ao ^Iuto8ired private Benu:ao menu:ao ^Iuto8ired private 6ole:ao role:ao ^9ransactional public 4erson save(4erson person) { return person:ao.save(person) ! ^9ransactional public 4erson delete(4erson person) { return person:ao.delete(person) ! public 4erson get4erson(;ong id) { return person:ao.get>y=d(id) ! public ;istT4ersonV get4ersons() { return person:ao.getIll() ! ^9ransactional public Benu save(Benu menu) { return menu:ao.save(menu) ! ^9ransactional public Benu delete(Benu menu) { return menu:ao.delete(menu) ! di dalam mengimplementasikan 4erson save(4erson person) 4erson delete(4erson person) 4erson get4erson(;ong id) ;istT4ersonV get4ersons() Benu save(Benu menu) Benu delete(Benu menu) Benu getBenu(;ong id) ;istTBenuV getBenus() 6ole save(6ole role) 6ole delete(6ole role) 6ole get6ole(=nteger id) ;istT6oleV get6oles() diletakkan dalam package

public Benu getBenu(=nteger id) { return menu:ao.get>y=d(id) ! public ;istTBenuV getBenus() { return menu:ao.getIll() ! ^9ransactional public 6ole save(6ole role) { return role:ao.save(role) ! ^9ransactional public 6ole delete(6ole role) { return role:ao.delete(role) ! public 6ole get6ole(;ong id) { return role:ao.get>y=d(id) ! public ;istT6oleV get6oles() { return role:ao.getIll() !

Fntuk mengetes apakah class Main ini sudah ditulis dengan benar, coba klik kanan class Main kemudian pilih -un *ile. Main*rame akan ditampilkan sekaligus anda akan melihat adanya log yang mengindikasikan Spring-+ibernate diload dengan benar, pastikan tidak ada pesan error terlihat di jendela Hutput 0et!eans. Setelah kerangka aplikasi sudah siap, kita kembali lagi ke ,erson,anel untuk melengkapi kodenya.

Melengka$i kode PersonPanel


.angkah pertama untuk melengkapi kode ,erson,anel adalah mensetting property dari ,erson,anel agar Jinternal*rame-nya bisa diminimiBe, dimaLimiBe dan diclose. .ihat tampilan jendela property di ba"ah ini /

Dibagian sebelumnya ketika membuat Main*rame dijelaskan bah"a ada object person,anel yang harus diset null setiap kali ,erson,anel ditutup menggunakan tombol ] atau tombol (eluar. Fntuk melakukan hal tersebut kita bisa memasang kodenya di event nternal *rame $losed, caranya dengan memilih ,erson,anel kemudian klik kanan dan pilih menu Mvents C nternal *rame C

nternal *rame $losed, di jendela Source yang terbuka silahkan tambahkan kode berikut ini / private void /orm=nternalHrameDlosed(#ava,.s8ing.event.=nternalHrame@vent evt) { Bain.getHrame().person4anel 7 null ! .angkah berikutnya kita akan menambahkan event ke tombol-tombol yang ada di dalam ,erson,anel. Sebelum kita mulai, kita bahas satu persatu apa saja yang behaviour setiap tombol ketika user mengklik tombol tersebut, setelah dipahami bagaimana behaviournya baru kita bahas bagaimana cara mengimplementasikan behavour itu di dalam kode. ,ertahikan tombol-tombol di ba"ah ini /

Tombol-tombol di atas adalah Jbutton biasa yang ditambahkan icon agar kelihatan fungsionalitasnya. Fntuk menambahkan icon ke dalam Jbutton caranya gampang, pertama do"nload dulu icon-icon di atas dari sini / http/99code.google.com9p9project-template9source9bro"se9Tsvn9trunk9java-desktopbook9code9src9images (emudian buat package dengan mana images dan letakkan semua image yang dido"nload dari F-. di atas ke dalam package tersebut. Setelah itu pilih misalnya tombol tambah kemudian buka jendela properties bagian icon, akan terlihat jendela seperti di ba"ah ini /

Setelah tampilan tombol-tombol disiapkan, mari kita bahas fungsionalitasnya satu per satu. Tombol Tambah / :ktif ketika ,erson,anel baru dibuka :ktif setelah tombol +apus, Simpan dan !atal ditekan 0on :ktif kalau tombol Tambah atau Mdit ditekan

(etika ditekan, tombol tambah akan melakukan / Mengkatifkan semua komponen dalam ,erson,anel Membersihkan ,erson,anel dan mereset variabel dalam ,erson,anel Menonaktifkan tombol Mdit, +apus dan Tambah Mengaktifkan tombol Simpan dan !atal

Tombol Mdit 0on :ktif ketika ,erson,anel baru dibuka :ktif ketika user memilih data ,erson dari table di sibelah kiri 0on :ktif kalau tombol Mdit atau !atal ditekan (etika ditekan, tombol edit akan melakukan / Mengaktifkan semua komponen dalam ,erson,anel Mengaktifkan tombol Simpan dan !atal Menonaktifkan tombol Mdit, +apus, dan Tambah

Tombol +apus 0on :ktif ketika ,erson,anel baru dibuka :ktif ketika user memilih data dari table di sebelah kiri 0on aktif ketika tombol +apus atau !atal ditekan (etika ditekan, tombol hapus akan melakukan / Mencoba menghapus object ,erson dari database (alau proses penghapusan gagal, misalnya karena data ,erson digunakan sebagai foreign key di table lain, maka popup ditampilkan untuk memberi keterangan error. (alau proses penghapusan berhasil, maka lakukan hal-hal berikut ini / !ersihkan nilai-nilai dari komponen di dalam ,erson,anel -eset variabel di dalam ,erson,anel -efresh nilai dalam tbl,erson :ktifkan tombol Tambah 0on :ktifkan tombol Mdit, +apus, Simpan dan !atal 0on :ktifkan semua komponen dalam ,erson,anel

Tombol Simpan 0on :ktif ketika ,erson,anel baru dibuka :ktif ketika user menekan tombol Tambah dan Mdit 0on :ktif ketika tombol Simpan atau !atal ditekan (etika ditekan, tombol Simpan akan melakukan / @alidasi ,erson,anel apakah sudah benar apa belum. Misalnya apakah teLt ?eld nama sudah diisi atau belum dan seterusnya. Tampilkan popup error kalau proses validasi gagal. nstansiate object baru dari class ,erson :mbil semua nilai dari komponen-komponen di dalam ,erson,anel dan masukkan nilainya ke dalam object ,erson. Mencoba menginsert data ,erson ke database kalau user menekan tombol Tambah

sebelumnya. Mencoba mengupdate data ,erson ke database kalau user menekan tombol Mdit sebelumnya. ,enanda untuk menentukan apakah ,erson akan diinsert atau diupdate ke database adalah nilai id dari ,erson. (alau nilai id null maka hibernate le"at method saveHrFpdate class Session akan menginsert ke database, sebaliknya kalau nilai id tidak sama dengan null maka ,erson akan coba diupdate. (alau proses insert atau update gagal maka tampilkan popup untuk menampilkan error (alau proses insert atau update berhasil maka lakukan hal-hal berikut ini / !ersihkan nilai-nilai dari komponen dalam ,erson,anel 0on :ktifkan semua komponen dalam ,erson,anel -eset variabel di dalam ,erson,anel -efresh tbl,erson dengan menampilkan data terbaru dari database :ktifkan tombol Tambah 0on :ktifkan tombol Mdit, +apus, Simpan dan !atal 0on :ktifkan semua komponen dalam ,erson,anel

Tombol !atal 0on :ktif ketika ,erson,anel baru saja dibuka :ktif ketika user menekan tombol Tambah atau Mdit 0on :ktif ketika user menekan tombol !atal (etika ditekan, tombol !atal akan melakukan / Membersihkan nilai-nilai dari komponen dalam ,erson,anel Menonaktifkan semua komponen dalam ,erson,anel :ktifkan tombol Tambah Menonaktifkan tombol Mdit, +apus, Simpan dan !atal

Tombol (eluar Selalu aktif Memanggil method dispose35 dari Jinternal*rame untuk menutup Jinternal*rame dan menandai objectnya agar dibersihkan garbage collector di cycle berikutnya Mengeset variabel person,anel di dalam Main*rame sebagai penanda bah"a ,erson,anel sudah ditutup. +al ini dilakukan untuk menghindari ,erson,anel dibuka berkali-kali kalau user memilih menu ,erson Data dari Menu !ar. Meload Mntity ,erson dari database, hal ini dilakukan karena data picture ditandai .aBy sehingga perlu diload secara manual dari database. Data picture ditandai .aBy dimaksudkan untuk menghemat band"ith ketika semua data ,erson ditampilkan dalam tbl,erson Set variabel person di dalam ,erson,anel dengan Mntity ,erson yang baru saja diload Masukkan nilai-nilai dari variabel person ke dalam komponen-komponen di dalam ,erson,anel :ktifkan tombol Mdit dan +apus 0onaktifkan komponen-komponen dalam ,erson,anel

Fser memilih satu baris di dalam tbl,erson

(alau kita lihat algoritma di atas terdapat beberapa fungsionalitas yang sama yang digunakan

berulang-ulang disetiap tombol di atas, sehingga kita bisa membuat satu method di dalam ,erson,anel untuk setiap fungsionalitas dalam algoritma di atas. !erikut ini daftar methodmethodnya / private void refreshTable35 digunakan untuk merefresh tbl,erson agar menampilkan data terbaru dari database private void enable*orm3boolean status5 digunakan untuk mengaktifkan atau menonaktifkan komponen-komponen dalam ,erson,anel. ,arameter status bernilai boolean untuk menandakan apakah kita ingin mengaktifkan atau menonaktifkan komponen-komponen tersebut private void clear*orm35 digunakan untuk membersihkan nilai-nilai komponen-komponen di dalam ,erson,anel sekaligus mereset variabel person menjadi null. private boolean validate*orm35 digunakan untuk memvalidasi komponen-komponen dalam ,erson,anel apakah sudah mempunyai nilai yang ditentukan private void load*ormToModel35 digunakan untuk memasukkan nilai komponen-komponen dalam ,erson,anel ke dalam variabel person private void loadModelTo*orm35 digunakan untuk memasukkan nilai dalam variabel person ke dalam komponen-komponen ,erson,anel dari ,erson,anel dan menyediakan

Method-method di atas akan membentuk kerangka fungsionalitas untuk digunakan oleh tombol-tombol.

$lass ,erson,anel juga memerlukan beberapa variabel untuk menampung data yang diperlukan, seperti image, person dan lain-lainya. @ariabel-variabel tersebut diletakkan tepat di ba"ah deklarasi class ,erson,anel dan tidak berada di dalam method apapun. public class 4erson4anel e,tends #ava,.s8ing.]=nternalHrame { private private private private private private ! ;istT4ersonV persons 4erson person ]HileD.ooser c.ooser /inal int ma,4ictureSi?e 7 %)N =mage=con image static /inal ;ogger log 7 ;ogger.get;ogger(4erson4anel.class)

CC0ode lain di sini

Selain method-method dan variabel-variabel di atas, kita memerlukan dua buah class di dalam ,erson,anel. $lass pertama adalah ,ersonTableModel yang meneLtends :bstractTable model, class ini digunakan untuk menampilkan .istA,ersonC ke dalam tbl,erson. $lass kedua adalah ,ersonTableSelection.istener yang mengimplementasikan interface .istSelection.istener, class ini dugunakan untuk mendengarkan event pemilihan baris di dalam tbl,erson. Setiap kali user memilih satu baris dalam tbl,erson maka data lengkap ,erson akan ditampilkan dalam ,erson,anel. :gar management kode lebih simpel, kedua class ini adalah inner class yang deklarasinya dilaksanakan di dalam class ,erson,anel. $lass ,ersonTableModel adalah sebagai berikut / private class 4erson9ableBodel e,tends Ibstract9ableBodel{ private ;istT4ersonV list4ersons public 4erson9ableBodel(;istT4ersonV list4ersons) { t.is.list4ersons 7 list4ersons ! public int get6o8Dount() { return list4ersons.si?e() ! public int getDolumnDount() { return ) !

public Ab#ect getPalueIt(int ro8=nde,+ int column=nde,) { 4erson p 7 persons.get(ro8=nde,) s8itc.(column=nde,){ case ' 3 return p.get<ame() case % 3 return p.get>irt.:ate() de/ault3 return ** ! ! ! $lass di atas hanya mengimplementasikan 7 buah method abstract dari :bstractTableModel, yaitu get-o"$ount untuk menentukan berapa banyak baris yang akan ditampilkan, get$olumn$ount menentukan berapa kolom yang akan ditampilkan dan get@alue:t digunakan untuk mendapatkan nilai dari setiap cell dalam tbl,erson. $lass ,ersonTableSelection.istener adalah sebagai berikut ini / private class 4erson9ableSelection;istener implements ;istSelection;istener{ public void valueD.anged(;istSelection@vent e) { i/(tbl4erson.getSelected6o8()V7'){ person 7 persons.get(tbl4erson.getSelected6o8()) person 7 Bain.getSecurityService().get4erson(person.get=d()) loadBodel9oHorm() btn:elete.set@nabled(true) btnIdd.set@nabled(/alse) btnDancel.set@nabled(true) btn@dit.set@nabled(true) btnSave.set@nabled(/alse) ! ! ! $lass ,ersonTableSelection.istener hanya mengimplementasikan satu method saja yaitu value$hanged dari interface .istSelection.istener. Di dalam method tersebut terdapat method loadModelTo*orm yang belum dibuat, di bagian berikutnya kita akan membuat method-method tersebut. !erikutnya kita akan implementasikan satu persatu method-method di atas beserta kode-kode yang akan dieksekusi ketika setiap tombol di atas diklik oleh user. Method refreshTable private void re/res.9able(){ persons 7 Bain.getSecurityService().get4ersons() tbl4erson.setBodel(ne8 4erson9ableBodel(persons)) ! Method enable*orm private void enableHorm(boolean status){ t,t<ame.set@nabled(status) t,t4ass8ord.set@nabled(status) #dc>irt.:ate.set@nabled(status) btn>ro8se.set@nabled(status) t,tHoto.set@nabled(/alse) t,t6emar0.set@nabled(status) cmbBaritalStatus.set@nabled(status) ! Method clear*orm private void clearHorm(){ t,t=d.set9e,t(**) t,t<ame.set9e,t(**)

t,t4ass8ord.set9e,t(**) t,t6emar0.set9e,t(**) t,tHoto.set9e,t(**) tbl4erson.getSelectionBodel().clearSelection() #dc>irt.:ate.set:ate(null) person 7 null lblHoto.set=con(null) ! Method validate*orm private boolean validateHorm(){ i/(t,t<ame.get9e,t().lengt.()V' YY t,t4ass8ord.get4ass8ord()!7null YY t,t4ass8ord.get4ass8ord().lengt.V'){ return true ! else { ]Aption4ane.s.o8Bessage:ialog(Bain.getHrame()+ *=si semua /ield!*+*@rror*+]Aption4ane.@66A6(B@SSIS@) return /alse ! ! Method load*ormToModel private void loadHorm9oBodel(){ person.set<ame(t,t<ame.get9e,t()) i/(person.get4ass8ord()77null ZZ !person.get4ass8ord().e\uals( ne8 String(t,t4ass8ord.get4ass8ord()))){ CCencrypt 0ata sandi dengan B:R String 0ataSandi 7 ne8 B:R(ne8 String(t,t4ass8ord.get4ass8ord())).asHe,() person.set4ass8ord(0ataSandi) ! person.set6emar0(t,t6emar0.get9e,t()) person.set>irt.:ate(#dc>irt.:ate.get:ate()) person.setStatus((BaritalStatus) cmbBaritalStatus.getSelected=tem()) i/(!t,tHoto.get9e,t().e\uals(**)){ Ab#ectAutputStream dataAutputStream 7 null try { >yteIrrayAutputStream outputStream 7 ne8 >yteIrrayAutputStream() dataAutputStream 7 ne8 Ab#ectAutputStream(outputStream) dataAutputStream.8riteAb#ect(image) dataAutputStream./lus.() person.set4icture(outputStream.to>yteIrray()) ! catc. (=A@,ception e,) { log.error(*gagal menguba. =mage 0e bytearray*+e,) ! /inally { try { dataAutputStream.close() ! catc. (=A@,ception e,) { @,ceptions.printStac09race(e,) ! ! ! ! Di dalam method ini terdapat class MD4 yang digunakan untuk membuat hash dari pass"ord user untuk disimpan ke database. +al ini penting untuk menghindari pass"ord user disimpan sebagai

palain teLt di dalam datatabase. $lass ini berasal dari project fast-md4 3fast-md4.jar5 yang bisa dido"nload dari t"macinta.com9myjava9fastSmd4.php kemudian tambahkan ke dalam libary project. $lass MD4 ini kompatibel dengan method md4 dari php sehingga tidak ada kekha"atiran table person ini nanti dibaca dari ,+, . (emudian terdapat kode untuk menyimpan gambar ke dalam database. Setelah berkutat dengan beberapa teknik penyimpanan data image ke database, akhirnya salah satu tekniknya berhasil. Teknik ini tidak langsung membaca image menjadi byte array karena nantinya proses merubah byte array ke image memerlukan informasi format image tersebut, karena setiap format image seperti jpg, gif atau png mempunyai codec yang berbeda. Teknik yang digunakan di atas adalah dengan membaca image dari ?le sebagai object mage H kemudian mage H disimpan ke dalam DataHbjectStream sebagai serialiBable object kemudian dibungkus oleh !yte:rrayHutputStream sebelum dirumah menjadi byte array. Dengan cara ini tidak diperlukan informasi tentang format image-nya, karena nanti pada "aktu membaca dari byte array di database langsung didapatkan object mage H yang langsung bisa ditampilkan sebagai icon dari Jlabel, sehingga gambarnya tampil di ,erson,anel. Method loadModelTo*orm private void loadBodel9oHorm(){ t,t=d.set9e,t(String.valueA/(person.get=d())) t,t<ame.set9e,t(person.get<ame()) t,t4ass8ord.set9e,t(person.get4ass8ord()) #dc>irt.:ate.set:ate(person.get>irt.:ate()) cmbBaritalStatus.setSelected=tem(person.getStatus()) t,t6emar0.set9e,t(person.get6emar0()) i/(person.get4icture()!7null){ try { Ab#ect=nputStream ob#ect=nputStream 7 ne8 Ab#ect=nputStream( ne8 >yteIrray=nputStream(person.get4icture())) image 7 (=mage=con) ob#ect=nputStream.readAb#ect() lblHoto.set=con(image) ! catc. (Dlass<otHound@,ception e,) { log.error(*=mage gagal dibaca*+ e,) ! catc. (=A@,ception e,) { log.error(*=mage gagal dibaca*+ e,) ! ! else { lblHoto.set=con(null) ! ! Di dalam method di atas terdapat kode untuk merubah byte array dari database menjadi mage H. (ebalikan dari method sebelumnya yang merubah ?le image menjadi byte array. Sekarang kita lihat kode di konstruktor ,erson,anel, di dalam konstruktor-nya tedapat kodekode untuk meload ,erson dari database dan diletakkan dalam tbl,erson, kemudian kode untuk membatasi panjang tLt0ama karena panjang kolom di database terbatas, kalau namanya terlalu panjang akan mengakibatkan SI. MLception. public 4erson4anel() { initDomponents() 9e,tDomponentGtils.setBa,imum;engt.(%''+ t,t<ame) tbl4erson.setIutoDreateDolumnsHromBodel(/alse) tbl4erson.getSelectionBodel().add;istSelection;istener( ne8 4erson9ableSelection;istener()) re/res.9able() enableHorm(/alse)

cmbBaritalStatus.setBodel(ne8 :e/aultDombo>o,Bodel(BaritalStatus.values())) CCpengaturan tombol 0eti0a person panel dibu0a btn:elete.set@nabled(/alse) btnIdd.set@nabled(true) btnDancel.set@nabled(/alse) btn@dit.set@nabled(/alse) btnSave.set@nabled(/alse) ! Di dalam kode di atas terdapat class TeLt$omponentFtils yang birisi utility untuk membatasi panjang tLt0ame. $lass ini bisa dido"nload dari / http/99code.google.com9p9project-template9source9bro"se9trunk9java-desktopbook9code9src9com9googlecode9projecttemplate9pos9util9TeLt$omponentFtils.java Setelah selesai mempersiapkan fungsi-fungsi dan variabel yang diperlukan, sekarang kita buat event handling untuk tombol-tombol. Fntuk menambahkan event ketika tombol diklik, pilih tombolnya kemudian klik kanan dan pilih menu Mvent C :ction ,erformed. Setelah itu jendela Source akan dibuka dan sebuah method akan dibuat, di dalam method inilah kode untuk mengimplementasikan algoritma yang kita bahas di a"al bagian ini. Tombol Tambah private void btnIddIction4er/ormed(#ava.a8t.event.Iction@vent evt) { clearHorm() enableHorm(true) CCpengaturan tombol btn:elete.set@nabled(/alse) btnIdd.set@nabled(/alse) btnDancel.set@nabled(true) btn@dit.set@nabled(/alse) btnSave.set@nabled(true) ! Tombol Mdit private void btn@ditIction4er/ormed(#ava.a8t.event.Iction@vent evt) { i/(person!7null){ enableHorm(true) btn:elete.set@nabled(/alse) btnIdd.set@nabled(/alse) btnDancel.set@nabled(true) btn@dit.set@nabled(/alse) btnSave.set@nabled(true) ! ! Tombol +apus private void btn:eleteIction4er/ormed(#ava.a8t.event.Iction@vent evt) { i/(person!7null){ try{ Bain.getSecurityService().delete(person) clearHorm() person 7 null re/res.9able() enableHorm(/alse) CCpengaturan tombol btn:elete.set@nabled(/alse) btnIdd.set@nabled(true) btnDancel.set@nabled(/alse)

btn@dit.set@nabled(/alse) btnSave.set@nabled(/alse) ! catc.(@,ception e,){ log.error(e,) ]Aption4ane.s.o8Bessage:ialog(t.is+ *:ata masi. diguna0an tida0 bisa di.apus!*+ *@rror*+]Aption4ane.@66A6(B@SSIS@) ! ! !

Tombol Simpan private void btnSaveIction4er/ormed(#ava.a8t.event.Iction@vent evt) { i/(validateHorm()){ i/(person 77 null){ person 7 ne8 4erson() ! loadHorm9oBodel() try{ Bain.getSecurityService().save(person) clearHorm() re/res.9able() enableHorm(/alse) CCpengaturan tombol btn:elete.set@nabled(/alse) btnIdd.set@nabled(true) btnDancel.set@nabled(/alse) btn@dit.set@nabled(/alse) btnSave.set@nabled(/alse) ! catc.(@,ception e,){ log.error(e,) ]Aption4ane.s.o8Bessage:ialog(t.is+ *:ata gagal disimpan!* +*@rror*+]Aption4ane.@66A6(B@SSIS@) ! ! ! Tombol !atal private void btnDancelIction4er/ormed(#ava.a8t.event.Iction@vent evt) { clearHorm() enableHorm(/alse) CCpengaturan tombol btn:elete.set@nabled(/alse) btnIdd.set@nabled(true) btnDancel.set@nabled(/alse) btn@dit.set@nabled(/alse) btnSave.set@nabled(/alse) ! Tombol (eluar private void btn@,itIction4er/ormed(#ava.a8t.event.Iction@vent evt) { Bain.getHrame().person4anel 7 null dispose() ! Selain kelima tombol di atas, ada satu lagi tombol bro"se yang digunakan untuk memilih ?le gambar. Tombol !ro"se

private void btn>ro8seIction4er/ormed(#ava.a8t.event.Iction@vent evt) { i/(c.ooser 77 null){ c.ooser 7 ne8 ]HileD.ooser(System.get4roperty(*user..ome*)) c.ooser.setHileSelectionBode(]HileD.ooser.H=;@S(A<;_) c.ooser.setHileHilter( ne8 Hile<ame@,tensionHilter(*#pgZpngZgi/*+ *#pg*+*png*+*gi/*)) ! int ret 7 c.ooser.s.o8Apen:ialog(t.is) i/(ret 77 ]HileD.ooser.I446AP@(A49=A<){ Hile / 7 c.ooser.getSelectedHile() try { =mage img 7 =mage=A.read(ne8 Hile=nputStream(/)) CCce0 u0uran /oto+ 0alau terlalu besar resi?e 0e ma,4ictureSi?e i/(img.getHeig.t(t.is)Vma,4ictureSi?e ZZ img.getWidt.(t.is)Vma,4ictureSi?e){ i/(img.getHeig.t(t.is) V img.getWidt.(t.is)){ /loat scale 7 img.getHeig.t(t.is)Cma,4ictureSi?e int 8idt.Si?e 7 (int) (img.getWidt.(t.is) C scale) img 7 img.getScaled=nstance(ma,4ictureSi?e+ 8idt.Si?e+ =mage.SDI;@(SBAA9H) ! else { /loat scale 7 img.getWidt.(t.is)Cma,4ictureSi?e int .eig.tSi?e 7 (int) (img.getHeig.t(t.is) C scale) img 7 img.getScaled=nstance(ma,4ictureSi?e+ .eig.tSi?e+ =mage.SDI;@(SBAA9H) ! ! image 7 ne8 =mage=con(img) lblHoto.set=con(image) t,tHoto.set9e,t(/.getIbsolute4at.()) ! catc. (=A@,ception e,) { log.error(*error membu0a /ile /oto*+e,) ! ! ! Di pojok kiri atas ada satu buah teLt ?eld yang digunakan sebagai pencarian data ,erson di tbl,erson. ,roses pencarianya berdasarkan nilai dari kolom di sebelah kiri, Jtabel mempunyai feature untuk memindah-mindahkan urutan kolom dengan cara mendrag-n-drop kolom, misalnya kita bisa memindahkan kolom Tanggal .ahir ke sebelah kiri atau sebaliknya memindahkan kolom 0ama ke sebelah kanan. ,encarianya menggunakan model pencocokan starts#ith dengan parameter huruf yang diketik di dalam teLt ?eld, misalnya diketik huruf EiG maka akan dicari nama yang dia"ali dengan string EiG, proses pencarian ini akan memilih nama dengan a"alan EiG yang ditemukan pertama kali dan tbl,erson akan discroll ke baris tersebut, jadi hasil pencarian tidak di?lter cuma nama dengan a"alan EiG saja. ,roses pencarianya dilakukan di client, jadi tidak ada database hit selama pencarian. (lik kanan di tLt$ari kemudian pilih menu Mvents C (ey C (ey -eleased kemudian tambahkan kode di ba"ah ini / private void t,tSearc.Key6eleased(#ava.a8t.event.Key@vent evt) { /or(int i7' iTtbl4erson.get6o8Dount() iEE){ i/(tbl4erson.getPalueIt(i+ ').toString().startsWit.(t,tSearc..get9e,t())){ CCselect baris yang ditemu0an tbl4erson.getSelectionBodel().setSelection=nterval(i+ i) CCscroll 0e baris tersebut 0alau ada di ba8a. atau bagian atas DomponentGtils.scroll9o6ect(tbl4erson+ i) brea0 ! !

! (ode di atas memerlukan class utility $omponentFtils yang dapat dido"nload di / http/99code.google.com9p9project-template9source9bro"se9trunk9java-desktopbook9code9src9com9googlecode9projecttemplate9pos9util9$omponentFtils.java (ode-kode di atas adalah tamplate untuk data master, untuk latihan silahkan buat panel untuk data -ole, Menu dan !arang. Di bagian berikutnya kita akan bahas bagaimana membuat data transaksi penjualan.

Data -ransaksi
,encatatan data transaksi di aplikasi ,HS adalah bagian paling penting dari aplikasi. Dari jendela inilah transaksi penjualan dilaksanakan. Tampilan jendela transaksi penjualan bisa dilihat di ba"ah ini/

!agian atas terdapat tombol-tombol untuk operasi data, ada satu lagi tambahan tombol $ari untuk melakukan pencarian data transaksi sebelumnya. Jika dilik, tombol $ari akan menampilkan jendela pencarian transaksi, kemudian user bisa memilih salah satu baris transaksi dari jendela ini. Setelah dipilih dan ditekan tombol H(, maka transaksi akan ditampilkan di dalam jendela penjualan, kemudian user bisa mengedit data penjualan tersebut.

(alau ,HS ini digunakan bersama dengan barcode scanner, maka kursor bisa diletakkan dalam kode barang, kemudian gunakan barcode scanner untuk menscan kode barang. !arcode scanner akan menampilkan kode barang plus karakter enter 3karakter kode )75 ke dalam teLt ?eld kode barang, kita akan memasang action,erformed listener di dalam teLt?eld tersebut agar setiap ada karakter enter dari barcode scanner langsung dilakukan \uery untuk mencari kode barangnya dan dibuatkan data transaksi penjualanya. Di sebelah kanan teLt?eld kode barang terdapat tombol lookup untuk melakukan pencarian terhadap barang secara manual, misalnya barang yang diba"a pembeli tidak ada kode barangnya karena lepas atau rusak. (asir bisa menggunakan fasilitas ini untuk mencari kode barang berdasarkan nama barangnya. *asilitas pencarian barang ini juga berguna untuk mencari harga barang jika ada pembeli yang ingin mengetahui harga barang tetapi harganya tidak tercantum di dalam rak.

TeLt?eld cari di dalam jendela ini bisa digunakan untuk melakukan pencarian terhadap barang, proses pencarian dilakukan terhadap kolom yang ada di sebelah kiri. (olom di sebelah kiri secara default akan menampilkan kode barang, kalau misalnya ingin melakukan pencarian berdasarkan nama barang, cukup drag kolom 0ama !arang ke sebelah kiri menggantikan kolom D !arang.

,enggeseran kolom ini bisa dilakukan terhadap semua Jtable, feature ini sudah build in di dalam Jtable, tidak perlu kode tambahan. Setelah mengetahui fungsionalitas jendela transaksi penjualan di atas, di bagian berikutnya kita akan membahas bagaimana menyiapkan ketiga screen di atas kemudian kita bahas satu per satu bagaimana membuat kodenya.

Mem$ersia$kan *creen &ransaksi Pen#ualan


Screen pertama yang kita siapkan adalah Jinternal*rame untuk menampilkan halaman penjualan. Screen ini terdiri dari tujuh buah tombol di sisi atas, satu tombol tambahan dibanding screen master adalah tombol $ari. (emudian ada dua buah teLt ?eld untuk menampilkan id transaksi dan id barang, satu buah tombol lookup untuk melakukan pencarian barang, sebuah date chooser dari Jcalendar untuk menampilkan tanggal transaksi dan sebuah Jlabel untuk menampilkan total transaksi.

Fntuk membuat J nternal*rame di atas, pilih menu *ile C 0e" *ile kemudian pilih S"ing KF *orm C Jinternal*rame *orm. !eri nama Sales,anel dan letakkan di package com.googlecode.projecttemplate.pos.ui.transaction. !eberapa kon?gurasi di properties yang perlu dilakukan adalah mengubah ukuran dan jenis font dari lblTotal. Seperti terlihat dari gambar di ba"ah ini. $ara menampilkan jendela font tersebut adalah dengan memilih baris *ont dari jendela properties lblTotal.

(emudian tblSalesDetail juga perlu diubah sedikit properties-nya, yang pertama adalah Model. ,ilih tblSalesDetail kemudian buka jendela properties dan pilih Model. Jendela editor untuk mengedit TableModel akan terlihat seperti gambar di ba"ah ini /

Selain properties model, ada satu lagi properties dari tblSalesDetail yang perlu diubah, yaitu

cellSelectionMnabled. $entang properties cellSelectionMnabled agar user bisa memilih cell dari tblSalesDetail, kalau tidak dicentang maka tblSalesDetail hanya bisa dipilih baris per baris. Setelah selesai menyiapkan screen transaksi penjualan, sekarang kita siapkan screen untuk menampilkan pencarian barang yang nantinya akan ditampilkan kalau tombol btn.ookup,roduct ditekan. !erbeda dengan screen transaksi penjualan yang merupakan J nternal*rame, screen pencarian barang adalah turunan dari Jdialog. Jdialog dipilih untuk menampilkan screen pencarian barang karena sifatnya yang EmodalG alias berada di atas screen lainya, dan selama screen pencarian barang ini tampil maka komponen lainya di ba"ahnya tidak bisa dipilih. Fser juga di"ajibkan untuk memilih salah satu barang di dalam tbl,roduct sebelum menekan tombol H(, atau menekan tombol $ancel. Fntuk membuat screen pencarian barang ini, pilih *ile C 0e" *ile kemudian pilih S"ing KF *orm C Jdialog *orm. !eri nama ,roduct.ookupDialog dan letakkan di dalam package yang sama dengan Sales,anel. Setelah selesai dibuat, kemudian tambahkan komponen-komponen ke dalam Jdialog seperti gambar di ba"ah ini. Jangan lupa untuk mengedit properties model dari tbl,roduct seperti di atas.

Setelah menyelesaikan screen pencarian barang, screen berikutnya yang akan kita buat adalah screen pencarian transaksi. Screen pencarian transaksi akan ditampilkan kalau user menekan tombol $ari. Tampilan screen pencarian transaksi ini sama persis dengan tampilan screen pencarian barang, hanya datanya saja yang berbeda. :gar pembuatan screen pencarian transaksi lebih cepat, kita bisa lakukan copy class ,roduct.ookupDialog kemudian paste di package yang sama dan ganti nama class-nya menjadi Sales.ookupDialog. Setelah proses copy paste selesai, ubah tampilan Sales.ookupDialog seperti gambar di ba"ah ini / dan nama-nama komponen dalam

Setelah ketiga screen di atas selesai dibuat, berikutnya kita akan mulai menulis kode-kode untuk mengimplementasikan fungsionalitas dari ketiga screen di atas. (ita mulai dari kodekode backend untuk mengakses entity ,roduct dan entity Sales.

Mem"uat *ervice dan DA! untuk *ales dan Product


Seperti yang sudah kita bahas sebelumnya, membuat D:H sangat mudah dengan adanya !aseDao+iberanate, cukup buat sebuah class dan eLtends !aseDao+iberanate maka semua fungsionalitas D:H sudah terpenuhi. (edua class D:H di ini diletakkan di dalam package yang sama dengan class-class D:H yang sudah dibuat. $lass ,roductDao adalah sebagai berikut / ^6epository public class 4roduct:ao e,tends >ase:aoHibernateT4roductV{ ! (emudian SalesDao adalah sebagai berikut / ^6epository public class Sales:ao e,tends >ase:aoHibernateTSalesV{ ! !isa dilihat bah"a kode kedua D:H di atas sangat sederhana, kalau tidak ada \uery yang berbeda dengan !aseDao+ibernate maka class D:H-nya akan kosong seperti di atas. !erikutnya kita akan membuat ,roductService dan ,roductService mpl. Sebenarnya kita tidak perlu membuat sebuah Service untuk setiap Mntity9D:H, satu Service bisa digunakan untuk beberapa Mntity9D:H, hanya saja perlu diingat agar class Service jangan sampai terlalu besar ukuranya untuk menghindari kode yang terlalu berantakan. Service dari Mntity yang tidak termasuk dalam transaction seperti ,roduct bisa disatukan dengan Mntity lain, tapi karena tidak ada lagi Mntity lain selain ,roduct yang tidak termasuk dalam transaction atau security, maka dibuatlah ,ersonService. (alau misalnya ada Mntity lain selain ,erson yang tidak termasuk kedua kategory Mntity di atas, bisa juga dibuat MasterService untuk mengakomodasi semua Mntity yang berjenis ini.

$lass ,roductService adalah sebagai berikut / public inter/ace 4roductService { 4roduct save(4roduct product) 4roduct delete(4roduct product) 4roduct get4roduct(;ong id) ;istT4roductV get4roduct() ;istT4roductV get4roduct(int start+ int num) ! $lass ,roductService mpl / ^Service(*personService*) ^9ransactional(readAnly7true) public class 4ersonService=mpl implements 4ersonService{ ^Iuto8ired private 4erson:ao person:ao ^9ransactional(readAnly7/alse) public void save(4erson person) { person:ao.save(person) ! ^9ransactional(readAnly7/alse) public void delete(4erson person) { person:ao.delete(person) ! public ;ong count() { return person:ao.count() ! public 4erson get4erson(;ong id) { return person:ao.get>y=d(id) ! public ;istT4ersonV get4ersons() { return person:ao.getIll() ! public ;istT4ersonV get4ersons(int start+ int num) { return person:ao.getIll(start+ num) ! ! (emudian kita buat class SalesService / public inter/ace SalesService { Sales save(Sales sales) Sales delete(Sales sales) Sales getSales(;ong id) ;istTSalesV getSales() ;istTSalesV getSales(int start+ int num) ! Terakhir adalah class SalesService mpl/ ^Service(value7*salesService*) ^9ransactional(readAnly7true) public class SalesService=mpl implements SalesService{ ^Iuto8ired private Sales:ao sales:ao ^9ransactional public Sales save(Sales sales) { CCagar yang diguna0an adala. :ate server bu0an date client 0alau CCdi#alan0an dengan arsite0tur t.ree tier

sales.setSales:ate(ne8 :ate()) return sales:ao.save(sales) ! ^9ransactional public Sales delete(Sales sales) { return sales:ao.delete(sales) ! public Sales getSales(;ong id) { Sales s 7 sales:ao.get>y=d(id) Hibernate.initiali?e(s.getSales:etails()) return s ! public ;istTSalesV getSales() { return sales:ao.getIll() ! public ;istTSalesV getSales(int start+ int num) { return sales:ao.getIll(start+ num) ! ! Setelah selesai membuat D:H dan Service, sekarang kita edit class Main dan meletakkan instance dari ,ersonService dan SalesService agar bisa diakses dari class lain yang memerlukan. ,roses penambahan instance Service ke dalam class Main dilakukan setiap kali ada Service baru yang dibuat. !erikut ini class Main yang sudah diedit / public class Bain { private static SecurityService securityService private static SalesService salesService private static 4roductService productService private static BainHrame /rame public static SecurityService getSecurityService() { return securityService ! public static SalesService getSalesService() { return salesService ! public static 4roductService get4roductService() { return productService ! public static BainHrame getHrame() { return /rame ! public static void main(String[] args) { #ava.a8t.@ventbueue.invo0e;ater(ne8 6unnable() { public void run() { IpplicationDonte,t applicationDonte,t 7 ne8 Dlass4at.JmlIpplicationDonte,t(*applicationDonte,t.,ml*) securityService 7 (SecurityService)applicationDonte,t.get>ean(*securityService*) salesService 7 (SalesService) applicationDonte,t.get>ean(*salesService*) productService 7 (4roductService) applicationDonte,t.get>ean(*productService*) /rame 7 ne8 BainHrame() /rame.setPisible(true) ! !) !

! Selesai sudah kode untuk mengakses data ,roduct dan Sales. .angkah berikutnya adalah membuat kode untuk F -nya. ,ertama kita implementasikan dahulu kode untuk screen ,roduct.ookupDialog.

Melengka$i Kode di Class ProductLooku$Dialog


$lass ,roduct.ookupDialog adalah class turunan dari JDialog, class ini termasuk kategori ElookupG untuk melakukan lookup 3pencarian5 data lain. Screen jenis ini hanya digunakan untuk menampilkan data dan pencarian, tidak ada proses perubahan data. (ode untuk membuat screen lookup juga kurang lebih sama, perbedaanya hanya pada Mntity apa yang akan dicari. Misalnya antara Sales dan ,roduct, perbedaan screen lookup dari kedua entity ini hanya pada Mntity saja. Dengan melakukan copy paste dari ,roduct.ookupDialog menjadi Sales.ookupDialog, mereplace ,roduct menjadi Sales dan mengganti kode untuk melakukan \uery ke database. !erikut ini kita bahas satu per satu bagian dari class ,roduct.ookupDialog. Setelah class-nya dibuat, hapus method public void main yang digenerate dari netbeans, kemudian ubah deklarasi class, property dan constructor public class 4roduct;oo0up:ialog e,tends #ava,.s8ing.]:ialog { private 4roduct product private ;istT4roductV products public 4roduct;oo0up:ialog() { super(Bain.getHrame()+ true) initDomponents() set;ocation6elative9o(null) tbl4roduct.setIutoDreateDolumnsHromBodel(/alse) tbl4roduct.getSelectionBodel().add;istSelection;istener( ne8 4roductSelection;istener()) products 7 Bain.get4roductService().get4roduct() tbl4roduct.setBodel(ne8 4roduct9ableBodel(products)) ! CC0ode lain di sini ! Dalah constructor class ,roduct.ookupDialog terdapat kode-kode untuk menginisialisasi Jdialog ini agar bersifat EmodalG, kode untuk melakukan setting modal ada di baris pertama, dengan memanggil constructor dari Jdialog dan mengeset parameter kedua dengan nilai true. Di baris berikutnya ada method init$omponents yang digunakan oleh 0et!eans mengenerate kode-kode layout. !aris berikitnya ada method set.ocation-elativeTo dengan parameter null, method ini dipanggil agar Jdialog diletakkan tepat di tengah-tengah dari layar. :papun ukuran layarnya set.ocation-elativeTo3null5 pasti bisa menletakkan Jdialog tepat di tengah tengah layar, jadi tidak perlu ada kalkulasi ukuran layar user untuk meletakkan Jdialog di tengah-tengah. Setelah itu ada kode-kode tbl,roduct.set:uto$reate$olumns*romModel3false5D yang digunakan untuk mencegah Jtable membuat ulang kolomnya kalau model-nya diset. (ode ini "ajib ditulis agar kolom dari Jtable yang sudah diubah secara visual di langkah sebelumnya tidak dioverride ketika model dari Jtable diset. Tiga baris berikutnya digunakan untuk mendaftarkan ,roductSelection.istener, mengambil data product dari database dan mengeset table model ke dalam tbl,roduct. Seperti halnya screen data master yang sebelumnya sudah kita buat, screen ini mempunyai sebuah table, oleh karena itu perlu dibuat class yang mengimplementasikan TableModel dan .istSelection.istener. (ode di atas terdapat class ,roductTableModel dan class ,roductSelection.istener, kedua class tersebut adalah inner class dari ,roduct.ookupDialog, jadi letakkan kodenya di dalam class ,roduct.ookupDialog. !erikut ini kode untuk kedua class tersebut. private class 4roduct9ableBodel e,tends Ibstract9ableBodel{ private ;istT4roductV products public 4roduct9ableBodel(;istT4roductV products) { t.is.products 7 products

! public int get6o8Dount() { return products.si?e() ! public int getDolumnDount() { return 1 ! public Ab#ect getPalueIt(int ro8=nde,+ int column=nde,) { 4roduct p 7 products.get(ro8=nde,) s8itc.(column=nde,){ case '3 return p.get=d() case %3 return p.get<ame() case )3 return p.get4rice() de/ault3 return ** ! ! ! $lass ,roductSelection.istener / private class 4roductSelection;istener implements ;istSelection;istener{ public void valueD.anged(;istSelection@vent e) { i/(tbl4roduct.getSelected6o8()V7'){ product 7 products.get(tbl4roduct.getSelected6o8()) ! ! ! (emudian kita akan membuat kode untuk action listener dari setiap komponen dalam ,roduct.ookupDialog, yang pertama ada lah ketika user mengetikkan huruf di dalam tLtSearch. Mvent yang digunakan adalah key-eleased, cara membuat event ini adalah dengan mengklik kanan tLtSearch kemudian pilih Mvents C (ey C key -eleased, di jendela $ode yang terbuka tambahkan kode berikut ini / private void t,tSearc.Key6eleased(#ava.a8t.event.Key@vent evt) { /or(int i 7' iTtbl4roduct.get6o8Dount() iEE){ String val 7 tbl4roduct.getPalueIt(i+ ').toString() i/(val!7null YY val.startsWit.(t,tSearc..get9e,t())){ tbl4roduct.getSelectionBodel().setSelection=nterval(i+ i) DomponentGtils.scroll9o6ect(tbl4roduct+ i) brea0 ! ! ! (ode di atas mengandung class $omponentFtils yang digunakan untuk menscroll Jtable kalau hasil pencarianya berada di bagian ba"ah atau bagian atas. Di bab sebelumnya terdapat link untuk mendo"nload class $omponentFtils ini. !erikutnya adalah kode ketika tombol H( ditekan, untuk menangkap event penekanan tombol H( digunakan listener untuk mendengarkan event action,erformed terhadap tombol H(. (lik kanan btnHk, kemudian plilih menu Mvent C action,erformed, dan tambahkan kode berikut ini / private void btnA0Iction4er/ormed(#ava.a8t.event.Iction@vent evt) { i/(product!7null){ dispose() ! else { ]Aption4ane.s.o8Bessage:ialog(t.is+*4ili. satu barang terlebi. da.ulu!*+ *error*+]Aption4ane.@66A6(B@SSIS@)

! ! .isterner yang terakhir perlu diimplementasikan adalah pada "aktu tombol $ancel ditekan, tambahkan listener untuk event action,erformed di tombol $ancel kemudian ubah kodenya menjadi seprti di ba"ah ini / private void btnDancelIction4er/ormed(#ava.a8t.event.Iction@vent evt) { product 7 null dispose() ! Tombol $ancel hanya akan mengeset variabel product menjadi null dan memanggil method dispose dari Jdialog agar menutup dirinya. (ode terakhir adalah method yang digunakan untuk memanggil ,roduct.ookupDialog dari class lain, kode ini sangat penting dan sedikit berbeda perilakunya dari kode-kode lainya. Mari kita lihat kodenya / public 4roduct get4roduct(){ setPisible(true) return product ! !aris pertama dari method di atas memanggil method set@isible dari Jdialog, method ini bersifat blocking, alias kursor eksekusi kode akan berhenti di baris tersebut hingga ada kode lain yang memanggil method dispose35 dari Jdialog. (alau kita lihat-lihat lagi ke atas, method dispose35 akan dipanggil ketika user menekan tombol H( atau tombol $ancel. 0ah setelah method dispose35 dipanggil barulah method get,roduct ini akan melanjutkan eksekusinya ke baris berikutnya yaitu mereturn nilai dari property product. (alau tombol H( yang ditekan property product harus berisi product yang sekarang sedang dipilih di tbl,roduct, kalau tombol $ancel yang ditekan maka property product akan diset menjadi null baru method dispose35 dipanggil. !agaimana cara menggunakan method iniZ (ita akan bahas di bagian berikutnya sekaligus menerangkan kodekode yang ada dalam class Sales,anel. Fntuk bahan latihan, silahkan buat Sales.ookupDialog dengan menggunakan kode dari ,roduct.ookupDialog di atas, ganti class ,roduct menjadi Sales, kemudian ubah class yang mengimplementasi TableModel-nya dan terakhir ubah cara mengambil data dari database. (alau ada yang bingung silahkan lihat kode Sales.ookupDialog dari F-. ini / http/99code.google.com9p9project-template9source9bro"se9trunk9java-desktopbook9code9src9com9googlecode9projecttemplate9pos9ui9transaction9Sales.ookupDialog.java Setelah selesai membuat dua buah screen lookup, sekarang kita bahas bagian utama buku ini/ Sales,anel.

Melengka$i Kode Class *alesPanel


Sales,anel adalah bagian utama ,HS yang akan digunakan oleh kasir melakukan input data penjulan di toko. Sebagian besar kode dalam Sales,anel sama dengan kode ,erson,anel, strukturnya pun nyaris sama, perbedaanya ada lah Sales,anel digunakan untuk memange data Sales-SalesDetail yang mempunyai patter Master-Detail, sehingga perlu sedikit penyesuain untuk mengakomodasi SalesDetail. Sebelum kita mulai listing kode-nya, kita bahas dulu fungsionalitas dari setiap komponen dalam Sales,anel ini mulai dari tombol-tombol yang ada di bagian atas.

Tombol Tambah / :ktif ketika Sales,anel baru dibuka

:ktif setelah tombol +apus, Simpan dan !atal ditekan 0on :ktif kalau tombol Tambah atau Mdit ditekan (etika ditekan, tombol tambah akan melakukan / Mengkatifkan semua komponen dalam Sales,anel Membersihkan Sales,anel dan mereset variabel dalam Sales,anel Menonaktifkan tombol Mdit, +apus dan Tambah Mengaktifkan tombol Simpan dan !atal

Tombol Mdit 0on :ktif ketika Sales,anel baru dibuka :ktif ketika user memilih data Sales dengan memilih satu baris dalam jendela pencarian data transaksi ketika user menekan tombol $ari. 0on :ktif kalau tombol Mdit atau !atal ditekan (etika ditekan, tombol edit akan melakukan / Mengaktifkan semua komponen dalam Sales,anel Mengaktifkan tombol Simpan dan !atal Menonaktifkan tombol Mdit, +apus, dan Tambah

Tombol +apus 0on :ktif ketika Sales,anel baru dibuka :ktif ketika user memilih data Sales dengan memilih satu baris dalam jendela pencarian data transaksi ketika user menekan tombol $ari. 0on aktif ketika tombol +apus atau !atal ditekan (etika ditekan, tombol hapus akan melakukan / Mencoba menghapus object Sales dari database (alau proses penghapusan gagal, maka popup ditampilkan untuk memberi keterangan error. (alau proses penghapusan berhasil, maka lakukan hal-hal berikut ini / !ersihkan nilai-nilai dari komponen di dalam Sales,anel -eset variabel di dalam Sales,anel -efresh nilai dalam tblSalesDetail :ktifkan tombol Tambah 0on :ktifkan tombol Mdit, +apus, Simpan dan !atal 0on :ktifkan semua komponen dalam Sales,anel

Tombol Simpan 0on :ktif ketika Sales,anel baru dibuka :ktif ketika user menekan tombol Tambah dan Mdit 0on :ktif ketika tombol Simpan atau !atal ditekan (etika ditekan, tombol Simpan akan melakukan / @alidasi Sales,anel apakah sudah benar apa belum. Misalnya apakah sudah ada SalesDetail yang diinput. Tampilkan popup error kalau proses validasi gagal. nstansiasi object baru dari class ,erson

:mbil semua nilai dari komponen-komponen di dalam Sales,anel dan masukkan nilainya ke dalam object Sales. Mencoba menginsert data Sales dan SalesDetail ke database kalau user menekan tombol Tambah sebelumnya. Mencoba mengupdate data Sales dan SalesDetail ke database kalau user menekan tombol Mdit sebelumnya. ,enanda untuk menentukan apakah Sales dan SalesDetail akan diinsert atau diupdate ke database adalah nilai id dari Sales. (alau nilai id null maka hibernate le"at method saveHrFpdate dari class Session akan menginsert ke database, sebaliknya kalau nilai id tidak sama dengan null maka Sales dan SalesDetail akan coba diupdate. $ascade :ll dan $ascade Delete Hrphan di dalam mapping class Sales membantu proses update kalau kasir menambah, mengedit jumlah transaksi atau mengahapus salah satu data SalesDetail. Tidak perlu kode tambahan untuk melakukan pengecekan mana SalesDetail yang ditambah, diedit atau dihapus, sangat praktis. (alau proses insert atau update gagal maka tampilkan popup untuk menampilkan error (alau proses insert atau update berhasil maka lakukan hal-hal berikut ini / !ersihkan nilai-nilai dari komponen dalam Sales,anel 0on :ktifkan semua komponen dalam Sales,anel -eset variabel di dalam Sales,anel !ersihkan isi tblSalesDetail dengan memberikan .ist kosong :ktifkan tombol Tambah 0on :ktifkan tombol Mdit, +apus, Simpan dan !atal 0on :ktifkan semua komponen dalam Sales,anel

Tombol !atal 0on :ktif ketika Sales,anel baru saja dibuka :ktif ketika user menekan tombol Tambah atau Mdit 0on :ktif ketika user menekan tombol !atal (etika ditekan, tombol !atal akan melakukan / Membersihkan nilai-nilai dari komponen dalam Sales,anel Menonaktifkan semua komponen dalam Sales,anel :ktifkan tombol Tambah Menonaktifkan tombol Mdit, +apus, Simpan dan !atal

Tombol $ari Selalu :ktif (etika ditekan, tombol $ari akan melakukan / Memanggil Sales.ookupDialog dan menunggu user menekan tombol H( atau $ancel (alau object Sales yang dikembalikan oleh Sales.ookupDialog maka tampilkan data Sales tersebut. Iuery ulang data Sales dari database dengan mem-fetch SalesDetail, hal ini harus dilakukan karena pada "aktu Sales.ookupDialog mengambil data Sales, data SalesDetailnya tidak ikut di\uery alias laBy fetch. (alau tidak dilakukan \uery ulang ke database maka .aBy nitialiBationMLception akan terjadi. Set nilai object sales dan salesDetail yang baru saja diambil dari database. :ktifkan tombol +apus dan Mdit. 0on :ktifkan tombil Tambah dan Simpan.

(alau object Sales yang dikembalikan Sales.ookupDialog bernilai null, artinya user menekan tombol $ancel, tidak perlu melakukan apa-apa kalau kondisi ini terjadi.

Tombol (eluar Selalu aktif Memanggil method dispose35 dari Jinternal*rame untuk menutup Jinternal*rame dan menandai objectnya agar dibersihkan garbage collector di cycle berikutnya Mengeset variabel sales,anel di dalam Main*rame sebagai penanda bah"a Sales,anel sudah ditutup. +al ini dilakukan untuk menghindari ,erson,anel dibuka berkali-kali kalau user memilih menu Transaksi C ,enjualan dari Menu !ar. tblSalesDetail bisa dipilih cell-per-cell oleh user, hanya kolom (uantitas saja yang bisa diedit. Jika user mengganti nilai kuantitas, maka sub total dari SalesDetail yang sedang dipilih berubah dan update lblTotal agar menampilkan total dari penjualan Iuery ke database untuk mendapatkan ,roduct berdasarkan id yang diinput user $ek ke dalam daftar SalesDetail dalam tblSalesDetail apakah barang tersebut sudah ada, kalau sudah ada maka tambah kuantitasnya dengan satu, update property subTotal dari SalesDetail dan update lblTotal untuk menampilkan total penjualan (alau ,roduct tersebut belum ada dalam tblSalesDetail, maka buat object SalesDetail, set property price dari SalesDetaild dari price yang ada di ,roduct. Set property \uantity menjadi satu, hitung total penjualan dan update lblTotal untuk menampilkan total penjualan. Tampilkan instansiasi ,roduct.ookupDialog dan tampilkan ke user. (alau user memilih salah satu product dan menekan tombol H( yang ditandai return dari ,roduct.ookupDialog tidak bernilai null, maka/ $ek ke dalam daftar SalesDetail dalam tblSalesDetail apakah barang tersebut sudah ada, kalau sudah ada maka tambah kuantitasnya dengan satu, update property subTotal dari SalesDetail dan update lblTotal untuk menampilkan total penjualan (alau ,roduct tersebut belum ada dalam tblSalesDetail, maka buat object SalesDetail, set property price dari SalesDetaild dari price yang ada di ,roduct. Set property \uantity menjadi satu, hitung total penjualan dan update lblTotal untuk menampilkan total penjualan.

Fser memilih satu baris di dalam tblSalesDetail

Fser mengetikkan id barang kemudian menekan enter di tLt,roduct d

Fser menekan tombol btn.ookup,roduct

(alau user menekan tombol $ancel di ,roduct.ookupDialog maka nilai kembalianya akan null dan tidak perlu dilakukan apa-apa

(alau kita lihat algoritma di atas terdapat beberapa fungsionalitas yang sama yang digunakan berulang-ulang disetiap tombol di atas, sehingga kita bisa membuat satu method di dalam ,erson,anel untuk setiap fungsionalitas dalam algoritma di atas. !erikut ini daftar methodmethodnya / private void refreshTable35 digunakan untuk merefresh tblSalesDetail agar menampilkan data SalesDetail yang diinput user private void enable*orm3boolean status5 digunakan untuk mengaktifkan atau menonaktifkan komponen-komponen dalam Sales,anel. ,arameter status bernilai boolean untuk menandakan apakah kita ingin mengaktifkan atau menonaktifkan komponenkomponen tersebut private void clear*orm35 digunakan untuk membersihkan nilai-nilai komponen-komponen di dalam Sales,anel sekaligus mereset variabel sales menjadi null, dan salesDetails menjadi .ist kosong. private boolean validate*orm35 digunakan untuk memvalidasi komponen-komponen dalam

Sales,anel apakah sudah ada transaksi SalesDetail yang diinput oleh user. private void load*ormToModel35 digunakan untuk memasukkan nilai komponen-komponen dalam Sales,anel ke dalam variabel sales private void loadModelTo*orm35 digunakan untuk memasukkan nilai dalam variabel sales ke dalam komponen-komponen Sales,anel private void refreshTotal.abel35 digunakan untuk menghitung total transaksi dan mengeset nilai total transaksi-nya ke lblTotal. private void addSalesDetail3,roduct p5 digunakan untuk membuat object SalesDetail dari ,roduct yang diset dalam parameter method tersebut. (emudian object SalesDetail ditambahkan ke .ist SalesDetail.

Setelah kita bahas algoritma dari setiap komponen dalam Sales,anel, sekarang kita listing satu per satu kodenya. Seperti biasa, kita listing dulu deklarasi class Sales,anel dan property9variabel yang dimiliki oleh class Sales,anel. public class Sales4anel e,tends #ava,.s8ing.]=nternalHrame { private Sales sales private ;istTSales:etailV sales:etails 7 ne8 Irray;istTSales:etailV() private static ;ogger log 7 ;ogger.get;ogger(Sales4anel.class) !erikutnya kita listing kode untuk method-method yang diterangkan di atas. Method clear*orm / private void clearHorm(){ t,t4roduct=d.set9e,t(**) lbl9otal.set9e,t(*6p. '*) #dc9ransaction.set:ate(ne8 :ate()) sales:etails 7 ne8 Irray;istTSales:etailV() sales 7 null tblSales:etail.setBodel(ne8 Sales:etail9ableBodel(sales:etails)) ! Method enable*orm / private void enableHorm(boolean status){ t,t4roduct=d.set@nabled(status) btn;oo0up4roduct.set@nabled(status) tblSales:etail.set@nabled(status) ! Method validate*orm / private boolean validateHorm(){ i/(sales:etails77null ZZ sales:etails.is@mpty()){ ]Aption4ane.s.o8Bessage:ialog(t.is+ *9ransa0si tida0 bole. 0osong!* +*@rror*+]Aption4ane.@66A6(B@SSIS@) return /alse ! return true ! Method load*ormToModel/ private void loadHorm9oBodel(){ sales.setSales:etails(sales:etails) sales.setSales:ate(ne8 :ate()) >ig:ecimal total 7 >ig:ecimal.`@6A /or (Sales:etail sales:etail 3 sales:etails) { total 7 total.add(sales:etail.getSubtotal()) sales:etail.setSales(sales)

! sales.set9otalSales(total) ! Method loadModelTo*orm / private void loadBodel9oHorm(){ sales:etails 7 sales.getSales:etails() tblSales:etail.setBodel(ne8 Sales:etail9ableBodel(sales:etails)) lbl9otal.set9e,t(9e,tDomponentGtils./ormat<umber(sales.get9otalSales())) ! Method refreshTable / private void re/res.9able(){ tblSales:etail.setBodel(ne8 Sales:etail9ableBodel(sales:etails)) ! Method refreshTotal.abel / private void re/res.9otal;abel(){ i/(sales:etails!7null YY !sales:etails.is@mpty()){ >ig:ecimal total 7 >ig:ecimal.`@6A /or (Sales:etail sales:etail 3 sales:etails) { total 7 total.add(sales:etail.getSubtotal()) ! lbl9otal.set9e,t(*6p. * E 9e,tDomponentGtils./ormat<umber(total)) ! ! Method addSalesDetail / private void addSales:etail(4roduct p){ i/(p!7null){ Sales:etail sales:etail 7 ne8 Sales:etail() sales:etail.set4roduct(p) sales:etail.set4rice(p.get4rice()) sales:etail.setbuantity(%) i/(sales:etail.getSubtotal() !7 null){ sales:etail.setSubtotal(sales:etail.getSubtotal().add(p.get4rice())) ! else { sales:etail.setSubtotal(p.get4rice()) ! sales:etails.add(sales:etail) re/res.9able() re/res.9otal;abel() ! else { ]Aption4ane.s.o8Bessage:ialog(t.is+ *>arang tida0 ada!* +*@rror*+]Aption4ane.@66A6(B@SSIS@) ! ! Dalam Sales,anel ini, yang ditampilkan dalam Jtable adalah SalesDetail, sehingga class yang akan dibuat adalah SalesDetailTableModel. $lass ini adalah inner class dari Sales,anel, jadi tambahkan di dalam class Sales,anel, jangan buat ?le .java lagi. private class Sales:etail9ableBodel e,tends Ibstract9ableBodel{ private ;istTSales:etailV sales:etails Sales:etail9ableBodel(;istTSales:etailV sales:etails) { t.is.sales:etails 7 sales:etails ! public int get6o8Dount() { return sales:etails.si?e()

! public int getDolumnDount() { return R ! public Ab#ect getPalueIt(int ro8=nde,+ int column=nde,) { Sales:etail s 7 sales:etails.get(ro8=nde,) s8itc.(column=nde,){ case '3 return s.get4roduct().get=d() case %3 return s.get4roduct().get<ame() case )3 return s.get4rice() case 13 return s.getbuantity() case 53 return s.getSubtotal() de/ault3 return ** ! ! ^Averride public DlassTWV getDolumnDlass(int column=nde,) { i/(column=nde, 77 ) ZZ column=nde, 77 5){ return >ig:ecimal.class ! else i/(column=nde, 77 1){ return =nteger.class ! return String.class ! ^Averride public boolean isDell@ditable(int ro8=nde,+ int column=nde,) { i/(column=nde, 77 1) { return true ! return /alse ! ^Averride public void setPalueIt(Ab#ect aPalue+ int ro8=nde,+ int column=nde,) { Sales:etail s 7 sales:etails.get(ro8=nde,) i/(column=nde, 77 1){ s.setbuantity((=nteger) aPalue) s.setSubtotal(s.get4rice().multiply( ne8 >ig:ecimal(s.getbuantity()))) re/res.9otal;abel() ! ! ! !erbeda dari TableModel yang sudah-sudah, class SalesDetailTableModel mengoverride beberapa method lain dari :bstractTableModel. +al ini dikarenakan ada satu kolom yaitu (uantitas yang sifatnya editable, user bisa mengganti nilai dari kolom (uantitas ini langsung di dalam tablenya, sehingga method get$olumn$lass, is$ellMditable dan set@alue:t harus dioverride. Method get$olumn$lass digunakan untuk mende?nisikan tipe data dari setiap kolom. +al ini penting terutama agar kolom (uantitas hanya bisa diinput angka saja, kalau user menginput String maka Jtable akan mengubah "arna huruf dalam cell tersebut menjadi merah, perubahan "arna ini mengindikasikan ke user bah"a inputan yang dimasukkan salah. Method is$ellMditable digunakan untuk mengetahui cell apa saja yang bisa diedit oleh user, dalam hal ini semua cell di kolom dengan indeL [ 7 3(uantitas5 bisa diedit. Method set@alue:t akan dipanggil oleh Jtable kalau user mengedit cell dalam Jtable. (arena hanya cell-cell di kolom (uantitas saja yang bisa diedit maka terdapat pengecekan terhadap parameter column ndeL. ,arameter a@alue berisi data yang diinput user ke dalam cell tersebut,

karena dalam method get$olumn$lass sudah di tentukan bah"a kolom (uantitas adalah nteger maka kita bisa melakukan casting langsung terhadap a@alue sebagai class nteger. Setelah itu dilakukan perhitungan sub total, total dan mengeset lblTotal untuk menampilkan total dari transaksi. Setelah property, method dan TableModel selesai dibuat, silahkan edit konstruktor dari class Sales,anel menjadi seperti berikut ini / public Sales4anel() { initDomponents() tblSales:etail.setIutoDreateDolumnsHromBodel(/alse) #dc9ransaction.set:ate(ne8 :ate()) enableHorm(/alse) btn:elete.set@nabled(/alse) btnIdd.set@nabled(true) btnDancel.set@nabled(/alse) btn@dit.set@nabled(/alse) btnSave.set@nabled(/alse) ! !erikutnya adalah kode-kode yang dieksekusi oleh setiap tombol-tombol di bagian atas Sales,anel / Tombol Tambah / private void btnIddIction4er/ormed(#ava.a8t.event.Iction@vent evt) { clearHorm() enableHorm(true) CCpengaturan tombol btn:elete.set@nabled(/alse) btnIdd.set@nabled(/alse) btnDancel.set@nabled(true) btn@dit.set@nabled(/alse) btnSave.set@nabled(true) ! Tombol Mdit / private void btn@ditIction4er/ormed(#ava.a8t.event.Iction@vent evt) { i/(sales!7null){ enableHorm(true) btn:elete.set@nabled(/alse) btnIdd.set@nabled(/alse) btnDancel.set@nabled(true) btn@dit.set@nabled(/alse) btnSave.set@nabled(true) ! ! Tombol +apus / private void btn:eleteIction4er/ormed(#ava.a8t.event.Iction@vent evt) { i/(sales!7null){ try{ Bain.getSalesService().delete(sales) clearHorm() sales 7 null re/res.9able() enableHorm(/alse) CCpengaturan tombol btn:elete.set@nabled(/alse) btnIdd.set@nabled(true) btnDancel.set@nabled(/alse)

! !

btn@dit.set@nabled(/alse) btnSave.set@nabled(/alse) ! catc.(@,ception e,){ log.error(e,) ]Aption4ane.s.o8Bessage:ialog(t.is+ *:ata masi. diguna0an tida0 bisa di.apus!* +*@rror*+]Aption4ane.@66A6(B@SSIS@) !

Tombol Simpan / private void btnSaveIction4er/ormed(#ava.a8t.event.Iction@vent evt) { i/(validateHorm()){ i/(sales 77 null){ sales 7 ne8 Sales() ! loadHorm9oBodel() try{ Bain.getSalesService().save(sales) clearHorm() re/res.9able() enableHorm(/alse) CCpengaturan tombol btn:elete.set@nabled(/alse) btnIdd.set@nabled(true) btnDancel.set@nabled(/alse) btn@dit.set@nabled(/alse) btnSave.set@nabled(/alse) ! catc.(@,ception e,){ log.error(e,) ]Aption4ane.s.o8Bessage:ialog(t.is+ *:ata gagal disimpan!* +*@rror*+]Aption4ane.@66A6(B@SSIS@) ! ! ! Tombol !atal / private void btnDancelIction4er/ormed(#ava.a8t.event.Iction@vent evt) { clearHorm() enableHorm(/alse) CCpengaturan tombol btn:elete.set@nabled(/alse) btnIdd.set@nabled(true) btnDancel.set@nabled(/alse) btn@dit.set@nabled(/alse) btnSave.set@nabled(/alse) ! Tombol $ari / private void btnSearc.Iction4er/ormed(#ava.a8t.event.Iction@vent evt) { Sales s 7 ne8 Sales;oo0up:ialog().getSales() i/(s!7null){ sales 7 Bain.getSalesService().getSales(s.get=d()) loadBodel9oHorm() CCedit mode btn:elete.set@nabled(true)

btnIdd.set@nabled(/alse) btnDancel.set@nabled(true) btn@dit.set@nabled(true) btnSave.set@nabled(/alse) ! !

Tombol cari di atas menggunakan class Sales.ookupDialog yang sudah dibuat sebelumnya, terlihat ada kode Sales s [ ne" Sales.ookupDialog35.getSales35D yang digunakan untuk memanggol Sales.ookupDialog, return dari method getSales bisa null atau ada nilainya. (alau ada nilainya berarti tombol H( yang ditekan, kalau nilainya null artinya tombol $ancel yang ditekan. Tombol (eluar / private void btn@,itIction4er/ormed(#ava.a8t.event.Iction@vent evt) { Bain.getHrame().sales4anel 7 null dispose() ! Tombol btn.ookup,roduct / private void btn;oo0up4roductIction4er/ormed(#ava.a8t.event.Iction@vent evt) { 4roduct p 7 ne8 4roduct;oo0up:ialog().get4roduct() i/(p!7null){ boolean is4roduct=nSales:etails 7 /alse /or (Sales:etail sales:etail 3 sales:etails) { i/(sales:etail.get=d()!7null YY sales:etail.get4roduct().get=d().e\uals(p.get=d())){ sales:etail.setbuantity(sales:etail.getbuantity() E %) sales:etail.setSubtotal(sales:etail.get4rice().multiply( ne8 >ig:ecimal(sales:etail.getbuantity()))) is4roduct=nSales:etails 7 true brea0 ! ! i/(is4roduct=nSales:etails){ re/res.9able() re/res.9otal;abel() ! else { addSales:etail(p) ! ! ! (etika user menekan enter di tLt,roduct d, atau ketika user melakukan barcode scan di tLt,roduct d maka event action,erformed dari tLt,roduct d akan dipanggil. Fntuk mendengarkan event action,erformed klik kanan di tLt,roduct d kemudian pilih Mvent C action,erformed dan tambahkan kode berikit ini dalam jendela $ode yang terbuka / private void t,t4roduct=dIction4er/ormed(#ava.a8t.event.Iction@vent evt) { String product=d 7 t,t4roduct=d.get9e,t() try { CCcari apa0a. barang suda. ada di dalam tblSales:etail ;ong p=d 7 ;ong.valueA/(product=d) boolean is4roduct=nSales:etails 7 /alse /or (Sales:etail sales:etail 3 sales:etails) { i/(sales:etail.get=d()!7null YY sales:etail.get4roduct().get=d().e\uals(p=d)){ sales:etail.setbuantity(sales:etail.getbuantity() E %) sales:etail.setSubtotal(sales:etail.get4rice().multiply( ne8 >ig:ecimal(sales:etail.getbuantity())))

! ! i/(is4roduct=nSales:etails){ re/res.9able() re/res.9otal;abel() ! else { 4roduct p 7 Bain.get4roductService().get4roduct(p=d) i/(p!7null){ addSales:etail(p) ! ! t,t4roduct=d.set9e,t(**) ! catc. (<umberHormat@,ception numberHormat@,ception) { ]Aption4ane.s.o8Bessage:ialog(t.is+ *=d barang .arus berupa ang0a!* +*@rror*+]Aption4ane.@66A6(B@SSIS@) !

is4roduct=nSales:etails 7 true brea0

Pang terakhir adalah menambahkan event Jinternal*rame closing dari class Sales,anel. $aranya dengan mengklik kanan Sales,anel kemudian pilih Mvents C nternal*rame C internal*rame$losing kemudian ubah kodenya seperti di ba"ah ini / private void /orm=nternalHrameDlosing(#ava,.s8ing.event.=nternalHrame@vent evt) { Bain.getHrame().sales4anel 7 null ! (ode di atas digunakan untuk mencegah Sales,anel dibuka berulang-ulang ketika menu Transaksi C ,enjualan dipilih user. Sebelum mencoba menjalankan aplikasi ,HS ini, perlu dibuat data ,roduct terlebih dahulu, karena tidak ada screen untuk menginput data ,roduct maka bisa kita lakukan insert langsung ke database. Jalankan \uery ini di dalam console -D!MS yang digunakan / insert into 9(46A:GD9(name+price) values (QindomieQ+%'R') insert into 9(46A:GD9(name+price) values (Q0ecap abcQ+5MR') insert into 9(46A:GD9(name+price) values (Qtraining #avaQ+)'%5MR') Sampai di sini kode untuk Data Transaksi selesai dibuat, sebagai bahan latihan silahkan buat ,urchase,anel yang kodenya mirip dengan Sales,anel hanya saja data yang diolah adalah ,urcahse. !agian berikutnya kita akan membahas bagaimana membuat report dengan Jasper-eport. -eport ini sangat penting untuk aplikasi bisanis, jenis report bisa bermacam-macam, bisa berupa report transaksi per harian yang berisi list data transaksi atau bisa juga berupa laporan perkembangan penjualan hari per hari yang ditampilkan dalam chart. .aporan pertama bisa dikategorikan sebagai laporan transaksi sedangkan yang kedua adalah jenis laporan Data Mining.

"A5IA@ $ Jas/er6e/orts

Jas$er)e$orts
'en!enalan
(onsep report sangat penting dalam aplikasi bisnis perusahaan, bahkan salah satu alasan kenapa semua transaksi harus dicatat adalah untuk membuat laporan keuangan. :da pertanyaan mungkin kenapa kok harus menggunakan library report seperti jasper iniZ :pakah tidak cukup menggunakan Jtable sajaZ Ja"abanya adalah dengan menggunakan library report seperti jasper kita bisa mendesain report dengan bantuan tools visual seperti i-eport. :lasan kedua adalah report bisa langsung di print karena formatnya sudah ready for print selain itu setelah report jadi, kita bisa eLport hasilnya ke berbagai format dokumen seperti ,D*, HpenHhce, MLcell dan #ords, bahkan bisa juga dieLport menjadi +TM.. Jasper-eports adalah library reporting paling populer di Java, kepopuleran Jasper-eports sangat ditunjang dengan adanya tools visual designer yaitu i-eport. Dengan menggunakan i-eports membuat report menjadi sangat cepat dan akurat. *eature-feature Jasper-eports juga sudah sangat lengkap, berikut ini adalah daftar featurenya yang diambil dari http/99jasperforge.org9projects9jasperreports / ,iLel-perfect page-oriented atau continuous output untuk "eb atau print Dashboards, tables, crosstabs, charts dan gauges #eb-based and piLel-perfect reports -eport output dalam format ,D*, ]M., +TM., $S@, ].S, -T*, T]T Sub-reports dapat dengan mudah digunakan untuk menampilkan layout yang kompleks Support barcode Dapat melakukan rotasi posisi teLt secara visual Styles library Drill-do"n 9 hyperteLt link, termasuk support untuk ,D* bookmarks Tidak ada batasan ukuran report $onditional printing Multi datasource dalam satu report nternationaliBed dan .ocaliBable

'ersiapan
Fntuk mulai bekerja dengan Jasper-eports kita perlu mendo"nload i-eport terlebih dahulu, installer i-eport dapat dido"nload dari / http/99sourceforge.net9projects9ireport9?les9i-eport9 Setelah proses do"nload selesai, kemudian silahkan install i-eport. ,roses instalasi sangat sederhana tinggal menekan tombol neLt, neLt, neLt. Setelah instalasi selesai, jalankan i-eport dan anda akan melihat tampilan i-eport. Tampilan i-eport mirip dengan 0et!eans, hal ini dikarenakan i-eport dikembangkan menggunakan 0et!eans ,latform. (ita akan bahas lebih banyak mengenai i-eport di bab-bab selanjutnya ketika membahas bagaimana caranya membuat laporan transaksi harian. ,ersiapan berikutnya adalah menambahkan library Jasper-eports ke dalam project ,HS. ,ada "aktu buku ini ditulis, versi Jasper-eports terbaru adalah 7.'.; dan Jar-jar yang dibutuhkan untuk mencompile dan menjalankan Jasper-eports 7.'.; ini antara lain /

commons-beanutils-).6.%.jar commons-collections-7.%.).jar commons-digester-).'.jar commons-javaUo"-%&&;&<)).jar commons-logging-).).jar groovy-all-).'.4.jar jasperreports-7.'.;.jar

:nda bisa mendo"nload Jasper-eports dari link di ba"ah ini / http/99sourceforge.net9projects9jasperreports9 atau mencari jar-jar di atas dari folder instalasi i-eport. (emudian tambahkan ke dalam folder lib dari project 0et!eans, dan terakhir tambahkan semua jar di atas ke dalam library project. Setelah proses persiapan selesai kita siap untuk membuat .aporan Transaksi +arian.

+aporan -ransaksi Harian


Dalam buku ini kita akan belajar membuat laporan tranksaksi harian, laporan ini ditampilkan dalam menu yang ada fasilitas pemilihan tanggal transaksi yang akan dibuatkan reportnya. .aporan transaksi harian terlihat seperti gambar di ba"ah ini /

Terlihat di bagian atas terdapat date chooser yang digunakan untuk memilih tanggal kemudian ada tombol H( untuk menampilkan report dan repor yang sudah dibuat ditampilkan di ba"ahnya menggunakan komponen Jasper-eports yaitu J-@ie"er. Fntuk membuat laporan di atas, diperlukan ?le reportnya yang dibuat menggunakan i-eport, kemudian Jinternal*rame untuk nemampilkan report dalam aplikasi dan -eportService yang digunakan untuk melakukan akses ke database dan mendapatkan data reportnya. Mari kita bahas satu per satu cara membuatnya.

Mem"uat Jas$er)e$orts Menggunakan i)e$ort %isual Designer


Di bab sebelumnya kita sudah membahas instalasi i-eport, sekarang kita bahas lebih lanjut bagaimana membuat report menggunakan i-eport ini. .angkah pertama adalah dengan membuat report baru dari i-eport. ,ilih menu *ile C 0e", kemudian di dialog yang muncul pilih -eport C !lank :<, simpan ?le reportnya dengan nama DailySales-eport.jrLml, letakkan di dalam folder src9reports dari project anda. Setelah proses pembuatan ?le report baru selesai, tampilan a"al i-eport bisa dilihat seperti gambar di ba"ah ini.

Sebelah (iri ada jendela -eport nspector yang berisi komponen-komponen yang ada dalam report. !agian terpenting yang berhubungan dengan kode kita nanti adalah ,armeters, *ields dan @ariables, kita akan bahas lebih banyak tentang ketiganya di bagian selanjutnya. (emudian di bagian tengah ada !and atau area dari report, ada title, page header, column header, detail, colomn footer dan summary. Sebelah kanan ada pallate yang berisi komponen-komponen report seperti garis, teLt, subreport, kotak, gambar dan lain-lainya. !iasanya untuk laporan keuangan komponen yang diletakkan dalam report cukup minimalis, hal ini dimasksudkan untuk menghemat tinta ketika diprint di kertas. Di ba"ah ,allete ada jendela ,roperties yang digunakan untuk mengedit property dari komponen report. !and Title digunakan untuk meletakkan judul dari report, komponen yang digunakan untuk judul adalah static teLt yang diubah font-nya agar kelihatan lebih besar.

!and ,age +eader digunkan kalau akan menampilkan sesuatu yang selalu ada di setiap halaman, misalnya nomer halaman report dan tanggal transaksi. !and $olumn +eader digunakan untuk menampilkan header column dari reportnya. !and Detail berisi ?eld-?eld yang akan ditampilkan, jadi nanti kita akan membuat tiga buah ?eld yaitu nama barang, jumlah dan subtotal untuk ditampilkan di report ini. !and $olumn *ooter digunakan untuk menampilkan sesuati setiap kolom selesai, dalam report ini tidak digunakan. !and ,age *ooter digunakan untuk menampilkan sesuatu di bagian ba"ah page, bisa digunakan untuk menampilkan halaman atau sub total setiap halaman report. !and Summary digunakan untuk menampilkan sesuatu di akhir dari report, misalnya menampilkan grand total atau misalnya tempat untuk tanda tangan. Setelah mengetahui bagian-bagian dari i-eport kita bisa mulai untuk menyusun reportnya, dimulai dari membuat *ield.

Mem"uat 4ield
,ada bagian sebelumnya di bab tentang +ibernate, kita sempat membahas class DailySales-eport yang digunakan untuk kepentingan report. *ield yang harus dibuat dalam report harus sama persis dengan property yang dimiliki oleh class DailySales-eport. Mari kita lihat class DailySales-eport / public class :ailySales6eport { private String product<ame private ;ong \uantity private >ig:ecimal sub9otal public String get4roduct<ame() { return product<ame ! public void set4roduct<ame(String product<ame) { t.is.product<ame 7 product<ame ! public ;ong getbuantity() { return \uantity ! public void setbuantity(;ong \uantity) { t.is.\uantity 7 \uantity ! public >ig:ecimal getSub9otal() { return sub9otal ! public void setSub9otal(>ig:ecimal sub9otal) { t.is.sub9otal 7 sub9otal ! ! (ita lihat di dalam class DailySales-eport di atas mempunyai tiga buah property yaitu product0ame, \uantity dan subTotal. Mari kita buat ketiga buah ?eld tersebut di dalam report, caranya dengan klik kanan node *ields C :dd *ield seperti gambar di ba"ah ini

Setelah ?eld di buat jangan lupa untuk merubah tipe dari ?eld di jendela properties sebelah kanan. Tipe ?eld harus sama persis dengan tipe property dalam class DailySales-eport, kalau tidak sama akan mengakibatkan $lass$astMLception. (emudian kita drag ?eld-?eld tersebut ke jendela sebelah kanan di bagian details, tambahkan kolom header yang sesuai dengan ?eldnya. +asilnya bisa dilihat di gambar di ba"ah ini /

Seperti kita lihat di atas, untuk ?eld angka gunakan +oriBontal :lign kanan agar posisi digit bisa dibandingkan dengan baris atasnya. !erikutnya kita akan menambahkan sum dari \uantity dan subTotal yang diletakkan di !and Summary agar ditampilkan sekali saja di akhir dari report. Fntuk membuat sum kita akan menambahkan @ariables, caranya dengan mengklik kanan @ariables C :dd @ariable, kemudian ganti nama variablenya menjadi SFMSIF:0T TP dan setting properties-nya seperti gambar di ba"ah ini /

Terlihat dari gambar di atas bah"a variabel name adalah SFMSIF:0T TP, class-nya sama persis dengan ?eld \uantity yaity java.lang..ong dan calculation Sum. !uat satu lagi variabel dengan nama SFMSSF!THT:. dengan tipe !igDecimal dan calculation Sum. (emudian letakkan kedua variabel tersebut di !and Summary, seperti gambar di ba"ah ini /

Terlihat bah"a setelah !and Detail langsung ada !and Summary sedangkan !and lain tidak terlihat, kita bisa mendrag !and-band tersebut hingga tingginya menjadi nol dan tidak terlihat lagi. (ita bisa mensetting ?eld dan variabel yang bertipe uang seperti subTotal dan SFMSSF!THT:. agar menggunakan format ribuan, caranya dengan mengganti ,attern dari keduanya. ,ilih subTotal dan SFMSSF!THT:. di jendela Designer, kemudian edit properties pattern dari jendela ,roperties, akan muncul dialog ,attern seperti gambar di ba"ah ini. ,ilih Decimal placess menjadi & atau angka yang dikehendaki, kemudian check combo boL Fse )&&& Sparator dan pilih pattern untuk 0egative numbers. .angkah selanjutnya adalah menambahkan nomor halaman di setiap halaman report, caranya dengan mendrag ke variabel ,:KMS0FM!M- yang sudah disediakan oleh Jasper-eports. .etakkan variabel ,:KMS0FM!M- di !and ,age +eader atau !and ,age *ooter, tergantung design dari report yang dikehendaki. !erikutnya adalah menambahkan tanggal dari laporan, misalnya kita ingin menampilkan laporan penjualan tanggal tertentu maka harus ada parameter tanggal yang dilempar ke report. $aranya adalah dengan membuat sebuah ,arameters dengan tipe java.util.Date, klik kanan di node

,arameters C :dd ,arameter dan beri nama date untuk parameter tersebut, kemudian drag parameter date dan letakkan di !and ,age +eader. *ormat tanggal bisa dirubah dengan mengedit properties pattern.

.angkah terakhir adalah menambahkan judul dari laporan dengan mendrag sebuag Static TeLt, beri judul E.:,H-:0 T-:0S:(S +:- :0G kemudian ubah font agar terlihat lebih besar. :gar tampilan laporan menjadi sedikit rapi, bisa ditambahkan garis untuk membatasi !and $olumn +eader, !and Detail dan !and Summary. +asil akhir dari report ini bisa dilihat seperti gambar di ba"ah ini /

,roses pembuatan DailySales-eport.jrLml sudah selesai, berikutnya kita tambahkan utility untuk mengcompile ?le .jrLml menjadi ?le .jasper

Mencom$ile 4ile #r,ml Men#adi #as$er Menggunakan Ant &ask


,roses pembentukan report di Jasper-eport dimulai dengan membuat design report, hasilnya adalah ?le jrLml. Setelah itu ?le jrLml akan dicompile menjadi ?le jasper, pada "aktu aplikasi berjalan ?le jasper ini akan diload dan diisi dengan data menjadi object Jasper,rint, nah object ini sudah berisi data-data yang diperlukan untuk diubah menjadi berbagai format dokumen seperti ,D*, MLcell atau #ords menggunakan JasperMLporter. :tau bisa juga Jasper,rint ditampilkan ke dalam komponen S"ing yaity J-@ie"er. ,roses kompilasi dari jrLml ke jasper bisa menggunakan i-eport dengan mengklik kanan node -eport-nya dan pilih menu $ompile -eport seperti gambar di halaman selanjutnya. +asil kompilasi berupa ?le jasper bisa diambil di folder yang ditampilkan di jendela -eport Hutput. Tetapi proses ini harus dilakukan setiap kali reportnya di ubah, ada kemungkinan lupa

mengcompile ?le-nya sehingga perubahan report-nya tidak terlihat.

$ara yang lebih baik adalah dengan membuat sebuah :nt Task untuk mengcompile semua ?le report setiap kali project 0et!eans di-$lean :nd !uild. Sebelum kita lanjutkan untuk membuat kode-nya, sedikit kita bahas apa itu :nt. :nt adalah build script tools yang digunakan untuk melakukan compile ?le .java, kemudian membuat jar dan juga bisa digunakan untuk menjalankan aplikasi yang sedang didevelop. !ahkan 0et!eans di belakang layar menggunakan :nt inti untuk semua kegiatanya, dari proses build hingga menjalankan application server atau menjalankan emulator Java MM. Semuanya dilaksanakan menggunakan :nt script. Dalam :nt script ada EtargetG dimana target adalah satu blok script yang bisa dieksekusi. Setiap kali ingin menbuat sebuah EtaskG yang dibuat adalah target ini. !entuk :nt Script adalah ?le ]M., anda bisa membuka :nt Script dari project 0et!eans yang sekarang sedang kita kerjakan dengan membuka folder nbproject dan cari ?le build-impl.Lml atau ?le build.Lml yang ada di root folder dari project 0et!eans. *ile build-impl.Lml adalah jantung dari project 0et!eans, jadi tidak boleh diedit secara manual sama sekali, sedangkan ?le build.Lml bisa diedit dengan memasangkan task yang ingin kita eksekusi. Dalam build.Lml ada beberapa target dengan nama spesial, target-target ini dieksekusi setelah perintah tertentu di dalam 0et!eans selesai dilaksanakan. Misalnya target E-post-compileG akan dilaksanakan setelah proses compile di 0et!eans selesai. Satu lagi istilah dalam :nt yang perlu diketahui, yaitu Taskdef. Setiap jenis task dalam :nt pada dasarnya adalah kode Java, nah taskdef ini digunakan untuk memapping antara istilah dalam :nt dan kode Java sebenarnya. Misalnya kita nanti akan mende?nisikan sebuah task yang tugasnya mencompile ?le jrLml menjadi ?le jasper, yang kita lakukan pertama kali adalah mende?nisikan task apa yang akan digunakan dan nama class untuk task tersebut. .ebih jauh mengenai :nt bisa dibaca dari "ebsite ant.apache.org Mari kita lihat kode :nt script yang ditambahkan dalam build.Lml untuk mengcompile ?le jrLml menjadi jasper di ba"ah ini / Ttas0de/ name7*#rc* classname7*net.s/.#asperreports.ant.]6IntDompile9as0*V Tclasspat.V T/ileset dir7*.Clib*V Tinclude name7*LLCL.#ar*CV TC/ilesetV TCclasspat.V TCtas0de/V Ttarget name7*$post$compile*V Tm0dir dir7*.CbuildCreports*CV

TdeleteV T/ileset /ile7*.CsrcCreportsCL.#asper*CV TCdeleteV T#rc srcdir7*.CsrcCreports* destdir7*.CsrcCreports* tempdir7*.CbuildCreports* 0eep#ava7*true* ,mlvalidation7*true*V Tinclude name7*LLCL.#r,ml*CV TC#rcV TCtargetV Seperti kita lihat di atas, :nt script dimulai dengan de?nisi taskdef jrc yang ditambahkan classpath dimana ?le-?le jar yang dibutuhkan untuk mencompile jrLml berada. Di ba"ahnya ada target dengan nama -post-compile, target ini dieksekusi setiap kali 0et!eans selesai mengcompile ? le-?le .java, di dalamnya ada script untuk membuat folder 3mkdir5, kemudian menghapus semua ?le jasper dan terakhir menggunakan taskdef jrc. $oba klik kanan project di 0et!eans kemudian pilih $lean and !uild, script di atas akan dieksekusi dan output dari script ini bisa dilihat di jendela Hutput / Dreated dir3 CGsersCi/nuC<et>eans4ro#ectsC#ava$des0top$boo0CcodeCbuildCreports Dompiling % report design /iles. log5#3WI6< <o appenders could be /ound /or logger (net.s/.#asperreports.engine.,ml.]6Jml:igesterHactory). log5#3WI6< 4lease initiali?e t.e log5# system properly. Hile 3 CGsersCi/nuC<et>eans4ro#ectsC#ava$des0top$ boo0CcodeCsrcCreportsC:ailySales6eport.#r,ml ... AK. -eport sudah siap, :nt Script sudah bisa mengcompile ?le jrLml, langkah berikutnya adalah menyiapkan -eportService untuk mengambil data dari database dan memasukkan datanya ke dalam jasper.

Mem$ersia$kan )e$ort*ervice
Seperti halnya modul-modul lain dalam aplikasi, kita membutuhkan service untuk mengambil data dari database. Dalam hal ini adalah -eportService, berbeda dengan service-service yang lain -eportService tidak memerlukan D:H, hal ini dikarenakan \uery untuk report selalu custom dan kita hanya memerlukan kolom-kolom yang ditampilkan dalam report saja, sedangkan kolom-kolom lain tidak diperlukan. Dengan cara seperti ini, proses \uery ke database menjadi lebih e?sien. !erikut ini kode untuk interface -eportService yang di letakkan dalam package yang sama dengan interface service lainya. public inter/ace 6eportService { ]asper4rint get:ailySales6eport(:ate date) ! (ode implementasi dari -eportService, yaitu -eportService mpl ^Service(*reportService*) ^9ransactional(readAnly7true) public class 6eportService=mpl implements 6eportService{ private static /inal ;ogger log 7 ;ogger.get;ogger(6eportService=mpl.class) ^Iuto8ired private SessionHactory sessionHactory public ]asper4rint get:ailySales6eport(:ate date) { try{ ;istT:ailySales6eportV dailySales6eports 7 sessionHactory.getDurrentSession() .createbuery(*select s.product.name as product<ame+* E * sum(s.\uantity) as \uantity+ * E * sum(s.subtotal) as sub9otal /rom Sales:etail s *

E * 8.ere day(s.sales.sales:ate) 7 day(3date) * E * group by s.product.name order by s.product.name*) .set4arameter(*date*+ date) .set6esult9rans/ormer( 9rans/ormers.alias9o>ean(:ailySales6eport.class)) .list() =nputStream is 7 6eportService=mpl.class .get6esourceIsStream(*CreportsC:ailySales6eport.#asper*) BapTString+Ab#ectV parameters 7 ne8 Has.BapTString+ Ab#ectV() parameters.put(*date*+ date) return ]asperHillBanager./ill6eport(is+ parameters+ ne8 ]6>eanDollection:ataSource(dailySales6eports)) !catc.(]6@,ception e,){ log.error(*error generate :ailySales6eport*+ e,) ! return null !

Mari kita bahas satu per satu kode di atas. Di bagian paling atas terdapat annotation Spring yaitu 8Service dan 8Transactional, kita sudah membahas panjang lebar mengenai kedua annotation ini. !erikutnya ada annotation dari Spring juga yaitu 8:uto"ired untuk menginject Session*actory ke dalam -eportService mpl ini. :da juga kode untuk menginisialisasi .ogger dari log<j. !agian berikutnya ada kode untuk mengeksekusi +I., \uery +I. yang dieksekusi adalah / select s.product.name as product<ame+ sum(s.\uantity) as \uantity+ sum(s.subtotal) as sub9otal /rom Sales:etail s 8.ere day(s.sales.sales:ate) 7 day(3date) group by s.product.name order by s.product.name +I. di atas melakukan \uery ke database untuk mendapatkan nama barang, jumlah dari barang tersebut dan jumlah subtotal-nya. *ungsi day digunakan untuk membandingkan hanya tanggal saja tanpa memperhatikan "aktu-nya. Kroup by digunakan untuk menjumlahkan jumlah barang dan subtotal berdasarkan nama barangnya. Hrder by digunakan untuk mengurutkan data berdasarkan nama barang. +I. di atas menyederhanakan SI. cukup signi?kan, hal ini dikarenakan kita tidak perlu melakukan join antara tiga buah table/ TS,-HDF$T, TSS:.MS dan TSS:.MSSDMT: .. $ukup select dari SalesDetail dan gunakan operator . 3titik5 untuk mengakses kolom lain yang berelasi dengan Mntity SalesDetail. Method set,arameter digunakan untuk memasukkan parameter tanggal transaksi ke dalam +I.. Sedangkan method set-esultTransformer digunakan untuk mentransformasi hasil \uery menjadi sebuah .ist of $lass. (alau tidak menggunakan set-esultTransformer maka hasil \uery di atas adalah .istAHbject=>C, dimana proses memasukkan data dengan struktur tersebut ke dalam report menjadi sedikit lebih susah. (arena Transformer yang digunakan adalah aliasTo!ean maka setiap kolom yang diselect harus ditambahkan as dan diikuti dengan nama properties dari class DailySales-eport. #alaupun nama kolom yang diselect dalam h\l sama persis dengan nama properties dari class DailySales-eport, as tetap harus dide?nisikan. (ode berikutnya digunakan untuk meload ?le jasper dari ?lesystem, kenapa harus menggunakan kode seperti di ba"ah ini Z =nputStream is 7 6eportService=mpl.class.get6esourceIsStream(*CreportsC:ailySales6eport.#asper*)

+al ini dikarenakan nantinya ?le jasper di atas akan diletakkan dalam jar. (ode di ba"ah ini bisa juga digunakan untuk meload ?le jasper, tetapi hanya bisa berjalan kalau aplikasi dijalankan dari 8et eans, kalau aplikasi dijalankan tanpa netbeans dlangsung dari jar yang dihasilkan, maka kodenya menjadi error / =nputStream is 7 ne8 Hile=nputStream(*srcCreportsC:ailySales6eport.#asper*) Mrror yang muncul adalah *ile0ot*oundMLception dikarenakan pada "aktu aplikasi sudah diinstall, tidak ada lagi ?lder src dan ?le jasper berada di dalam jar. (ode berikutnya digunakan untuk melempar ,arameters dari kode java ke dalam report. Struktur yang digunakan adalah Map, dimana key bertipe String dan value bertipe Hbject. 0ilai key harus sama dengan nama parameter di dalam report dan tipe dari value-nya harus sama persis dengan tipe value di dalam ,arameter report. (alau kita lihat kembali di bagian sebelumnya, report DailySales-eport hanya mempunyai satu ,arameters bernama EdateG dengan tipe java.util.Date. (ode terakhir digunakan untuk mengisi reprort dengan data yang sudah diambil dari database. -eturn dari method ini adalah Jasper,rint yang bisa ditampilkan dalam komponen J-@ie"er. (ita juga perlu memodi?kasi class Main untuk memegang instance dari -eportService ini. (ode class Main menjadi seperti berikut ini / public class Bain { private private private private private static static static static static SecurityService securityService SalesService salesService 4roductService productService 6eportService reportService BainHrame /rame

public static SecurityService getSecurityService() { return securityService ! public static SalesService getSalesService() { return salesService ! public static 6eportService get6eportService() { return reportService ! public static 4roductService get4roductService() { return productService ! public static BainHrame getHrame() { return /rame ! public static void main(String[] args) { #ava.a8t.@ventbueue.invo0e;ater(ne8 6unnable() { public void run() { IpplicationDonte,t applicationDonte,t 7 ne8 Dlass4at.JmlIpplicationDonte,t(*applicationDonte,t.,ml*) securityService 7 (SecurityService) applicationDonte,t.get>ean(*securityService*) salesService 7 (SalesService) applicationDonte,t.get>ean(*salesService*) productService 7 (4roductService) applicationDonte,t.get>ean(*productService*) reportService 7 (6eportService) applicationDonte,t.get>ean(*reportService*) /rame 7 ne8 BainHrame()

/rame.setPisible(true) !) ! ! !

.angkah berikutnya adalah membuat F untuk menampilkan report di atas. Main*rame perlu ditambahkan satu menu dan membuat class DailySales-eport,anel yang bertipe Jinternal*rame.

Mem"uat .I )e$ort
.angkah pertama adalah mengubah Main*rame dengan menambahkan satu menu baru untuk report. ,erhatikan gambar di ba"ah ini /

mnu-eport adalah Jmenu yang diletakkan dalam menu!ar dan mnuDailySales-eport adalah Jmenu tem yang diletakkan di ba"ah mnu-eport. Tambahkan event action,erformed di dalam mnuDailySales-eport, jendela $ode akan terbuka dan tambahkan kode di ba"ah ini / public :ailySales6eport4anel dailySales6eport4anel private void mnu:ailySales6eportIction4er/ormed(#ava.a8t.event.Iction@vent evt) { try { i/ (dailySales6eport4anel 77 null) { dailySales6eport4anel 7 ne8 :ailySales6eport4anel() des0top4ane.add(dailySales6eport4anel) ! else { dailySales6eport4anel.toHront() ! dailySales6eport4anel.setPisible(true) dailySales6eport4anel.setSelected(true) dailySales6eport4anel.setSi?e(des0top4ane.getSi?e()) ! catc. (4ropertyPeto@,ception e,) { log.error(*error 0eti0a menampil0an sales panel*+ e,) ! ! !erikutnya kita akan membuat DailySales-eport,anel, pilih menu *ile C 0e" kemudian di dialog yang muncul pilih S"ing KF *orm C Jinternal*rame *orm. .etakkan dalam package com.googlecode.projecttemplate.pos.ui.reports

$lass DailySales-eport,anel di atas terdiri dari sebuah label Tanggal, kemudian Jdate$hooser jdcTransactionDate, di ba"ahnya ada dua buah Jbutton yaitu btnHk dan btnMLit. Di bagian paling ba"ah ditandai dengan garis coklat-kuning adalah Jpanel pnl-eport. Jpanel di bagian paling ba"ah ini digunakan untuk menampilkan J-@ie"er dari Jasper-eport. .ayout dari pnl-eport harus diganti dengan !order.ayout agar J-@ie"er yang ditampilkan menempati penuh pnl-eport. $ara mengubah layoutnya adalah dengan mengklik kanan pnl-eport kemudian pilih menu Set .ayout C !order .ayout. Setelah screen siap, mari kita lihat kode apa saja yang ada dalam class ini. ,ertama kita lihat konstruktornya / public :ailySales6eport4anel() { initDomponents() #dc9ransaction:ate.set:ate(ne8 :ate()) ! (ode di atas hanya melakukan satu hal yaitu mengeset tanggal dari jdcTransactionDate dengan tanggal hari ini. (edua adalah kode ketika tombol (eluar ditekan, untuk memasang listener ketika tombol (eluar ditekan bisa dilakukan dengan mengklik dua kali tombol (eluar atau klik kanan tombol keluar kemudian pilih Mvents C action,erformed. private void btn@,itIction4er/ormed(#ava.a8t.event.Iction@vent evt) { Bain.getHrame().dailySales6eport4anel 7 null dispose() ! (ode di atas tidak jauh berbeda dengan semua kode untuk tombol (eluar yang sudah kita tulis di bagian-bagian sebelumnya. !erikutnya kita harus memasang listener ketika user menekan icon ] dan menutup Jinternal*rame, kode yang harus dieksekusi hanya mengeset variabel dailySales-eport di

dalam frame menjadi null. +al ini diperlukan untuk mencegah Jinternal*rame dibuka double ketika user menekan menu .aporan ,enjualan +arian ditekan berkali-kali. (lik kanan DailySales-eport,anel di jendela Design kemudian pilih Mvents C nternal*rame C internal*rame$losing private void /orm=nternalHrameDlosing(#ava,.s8ing.event.=nternalHrame@vent evt){ Bain.getHrame().dailySales6eport4anel 7 null ! (ode terakhir adalah listener ketika tombol H( ditekan. Di dalamnya ada kode untuk memanggil -eportService kemudian membuat object J-@ie"er yang dipasang di dalam pnl-eport dan update F -nya agar tampilan pnl-eport direfresh / private void btnA0Iction4er/ormed(#ava.a8t.event.Iction@vent evt) { ]asper4rint print 7 Bain.get6eportService().get:ailySales6eport( #dc9ransaction:ate.get:ate()) ]6Pie8er vie8er 7 ne8 ]6Pie8er(print) pnl6eport.removeIll() pnl6eport.add(vie8er+>order;ayout.D@<9@6) pnl6eport.updateG=() ! 0ah sekarang kode-nya sudah selesai, silahkan jalankan aplikasi-nya dan pastikan tidak ada error pada "aktu menampilkan report. ,roses pembuatan report selanjutnya sama dengan langkah-langkah yang sudah kita kerjakan, a"ali dengan mempersiapkan report, usahakan report yang dibuat cukup sederhana, kemudian lakukan \uery dan pengolahan data agar mudah ditampilkan di dalam report. !erikutnya adalah mempersiapkan F dengan parameter-parameter yang diperlukan oleh report. !est practice yang saya ikuti adalah buat report sesederhana mungkin pada "aktu mendesign, kemudian lakukan pengolahan data di dalam kode Java. +al ini lebih mudah dilakukan karena proses logic yang terlalu rumit di dalam report menjadi susah dipahahami. .ebih baik pengolahan data yang rumit dilakukan di dalam kode Java. Tetapi perlu diperhatikan juga bah"a semua data report diload ke dalam aplikasi menjadi .ist, kalau ukuran data dalam database sangat besar hingga ribuan baris, maka aplikasi rentan terkena HutHfMemoryMLception. Jika hal tersebut tidak bisa dihindari, sebaiknya gunakan \uery atau Stored,rocedure yang dipanggil dari ?le report. (emudian detail koneksi database harus menggunakan username yang hanya bisa membaca database saja, jangan sampai menyimpan informasi Super Fser database di dalam report.

"A5IA@ ' A60I48K4:6 4H688 4I86

Arsitektur &hree &ier


Selama ini aplikasi desktop sebagian besar menggunakan arsitektur $lient Server, dimana client akan langsung melakukan koneksi ke database. (onsep ini dipopulerkan oleh Microsoft bersama dengan platform @!. (onsep utamanya adalah meletakkan bisnis proses dan logic aplikasi di dalam server database le"at Stored ,rocedure dan Trigger. !elakangan konsep client-server mulai mendapat tantangan dengan berkembangnya jaringan internet. ,erusahaan ingin membuat aplikasi desktop namun kantor-kantor cabang tersebar di beberapa tempat, jika masih ingin menggunakan arsitektur client-server le"at jaringan internet, maka banyak sekali pertimbangan keamanan yang perlu diperhatikan, karena membuka port database di jalur internet bukanlah ide yang baik dari sisi security. Masalah lain adalah lisensi, banyak database vendor yang memberlakukan lisensi per user untuk menentukan harga lisensi. Dengan arsitektur client server, setiap client harus menggunakan user yang berbeda sehingga secara drastis menaikkan harga lisensi mana kala ada ratusan client terhubung ke server. Masalah lain yang muncul adalah jika client menggunakan koneksi dialup miskin band"ith, komunikasi client ke server akan sedikit terganggu 3corupt5. Selain alasan di atas, alasan performance tuning juga menjadi perhatian kalau menggunakan arsitektur client server. Misalnya clientnya sudah membengkak menjadi ratusan, maka server 3database5 harus melayani semua client tersebut, kalau database sudah tidak sanggup lagi maka harus beli hard"are lebih besar dan migrasi dari hard"are lama. :rsitektur Three tier dapat mengatasi hal ini dengan membebankan sebagian pekerjaan ke Server :plikasi, sehingga database server tidak bekerja sendirian. Teknologi-teknologi baru seperti cache dan +ibernate Search dapat meningkatkan kinerja aplikasi secara keseluruhan dengan meminimalisasi hit ke database. Dimana database connection sering kali menjadi bottleneck dalam aplikasi dengan ukuran data yang sangat besar. Fkuran data yang besar memunculkan masalah serius, yaitu slo" \uery. +al ini terjadi karena proses select-join dilakukan dalam table yang berukuran sangat besar :rsitektur aplikasi three tier membagi aplikasi menjadi tiga lapisan. .apisan pertama berada di sini client, lapisan pertama tidak terhubung langsung ke database melainkan terhubung ke lapisan kedua yaitu :pplication server, koneksi ke database berada di application server. (euntungan utamanya adalah setiap client tidak perlu mempunyai user dalam database, koneksi ke database bisa dipool di dalam application server, sehingga bisa dikelola see?sien mungkin. .apisan terakhir adalah database sebagai tempat penyimpanan data permanen. :rsitektur three tier tidak menyaratkan semua lapisan harus dijalankan dalam server ?sik yang berbeda, bisa saja dari client, application server hingga database server dijalankan dalam satu server. Tetapi arsitektur ini mempunyai Ueksibilitas tinggi sehingga kalau load aplikasi menjadi besar, setiap lapisan bisa dipisahkan menjadi beberapa server ?sik. :da juga alasan keamanan yang menjadikan arsitektur ini sangat strategis, berdasarkan level sensiti?tasnya, database berada di level paling dalam dari aplikasi yang disebut dengan area DMf 3demiliteriBed fone5. :rea DMf ini hanya bisa diakses dari net"ork internal saja dan hanya sedikit sekali orang yang mempunyai akses ke dalam area ini. Sehingga antar setiap lapisan bisa di?lter menggunakan ?re"all yang makin ke dalam makin strict aturanya. Misalnya application server hanya bisa diakses dari , yang diijinkan saja, kemudian ditambah satu lagi ?re"all antara application server dengan database dimana hanya , application server plus , untuk administrasi saja yang bisa melakukan koneksi. (oneksi antara client ke application server menggunakan protokol yang disebut remoting. :lternatif remoting di Java sangat banyak, pilih salah satu alternatif yang sesuai dengan infrastruktur dan kebutuhan. Di ba"ah ini adalah matriks perbandingan antara berbagai macam remoting yang bisa digunakan /

Matriks Per"andingan antar $rotokol remoting


7emotin g Jenis 7emo ting #rotok ol Iteroper ability dengan plat!orm lain +anya aplikasi Java Java, $Q Q, ,ython dll Java dan harus pake spring Java dan library hessian Java dan library hessian Semua platform bisa Semua platform bisa. :pache +TT,$lie nt Implementa si 4ebutuhan bandwith

-M

!inary

T$, socket T$, socket

MJ!, murni

-M

Sangat besar, cocok di intranet

$H-!:

!inary

mplementasi sudah jarang, nyaris absolete Spring remoting

Sangat besar, cocok di intranet

Spring +TT,inv oker +essian

!inary

+TT,

$ukup besar, cocok untuk intranet

!inary

+TT,

+essian

$ukup besar, cocok untuk intranet

+essian

TeLt 9 ]M. TeLt 9 ]M. TeLt 9 json 9 ]M.

+TT,

+essian

$ocok untuk berbasis teLt $ocok untuk berbasis teLt $ocok untuk berbasis teL

internet,

karena

#ebservi ce +TT, call "ith json9]M.

+TT,

J:]-#S, Spring :Lis%

internet,

karena

#S,

+TT,

Jakson, JSH0 lib,

internet,

karena

Jika aplikasi akan di jalankan dalam lingkungan intranet dimana band"ith dan stabilitas koneksi tidak menjadi masalah maka pilihan remoting bisa dijatuhkan kepada Spring -emoting menggunakan protokol +TT, nvoker. Jika aplikasi di sisi server akan dieLpose ke internet sehingga band"ith menjadi sangat penting dan stabilitas koneksi tidak bisa dihandalkan maka remoting menggunakan menggunakan +TT, call dengan format data ]M.9JSH0 menjadi pilihan yang tepat. +al ini dikarenakan kalau paket data berupa binary dan urutan datangnya paket tidak beraturan maka pake binary akan menjadi corrupt dan tidak bisa oleh penerima. (euntungan +TT, nvoker adalah kode untuk komunikasi antara client dengan application server menjadi sangat sederhana menggunakan feature Spring -emoting. Tidak ada perubahan kode sama sekali, hanya perlu ditambahkan kon?gurasi untuk server dan kon?gurasi untuk cleint. Sangat mengesankan.

Im$lementasi Arsitektur &hree &ier


(ode yang sudah kita buat di tujuh bab sebelumnya tidak banyak berubah, hanya saja semua Mntity harus mengimplementasikan interface SerialiBable. +al ini dikarenakan setiap object yang akan dikirim dari client ke application server atau sebaliknya akan dirubah menjadi binary data kemudian ditransfer le"at jaringan dan di tujuan akan disusun lagi menjadi object di dalam Java. ,roses transfer object dari satu tempat ke tempat yang lain menyaratkan bah"a class dari object tersebut harus mengimplementasikan interface SerialiBable dan semua property di dalam class tersebut harus juga mengimplementasikan interface SerialiBable.

.ihat package com.googlecode.projecttemplate.pos.model dan pastikan semua class di dalam package tersebut implements SerialiBable. ,erhatikan pula di semua Service yang ditulis, method save dan delet akan mengembalikan object Mntity, hal ini dimaksudkan agar client dapat memperoleh object yang sudah dimanipulasi dalam database. Misalnya pada "aktu save property id dari Mntity bernilai null kalau datanya masih baru, id tersebut akan diset di server pada "aktu proses save selesai dan diisi nilai yang digenerate dari database. Hbject Mntity yang ada di client nilai id-nya masih null sehingga perlu diupdate dengan object yang dikembalikan oleh server. mplementasi three tier menggunakan Spring sangat mudah, perubahan kode Java sangat minimal dan hanya perlu menambahkan dua buah kon?gurasi masing-masing untuk client dan server. ,erubahan kode Java hanya membuat satu buah class untuk start server dan sedikit perubahan di class Main. Pang pertama akan kita lakukan adalah membuat kon?gurasi untuk Server-nya. !uat sebuah Lml di dalam folder src, namakan dengan server$onteLt.Lml, kemudian isikan kode berikut ini di dalam server$onteLt.Lml / TW,ml version7*%.'* encoding7*G9H$N*WV Tbeans ,mlns7*.ttp3CC888.spring/rame8or0.orgCsc.emaCbeans* ,mlns3,si7*.ttp3CC888.81.orgC)''%CJB;Sc.ema$instance* ,mlns3conte,t7*.ttp3CC888.spring/rame8or0.orgCsc.emaCconte,t* ,mlns3t,7*.ttp3CC888.spring/rame8or0.orgCsc.emaCt,* ,mlns3p7*.ttp3CC888.spring/rame8or0.orgCsc.emaCp* ,si3sc.ema;ocation7*.ttp3CC888.spring/rame8or0.orgCsc.emaCbeans .ttp3CC888.spring/rame8or0.orgCsc.emaCbeansCspring$beans$).R.,sd .ttp3CC888.spring/rame8or0.orgCsc.emaCconte,t .ttp3CC888.spring/rame8or0.orgCsc.emaCconte,tCspring$conte,t$).R.,sd .ttp3CC888.spring/rame8or0.orgCsc.emaCt, .ttp3CC888.spring/rame8or0.orgCsc.emaCt,Cspring$t,$).R.,sd*V Tbean class7*org.spring/rame8or0.remoting.support.SimpleHttpServerHactory>ean*V Tproperty name7*conte,ts*V TmapV Tentry 0ey7*C4ersonService* value$re/7*personServiceHttp=nvo0er*CV Tentry 0ey7*C4roductService* value$re/7*productServiceHttp=nvo0er*CV Tentry 0ey7*C4urc.aseService*value$re/7*purc.aseServiceHttp=nvo0er*CV Tentry 0ey7*C6eportService* value$re/7*reportServiceHttp=nvo0er*CV Tentry 0ey7*CSalesService* value$re/7*salesServiceHttp=nvo0er*CV Tentry 0ey7*CSecurityService* value$re/7*securityServiceHttp=nvo0er*CV TCmapV TCpropertyV Tproperty name7*port* value7*M'M'*CV TCbeanV Tbean id7*personServiceHttp=nvo0er* class7*org.spring/rame8or0.remoting..ttpinvo0er.SimpleHttp=nvo0erService@,porte p3service$re/7*personService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4ersonService*CV Tbean id7*productServiceHttp=nvo0er* class7*org.spring/rame8or0.remoting..ttpinvo0er.SimpleHttp=nvo0erService@,porte r* V p3service$re/7*productService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4roductService*C Tbean id7*purc.aseServiceHttp=nvo0er* class7*org.spring/rame8or0.remoting..ttpinvo0er.SimpleHttp=nvo0erService@,porte r* CV p3service$re/7*purc.aseService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4urc.aseService*

r*

Tbean id7*reportServiceHttp=nvo0er* class7*org.spring/rame8or0.remoting..ttpinvo0er.SimpleHttp=nvo0erService@,po rter* p3service$re/7*reportService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.6eportService *CV Tbean id7*salesServiceHttp=nvo0er* class7*org.spring/rame8or0.remoting..ttpinvo0er.SimpleHttp=nvo0erService@,po rter* p3service$re/7*salesService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.SalesService* CV Tbean id7*securityServiceHttp=nvo0er* class7*org.spring/rame8or0.remoting..ttpinvo0er.SimpleHttp=nvo0erService@,po rter* p3service$re/7*securityService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.SecurityServi ce*CV TCbeansV !agian paling atas ? le ]M. ini adalah deklarasi namespace dari Spring, kemudian di ba"ahnya ada kode untuk mensetting Java ; Sun +ttp Server. Semenjak Java ;, Sun menyertakan modul kecil "eb server yang bisa digunkan sehagai +ttp Server, dalam arsitektur three tier +ttp Server ini digunakan sebagai middle tier untuk menjembatani client dengan database. (alau misalnya project-nya berukuran cukup besar dan user cukup banyak, sebaiknya gunakan application server yang lebih besar semisal tomcat atau glass?sh. (on?gurasi di atas hanya bisa digunakan untuk Sun +ttp Server yang ada di Java ;, kalau ingin menggunakan tomcat atau glass?sh maka kon?gurasi di atas harus diubah, kemudian harus dibuat project baru bertipe "eb project, kon?gurasi perlu dilakukan di "eb.Lml dan "ar yang dihasilkan dari "eb project tersebut bisa di deploy di dalam tomcat atau glass?sh. Spring menyediakan class untuk mengkon ?gurasi Sun +ttp Server yaitu Simple+ttpServer*actory!ean, class tersebut memerlukan port dan map untuk memapping F-. 3conteLt path5 dengan +ttp+andler. Seperti contoh di atas, untuk setiap service kita akan membuat +ttp nvoker eLporter yang bertipe +ttp+andler, kemudian dimapping dengan F-.. Misalnya kon?gurasi di ba"ah ini / Tentry 0ey7*C4ersonService* value$re/7*personServiceHttp=nvo0er*CV (on?gurasi di atas akan memapping bean personService+ttp nvoker 9,ersonService, url tersebut nantinya bisa diakses oleh client dari url / .ttp3CClocal.ost3M'M'C4ersonService !ean personService+ttp nvoker sendiri adalah Simple+ttp nvokerServiceMLporter yang mengimplementasikan mengekspose personService sebagai http invoker. ke dalam Frl

instansiasi +ttp+andler

class dan

Setelah selesai membuat kon?gurasi untuk server, sekarang kita buat kon?gurasi untuk clientnya. (on?gurasi client akan melakukan sebalikna dari yang dilakukan server, kalau di server adalah mengekspose Spring Service menjadi sebuah F-., maka kon?gurasi client akan mengubah sebuah F-. menjadi Spring Service. !uat sebuah ?le ]M. dengan nama client$onteLt.Lml di dalam folder src kemudian isikan kode berikut ini / TW,ml version7*%.'* encoding7*G9H$N*WV Tbeans ,mlns7*.ttp3CC888.spring/rame8or0.orgCsc.emaCbeans* ,mlns3,si7*.ttp3CC888.81.orgC)''%CJB;Sc.ema$instance* ,mlns3conte,t7*.ttp3CC888.spring/rame8or0.orgCsc.emaCconte,t* ,mlns3t,7*.ttp3CC888.spring/rame8or0.orgCsc.emaCt,* ,mlns3p7*.ttp3CC888.spring/rame8or0.orgCsc.emaCp* ,si3sc.ema;ocation7*.ttp3CC888.spring/rame8or0.orgCsc.emaCbeans

.ttp3CC888.spring/rame8or0.orgCsc.emaCbeansCspring$beans$).R.,sd .ttp3CC888.spring/rame8or0.orgCsc.emaCconte,t .ttp3CC888.spring/rame8or0.orgCsc.emaCconte,tCspring$conte,t$).R.,sd .ttp3CC888.spring/rame8or0.orgCsc.emaCt, .ttp3CC888.spring/rame8or0.orgCsc.emaCt,Cspring$t,$).R.,sd*V Tconte,t3property$place.older location7*classpat.3server.properties*CV Tbean id7*personService* class7*org.spring/rame8or0.remoting..ttpinvo0er.Http=nvo0er4ro,yHactory>ean* p3serviceGrl7*.ttp3CC"{server.ip!3"{server.port!C4ersonService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4ersonService*V TCbeanV Tbean id7*productService* class7*org.spring/rame8or0.remoting..ttpinvo0er.Http=nvo0er4ro,yHactory>ean* p3serviceGrl7*.ttp3CC"{server.ip!3"{server.port!C4roductService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4roductService*V TCbeanV Tbean id7*purc.aseService* class7*org.spring/rame8or0.remoting..ttpinvo0er.Http=nvo0er4ro,yHactory>ean* p3serviceGrl7*.ttp3CC"{server.ip!3"{server.port!C4urc.aseService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4urc.aseService*V TCbeanV Tbean id7*reportService* class7*org.spring/rame8or0.remoting..ttpinvo0er.Http=nvo0er4ro,yHactory>ean* p3serviceGrl7*.ttp3CC"{server.ip!3"{server.port!C6eportService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.6eportService*V TCbeanV Tbean id7*salesService* class7*org.spring/rame8or0.remoting..ttpinvo0er.Http=nvo0er4ro,yHactory>ean* p3serviceGrl7*.ttp3CC"{server.ip!3"{server.port!CSalesService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.SalesService*V TCbeanV Tbean id7*securityService* class7*org.spring/rame8or0.remoting..ttpinvo0er.Http=nvo0er4ro,yHactory>ean* p3serviceGrl7*.ttp3CC"{server.ip!3"{server.port!CSecurityService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.SecurityService*V TCbeanV TCbeansV Seperti biasa, kode ]M. Spring dia"ali dengan deklarasi namespace. (emudian di ba"ahnya ada kode untuk meload property server.properties yang berisi kon?gurasi , dari server dan port-nya. si dari server.properties adalah / server.ip7%)-.'.'.% server.port7M'M' Di dalam ]M. property di atas bisa diakses menggunakan sintaks NWserver.ipX dan N Wserver.portX. !agian berikutnya adalah merubah F-. menjadi Spring Service, contohnya / Tbean id7*personService* class7*org.spring/rame8or0.remoting..ttpinvo0er.Http=nvo0er4ro,yHactory>ean* p3serviceGrl7*.ttp3CC"{server.ip!3"{server.port!C4ersonService* p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4ersonService*V TCbeanV kon?gurasi di atas berusaha membuat bean dengan nama personService di cleint, bean ini berasal dari F-. berikut ini setelah di substitusi dengan nilai dari server.properties / http/99)%'.&.&.)/1&1&9,ersonService nterface yang digunakan sebagai tipe service-nya adalah ,ersonService. Jadi secara sederhana

bisa dikatakan bah"a kon?gurasi di atas memindahkan Service yang ada diserver supaya bisa diakses dari client.

Mem"uat *erver dan Client Class


Seperti disebutkan di atas, kita perlu membuat sebuah class untuk menjalankan server, class ini fungsinya sama denga class Main, bedanya hanya pada ?le Spring $onteLt apa yang dieksekusi. *ile application$onteLt.Lml dan server$onteLt.Lml akan dijalankan di server sedangkan cleint hanya menjalankan cleint$onteLt.Lml, sehingga perlu dilakukan perubahan sedikit di dalam class Main yang bertindak sebagai client. !uat sebuah class namakan ,HSServer di package com.googlecode.projecttemplate.pos.server kemudian tambahkan kode di ba"ah ini / public class 4ASServer { public static void main(String[] args) { IbstractIpplicationDonte,t ct, 7 ne8 Dlass4at.JmlIpplicationDonte,t( ne8 String[]{*applicationDonte,t.,ml*+*serverDonte,t.,ml*!) ct,.registerS.utdo8nHoo0() ! ! (emudian lakukan perubahan di dalam class Main untuk mengganti application$onteLt.Lml dengan client$onteLt.Lml seperti di ba"ah ini / CCIpplicationDonte,t applicationDonte,t 7 CC ne8 Dlass4at.JmlIpplicationDonte,t(*applicationDonte,t.,ml*) IpplicationDonte,t applicationDonte,t 7 ne8 Dlass4at.JmlIpplicationDonte,t(*clientDonte,t.,ml*) Terlihat dalam kode di atas, dua baris pertama dimatikan dengan memberi tanda komentar dan digantikan dengan % baris berikutnya. (alau ingin merubah kembali arsitektur three tier ke client-server cukup hilangkan tanda komentar di % baris pertama dan tambahkan komentar di % baris berikutnya, sangat simple dan tetapi po"erfull. Fntuk mencoba arsitektur three tier, anda harus menjalankan class ,HSServer terlebih dahulu baru kemudian class Main. Tidak boleh ada dua ,HSServer dijalankan sekaligus karena bisa terjadi bentrok untuk memperebutkan port 1&1&. Secara fungsional tidak ada yang berbeda antara arsitektur client-server dan three-tier, perbedaanya ada pada middle tier yang bisa mengurangi load di client, karena sekarang client tidak perlu memanage Session*actory dari hibernate. Session*actory hibernate ada di sisi middle tier 3application server5, sehingga kita bisa menerapkan caching, kalau Session*actory ada di client maka caching menjadi tidak optimal karena setiap client mempunyai caching sendiri-sendiri. Sampai di sini aplikasi sudah siap, langkah berikutnya adalah membuat installer untuk menginstall client maupun server. (ita akan menggunakan library iBpack untuk membuat installer.

"A5IA@ ) &8&":A4 I@04ALL86 D8@5A@ IKPA(K

I8$ack
B,ack adalah tools yang membantu memecahkan masalah instalasi aplikasi di berbagai platform. Seperti halnya Java, B,ack dapat membuat instalasi yang bisa berjalan di semua platform, "indo"s, linuL maupun Mac HS]. +al ini dimungkinkan karena B,ack juga berbasis Java. nstaller hasil generate dari B,ack adalah eLecutable jar yang ketika diklik akan menjalankan proses instalasi aplikasi. B,ack mempunyai banyak tools dan modul yang dapat dengan mudah dikon?gurasi berdasarkan setiap platform dimana aplikasi akan diinstall, misalkan kita bisa mempunyai kondisi kalau di "indo"s akan diinstall ? le .bat untuk menjalankan aplikasi sedangkan di YniL yang diinstall adalah ?le .sh B,ack didesign sangat modular dan mudah dicostumisasi sesuai dengan kebutuhan kita. (onsep modular di dalam B,ack terlihat dari digunakanya ]M. sebagai kon?gurasi untuk mende?nisikan proses instalasi aplikasi. Di dalam ]M. kon?gurasi tersebut kita bisa mende?nisikan langkah-langkah instalasi dan panel apa saja yang akan ditampilkan dalam langkah-langkah instalasi. Sebagai contoh, kita bisa mende?nisikan langkah pertama instalasi adalah panel untuk memilih folder instalasi, kemudian menampilkan readme, kemudian menampilkan lisensi aplikasi, dan terakhir menampilkan progress bar proses instalasi. Semua panel yang disebutkan tadi sudah disediakan secara default oleh B,ack, kita juga bisa membuat sendiri panel yang kita inginkan dengan mengimplementasikan interface yang disediakan oleh B,ack. ,endekatan ini membuat B,ack sangat modular dan mudah dikostumisasi. Setelah mende?nisikan ]M. untuk proses instalasi, dengan dua cara berbeda / B,ack dapat mengenerate installer

Dengan menggunakan command line yang disediakan oleh B,ack Dengan menggunakan :nt Task yang sudah disediakan oleh B,ack

(ita akan mencoba kedua pendekatan di atas, cara pertama kita coba menggunakan sample instalasi yang disediakan oleh B,ack, sedangkan cara kedua kita gunakan untuk membuat instalasi ,HS server dan ,HS client. !erikut ini adalah daftar beberapa feature yang dipunyai oleh B,ack / (on?gurasi ]M. untuk mengenerate installer Multi bahasa, sudah tersedia )& bahasa 3sayang bahasa indonesia tidak termasuk5 ntegrasi dengan :nt, atau menggunakan command line (ustomisasi yang mudah dengan panel dan :, yang sangat lengkap (onsep variabel kon?gurasi yang sangat po"erfull (onsep kondisi yang bagus untuk segala kemungkinan proses instalasi Dapat mengenerate berbagai macam installer / standard, "eb-based, multi-volume dll Dapat mengeksekusi command line di YniL maupun "indo"s +asil instalasi berupa satu buah didistribusikan ? le tunggal 3jar5 sehingga sangat ringkas untuk

ntegrasi dengan kode native platform dst

Setelah kita bahas sedikit background B,ack, sekarang "aktunya kita coba untuk membuat installer

embuat Installer dari Sample di I4'a&k


B,ack dapat dido"nload dari / http/99iBpack.org9do"nloads , pada "aktu buku ini ditulis versi

B,ack stable adalah <.7.7. Setelah do"nload selesai, B,ack dapat diinstall dengan mudah, buka command prompt dan cd ke dalam folder dimana ?le B,ack installer berada, kemudian jalankan perintah berikut ini / " #ava $#ar i?pac0$install$5.1.1.#ar :tau silahkan double click ?le iBpack-install-<.7.7.jar. Setelah proses instalasi selesai, mari kita periksa satu per satu folder instalasi B,ack.

*older bin berisi command line untuk membuat installer dari ]M. kon?gurasi. *older doc berisi semua dokumentasi B,ack, ada versi html dan versi pdf. *older berikutnya adalah installinfo dan legal yang berisi informasi proses instalasi dan berisi lisensi B,ack. *older lib berisi libary-library yang diperlukan oleh B,ack. *older sample berisi contoh ]M. kon?gurasi B,ack, di bagian selanjutnya nanti kita akan menggunakan ]M. kon?gurasi yang ada di dalam folder sample ini untuk mencoba membuat installer dengan B,ack. *older src berisi source code dari B,ack. Fninstaller berisi jar yang digunakan untuk uninstall B,ack dari system. *older terakhir adalah utils yang berisi utility seperti native launcher 3eLe5 untuk berbagai macam platform. 0ah sekarang mari kita coba membuat installer dengan B,ack dari sample yang disediakan. *older sample berisi ?le seperti gambar di ba"ah ini /

Terdapat ? le install.Lml yang merupakan ]M. kon?gurasi B,ack, kita akan menggunakan install.Lml ini untuk membuat installer. $ara yang kita gunakan untuk membuat installer dalam bagian ini adalah dengan menggunakan command line. Silahkan buka command prompt atau console kemudian navigasi 3cd5 ke dalam folder N f,:$(S+HMM9sample9simple, dimana N f,:$(S+HMM adalah folder dimana B,ack diinstall. (emudian jalankan perintah berikut ini /

" ..C..CbinCcompile install.,ml :kan keluar output di console seperti di ba"ah ini / .33 =?4ac0 $ Persion 5.1.1 33. T compiler speci/ications version3 %.' V $ Dopyrig.t (c) )''%$)''N ]ulien 4onge $ Pisit .ttp3CCi?pac0.orgC /or t.e latest releases $ 6eleased under t.e terms o/ t.e Ipac.e So/t8are ;icense version ).'. $V $V $V $V $V $V $V 4rocessing 3 Autput 3 >ase pat. 3 Kind 3 Dompression 3 Dompr. level3 =?4ac0 .ome 3 install.,ml install.#ar . standard de/ault $% CIpplicationsC=?4ac0

Idding resource3 =?4ac0.uninstaller Setting t.e installer in/ormation Setting t.e SG= pre/erences Idding langpac03 eng Idding resource3 /lag.eng Idding langpac03 /ra Idding resource3 /lag./ra Idding resource3 ;icence4anel.licence Idding resource3 =n/o4anel.in/o Idding content o/ #ar3 /ile3CIpplicationsC=?4ac0ClibCstandalone$ compiler.#ar!CbinCpanelsCHello4anel.#ar Idding content o/ #ar3 /ile3CIpplicationsC=?4ac0ClibCstandalone$ compiler.#ar!CbinCpanelsC=n/o4anel.#ar Idding content o/ #ar3 /ile3CIpplicationsC=?4ac0ClibCstandalone$ compiler.#ar!CbinCpanelsC;icence4anel.#ar Idding content o/ #ar3 /ile3CIpplicationsC=?4ac0ClibCstandalone$ compiler.#ar!CbinCpanelsC9arget4anel.#ar Idding content o/ #ar3 /ile3CIpplicationsC=?4ac0ClibCstandalone$ compiler.#ar!CbinCpanelsC4ac0s4anel.#ar Idding content o/ #ar3 /ile3CIpplicationsC=?4ac0ClibCstandalone$ compiler.#ar!CbinCpanelsC=nstall4anel.#ar Idding content o/ #ar3 /ile3CIpplicationsC=?4ac0ClibCstandalone$ compiler.#ar!CbinCpanelsCHinis.4anel.#ar >uilding installer #ar3 CIpplicationsC=?4ac0CsampleCsimpleCinstall.#ar [ >egin ] Dopying Dopying Berging Writing Writing Writing Writing t.e s0eleton installer - /iles into installer - #ars into installer 1 4ac0s into installer 4ac0 '3 >ase 4ac0 %3 :ocs 4ac0 )3 Sources

[ @nd ] >uild time3 Sat :ec '5 %53R131) SS9 )'%' ,roses pembuatan installer ini akan menghasilkan sebuah ?le dengan nama install.jar, ?le ini sudah berisi semua aplikasi plus installer-nya. Jadi cukup satu ?le ini saja yang dicopy atau

didistribusikan sebagai installer. 0ah sekarang mari kita coba untuk menjalankan install.jar ini, jalankan perintah ini dari folder N f,:$(S+HMM9sample9simple / N java -jar install.jar :tau bisa juga langsung double click install.jar karena ini adalah eLecutable jar. Setelah itu akan muncul jendela langkah-langkah instalasi seperti di ba"ah ini / Memilih !ahasa

+alaman selamat datang dan keterangan tentang aplikasi yang akan diinstall

Menampilkan -eadme

Menampilkan lisensi

Menampilkan halaman untuk memilih folder instalasi

Memilih modul apa saja yang akan diinstall

,rogress !ar menampilkan proses instalasi sukses

-ekap proses instalasi sukses dijalankan

Setelah melihat bagaimana mudahnya membuat installer dengan B,ack, sekarang "aktunya belajar yang agak susah, yaitu membuat ]M. kon?gurasi. (ita akan mengunakan install.Lml dari sampe B,ack kemudian kita bahas satu per satu bagian dari install.Lml tersebut.

5 + Konfi!urasi I4'a&k
Fntuk membuat installer yang kita lihat sebelumnya, diperlukan sebuah ?le ]M. kon?gurasi. *ile ini dibuat dengan tangan alias tidak ada aplikasi KF untuk mengenerate. Sekarang mari kita lihat install.Lml dan kita bahas satu per satu bagianya / TW,ml version7*%.'* encoding7*iso$NNRM$%* standalone7*yes* WV Tinstallation version7*%.'*V Tin/oV TappnameVSample =nstallationTCappnameV TappversionV%.5 beta &&&TCappversionV Taut.orsV Taut.or name7*]4?* email7*#p?^superman.org*CV Taut.or name7*Hidden Ban* email7*.idden^.isdomain.com*CV TCaut.orsV TurlV.ttp3CC888.anot.er8orld$inspace$8ebsite.netCTCurlV

TCin/oV Tguipre/s 8idt.7*&5'* .eig.t7*5N'* resi?able7*yes*CV TlocaleV Tlangpac0 iso17*eng*CV Tlangpac0 iso17*/ra*CV TClocaleV TresourcesV Tres id7*;icence4anel.licence* src7*;icence.t,t*CV Tres id7*=n/o4anel.in/o* src7*6eadme.t,t*CV TCresourcesV TpanelsV Tpanel classname7*Hello4anel*CV Tpanel classname7*=n/o4anel*CV Tpanel classname7*;icence4anel*CV Tpanel classname7*9arget4anel*CV Tpanel classname7*4ac0s4anel*CV Tpanel classname7*=nstall4anel*CV Tpanel classname7*Hinis.4anel*CV TCpanelsV Tpac0sV Tpac0 name7*>ase* re\uired7*yes*V TdescriptionV9.e base /ilesTCdescriptionV T/ile src7*6eadme.t,t* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*;icence.t,t* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*script.bat* targetdir7*"=<S9I;;(4I9H*CV Tparsable target/ile7*"=<S9I;;(4I9HCscript.bat*CV T!$$ 9.e /ile 8ill be parsed $$V TCpac0V Tpac0 name7*:ocs* re\uired7*no*V TdescriptionV9.e documentationTCdescriptionV T/ile src7*doc* targetdir7*"=<S9I;;(4I9H*CV T!$$ 6eccursive adding $$V TCpac0V Tpac0 name7*Sources* re\uired7*no*V TdescriptionV9.e sourcesTCdescriptionV T/ile src7*src* targetdir7*"=<S9I;;(4I9H*CV TCpac0V TCpac0sV TCinstallationV Seperti hal-nya ?le ]M., install.Lml dia"ali dengan tag AZLmlC di baris paling atas. +al ini "ajib dilakukan untuk sebuah ?le ]M. yang valid. B,ack ]M. kon?gurasi mempunyai AinstallationC sebagai root tag-nya, attribute version digunakan untuk mende?nisikan versi dari ]M. kon?gurasi, untuk saat ini cukup diisi dengan E).&G. Tag berikutnya adalah AinfoC yang berisi informasi aplikasi seperti nama aplikasi, pembuat, "ebsite dan seterusnya. Di ba"ahnya ada AguiprefsC yang digunakan untuk mende?nisikan ukuran layar dari installer. AlocaleC digunakan untuk mengkon?gurasi bahasa apa saja yang bisa digunakan dalam proses instalasi. AresourcesC digunakan untuk mende?nisikan berbagai macam resource yang diperlukan oleh tag berikutnya yaity ApanelsC, misalnya dalam contoh di atas ada .icence,anel dan nfo,anel yang memerlukan resource berupa teLt ?le yang perlu ditampilkan. !agian terpenting dari ]M. kon?gurasi ini adalah ApacksC dimana proses mengkopi ?le yang perlu diinstall ke dalam folder instalasi. (ita bisa membagi ?le-?le yang perlu di copy dalam ApackC, misalnya di contoh di atas, ada !ase, Docs dan Sources. :da attribute re\uired untuk menentukan apakah ApackC tersebut harus diinstall dengan memberi nilai no ataukah pengguna bisa memilih untuk tidak menginstall dengan memberi nilai yes. Setelah kita ulas sekilas ]M. kon?gurasi di atas, mari kita bahas lebih mendetail.

&ag Intsallation;installation<
Tag ini adalah root dari ]M. kon?gurasi B,ack, tidak ada yang istime"a dari tag ini, hanya ada satu attribute yaitu version dan isinya harus ).&

&ag In ormation ;in o<


!erisi informasi informasi umum aplikasi, di dalam tag AinfoC bisa berisi tag / AappnameC / nama aplikasi AappversionC / versi aplikasi AappsubpathC / sub path yang diturunkan dari path default instalasi yang diinput user pada "aktu proses instalasi berjalan. (ita bisa meletakkan variabel di dalam appsubpath ini, B,ack akan mengevaluasi variabel dan menggantinya degan nilai sebenarnya pada "aktu proses instalasi berjalan. (alau tidak diset maka appname akan digunakan sebagai nilai default. AurlC / "ebsite aplikasi AauthorsC / mendaftarkan pembuat aplikasi, bisa lebih dari satu dengan menambahkan AauthorC di dalamnya. AauthorC mempunyai dua atribute name / nama dari pembuat aplikasi email / email dari pembuat aplikasi

AuninstallerC / digunakan untuk mende?nisikan apakah setelah proses instalasi selesai akan dibuat uninstaller atau tidak, serta mende?nisikan nama uninstallernya. Tag ini mempunyai attribute E"riteG yang nilainya EyesG atau EnoG. Secara default akan dibuat uninstaller, dan hanya jika uninstaller tag diset serta "rite [ EnoG maka uninstaller tidak akan dibuat. AjavaversionC / mende?niskan versi minimum Java yang diperlukan untuk instalasi, misalnya/ ).), ).%, ).7, ).<, ).4 atau ).;. 0ilai ini akan digunakan untuk dibandingkan dengan nilai yang ada dalam system properties java.version. Are\uiresjdkC / nilai yang diijinkan adalah yes atau no, digunakan untuk menentukan apakah installer ini memerlukan JD( atau hanya memerlukan J-M A"ebdirC / digunakan untuk membuat E"eb installerJ, nilai dari tag ini adalah url dimana pacakge instalasinya berada di internet, harus berisi url lengkap, misalnya http/99ifnubima.org9pos9installer Asummarylog?lepathC / digunakan untuk mende?nisikan letak log?le untuk instalasi. A"riteintallationsummaryC / mende?nisikan apakah ?le .installinformation akan ditulis atau tidak. Defaultnya adalah ditulis 3yes5 Apack%&&9C / tambahkan tag ini jika ingin jar yang ada dalam installer dikompres menggunakan pack%&&, kecuali signed jar. Fkuran installer nantinya akan menurun drastis dari ukuran sebelum dikompres. Arun-privileged9C / menambahkan tag ini akan berusaha menjalankan installer dalam mode administrator dan menampilkan popup untuk login sebagai user sebelum installer berjalan.

Silahkan melihat listing ?le install.Lml untuk melihat bagaimana tag AinfoC ini digunakan dalam ]M. kon?gurasi B,ack.

%aria"el- &ag %aria"el ;varia"le< dan &ag dynamic varia"el ;dynamicvaria"le<


Dalam ?le install.Lml di atas terdapat sebuah variabel yang ditandai dengan simbol N yaitu N 0ST:..S,:T+. B,ack menyediakan banyak variabel yang dapat digunakan dalam ]M. kon?gurasi, daftar lengkap variabel yang sudah disediakan B,ack adalah sebagai berikut/ N 0ST:..S,:T+ / path ke folder instalasi N:,,. $:T H0SSDM*:F.TS-HHT / path default untuk aplikasi NJ:@:S+HMM / letak instalasi Java 3J-M5

N$.:SSS,:T+ / $lass path yang digunakan untuk mende?nisikan letak libaray 9 class, digunakan oleh Java. NFSM-S+HMM / direktori home dari user di HS NFSM-S0:MM / nama user yang digunakan untuk login ke HS N:,,S0:MM / nama aplikasi yang dide?nisikan di AinfoC N:,,SF-. / url aplikasi yang dide?nisikan di dalam AinfoC N:,,S@M- / versi aplikasi yang dide?nisikan di dalam AinfoC N SH7S.:0K / kode bahasa yang dipilih user di langkah pertama instalasi 3lihat gambar di bab sebelumnya5 N ,S:DD-MSS / alamat ip komputer user N+HSTS0:MM / nama host dari komputer user N* .MSSM,:-:TH- / pemisah folder dari HS yang digunakan user. (alau "indo"s R kalau YniL 9 NDesktopShortcut$heckboLMnabled/ variabel ini digunakan sebagai penanda apakah setelah instalasi selesai akan dibuatkan shortcut di desktop user apa tidak. Fntuk mengeset variabel ini harus menggunakan tag AvariableC, hati-hati nama variablenya case-sensitive. N nstaller*rame.log?le,ath / path untuk log proses instalasi. (alau variabel ini tidak diset, maka digunakan nilai default / N 0ST:..S,:T9Fninstaller9install.log

@ariabel-variabel di atas bisa digunakan dalam proses instalasi untuk bermacam-macam kebutuhan. Selain variabel yang sudah disiapkan oleh B,ack di atas, ada juga variabel yang bersifat dinamis, dimana kita bisa mende?nisikan sendiri. AdynamicvariablesC digunakan bersama AvariableC untuk mende?nisikan dynamic variabel ini, contohnya/ TdynamicvariablesV Tvariable name7*app$version* value7*%.'* condition70ondisi%CV Tvariable name7*released$on* value7*'NC'1C)'%'* condition7!0ondisi)CV TCdynamicvariablesV B,ack juga mempunyai feature sangat po"erfull dengan adanya ,arse ?le, dimana kita bisa mende?nisikan variabel di dalam teLt ?le, kemudian B,ack akan memparsing ?le tersebut untuk disubstitusi dengan nilai variabelnya. 0anti di bagian ApackC akan dibahas sedikit bagaimana feature parse ini digunakan.

Kondisi dan &ag Kondisi ;conditions<


B,ack mempunyai feature percabangan eksekusi dengan menggunakan kondisi. Di sebagian besar tag terdapat attribute condition yang digunakan untuk mengetasi suatu kondisi tertentu dipenuhi atau tidak, kalau dipenuhi berarti tag tersebut akan dieksekusi, sebaliknya kalau tidak dipenuhi maka tag tersebut tidak akan dieksekusi. $ontohnya adalah di listing kode di atas, terdapat attribute condition di dalam tag variabel, misalnya kondisi) tidak bernilai benar maka variabel dengan nama app-version tidak akan dibuat. B,ack mengijinkan kondisi ini dioperasikan menggunakan operator logika / Q / operator logika dan 3and5 a / operator logika atau 3or5 R / operator logika ]or _ / operator negasi 3not5

B,ack juga menyediakan kondisi yang langsung bisa digunakan dalam ]M. kon?gurasi. (ondisi-kondisi tersebut antara lain / iBpack."indo"sinstall / bernilai benar jika HS yang digunakan adalah "indo"s dan keluarganya

iBpack."indo"sinstall.Lp / bernilai benar jika HS yang digunakan adalah "indo"s ], iBpack."indo"sinstall.%&&7 / bernilai benar jika HS yang digunakan adalah "indo"s %&&7 iBpack."indo"sinstall.vista / bernilai benar jika HS yang digunakan adalah "indo"s @ista iBpack."indo"sinstall.' / bernilai benar jika HS yang digunakan adalah "indo"s ' iBpack.macinstall / bernilai benar jika HS yang digunakan adalah Mac HS] iBpack.solarisinstall / bernilai benar jika HS yang digunakan adalah Solaris iBpack.solarisinstall.L6; / bernilai benar jika HS yang digunakan adalah Solaris yang berjalan di processor dengan arsitektur L6; seperti ntel dan :MD iBpack.solarisinstall.sparc / bernilai benar jika HS yang digunakan adalah berjalan di processor sparc Solaris yang

Selain kondisi yang sudah disediakan B,ack, kita juga bisa mende?nisikan kondisi tertentu dengan menggunakan tag AconditionsC dan AconditionC. $ontohnya / TconditionsV Tcondition type7*variable*V TnameV0ondisi%TCnameV TvalueVtrueTCvalueV TCconditionV Tcondition type7*variable*V TnameV0ondisi)TCnameV TvalueV/alseTCvalueV TCconditionV TCconditionsV

&ag (.I Pre erence ;gui$re s<


Tag guiprefs digunakan untuk mende?nisikan ukuran jendela installer, tampilan lookandfeel, serta beberapa parameter tampilan . Terdapat beberapa attribute dalan tag ini / resiBable / digunakan untuk mende?nisikan apakah jendela installer dapat diubah ukuranya. 0ilainya adalah yes atau no "idth / lebar dari "indo" height / tinggi "indo"

di dalam tag guipref bisa ditambahkan tag laf untuk mende?nisikan lookandfeel installer, lookand feel yang tersedia antara lain / kunststo^ li\uid metouia jgoodies substance

Tag laf memerlukan tag AosC untuk menentukan lookandfeel apa yang digunakan dalam HS tersebut, kalau tidak disebutkan maka lookandfeel default untuk setiap HS akan digunakan. #indo"s defaultnya adalah "indo"s lookandfeel, Mac / :\ua dan YniL / metal. $ontoh penggunaanya / Tguipre/s .eig.t7*&''* resi?able7*yes* 8idt.7*N''*V Tla/ name7*metouia*V Tos /amily7*uni,* CV TCla/V Tla/ name7*loo0s*V Tos /amily7*8indo8s* CV

Tparam name7*variant* value7*e,t8in* CV TCla/V TCguipre/sV

&ag Locali8ation ;locale<


Tag ini digunakan untuk mendaftarkan pilihan bahasa apa saja yang bisa digunakan dalam proses instalasi. Secara default B,ack menyediakan )& bahasa. Dalam tag AlocaleC terdapat tag AlangpackC untuk mendaftar satu per satu bahasa yang didukung installer anda. !erikut ini contoh penggunaanya / TlocaleV Tlangpac0 iso17*eng*CV Tlangpac0 iso17*/ra*CV TClocaleV

&ag )esources ;resources<


!eberapa panel, seperti panel -eadme dan .icence memerlukan ? le teLt yang akan ditampilkan di masing-masing panel. *ile teLt tersebut harus dide?nisikan dalam tag AresurcesC ini agar dikenali oleh panelnya. B,ack sayangnya tidak menyediakan feature untuk mengecek apakah resource yang dide?nisikan benar-benar ada pada "aktu membuat installer, sehingga terkadang B,ack mengeluarkan pesan bah"a installer berhasil dibuat tetapi ketika dijalankan, terdapat error yang membuat installer gagal. Di dalam tag ini terdapat tag AresC yang mempunyai beberapa attribute, antara lain/ src / path dimana resource berada. id / identi?ers untuk menandai nama resourcenya parse / mempunyai nilai yes atau no. (alau diset yes, B,ack akan memparsing resource ini dan melakukan pencarian apakah ada de?nisi variabel di dalamnya, kalau ada maka B,ack akan mengganti variabel tersebut dengan nilai sebenarnya. type / tipe dari resource. Kunakan attribute ini kalau resource berupa ?le teLt. 0ilai dari attribute type ini antara lain/ javaprop, Lml, plain, java, shel, at, ant encoding / tipe encoding yang digunakan jika resource berupa ?le teks

!erikut ini adalah contoh penggunaanya / TresourcesV Tres id7*;icence4anel.licence* src7*;icence.t,t*CV Tres id7*=n/o4anel.in/o* src7*6eadme.t,t*CV TCresourcesV

Panel ;$anels<
Tag ini sangat penting, karena mende?nisikan halaman apa saja yang akan ditampilkan dalam langkah-langkah instalasi aplikasi. B,ack menyediakan beberapa jenis panel yang bisa digunakan dalam installer. Fntuk banyak kasus, panel-panel ini sudah mencukupi semua kebutuhan. B,ack juga mengijinkan kita mende?nisikan panel buatan kita sendiri, dalam buku ini kita tidak membahas topik panel hingga mendetail ke pembuatan custom panel, silahkan merujuk ke manual B,ack untuk topik tersebut. Tag ApanelC mempunyai beberapa attribute, antara lain / classname / nama class dari panel id / identitas atau nama dari panel yang sedang dibuat condition / kondisi yang bisa digunakan untuk menentukan apakah panel ini ditampilkan atau tidak jar / nama jar dimana class dari panel ini berada.

!erikut ini contoh penggunaanya / TpanelsV Tpanel classname7*Hello4anel*CV Tpanel classname7*=n/o4anel*CV Tpanel classname7*;icence4anel*CV Tpanel classname7*9arget4anel*CV Tpanel classname7*4ac0s4anel*CV Tpanel classname7*=nstall4anel*CV Tpanel classname7*Hinis.4anel*CV TCpanelsV Tag ApanelsC mempunyai beberapa tag optional yang bisa digunakan, yang pertama adalah tag AhelpC, tag ini digunakan untuk mende?nisikan bantuan untuk panel tertentu. Tag AhelpC mempunyai attribute iso7 yang mende?nisikan bahasa bantuan, kalau misalnya installer mendukung 7 bahasa, sebaiknya tag AhelpC ini juga menyediakan bantuan untuk ketiga bahasa tersebut. !erikut ini contohnya / Tpanel classname7*Hello4anel*V T.elp iso17*deu* src7*Hello4anelHelp(deu..tml* CV T.elp iso17*eng* src7*Hello4anelHelp(eng..tml* CV TCpanelV Tag kedua adalah AvalidatorC, tag ini digunakan untuk memvalidasi inputan yang ada dalam panel. Misalnya kita akan membuat panel untuk mengkon?gurasi koneksi ke database, namakan saja panelnya (on?guasiDatabase, kemudian di dalam panel ini ada teLt ?eld untuk menginput jdbc url, username dan pass"ord. (emudian kita ingin memvalidasi apakah inputan ini sudah benar dan koneksi ke database berhasil, maka kita buat misalnya Jdbc$onnection@alidator, class ini harus mengimplemntasi interface com.iBforge.iBpack.installer.Data@alidator. !erikut ini contoh penggunaanya / Tpanel classname7*:atabase4anel*V Tvalidator classname7]dbcDonnectionPalidatorCV TCpanelV ,anel juga mendukung feature action dengan tag AactionsC. Tag AactionsC ini bisa digunakan kalau kita ingin menjalankan suatu aksi tertentu. Tag AactionsC mempunyai dua buah attribute, yaitu / classname / berisi nama class dari action yang akan dieksekusi stage / tahapan dimana action ini akan dieksekusi, nilai yang bisa digunakan untuk attribute stage ini adalah preconstruct, preactivate, prevalidate, postvalidate.

!erikut ini adalah contoh penggunaan actions Tpanel id70one0si:atabase classname7*:atabase4anel*V Tvalidator classname7]dbcDonnectionPalidatorCV TactionsV Taction stage7preconstruct classname7]dbcDonnection4reDonstructCV Taction stage7preactivate classname7]dbcDonnection4reIctivateCV Taction stage7prevalidate classname7]dbcDonnection4rePalidateCV Taction stage7postvalidate classname7]dbcDonnection4ostPalidateCV TCactionsV TCpanelV Tag ,acks ApacksC Tag ini sangat penting karena berfungsi untuk mende?nisikan ?le apa saja yang akan dicopy 9 diinstall. Di dalam tag ApacksC terdapat beberapa tag lain, yaitu / ApackC, ArefpackC dan ArefpacksetC. Tag ApacksC mempunyai beberapa attribute, antara lain / name / nama dari packs, nama ini nanti akan muncul pada panel instalasi re\uired / nilainya yes atau no. (alau diisi yes berarti pada "aktu panel instalasi menampilkan apa saja pack 3modul5 yang akan diinstall, pack ini tidak bisa di-uncheck.

Sebaliknya, kalau diisi no berarti pack ini bisa diuncheck dan menginstall ?le-?le yang dide?nisikan dalam pack ini.

B,ack tidak akan

os / bersifat optional. :trribute ini digunakan untuk menentukan target HS dari pack ini. 0ilainya bisa "indo"s, mac, uniL dan seterusnya. preselected / attribute ini bersifat optional, digunakan untuk menentukan apakah pack ini secara default dipilih atau tidak. loose / attribute ini bisa digunakan jika ingin ?le-?le dalam pack ini tidak diletakkan dalam jar hasil instalasi, hal ini dimaksudkan agar aplikasi bisa dijalankan langsung. Skenario yang mungkin terjadi misalnya/ kita ingin aplikasi kita bisa dijalankan langsung dari $D installer, tetapi bisa juga diinstall langsung di ,$ pengguna. (alau semua ?le ditetakkan dalam jar maka aplikasi harus diinstall terlebih dulu baru bisa digunakan. ,erlu diperhatikan juga relative path dalam aplikasi, karena aplikasi dijalankan langsung dari $D tentu saja berbeda path-nya dengan aplikasi yang diinstal di dalam ,$. id / attribute ini digunakan sebagai identi?ers dan bersifat uni\ue. Selain itu attribute ini juga digunakan dalam proses penterjemahan pack ke dalam suatu bahasa tertentu. pack mg d / digunakan kalau kita ingin menampilkan gambar untuk pack ini. 0ilainya harus dide?nisikan dalam tag AresourcesC dan harus bernilai sama dengan id yang ada dalam pack AresC condition / digunakan untuk mengetes kondisi tertentu sebelum pack ini diinstall. (alau nilai dari kondisi salah maka pack tidak akan diinstall 9 ditampilkan dalam proses instalasi. hidden / dapat bernilai true atau false, digunakan untuk menampilkan atau menyembunyikan pack pada proses instalasi. :ttribute ini cukup berguna kalau kita ingin menambahkan pack yang dieksekusi tetapi tidak ingin ditampilkan.

Tag ArefpackC hanya mempunayai satu attribute saja yaitu ?le, yang berisi nilai relative path dari suatu ]M. kon?guration yang dibuat sebelumnya. Jadi kita bisa membuat ]M. kon?guration lebih dari satu kemudian memanggil ]M. tersebut dari ]M. kon?guration utama dengan menggunakan ArefpackC ini, konsepnya mirip sebuah class mengimport class lain. +al ini memungkinkan ]M. kon?guration dipecah menjadi beberapa ?le terpisah untuk memudahkan maintenance kalau ada beberapa orang yang bertanggung ja"ab untuk memelihara modulnya masing-masing. ]M. kon?guration yang bisa digunakan oleh ArefpackC hanya boleh berisi tag AresourcesC dan tag ApacksC saja. Tag ArefpacksetC digunakan kalau kita tidak ingin mende?nisikan refpack apa saja yang akan diikutkan, tetapi kita cukup mende?nisikan sebuah folder yang akan discan oleh B,ack untuk menemukan semua ]M. kon?gurasi yang lain. Tag ini mempunyai dua buah attribute, yaitu / dir / berisi direktori yang akan discan oleh B,ack untuk menemukan semua refpack includes / berisi pattern bagaimana menemukan refpack

$ontoh penggunaan refpackset / Tre/pac0set dir7 includes7LLCre/pac0.,mlCV Sampai di sini semua tag yang kita perlukan untuk membuat ]M. kon?gurasi B,ack sudah cukup diterangkan. Tidak semua tag Lml dijelaskan dalam buku ini, kalau ingin membaca referensi lebih lengkap tentang sintaks dari ]M. kon?gurasi ini, silahkan membaca dokumentasi B,ack yang disertakan dalam instalasi B,ack.

'anel0'anel yan! Disediakan I4'a&k


Di bab ini kita akan membahas satu per satu ,anel yang disediakan oleh B,ack, selain panel yang disediakan, kita juga bisa membuat panel sendiri, tetapi topik ini tidak dibahas dalam buku ini karena memerlukan penjelasan cukup panjang. (onsep panel dalam B,ack berbeda dengan panel dalam S"ing, karena panel dalam B,ack dide?nisikan menggunakan ]M., tidak menggunakan kode Java untuk membuat layoutnya. Fntuk kebutuhan yang umum, B,ack menyediakan cukup lengkap panel-panel yang dibutuhkan. (ita akan membahas panel-panel ini sebelum membahas ]M. kon?gurasi untuk membuat installer ,HS.

/elloPanel dan /&ML/elloPanel


,anel ini digunakan untuk menampilkan detail informasi aplikasi, semisal nama, versi, F-., pembuat aplikasi dan seterusnya. Sedangkan +TM.+ello,anel mengijinkan ?le html digunakan untuk menampilkan detail aplikasi.

Checked/elloPanel
*ungsinya sama persis dengan +ello,anel, hanya saja panel ini akan melakukan pemeriksaan ke dalam registri "indo"s akan dibuat untuk menandakan aplikasi tersebut sudah diinstall, selain itu juga dilakukan pemeriksaan pada registri yang sama apakah aplikasi sudah pernah diinstall sebelumnya. (alau menggunakan panel ini jangan lupa untuk mende?nisikan registri apa yang akan digunakan.

In oPanel dan /&MLIn oPanel


,anel ini digunakan untuk menampilkan -M:DMM, info lebih lengkap tentang aplikasi yang akan diinstall. TeLt ?le yang akan ditampilkan harus dide?niskan di dalam resource dengan nama E nfo,anel.infoG. B,ack mengijinkan substitusi variabel di dalam ?le teLt-nya, sehingga kita bisa mende?nisikan variabel di dalam ]M. kon?gurasi dan menggunakanya di dalam teLt ?le. +TM. nfo,anel digunakan kalau ingin menampilkan ?le +TM.. Kambar bisa dimasukkan dalam +TM., src menunjuk ke nama resource yang harus dide?nisikan di dalam ]M. kon?gurasi. Misalnya di dalam +TM. ada Aimg src[GabcdGC maka harus dibuat resource dengan nama abcd yang menunjuk ke ?le gambar tertentu.

LicencePanel dan /&MLLicencePanel


*ungsi-nya sama dengan nfo,anel, hanya saja panel ini digunakan untuk menampilkan lisensi dari aplikasi. TeLt ?le yang akan ditampilkan harus dide?nisikan sebagai resource dengan nama E.icence,anel.licenceG. +al yang sama juga berlaku untuk +TM..icence,anel.

PacksPanel
,anel ini akan menampilkan ApacksC yang dide?nisikan di dalam ]M. kon?gurasi. Tidak perlu ada kon?gurasi tambahan untuk mende?nisikan ,acks,anel. Semua informasi yang akan ditampilkan diambil dari ]M. kon?gurasi. ,acks,anel mempunyai beberapa varian, antara lain mg,acks,anel dan Tree,acks,anel, perbedaanya hanya di cara menampilkan packs saja.

&argetPanel
,anel ini digunakan untuk memilih di mana folder instalasi. Fser mende?nisikan di mana aplikasi akan diinstall, atau bisa juga menggunakan tombol bro"se untuk memilih folder instalasi.

InstallPanel
+arus ada di setiap ]M. kon?gurasi, panel ini akan melakukan proses instalasi sebenarnya, mulai dari unpack ?le, copy ?le hingga eksekusi semua perintah yang dide?nisikan di dalam ]M. kon?gurasi.

4inishPanel
Menampilkan rekap proses instalasi dan menampilkan keterangan kalau instalasi selesai dieksekusi.

embuat Installer Aplikasi '"S


Sampai di sini penjelasan mengenai B,ack sudah cukup panjang lebar, sekarang kita akan membuat installer untuk aplikasi ,HS. Sebelum ]M. kon?gurasi dibuat, ada beberapa langkah persiapan yang harus dilaksanakan, seperti membuat startup script berupa ?le bat 3"indo"s5 dan ?le sh 3YniL5. (emudian menyediakan ? le readme dan licence, langkah terakhir adalah menyiapkan ant script untuk digabungkan dengan build.Lml dari netbeans, sehingga kita bisa membuat installer secara otomatis. nstaller yang akan dibuat ada % jenis, yaitu installer untuk ,HS Server dan installer untuk ,HS

$lient. (edua installer ini mempunyai ?le binary yang sama, perbedaanya ada di dalam class main yang dieksekusi. (alau ,HS Server akan menjalankan class ,HSServer sedangkan ,HS $lient akan menjakankan class Main.

Persia$an
,ersiapan untuk membuat installer ada beberapa tahap, dia"ali dengan mempersiapkan struktur folder. !uat dua buah folder yaitu installer dan installer-lib. (emudian copy ?le standalone-compiler.jar dari folder instalasi B,ack ke dalam installer-lib. .ihat gambar di ba"ah ini /

*older installer digunakan untuk meletakkan semua ?le yang diperlukan untuk membuat installer, sedangkan installer-lib digunakan untuk meletakkan library B,ack. .ibrary B,ack tidak diletakkan di dalam folder lib karena tidak digunakan ketika aplikasi berjalan, hanya digunakan untuk membuat installer, sehingga sebaiknya dipisahkan dari folder lib. Seperti terlihat pada gambar di atas, kita perlu membuat -eadme-client.tLt untuk menampilkan keterangan apa saja yang perlu user baca ketika menginstall ,HS $lient. (lik kanan foldernya pilih 0e" C Hther di dalam jendela ne" ?le pilih Hther C Mmtpy *ile, kemudian beri nama -eadme-client.tLt. si ?le tersebut dengan keterangan, misalnya seperti ini / Ipli0asi client 4AS. ]angan lupa setting server.properties agar =4 dan port$nya sesuai dengan yang ada di serverDonte,t.,ml !uat -eadme-server.tLt dengan langkah yang sama dan isi ? lenya dengan keterangan, misalnya seperti ini/ Ipli0asi server 4AS. ]angan lupa setting server.properties agar =4 dan port$nya sesuai dengan yang ada di serverDonte,t.,ml !erikutnya kita akan membuat ?le .icence.tLt untuk ditampilkan dalam .icence,anel. .angkah membuat ?le tersebut sama dengan dua ?le di atas, isi dengan pernyataan tetang lisensi aplikasi, misalnya seperti di ba"ah ini / Ipli0asi server dan client 4AS lisensi Ipac.e ;icence ).'

Mem"uat *tartu$ *cri$t


Startup Script adalah sebuah ?le teLt yang berisi kode untuk menjalankan aplikasi Java, jadi

sifatnya eLecutable. (alau di "indo"s bentuknya adalah ?le bat, kalau di YniL bentuknya ?le sh. (ita akan membuat empat buah startup script untuk menjalankan ,HS Server dan ,HS $lient di "indo"s dan YniL. Fntuk menjalankan ,HS Server, class yang dipanggil adalah ,HSServer sendankan ,HS $lient yang dipanggil adalah Main. Startup script yang akan kita buat adalah / start-client.bat / digunakan menjalankan ,HS $lient di "indo"s #ava $cp 4AS.#ar libCL com.googlecode.pro#ecttemplate.pos.Bain start-cleint.sh / digunakan menjalankan ,HS $lient di YniL #ava $cp 4AS.#ar3libCL com.googlecode.pro#ecttemplate.pos.Bain start-server.bat / digunakan menjalankan ,HS Server di "indo"s #ava $cp 4AS.#ar libCL com.googlecode.pro#ecttemplate.pos.server.4ASServer start-server.sh / digunakan menjalankan ,HS Server di YniL #ava $cp 4AS.#ar3libCL com.googlecode.pro#ecttemplate.pos.server.4ASServer ,erbedaan antara ?le bat dan sh terletak pada tanda pemisah classpath, kalau di "indo"s tanda pemisah classpath adalah D 3titik koma5, sedangkan di YniL adalah / 3titik dua5. Membuat ]M. (on?gurasi ,HS $lient dan ,HS Server Sebagian besar ]M. kon?gurasi untuk ,HS $lient dan ,HS Server tidak jauh berbeda. ,roses instalasi kedua aplikasi ini juga sangat sederhana, copy ,HS.jar dan semua jar yang ada di dalam folder dist. (emudian copy Startup Script ke folder instalasi. Sehingga struktur ]M. kon?gurasinya nyaris sama, perbedaanya hanya di setting saja. ]M. kon?gurasi untuk ,HS $lient adalah installer-client.Lml, untuk membuat ?le ini klik kanan di folder installer kemudian pilih 0e" C Hther, di jendela 0e" *ile pilih node ]M. kemudian di sebelah kanan pilih ]M. Document, beri nama installer client. Mari kita lihat ]M. kon?gurasi dari ,HS $lient kemudian kita bahas satu per satu bagianya. TW,ml version7*%.'* encoding7*iso$NNRM$%* standalone7*yes* WV Tinstallation version7*%.'*V Tin/oV TappnameV4AS >ang0it DellTCappnameV TappversionV%.'TCappversionV Taut.orsV Taut.or name7*=/nu >ima* email7*i/nubima^gmail.com*CV TCaut.orsV TurlV.ttp3CCpro#ect$template.googlecode.comTCurlV TCin/oV Tguipre/s 8idt.7*&5'* .eig.t7*5N'* resi?able7*yes*CV TlocaleV Tlangpac0 iso17*eng*CV TClocaleV TresourcesV Tres id7*;icence4anel.licence* src7*installerC;icence.t,t*CV Tres id7*=n/o4anel.in/o* src7*installerC6eadme$client.t,t*CV TCresourcesV TpanelsV Tpanel classname7*Hello4anel*CV Tpanel classname7*=n/o4anel*CV Tpanel classname7*;icence4anel*CV Tpanel classname7*9arget4anel*CV Tpanel classname7*4ac0s4anel*CV Tpanel classname7*=nstall4anel*CV Tpanel classname7*Hinis.4anel*CV TCpanelsV Tpac0sV Tpac0 name7*4AS Dlient* re\uired7*yes*V

TdescriptionV4AS DlientTCdescriptionV T/ile src7*installerC6eadme$client.t,t* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*installerC;icence.t,t* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*distClib* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*distC4AS.#ar* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*installerCstart$client.bat* targetdir7*"=<S9I;;(4I9H* condition7*i?pac0.8indo8sinstall*CV T/ile src7*installerCstart$client.s.* targetdir7*"=<S9I;;(4I9H* condition7*!i?pac0.8indo8sinstall*CV TCpac0V TCpac0sV TCinstallationV ]M. (on?gurasi di atas cukup sederhana, di bagian atas terdapat tag AinfoC yang berisi detail dari aplikasi. (emudian di ba"ahnya terdapat AguiprefsC untuk mende?nisikan lebar dan tinggi jendela installer. Selanjutnya ada AlocaleC yang berisi bahasa untuk installer ini, yaitu bahasa inggris 3eng5. Tag AresourcesC berisi dua buah resource yaitu .icence,anel.licence yang berisi ? le .icence.tLt, isi dari ?le ini nantinya akan ditampilkan dalam .icence,anel. Pang kedua adalah nfo,anel.info yang berisi ?le -eadme-client.tLt, ?le ini nantinya akan ditampilkan pada nfo,anel. Tag ApanelsC berisi panel-panel yang akan ditampilkan dalam proses instalasi, ada tujuh buah panel. Semua panel di atas sudah diterangkan di bagian sebelumnya, kalau ingin melihat panel-panel lain silahkan rujuk ke manual B,ack. !agian terakhir adalah bagian terpenting dari ]M. kon?gurasi ini, tag ApacksC digunakan untuk mendaftarkan semua ?le-?le yang akan disertakan dalam proses instalasi. *ile pertama adalah readme-client.tLt yang diletakkan dalam folder instalasi 3N 0ST:..S,:T+5. *ile kedua adalah .icence.tLt yang juga akan diletakkan dalam folder instalasi. !erikutnya adalah satu buah folder yaitu lib, folder ini berisi semua ?le jar yang diperlukan oleh ,HS $lient. (alau kita memasukkan folder dalam src maka semua isi dalam folder tesebut akan ikut dicopy. *ile berikutnya adalah ,HS.jar dimana semua kode yang kita tulis berada, letaknya ada di dalam folder dist. *ile berikutnya adalah startup script untuk "indo"s, start.cleint.bat, ?le ini akan dicopy jika installer dijalankan di lingkungan "indo"s. Terlihat dari adanya attribute condition[GiBpack."indo"sinstallG. *ile terakhir adalah startup script untuk YniL, ?le ini hanya dicopy jika installer dijalankan di lingkungan selain "indo"s, terlihat dari attribute condition yang berisi G_iBpack."indo"sinstallerG. ]M. kon?gurasi untuk ,HS Server tidak jauh berbeda, seperti yang sudah kita bahas sebelumnya, perbedaanya hanya pada setting, sedangkan struktur ]M. kon?gurasi sama persis. ]M. kon?gurasi untuk ,HS Server diletakkan dalam installer-server.Lml, cara membuat ?le ini juga sama persis dengan cara membuat ?le installer-client. !erikut ini adalah isi dari installer-server.Lml / TW,ml version7*%.'* encoding7*G9H$N*WV Tinstallation version7*%.'*V Tin/oV TappnameV4AS >ang0it DellTCappnameV TappversionV%.'TCappversionV Tappsubpat.V4AS$serverTCappsubpat.V Taut.orsV Taut.or name7*i/nu bima* email7*i/nubima^gmail.com*CV TCaut.orsV TurlV.ttp3CCpro#ect$template.googlecode.comTCurlV TCin/oV Tguipre/s 8idt.7*&5'* .eig.t7*5N'* resi?able7*yes*CV TlocaleV Tlangpac0 iso17*eng*CV Tlangpac0 iso17*/ra*CV

Tlangpac0 iso17*spa*CV TClocaleV TresourcesV Tres id7*;icence4anel.licence* src7*installerC;icence.t,t*CV Tres id7*=n/o4anel.in/o* src7*installerC6eadme$server.t,t*CV TCresourcesV TpanelsV Tpanel classname7*Hello4anel*CV Tpanel classname7*=n/o4anel*CV Tpanel classname7*;icence4anel*CV Tpanel classname7*9arget4anel*CV Tpanel classname7*4ac0s4anel*CV Tpanel classname7*=nstall4anel*CV Tpanel classname7*Hinis.4anel*CV TCpanelsV Tpac0sV Tpac0 name7*4AS Server* re\uired7*yes*V TdescriptionV4AS ServerTCdescriptionV T/ile src7*installerC;icence.t,t* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*installerC6eadme$server.t,t* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*distClib* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*distC4AS.#ar* targetdir7*"=<S9I;;(4I9H*CV T/ile src7*installerCstart$server.bat* targetdir7*"=<S9I;;(4I9H* condition7*i?pac0.8indo8sinstall*CV T/ile src7*installerCstart$server.s.* targetdir7*"=<S9I;;(4I9H* condition7*!i?pac0.8indo8sinstall*CV TCpac0V TCpac0sV TCinstallationV Setelah selesai membuat ]M. kon?gurasi langkah terakhir adalah membuat ant script di dalam build.Lml agar installer dibuat secara otomatis.

Mem"uat Ant *cri$t Installer


,ada bagian sebelumnya kita mencoba membuat installer dengan sample menggunakan command line, nah sekarang kita akan menjalankan install-server.Lml dan install-cleint.Lml menggunakan ant script. B,ack menyediakan ant task untuk menjalankan ]M. kon?gurasi dari ant. !uka ?le build.Lml di 0et!eans, kemudian tambahkan script ant berikut ini di dalam tag AprojectC, sama persis dengan yang kita lakukan pada "aktu membuat ant script untuk mengcompile jasper report / Ttas0de/ name7*=?4ac0* classname7*com.i?/orge.i?pac0.ant.=?4ac09as0*V Tclasspat.V T/ileset dir7*.Cinstaller$lib*V Tinclude name7*LLCL.#ar*CV TC/ilesetV TCclasspat.V TCtas0de/V Tproperty name7*base.dir* value7*CGsersCi/nuC<et>eans4ro#ectsCpro#ect$templateC#ava$des0top$boo0Ccode*CV Ttarget name7*$post$#ar*V T=?4ac0 input7*"{base.dir!CinstallerCinstall$client.,ml* output7*"{base.dir!CdistC4AS$client$installer.#ar* installer9ype7*standard* basedir7*"{base.dir!*CV T=?4ac0 input7*"{base.dir!CinstallerCinstall$server.,ml* output7*"{base.dir!CdistC4AS$server$installer.#ar*

installer9ype7*standard* basedir7*"{base.dir!*CV TCtargetV !agian pertama dari ant script tersebut adalah AtaskdefC yang digunakan untuk mende?nisikan task baru dari B,ack. 0amanya adalah E B,ackG, di dalamnya perlu dide?nisikan nama class dari taskdef dan classpath dimana class tersebut bisa ditemukan. (emudian ada satu property yang bernama Ebase.dirG property ini digunakan untuk mende?nisikan di mana folder kerja kita, isinya berupa absolute path dari folder kerja. (emudian ada target dengan nama E-post-jarG, target ini adalah target spesial yang dikenali oleh 0et!eans, target dengan nama ini akan dijalankan setelah proses kompilasi dan pembuatan jar dari project ,HS ini selesai dilaksanakan. Misalnya kita memilih menu $lean and !uild dari project, maka target E-post-jarG ini akan dieksekusi. si target E-post-jarG adalah dua buah anttask B,ack, ada tiga buah attribute dari anttask B,ack, yaitu / input berisi ?le ]M. kon?gurasi/ install-client.Lml atau install-server.Lml output berisi nama ?le installer yang dihasilkan oleh B,ack installerType kita isi dengan standard baseDir berisi folder kierja kita yang sudah dide?nisikan dalam property base.dir

0ah sekarang silahkan coba jalankan $lean and !uild dari project ,HS, kemudian silahkan coba eksekusi ?le installer yang dihasilkan oleh B,ack/ ,HS-client-installer.jar dan ,HSserver-installer.jar. Setelah proses instalasi dari kedua installer itu berhasil dilaksanakan, coba jalankan startup script dan pastikan aplikasi berjalan sesuai yang diinginkan ,roses instalasi ini masih mempunyai banyak kelemahan, misalnya kita harus melakukan chmod ke startup script untuk YniL agar ?le sh-nya dapat dieksekusi. (emudian proses instalasi database juga masih harus dilakukan secara manual dengan menginstall server -D!MS-nya, membuat database 9 Schema, membuat user database dan terakhir kemudian menjalankan DD. untuk membuat table-table yang diperlukan aplikasi. Sampai di sini kita sudah mempelajari ilmu dasar dari pembuatan aplikasi Java desktop. .atihan dan hands-on langsung sangat diperlukan untuk mengetahui berbagai macam pemecahan masalah yang dihadapi ketika membuat aplikasi. Tidak ada cara cepat untuk menguasai semua teknik tersebut, dibutuhkan "aktu cukup lama agar semua teknik dikuasai dengan baik. Semoga buku ini bisa membuka "a"asan anda dalam membuat aplikasi Java Desktop. Selamat belajar.

Penutu$
Dengan ilmu yang sudah diperoleh dari buku ini, anda sudah bisa mulai untuk membuat program Java desktop sederhana. ,ada a"alnya pasti terasa sulit, sikapi dengan pantang menyerah dan selalu cari cara yang lebih baik dalam membuat aplikasi. .angkah selanjutnya anda bisa mulai aktif bertanya atau menja"ab hal-hal yang berhubungan dengan Java. Media yang bisa digunakan banyak sekali, bisa forum, milis atau diskusi dengan teman. ni cara terbaik untuk mengetes apakah pemahaman anda mengenai Java sudah cukup lengkap atau anda masih perlu belajar lebih banyak lagi. Setelah yakin dengan kemampuan anda, ber?kirlah untuk mengambil serti?kasi profesional Java. ,elatihan untuk persiapan serti?kasi Java banyak tersedia di lembaga pelatihan. (alau anda merasa terlalu berat secara ?nansial mengambil kursus persiapan serti?kasi, berlatihlah sendiri menggunakan materi yang banyak tersedia di internet, misalnya javaranch.com. $ara belajar Java yang paling efektif adalah dengan melibatkan diri dalam project berbasis Java. Jika di perusahaan anda tidak memungkinkan, di luar sana banyak sekali project opensource yang memerlukan bantuan anda. !erkunjunglah ke "ebsite-"ebsite open source project hosting seperti sourceforge.net atau dev.java.net .earn, Try dan Teach adalah formula untuk meningkatkan pengetahuan anda tentang Java. Jika sudah belajar dan sukses mencoba, tularkan ilmu anda pada orang disekeliling anda, dijamin ilmunya bakalan bertambah berlipat-lipat.

)e erensi dan Bacaan Le"ih Lan#ut


). %. 7. <. 4. ;. '. 6. 1. Java Tutorial / http/99do"nload.oracle.com9javase9tutorial Java Documentation / http/99do"nload.oracle.com9javase9;9docs9 0etbeans ndonesia / http/99groups.yahoo.com9group90etbeans-indonesia9 Java Fser Kroup ndonesia / http/99groups.yahoo.com9group9jug-indonesia9 Java Design ,attern / http/99""".javacamp.org9design,attern9 Java Desktop / http/99""".javadesktop.org JKoodies / http/99""".jgoodies.com S"ing] / http/99""".s"inglabs.org Java ,ersistence / http/99en."ikibooks.org9"iki9JavaS,ersistence

)&. !igDecimal / http/99blogs.sun.com9$oreJavaTechTips9entry9theSneedSforSbigdecimal )). Joda Time / http/99""".ibm.com9developer"orks9java9library9j-jodatime.html )%. Joda Time / java.oci"eb.com9mark9programming9JodaTime.pdf )7. nputStream / http/99tutorials.jenkov.com9java-io9inputstream.html )<. S$J, Sun $erti?ed ,rogrammer for Java ; MLam 7)&-&;4. (atherine Sierra. !ert !ates.

Anda mungkin juga menyukai