You are on page 1of 304

Java Desktop

Aplikasi POS Berarsitektur Three Tier


Menggunakan Swing, Hibernate dan
Spring
Inu Bi!a
inubi!a"org
#inubi!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, !ogor 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 untuk institusi pendidikan dan untuk institusi non
pendidikan9perorangan9komunitas.
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-nc-
sa$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-nc-
nd$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 EJll 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 Ases ontrol................................................................................ !
Keyword "ahasa Pe#rogra#an Java ...............................................................................!
Identifiers ......................................................................................................................... $
A%%ess &odifier................................................................................................................ '
Anato#i (lass Java................................................................................................................'
Delarasi (lass..................................................................................................................)
Delarasi Interfa%e ........................................................................................................... *
(lass vs +,-e%t................................................................................................................ ..
&ethod............................................................................................................................ ..
(onstru%tor.......................................................................................................................2
Pro/erty........................................................................................................................... .!
Konstanta........................................................................................................................ .'
0trutur A/liasi 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 Logia.............................................................................................................. 3*
7low (ontrol........................................................................................................................ !3
If ..................................................................................................................................... !.
0wit%h............................................................................................................................. !.
89%e/tion............................................................................................................................. !3
0intas 89%e/tion............................................................................................................!3
(all 0ta%, 0ta% 4ra%e dan :n%aught 89%e/tion ..........................................................!!
(lass 89%e/tion...............................................................................................................!'
Hirari (lass 89%e/tion.................................................................................................. !)
4hrows dan 4hrow.......................................................................................................... $3
Perulangan ; Iterasi.............................................................................................................. $2
for.................................................................................................................................... $2
while ...............................................................................................................................$3
do<while.......................................................................................................................... $!
++P dengan Java................................................................................................................. $!
8na/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#,ahan Li,rary........................................................................................................3)
&enggunaan 8ditor......................................................................................................... .3*
&enggunaan 2isual Designer.......................................................................................... ..'
&e#,uat 2isual (o#/onent............................................................................................. ..'
"eer-a dengan -endela /allet............................................................................................ ..)
"eer-a dengan -endela /ro/erties..................................................................................... ..)
"eer-a dengan -endela Ins/e%tor...................................................................................... ..)
De,ugging ...........................................................................................................................)
Ases Data,ase dengan JD"(............................................................................................... .2.
&engenal JD"(................................................................................................................ .2.
Data,ase Driver................................................................................................................. .2.
&e#,uat Konesi...............................................................................................................22
&enyia/an 4a,le ..............................................................................................................23
&enga#,il dan &e#ani/ulasi Data dari Data,ase............................................................23
&enggunaan Pre/ared0tate#ent..................................................................................... .2$
"at%h 89e%ution..................................................................................................................2)
&enangani 4ransa%tion.......................................................................................................2)
&enda/atan 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 Ketidasesuaian.................................... .3*
Identitas......................................................................................................................... .3*
Asosiasi......................................................................................................................... .3*
@avigasi data..................................................................................................................3*
&a//ing 0ederhana........................................................................................................... .!3
Konfigurasi Hi,ernate ..................................................................................................... .!.
&en-alanan Hi,ernate ......................................................................................................!3
(lass<%lass Penting dala# Hi,ernate .................................................................................!!
&enggunaan Hi,ernate dengan 0/ring +6&................................................................. .!!
Hi,ernate DA+ #enggunaan 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 .................................................................................... .))
&elauan o#/ilasi /rogra# HelloWorld................................................................. .))
&en-alanan /rogra# HelloWorld............................................................................... .))
&e#,uat 0wing HelloWorld dengan @et"eans ............................................................... .))
Ko#/onen 0wing ................................................................................................................. .)*
0trutur Ko#/onen 0wing................................................................................................ .)*
"eer-a dengan JLa,el, J4e9t7ield dan J"utton.................................................................)*
"eer-a dengan J(he%"o9 dan J6adio"utton................................................................. .12
"eer-a dengan JList dan J(o#,o"o9 ..............................................................................1!
"eer-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/liasi P+0.......................................................................................................................... 23)
Data &aster........................................................................................................................231
&endesign 0%reen ........................................................................................................ 23*
&e#,uat %lass &ain dan Inisialisasi 0/ring A//li%ation (onte9t...............................2.2
&elenga/i ode PersonPanel...................................................................................... 2.$
Data 4ransasi................................................................................................................... 22'
&e#/ersia/an 0%reen 4ransasi Pen-ualan................................................................ 221
&e#,uat 0ervi%e dan DA+ untu 0ales dan Produ%t.................................................. 232
&elenga/i Kode di (lass Produ%tLoou/Dialog....................................................... 23$
&elenga/i Kode (lass 0alesPanel.............................................................................. 23)
Jas/er6e/orts..........................................................................................................................2!*
Pengenalan ........................................................................................................................ 2!*
Persia/an............................................................................................................................2!*
La/oran 4ransasi Harian..................................................................................................2$3
&e#,uat Jas/er6e/orts &enggunaan i6e/ort 2isual Designer................................2$.
&e#,uat 7ield.............................................................................................................. 2$2
&en%o#/ile 7ile -r9#l &en-adi -as/er &enggunaan Ant 4as ................................2$!
&e#/ersia/an 6e/ort0ervi%e..................................................................................... 2$'
&e#,uat :I 6e/ort...................................................................................................... 2$*
Arsitetur 4hree 4ier.............................................................................................................. 2'3
&atris Per,andingan antar /rotool re#oting............................................................ 2'!
I#/le#entasi Arsitetur 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 Disediaan 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/liasi 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 /
). Java harus Esederhana, object oriented dan mudah dimengertiG
%. Java harus Ekuat dan amanG
7. Java harus Enetral terhadap arsitektur system 3HS,processor5 dan bisa jalan di manapunG
<. Java harus bisa dijalankan dengan Ekinerja yang tinggiG
4. 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
). klik kanan my computer, pilih properties
%. setelah terbuka jendela properties, pilih tab advance
7. di dalam path path advance klik tombol system variables
<. di dalam jendela system variables pilih baris yang terdapat path, klik tombol edit
4. 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 !oolean break byte case catch
char class const continue default do
double else eLtends ?nal ?nally Uoat
for goto f implements import instanceof
int interface long native ne" package
private protected ,ublic return short static
strictfp super s"itch synchroniBed this thro"
thro"s transient try void volatile "hile
assert enum
(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.
Identifers
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 / getndeL, setndeL, 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 komponen-
komponen 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, getndeL 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, setndeL, 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 Modifer
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 .class-
nya 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 Interace
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 ,ersonDaompl yang mengimplementasikan interface
,ersonDao, di dalam interface ,ersonDao ada tiga buah method/ save, delete dan get!yd
sehingga class ,ersonDaompl 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 method-
method 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 3J05 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 dipisah-
pisahkan 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 class-
nya 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/Rsample-
code-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 dipindah-
pindah 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){ CClocal variable a=d
t.is.id 7 a=d
!
public ;ong get=d(){
return t.is.id
!
public void set<ama(;ong a<ama){ CClocal variable a<ama
t.is.nama 7 a<ama
!
public String get<ama(){
return t.is.nama
!
!
.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 klonenganfnu, 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 klonenganfnu menunjuk ke object yang sama, maka ketika
klonenganfnu 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 klonganenganfnu, 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 /
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 reerence
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
main() ifnu
setNama() aNama
main() klonenganIfnu
setId() aId
ifnu
Instance variabel:
- id
- nama
Klonengan ifnu
String object
Person object
et!od "ocal variabel
Stack

String object
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 Min MaL (eterangan
byte 6 bit -)%6 )%' Kunakan tipe data ini kalau range datanya kecil untuk menghemat
memori dibanding dengan int, terutama kalau datanya berupa
array
short ); bit -7%';6 7%';' Sama dengan byte, gunakan kalau perlu optimisasi penggunaan
memory, terutama kalau datanya berupa array
int 7% bit -
%)<'<6
7;<6
%)<'<
67;<'
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.
long ;< bit -
1.%%MQ
&)6
1.%%M
Q&)6
Kunakan tipe data ini jika jangkauan angkanya lebih lebar
daripada int
Uoat 7% bit - - 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 ;< bit 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.
boolean - - - Tipe data boolean hanya mempunyai dua nilai, true atau false.
char ); JRu&&&&
J atau &
JRu^^J
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 #rapper class
byte nteger
short Short
int nteger
long .ong
Uoat *loat
double Double
boolean !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 :rrayndeLHf!oundMLception. Mari
kita simulasikan bagaimana error :rrayndeLHf!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 /
, 7 , E %''
, 7 , U %
y 7 y L 1
y 7 y C %'
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){ CCmenyebab0an error pada 8a0tu 0ompilasi
CCla0u0an sesuatu di sini
!
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 *hit
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 bertumpuk-
tumpuk. 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 /
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 /
# met!odKetiga()
$ met!odPertama()
% met!odKedua()
& main()
' met!odKeem(at()
) met!odKelima()
*all Stack
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.
+,ce(tion +rror
-untime+,ce(tion
.bject
/!ro0able
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 parsent, 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" *ilenputStream3Obuka-
?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" *ilenputStream3Obuka-?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, mirip-
mirip 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 3nput9Hutput5 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 3HMLception5.
(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
3F5 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 setd dan getd dapat digunakan. +al ini dikarenakan
Member$ustomer mengeLtends $ustomer, sehingga method setd dan getd 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.
Polimorfsme 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 setd untuk memeriksa apakah id yang
dimasukkan bernilai null atau tidak, kalau nilainya null maka sebuah pesan dicetak ke dalam
console. Setelah pesan dicetak, method setd 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 setdZ
:pakah method setd 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 setd 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 )eerence
,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
Interace
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 ,ersonDaompl 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 ,ersonDaompl 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 Set SortedSet
.ist Map SortedMap
Iueue 0avigableSet 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 Set .ist Iueue
+ashMap +ashSet :rray.ist ,riorityIueue
+ashTable .inked+ashSet @ector
TreeMap TreeSet .inked.ist
.inked+ashMap
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 /
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
1
a
&
b
$
c
%
a
#
2
inde,
item
$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 /
: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
% $ &
a b ab
ba
keranjang
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 method-
method 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.getnstance35 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 Tipe data 3ontoh
K Mra Teks :D, !$
y Tahun Tahun )11;, 1;
M !ulan !ulan )),Jul,July
" Minggu dalam satu tahun :ngka %'
# Minggu dalam satu bulan :ngka 7
D +ari dalam satu tahun :ngka %41
d +ari dalam satu bulan :ngka %7
* Minggu dalam satu bulan :ngka <
M +ari dalam satu minggu Teks Tuesday, Tue
a ,enanda :M9,M Teks :M, ,M
+ Jam dalam satuan %< jam 3&-%75 :ngka )&
k Jam dalam satuan %< jam 3)-%<5 :ngka %<
( Jam dalam satuan )% jam 3&-))5 :ngka ))
h Jam dalam satuan )% jam 3)-)%5 :ngka )%
m Menit :ngka 7&
s Detik dalam satu menit :ngka 7;
S Milidetik :ngka )'6
B Daerah "aktu 3timeBone5 Tanda daerah "aktu ,ST, KMTQ', ,aci?c
Standard Time
f Daerah "aktu 3timeBone5 Daerah "aktu berdasar
-*$-6%%
Q&6&&, -&)&&
!erikut ini adalah contoh format tanggal dan hasilnya kalau dieksekusi /
1ormat tanggal dan waktu 2asil
Odd9MM9yyyyO %)9&79%&&<
Odd9MM9yyyy ++/mm/ssO %)9&79%&&< %7/&)/)1
Odd.MM.yyyy ++/mm/ss BO %).&7.%&&< %7/&)/)1 SKT
Odd MMM yyyyO &) Jan &1
Odd MMMM yyyyO %< *ebruary %&)&
Odd MMM yyyy hh/mm/ss a BO %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.
$lass-class implementasi dari setiap konsep di atas adalah sebagai berikut /
4onsep 3lass Immutable 3lass -utable
nstant nstant, DateTime, DateMidnight MutableDateTime
,arsial .ocalDate, .ocalTime,
.ocalDateTime,,artial
nterval nterval Mutablenterval
,eriode ,eriod, Minutes, +ours, Days,
#eeks, Months, Pears
Mutable,eriod
Durasi Duration
$hronology Kregorian$hronology,
SH$hronology 3default5,
!uddhist$hronology,
Julian$hronology,
Mthiopic$hronology,
$optic$hronology, KJ$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 method-
method 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 DatanputStream 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 dalam ?le menggunakan
*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()
!
!
!
(ode di atas akan membaca "ebsite yahoo.com kemudian mengambil isinya dan menyimpan teLt
html ke dalam ?le yahoo.tLt
ImageI!
mageH adalah class yang berisi utility untuk bekerja dengan gambar. :da beberapa class di
dalam java yang merepresentasikan gambar, antara lain con, magecon, mage dan
!u^eredmage.
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. magecon adalah implementasi con yang diperoleh dari
sebuah mage. Sedangkan !u^eredmage 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.
mageH 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 mageH 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 /
). Membuka ServerSocket
%. !erusaha menerima client
7. membuat reader dan "riter untuk menerima dan mengirim data ke client
<. dalam sebuah loop akan membaca data yang dikirim client
4. (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 /
). Membuat client socket sekaligus menghubungi server
%. Membuat reader dan "riter untuk membaca dan menulis data ke server
7. Dalam sebuah loop, kirim data ke server
<. Dalam loop yang sama berusaha terima data dari server
4. 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 nteger
double Double
Uoat *loat
short Short
char $haracter
byte !yte
boolean !oolean
long .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.
7. 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.
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 satu-
satu, 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 meng-
eLtend 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 library-
library 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 getd, setd, 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
*ilenputStream 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 MyS:M tidak mendukung transaction dan constraint. Dari sisi performance MyS: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
MyS: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.
JD!$ menyediakan tiga tipe result set untuk tujuan berbeda/
). 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..S0SM0ST@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.
7. TP,MSS$-H..SSM0ST@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.
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. getnt 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 /
). melakukan parsing terhadap \uery
%. membuat eLecution plan
7. 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 Ueksible, 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, setnt 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 MyS: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 pnser.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!yd 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 bagian-
bagian 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 sstem.
,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 sstem dalam harddisk, /le ]M., 1eb
Service, ,+2(S 3,b-ect +ata 2ase (ana%ement Sstem4" 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 untuk en!atasi asala*
Ketidaksesuaian
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 3a.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.
8d digunakan untuk menandakan sebuah property sebagai primary key. (onsekuensinya adalah
nilai property harus uni\ue dan tidak boleh null. 8d 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 8d 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 berisi informasi
username dan pass"ord ke database server.
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 3D5 atau nversion of $ontrol 3o$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!yd 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, fungsi-
fungsi 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 ,ersonServicempl 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 ,ersonServicempl 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 ,ersonServicempl
^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 ,ersonServicempl 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 ,ersonServicempl. :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 ,ersonServicempl 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"ork-
reference9html9transaction.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 class-
class 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 kon?gurasi
Declarative Transaction akan menggunakan annotation 8Transactional
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 8d, 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 8d 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 8d 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.TMMST:M, atau TemporalType.TMM. . 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-D0:.
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 8d.
Id (eneration
8Kenerated@alue adalah annotation yang digunakan berbarengan dengan 8d, 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 DM0TTP. ,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-F000KS0FM!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-SH0SD akan bertambah satu secara otomatis untuk mencatat
id terakhir yang digunakan.
0:MM $HF0T
,M-SH0SD )%7
,M0JF:.:0SD 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.DM0TTP 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 DM0TTP, 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 FFD yang akan mengenerate string yang
dipastikan uni\ue setiap kali digenerate. !erikut ini kon?gurasi 8Kenerated@alue yang
menggunakan FFD string /
^SeneratedPalue(generator7*system$uuid*)
^SenericSenerator(name7*system$uuid*+strategy7*uuid*)
,embahasan mengenai 8d 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 contoh-
contoh di bagian sebelumnya. $lass ,erson mempunyai beberapa relationship, salah satunya
adalah Hne-to-Hne relationshipe ke class $ustomer. $lass ,erson juga mempunyai relasi Many-
to-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 Detail-
nya 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/
). 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.
7. 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 8ndeL$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 DM0TTP 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
.aBynitialiBationMLception 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.
&ransormation
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 -ead-Hnly 0on strict read
"rite
-ead #rite Transactional
Mh$ache Pes Pes Pes 0o
HS$ache Pes Pes Pes 0o
S"arm$ache Pes Pes 0o 0o
Jboss Tree$ache Pes 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.
maLMlementsnMemory 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.
timeTodleSeconds digunakan untuk menandai berapa lama cache tidak digunakan sebelum
deremove. (alau data tersebut sudah mencapai "aktu di timeTidleSeconds 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 Deskripsi
(omponen S"ing Memuat semua class-class yang dibutuhkan untuk membuat aplikasi
berbasis KF, dari tombol, table, tab, menu, toolbar dan sebagainya
.ook and *eel 3.a*5 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.
:ccessibility :, *aslititas untuk mengembangkan aplikasi bagi penyandang cacat,
misalnya dukungan untuk membuat huruf braile, kemampuan
mengambil input dari layar sentuh dan sebagainya.
Java %D :, !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.
Drag-and-drop Menyediakan kemampuan drag-and-drop antara program Java dan
program lain yang ditulis spesi?k untuk suatu platform sistem
operasi tertentu.
nternationaliBation 3i)6n5 Membantu pengembang perangkat lunak untuk membangun aplikasi
yang dapat mendukung semua bahasa dan huruf yang ada di dunia.
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.plaf javax.swing.text
javax.swing javax.swing.plaf.basic javax.swing.text.html
javax.swing.border javax.swing.plaf.metal javax.swing.text.rtf
javax.swing.colorchooser javax.swing.plaf.multi javax.swing.table
javax.swing.event javax.swing.plaf.synth javax.swing.tree
javax.swing.flechooser 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 langkah-
langkah yang harus anda lakukan untuk membuat program E+ello#orldG berbasis komponen
S"ing/
). nstall Java Development (it 3JD(5
%. Membuat program +ello#orld itu sendiri
7. 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 komponen-
komponen 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 S+*T Q *;, atau klik kanan ?le
,enjumlahan.java kemudian pilih menu -un *ile.
$atatan /
Method nteger.parsent 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 komponen-
komponen/
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 getSelectedtem 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 JMenutem. JMenutem 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 JMenutem, JMenu juga dapat menerima class
J$heck!oLMenutem dan J-adio!uttonMenutem.
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 /
). ]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
7. ]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,.
4. ]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-and-
dropnya 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.
7. 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
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 JMenutem. .angkah berikutnya adalah menambahkan JMenutem 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 JMenutem dari
Jendela nspector, kemudian untuk masing-masing JMenutem 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 JMenutem, 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!oLMenutem. ,erilaku J$heck!oLMenutem tidak berbeda jauh
dengan J$heck!oL biasa, bedanya hanyalah J$heck!oLMenutem berada dalam struktur
menu. $ara menambahkan J$heck!oLMenutem 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!oLMenutem sedikit sepesial dibandingkan dengan JMenutem, karena
J$heck!oLMenutem memiliki properties selected. ,roperties selected ini digunakan untuk
menentukan apakah J$heck!oLMenutem dalam keadaan terpilih atau tidak.
6. Menambahkan J-adio!uttonMenutem. Dalam contoh ini kita akan mempunyai dua buah
J-adio!uttonMenutem, 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!uttonMenutem juga
memerlukan !uttonKroup agar hanya satu buah J-adio!uttonMenutem 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!uttonMenutem ke dalam !uttonKroup. ,ilih masing-masing
J-adio!uttonMenutem dari Jendela nspector, kemudian perahatikan Jendela ,roperties dari
J-adio!uttonMenutem tersebut, pada bagian group!utton pilih item groupHpenMethod,
seperti terlihat dalam gambar di ba"ah ini /
,roperties dari J-adio!uttonMenutem
)). $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 JMenutem. Seperti halnya JMenu!ar, J,opupMenu dapat memiliki child
berupa JMenu, JMenutem, J$heck!oLMenutem, J-adio!uttonMenutem dan JSeparator.
Menambahkan JMenutem 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 JMenutem 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 $re0defned 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 Deskripsi
sho"$on?rmDialog Meminta kon?rmasi daru user, seperti yes9no9cancel
sho"nputDialog Meminta input dari user, baik berupa input teLt menggunakan JTeLt*ield
maupun pilihan menggunakan J$ombo!oL
sho"MessageDialog Memberitahukan user tentang apa yang baru saja terjadi
sho"HptionDialog Kabungan dari ketiga jenis dialog di atas
S"ing juga menyediakan method sho"nternal]]] yang digunakan jika kita bekerja dengan
Jnternal*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 ditengah-
tengah 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:TH0SMMSS:KM
c5 #:-00KSMMSS:KM
d5 ,.:0SMMSS:KM 3tanpa icon5
<. optionType / Mende?sikan tombol-tombol yang akan ditampilkan di bagian ba"ah dari
dialog.
a5 DM*:F.TSH,TH0
b5 PMSS0HSH,TH0
c5 PMSS0HS$:0$M.SH,TH0
d5 H(S$:0$M.SH,TH0
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.
'. Title / Judul dari dialog yang diletakkan di bagian paling atas dari dialog.
6. nitial@alue / 0ilai default dari pilihan yang mungkin ada dalam dialog.
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)
4. 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.())
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.())
!
!
6. $ompile dan jalankan aplikasinya dengan menekan tombol S+*T Q *;
!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 untuk merepresentasikan Model dalam bentuk visual. Semisal
komponen S"ing, seperti / JTable, J.ist, J$ombo!oL dan sebagainya. @ie" juga bertanggung
ja"ab untuk menangkap interaksi user terhadap sistem, semisal / klik mouse, penekanan
tombol keyboard, barcode 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-per-
halaman 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
addtem 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 -oled$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 Jnternal*rame. .angkah-
langkahnya 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 letakkan di package
com.googlecode.projecttemplate.pos.ui.security
!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
%. (emudian beri nama untuk satu per satu untuk setiap tombol di atas / btn:dd, btnMdit,
btnDelete, btnSave, btn$ancel dan btn(eluar
7. (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 /
). 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.
7. .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
4. !erikutnya adalah menambahkan Jmenutem 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
'. Setelah menu selesai dibuat, langkah terakhir adalah meletakkan Jdesktop,ane ke dalam
Main*rame sebagai tempat dimana nanti Jternal*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 SecurityServicemp,
berikut ini adalah class-class yang diperlukan untuk membuat SecurityService/
$lass MenuDao dan -oleDao yang diletakkan dalam package
com.googlecode.projecttemplate.pos.dao
^6epository
public class Benu:ao e,tends >ase:aoHibernateTBenuV{
!
^6epository
public class 6ole:ao e,tends >ase:aoHibernateT6oleV{
!
(arena kita sudah membuat class !aseDao+ibernate maka membuat MenuDao dan -oleDao
menjadi sangat ringkas.
nterface SecurityService yang diletakkan dalam package
com.googlecode.projecttemplate.pos.service
public inter/ace SecurityService {
public 4erson save(4erson person)
public 4erson delete(4erson person)
public 4erson get4erson(;ong id)
public ;istT4ersonV get4ersons()
public Benu save(Benu menu)
public Benu delete(Benu menu)
public Benu getBenu(;ong id)
public ;istTBenuV getBenus()
public 6ole save(6ole role)
public 6ole delete(6ole role)
public 6ole get6ole(=nteger id)
public ;istT6oleV get6oles()
!
Dan terakhir class SecurityServicempl di dalam
packagecom.googlecode.projecttemplate.pos.service.impl yang mengimplementasikan
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)
!
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-desktop-
book9code9src9images
(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.
Fser memilih satu baris di dalam tbl,erson
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
(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 method-
methodnya /
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
Method-method di atas akan membentuk kerangka dari ,erson,anel dan menyediakan
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 ;istT4ersonV persons
private 4erson person
private ]HileD.ooser c.ooser
private /inal int ma,4ictureSi?e 7 %)N
private =mage=con image
private 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 mageH kemudian mageH
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 mageH 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
mageH. (ebalikan dari method sebelumnya yang merubah ?le image menjadi byte array.
Sekarang kita lihat kode di konstruktor ,erson,anel, di dalam konstruktor-nya tedapat kode-
kode untuk meload ,erson dari database dan diletakkan dalam tbl,erson, kemudian kode
untuk membatasi panjang tLt0ama karena panjang kolom di database terbatas, kalau nama-
nya 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-desktop-
book9code9src9com9googlecode9projecttemplate9pos9util9TeLt$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-desktop-
book9code9src9com9googlecode9projecttemplate9pos9util9$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 Jnternal*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 Jnternal*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 dan nama-nama komponen dalam
Sales.ookupDialog seperti gambar di ba"ah ini /
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 kode-
kode 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 ,roductServicempl. 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 ,roductServicempl /
^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 SalesServicempl/
^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 kode-
kode 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-desktop-
book9code9src9com9googlecode9projecttemplate9pos9ui9transaction9Sales.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 .aBynitialiBationMLception 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.
Fser memilih satu baris di dalam tblSalesDetail
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
Fser mengetikkan id barang kemudian menekan enter di tLt,roductd
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.
Fser menekan tombol btn.ookup,roduct
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.
(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 method-
methodnya /
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 komponen-
komponen 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 columnndeL. ,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,roductd, atau ketika user melakukan barcode scan di
tLt,roductd maka event action,erformed dari tLt,roductd akan dipanggil. Fntuk
mendengarkan event action,erformed klik kanan di tLt,roductd 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())))
is4roduct=nSales:etails 7 true
brea0
!
!
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@)
!
!
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:0TTP dan setting
properties-nya seperti gambar di ba"ah ini /
Terlihat dari gambar di atas bah"a variabel name adalah SFMSIF:0TTP, 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 meng-
compile ?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 -eportServicempl
^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 -eportServicempl 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 8eteans, 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 static SecurityService securityService
private static SalesService salesService
private static 4roductService productService
private static 6eportService reportService
private static 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
Jmenutem 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
Implementa
si
4ebutuhan bandwith
-M !inary T$,
socket
+anya
aplikasi
Java
MJ!, -M
murni
Sangat besar, cocok di intranet
$H-!: !inary T$,
socket
Java, $Q
Q,
,ython
dll
mplementasi
sudah jarang,
nyaris
absolete
Sangat besar, cocok di intranet
Spring
+TT,inv
oker
!inary +TT, Java dan
harus
pake
spring
Spring
remoting
$ukup besar, cocok untuk intranet
+essian !inary +TT, Java dan
library
hessian
+essian $ukup besar, cocok untuk intranet
+essian TeLt 9
]M.
+TT, Java dan
library
hessian
+essian $ocok untuk internet, karena
berbasis teLt
#ebservi
ce
TeLt 9
]M.
+TT, Semua
platform
bisa
J:]-#S,
Spring #S,
:Lis%
$ocok untuk internet, karena
berbasis teLt
+TT,
call "ith
json9]M.
TeLt 9
json 9
]M.
+TT, Semua
platform
bisa.
:pache
+TT,$lie
nt
Jakson, JSH0
lib,
$ocok untuk internet, karena
berbasis teL
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
r*
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*
p3service$re/7*productService*
p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4roductService*C
V
Tbean id7*purc.aseServiceHttp=nvo0er*
class7*org.spring/rame8or0.remoting..ttpinvo0er.SimpleHttp=nvo0erService@,porte
r*
p3service$re/7*purc.aseService*
p3service=nter/ace7*com.googlecode.pro#ecttemplate.pos.service.4urc.aseService*
CV
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 +ttpnvoker 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+ttpnvoker ke dalam Frl
9,ersonService, url tersebut nantinya bisa diakses oleh client dari url /
.ttp3CClocal.ost3M'M'C4ersonService
!ean personService+ttpnvoker sendiri adalah instansiasi class
Simple+ttpnvokerServiceMLporter yang mengimplementasikan +ttp+andler dan
mengekspose personService sebagai http invoker.
Setelah selesai membuat kon?gurasi untuk server, sekarang kita buat kon?gurasi untuk client-
nya. (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, B,ack dapat mengenerate installer
dengan dua cara berbeda /
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 ?le tunggal 3jar5 sehingga sangat ringkas untuk
didistribusikan
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 Nf,:$(S+HMM9sample9simple, dimana
Nf,:$(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 4rocessing 3 install.,ml
$V Autput 3 install.#ar
$V >ase pat. 3 .
$V Kind 3 standard
$V Dompression 3 de/ault
$V Dompr. level3 $%
$V =?4ac0 .ome 3 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 t.e s0eleton installer
Dopying - /iles into installer
Berging - #ars into installer
Writing 1 4ac0s into installer
Writing 4ac0 '3 >ase
Writing 4ac0 %3 :ocs
Writing 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 Nf,:$(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 Inormation ;ino<
!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
N0ST:..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/
N0ST:..S,:T+ / path ke folder instalasi
N:,,.$:TH0SSDM*: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
NSH7S.: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.
Nnstaller*rame.log?le,ath / path untuk log proses instalasi. (alau variabel ini tidak diset,
maka digunakan nilai default / N0ST:..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 Solaris yang
berjalan di processor sparc
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 Preerence ;gui$res<
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 B,ack tidak akan
menginstall ?le-?le yang dide?nisikan dalam pack ini.
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.
packmgd / 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.
InoPanel dan /&MLInoPanel
,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
Enfo,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.#arlibCL 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.#arlibCL 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?gurasi-
nya 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 3N0ST:..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 EB,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 ,HS-
server-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.
)eerensi dan Bacaan Le"ih Lan#ut
). Java Tutorial / http/99do"nload.oracle.com9javase9tutorial
%. Java Documentation / http/99do"nload.oracle.com9javase9;9docs9
7. 0etbeans ndonesia / http/99groups.yahoo.com9group90etbeans-indonesia9
<. Java Fser Kroup ndonesia / http/99groups.yahoo.com9group9jug-indonesia9
4. Java Design ,attern / http/99""".javacamp.org9design,attern9
;. Java Desktop / http/99""".javadesktop.org
'. JKoodies / http/99""".jgoodies.com
6. S"ing] / http/99""".s"inglabs.org
1. 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.

You might also like