Pemrograman J2me
Pemrograman J2me
Copyright 2004 CSRG STMIK-AMIKBANDUNG Jl. Jakarta 28 Bandung 40272 Website http://linux.stmik-abg.ac.id
DAFTAR ISI
1. Pengantar Java . 2. Java dasar .. 3. Pemrograman berorientasi objek dalam java . 4. Java lanjut .. 5. I/O Stream . 6. Pengantar J2ME .. 7. Pengembangan aplikasi dengan J2ME . 8. MIDlet dasar .. 9. Event handling .. 10. User interface . 11. Pemrograman database dengan RMS 12. Pemrograman client-server dengan socket .. 13. Installasi aplikasi pada perangkat wireless . 14. Penutup 15. Daftar Pustaka .. 16. Lampiran 1 3 6 11 14 16 18 21 23 25 27 33 41 43 44
Pengantar Java Java dasar Pemrograman berorientasi objek dalam Java Java lanjut I/O Stream
J2SE
Bagian 1
1
Pengantar JAVA
Java merupakan bahasa pemrograman general purpose, Java bisa digunakan untuk pembuatan aplikasi web, database, grafis dan berbagai aplikasi lainnya seperti bahasa pemrograman lainnya. Mengapa Java menjadi andalan bagi para programmer ? Selain dukungan API yang begitu lengkap, hasil program Java akan bisa dijalankan di semua platform selama disitu terdapat JVM (Java Virtual Machine). Kalau seorang programmer memilih Java sebagai bahasa untuk pengembangan aplikasinya, maka dia tidak perlu pusing memikirkan apakah sistem operasi usernya mendukung atau tidak sehingga Java mempunyai slogan write once, run every where. Memang kalau hanya sekedar program helloWord jika ditulis dengan bahasa C akan bisa dijalankan di berbagai platform, akan tetapi untuk untuk program-program yang sudah menyentuh operasi I/O, komunikasi network dan berbagai hal yang spesifik terhadap platform tertentu maka kebutuhan bahasa yang cross platform menjadi penting dan Java adalah solusinya.
A. Keluarga Java
Sun Microsystem sebagai pengembang bahasa Java telah mengembangkan beberapa versi Java, seperti: J2EE (Java 2 Enterprise Edition), J2SE (Java 2 Standar Edition), J2ME (Java 2 Micro Edition), Java Card. J2EE dan J2SE dikembangkan untuk platform Server dan PC, J2ME dikembangkan untuk platform mobile device sedangkan Java Card untuk platform simcard. Pada dasarnya versi-versi tersebut sama, hanya penggunaan API yang berbeda sesuai dengan target platform yang akan digunakan dan kompatibilitas platform tersebut.
myProgram.java
Compiler
myProgram.class
Gambar 1.2 Alur pembuatan aplikasi dengan Java Dalam pembuatan aplikasi dengan bahasa Java, pertama yang dilakukan adalah mengetik program dengan editor sembarang dan kemudian menyimpannya dengan ekstensi .java. Setelah itu program dikompile sehingga mendapatkan class-classnya. File class inilah yang dirun oleh interpreter (dalam hal ini JVM) menjadi aplikasi seperti program-program yang dibuat dengan bahasa-bahasa pemrograman lainnya.
2
Java Dasar
A. Kebutuhan software
Untuk membuat program Java diperlukan Java Development Kit yang berguna untuk mengkompile source kode sehingga didapatkan class-classnya. Java Development Kit bisa didownload di http://java.sun.com/
public class notHelloWorld { public static void main(String[] args) { System.out.println("Not Hello World"); } }
Sebagai contoh kompilasi program notHelloWorld yang berada di direktori D:\java adalah sebagai berikut
D:\java>javac notHelloWorld.java
Hasil kompilasi berupa file notHelloWorld.class seperti tampak pada output berikut.
D:\java>dir Volume in drive D is DATA-20 GB Volume Serial Number is 0930-1ED9
Sebagai contoh untuk menjalankan file notHelloWorld.class perintahnya adalah sebagai berikut
D:\java>java notHelloWorld Not Hello World
Sebagai contoh pembuatan dokumentasi program notHelloWorld di atas yang telah dibuat adalah sebagai berikut
D:\java>javadoc notHelloWorld.java Loading source file notHelloWorld.java... Constructing Javadoc information... Standard Doclet version 1.4.0 Generating constant-values.html... Building tree for all the packages and classes... Building index for all the packages and classes... Generating overview-tree.html... Generating index-all.html... Generating deprecated-list.html... Building index for all classes... Generating allclasses-frame.html... Generating allclasses-noframe.html... Generating index.html... Generating packages.html... Generating notHelloWorld.html... Generating package-list... Generating help-doc.html... Generating stylesheet.css...
Sehingga akan dihasilkan dokumentasi program dalam format HTML seperti gambar berikut
3
Pemrograman Berorientasi Objek dalam Java
Java merupakan bahasa pemrograman yang 100% berorientasi objek sehingga untuk membuat aplikasi berbasis Java, kita harus memahami konsep dan implementasi pemrograman berorientasi objek.
Kelas
instantiasi
Objek
Gambar 3.1. Pembuatan objek dari kelas dengan instantiasi Sebagai contoh kita ambil kelas manusia. Kelas manusia mempunyai atribut : nama. Selain itu kelas manusia juga mempunyai metodh: tampilkanNama, kerja, makan. Kasus diatas diimplementasikan dalam bahasa Java sebagai berikut
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: public class manusia { public String nama; public manusia(String n) { this.nama = n; } public String tampilkanNama() { return nama; } public void makan() { System.out.println("Nyam... nyam... nyam..."); } public void kerja() {
Adapun kode untuk menginstantiasi kelas manusia menjadi objek Andi yang mengimplementasikan metodh: tampilkanNama dan makan adalah sebagai berikut.
1: 2: 3: 4: 5: 6: 7: 8: 9: public class andi { public static void main(String arg[]) { manusia andi= new manusia("Andi"); System.out.println("Nama= "+ andi.tampilkanNama()); andi.makan(); } }
B. Pewarisan
Salah satu kelebihan pemrograman berorientasi objek adalah penggunaan ulang kodekode yang telah dibuat. Pewarisan adalah salah satu cara untuk menggunakan kodekode yang telah dibuat sebelumnya. Sebagai contoh kelas manusia diturunkan menjadi kelas programmer.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: public class programmer extends manusia { public programmer(String n) { super(n); } public void kerja() { System.out.println("TakTakKlik.."); } public void bersantai() { System.out.println("Game over, You lose..."); } }
Badu adalah seorang programmer keturunan manusia, setelah dia makan lalu kerja dan terakhir dia bersantai dengan komputernya sehingga implementasi dengan kode javanya adalah
1: 2: 3: 4: 5: 6: 7: 8: 9: public class badu { public static void main(String arg[]) { programmer badu= new programmer("badu"); System.out.println("Nama= "+ badu.tampilkanNama()); badu.makan(); badu.kerja(); badu.bersantai();
Setelah Objek Badu memberitahu namanya, dia makan dengan metodh warisan dari kelas manusia, kemudian dia kerja dengan metodh khusus kelas programmer dan terakhir dia bersantai juga dengan metodh khusus kelas programmer. Kelas turunan akan mewariskan atribut-atribut dan metodh-metodh parentclassnya/baseclass, akan tetapi dia tidak mewarisi konstruktor-konstruktornya sehingga ketika andi makan maka dia makan dengan metodh dari parentclassnya (manusia). Akan tetapi ketika dia kerja, dia kerja dengan metodh baru yang didefinisikan khusus pada kelas programmer (TakTakKlik.. bukan Kerja.kerjaaa), inilah yang disebut dengan metodh overriding.
C. Polymorfisne
Salah satu pilar Pemrograman Berorientasi Objek yang lain adalah polymorfisme yaitu kemampuan beberapa objek bertipe sama bereaksi secara berbeda terhadap pesan yang sama. Sebagai contoh kita tambah lagi turunan dari manusia yaitu kelas sopir. Kelas sopir diimplementasikan dalam java
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: public class sopir extends manusia { public sopir(String n) { super(n); } public void kerja() { System.out.println("Ngung... Ngung... Ngung...Ciiit.."); } }
Dedi adalah seorang sopir keturunan manusia, untuk menginstantiasi objek dedi ditunjukkan dalam kode berikut.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: public class dedi { public static void main(String arg[]) { sopir dedi= new sopir("Dedi"); System.out.println("Nama= "+ dedi.tampilkanNama()); dedi.makan(); dedi.kerja(); } }
Kemudian Badu sang programmer dan Dedi sang sopir diperintahkan untuk bekerja, apa reaksinya? Untuk melihat reaksi masing-masing, perhatikan kode java berikut!
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: public class pekerja { public static void main(String args[]) { manusia[] profesi= new manusia[2]; profesi[0]=new programmer("Andii"); profesi[1]=new sopir("Dedi"); for (int i=0; i<2; i++) { profesi[i].kerja(); } } }
Dari contoh di atas terlihat bahwa dengan pesan yang sama akan menghasilkan reaksi yang berbeda tergantung implementasi metodhnya.
D. Pengkapsulan
Pilar terakhir dari 3 pilar Pemrograman Berorientasi Objek adalah pengkapsulan, dimana pengembang software dapat menyembunyikan detail suatu objek. Hak akses public memungkinkan semua kelas mengaksesnya, hak akses protected hanya diberikan kepada kelasnya sendiri dan turunannya, serta kelas-kelas dalam satu paket. sedangkan private hanya boleh diakses oleh kelasnya sendiri.
E. Interface
Untuk membuat suatu kelas dapat kita turunkan dengan pewarisan field-field dan metodh pada base classnya. Bagaimana kita membuat kelas yang menurunkan sifat dari beberapa base class? misalkan kita akan membuat kelas superman yang dia bisa membuat program layaknya programmer, dia juga ahli menggunakan senjata layaknya tentara, bahkan dia bisa terbang seperti elang (keturunan binatang)? Caranya adalah dengan pewarisan ganda. Dalam Java tidak dikenal pewarisan ganda, sehingga digunakan interface. Contoh pewarisan ganda yang tidak benar dalam Java
1: 2: 3: public class superman extends programmer,kambing,sapi { }
10
Kemudian kelas superman diinstantiasi menjadi objek bernama bejo, contoh kode program javanya sebagai berikut:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: public class bejo { public static void main(String arg[]) { superman bj= new superman(); bj.memrogram(); { System.out.println("Implementasi memrogram ...tak..tik"); } bj.menembak(); { System.out.println("Implementasi menembak ...dor..dor"); } bj.terbang(); { System.out.println("Implementasi terbang......Zap...."); } } }
Dalam kode diatas bejo menentukan sendiri cara mengimplementasi beberapa metodh dari interface yang telah didefiniskan dalam kelas superman (misalkan cara memrogramnya bagaimana, cara menembaknya bagaimana dan cara terbangnya seperti apa), selain itu bejo tidak berminat untuk mengimplementasikan metodh buangKotoran dari interface burung (misalnya karena burung biasa membuang kotoran di sembarang tempat). Jadi interface dapat dianalogikan seperti menandatangani kontrak kerja, misalnya sebagai dosen dia wajib mengajar, membuat soal ujian dsb, akan tetapi cara mengajarnya dan membuat soalnya dilakukan terserah masing-masing dosen (tidak ditentukan dalam kontrak kerja)
11
4
Java Lanjut
A. Pemaketan kelas-kelas
Ketika kelas-kelas yang dibuat semakin banyak dan semakin banyak, hal ini akan membuat struktur program menjadi rumit kalau tidak dikelola dengan baik. Untuk itu kelas-kelas disimpan dalam paket-paket tertentu, misalkan kelas programmerC, programmerJava, programmerPHP berada/disimpan dalam paket programmer. Sementara marinir, kopasus, paskhas berada dalam paket tentara. Keuntungan pengaturan program dalam nama paket-paket adalah: 1. Terhindar dari konflik penamaan. Misalkan saja dalam membuat program kita menggunakan/mengimport kelas dari luar yang dibuat oleh programmer lain, sehingga mungkin saja dalam penamaan kelas terjadi persamaan. Dengan menunjukkan nama lengkap paket/kelasnya maka tidak akan terjadi konflik penamaan 2. Teratur. Misalkan paket dosen terdapat kelas dosenPBO, dosenKalkulus, dosenEtika. Paket tentara terdapat marinir, kopasus, paskhas. Dengan struktur demikian, maka akan mempermudah ketika ketika kita akan menggunakan/mengimport kelas, misalkan saja kita akan mengimport kelas kopasus, tentunya kita mencari dalam paket tentara-bukan paket dosen. Sebagai contoh kita akan membuat 2 paket: paket programmer dan paket tentara. Paket programmer terdiri dari kelas programmerC dan programmerJava. Sedangkan paket tentara terdiri dari kelas kopasus dan marinir.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: /* Disimpan dalam "programmer/programmerC.java" */ package programmer; public class programmerC { public programmerC() { } public void kerja() { System.out.println("Implementasi metodh kerja Programmer C .."); } public void bersantai() { System.out.println("Implementasi metodh bersantai Programmer .. "); } }
12
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
/* Disimpan dalam file "programmer/programmerJava.java" */ package programmer; public class programmerJava { public programmerJava() { } public void kerja() { System.out.println("Implementasi metodh kerja Programmer Java .."); } public void bersantai() { System.out.println("Implementasi metodh bersantai Programmer Java.. "); } }
13
B. Mengimport kelas
Untuk dapat mengimport kelas digunakan keyword import [nama paketnya]. Sebagai contoh instantiasi kelas programmerJava dalam paket programmer menjadi objek ahmed.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: /* Disimpan dalam file "ahmed.java" */ import programmer.programmerC; class ahmed { public static void main(String arg[]) { programmerC ahmed= new programmerC(); ahmed.kerja(); } }
Banyak sekali kelas-kelas yang telah dibuat oleh Sun Microsystem yang dapat kita gunakan, misalkan untuk membuat windows bisa digunakan/import paket awt dan swing.
/* Disimpan dalam file "JavaOk.java" */ import javax.swing.*; public class JavaOk { public static void main(String[] args) { JFrame frame = new JFrame("Java?"); final JLabel label = new JLabel("Java is Ok Sir"); frame.getContentPane().add(label); frame.pack(); frame.setVisible(true); } }
14
5
I/O Stream
A. Membaca isi file
Java menyediakan paket java.io yang berisi kelas-kelas untuk input-output data. Contoh berikut digunakan untuk membaca isi file dan menampilkannya dalam layar. Pertama buatlah file data.txt kemudian isikan dengan nama-nama teman Anda. Program bacaFile akan membaca isi file data.txt perbaris dan menampilkannya ke layar.
15
Program diatas akan membaca isi file dengan kelas FileInputStream byte demi byte pada tiap baris dan kemudian ditampung dengan BufferedReader dan akhirnya dicetak ke layar.
B. Menulis ke file
Program kedua tentang I/O stream akan menuliskan ke file data2.txt. Kelas yang digunakan merupakan lawan pada program membaca file yakni FileOutputStream. Kode program untuk menuliskan ke file data2.txt adalah seperti berikut.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: import java.io.*; class tulisFile{ public static void main(String args[]) { String namaFile="data2.txt"; try{ BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in)); String masukan, isi; System.out.println("Tulis input"); masukan=stdin.readLine(); FileOutputStream fout; fout=new FileOutputStream(namaFile); new PrintStream(fout).print(masukan); new PrintStream(fout).println(); fout.close(); } catch(Exception e) { System.out.println("Error:"+e); } } }
Hasil penulisan ke file data2.txt akan berisi string yang dimasukkan ketika menjalankan program tulisFile
Pengantar J2ME Pengembangan aplikasi dengan J2ME MIDlet dasar Event handling User interface Pemrograman database dengan RMS Pemrograman Client Server dengan Socket Installasi Aplikasi pada Perangkat Wireless Penutup
J2ME
Bagian 2
16
6
Pengantar J2ME
Perkembangan pemrograman aplikasi selama ini terfokus pada pengembangan aplikasi stand alone, kemudian berkembang lagi menjadi aplikasi client server serta aplikasi berbasis web. Dengan berkembangnya teknologi wireless seperti PDA dan handphone pada beberapa tahun terakhir ini, maka mulailah babak baru berupa aplikasi wireless. Dengan semboyan write once run everywhere, teknologi Java dengan portabilitas yang tinggi, memungkinkan untuk jalan di segala sistem operasi selama disitu ada JVM (Java Virtual Machine) termasuk perangkat wireless dengan ukuran memori yang relatif kecil.
17
Salah satu kelemahan CLDC yang merisaukan programmer adalah tidak adanya dukungan floating point sehingga kreatifitas programmer sangat diperlukan. Pembahasan buku ini mengacu pada J2ME configuration CLDC.
18
7
Pengembangan Aplikasi Dengan J2ME
A. Perangkat pengembangan
Selain JDK dalam pengembangan aplikasi dengan J2ME diperlukan juga software tambahan yakni J2ME Wireless Toolkit. Dalam Toolkit ini terdapat API J2ME dan emulator beberapa perangkat wireless. Toolkit ini berfungsi untuk mengkompile dan mensimulasikan aplikasi pada emulator.
Gambar 7.1 J2ME Wireless Toolkit Beberapa menu fungsi utama J2ME Wireless Toolkit antara lain: File New Project, tombol ini digunakan untuk memulai membuat project File Open Project, tombol ini digunakan untuk membuka project yang pernah dibuat Project Build, tombol ini digunakan untuk mengkompile source kode yang terdapat di dalam direktori /apps/nama_project/src/ Project Run, tombol ini digunakan untuk menjalankan aplikasi pada emulator sesuai pilihan Project Package, menu ini untuk membundel aplikasi yang telah dibuat. Menu ini digunakan terakhir kali setelah semua tahapan pengembangan selesai Project Setting, tombol ini digunakan untuk menyeting beberapa parameter aplikasi yang dibuat
19
Sedangkan keterangan direktori-direktori yang ada didalam J2ME Wireless Toolkit adalah sebagai berikut: File/Direktori appdb\ apps\ bin\ docs\ lib\midpapi.zip sessions\ wktlib\devices\ Keterangan Direktori berisi file-file database, seperti file-file RMS file Direktori yang berisi demo aplikasi dan aplikasi-aplikasi yang dibuat dengan KToolbar Batch file dan file-file executable tool Direktori yang berisi dokumtasi API Arsip kelas-kelas API CLDC dan MIDP. File-file ini digunakan pada proses kompilasi dan preverification Direktori default yang berisi profiling, monitoring memori dan session file pada monitoring network Direktori yang berisi file-file properti device-device yang digunakan pada emulator
B. Tahapan pengembangan
Pengembangan aplikasi dengan J2ME memerlukan tahapan-tahapan seperti yang dijelaskan dalam gambar dibawah ini
Gambar 7.2 Tahapan pengembangan aplikasi dengan J2ME Setelah semua fungsional aplikasi sesuai dengan yang direncanakan, aplikasi perlu disimulasikan ke beberapa emulator sesuai dengan target usernya. Secara umum semua perangkat wireless yang telah mensupport Java(J2ME) maka aplikasi yang kita buat akan bisa dijalankan di perangkat tersebut, namun terkadang untuk tiap devais target
20
mempunyai kekhususan seperti lebar dan tinggi layar/display, sehingga mungkin kita perlu membuat beberapa versi distribusi aplikasi kita yang disesuaikan dengan devais targetnya.
21
8
MIDlet Dasar
A. Siklus hidup sebuah MIDlet
MIDlet (Mobile Information Device Applet) mempunyai 3 kemungkinan kondisi: pause, active dan destroyed. Ketika MIDlet mulai dijalankan, maka MIDlet berada pada kondisi aktif. Jika terdapat interupsi seperti adanya panggilan pada ponsel maka MIDlet berada pada kondisi pause. Dan ketika selesai menjalankan MIDlet maka diperlukan metodh untuk membunuh MIDlet dengan destroyApp(). Ketiga kondisi ini digambarkan pada diagram di bawah ini:
B. MIDlet sederhana
Untuk memulai belajar J2ME ini kita ambil contoh program NotHelloWorld yang akan menampilkan tulisan Not Hello World melalui TextBox. Pertama yang perlu dilakukan adalah membuat project baru dan memberi nama NotHelloWorld, kemudian salinlah kode berikut dan simpan ke dalam file NotHelloWorld.java di dalam direktori /apps/NotHelloWorld/src/.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: import javax.microedition.MIDlet.*; import javax.microedition.lcdui.*; public class NotHelloWorld extends MIDlet { private Display display; public NotHelloWorld() { display = Display.getDisplay(this); } public void startApp() {
22
Contoh kode diatas akan menampilkan sebuah TextBoox yang diberi label Not dan didalamnya terdapat kata Not Hello World. Ketika program dipanggil maka state MIDlet berada pada active dengan memanggil metodh startApp() dan pada state inilah sebuah TextBoox dibuat (instantiasi) untuk kemudian menampilkan string Not Hello World. Setiap MIDlet harus mempunyai minimal 3 metodh: startApp(), pauseApp() dan destroyApp(boolean unconditional). Output program diatas seperti pada gambar di bawah ini
23
9
Event Handling
Event berguna untuk menangani interaksi user dengan program, misalnya user memilih sebuah menu dalam aplikasi MIDlet.Untuk menangani event perlu mengimplementasikan interface CommandListener dan atau ItemListener. CommandListener berfungsi untuk menangani jika user memilih Command tertentu sedangkan ItemListener berfungsi untuk menangani jika user mengubah nilai seperti misalnya mengubah pilihan pada ChoiceGroup. Untuk memberikan gambaran sebuah event bekerja, perhatikan contoh berikut.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: import javax.microedition.MIDlet.*; import javax.microedition.lcdui.*; public class NotHelloWorld2 extends MIDlet implements CommandListener{ private Command cmdExit; private Display display; public NotHelloWorld2() { display = Display.getDisplay(this); cmdExit = new Command("Exit", Command.SCREEN,2); } public void startApp() { TextBox t = new TextBox("Not ","Not Hello World",256,0); t.addCommand(cmdExit); t.setCommandListener(this); display.setCurrent(t); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command cmd,Displayable disp) { if(cmd==cmdExit) { destroyApp(false); notifyDestroyed(); } } }
24
Pada contoh kedua ini, kita tambahkan sebuah Command untuk keluar dari aplikasi yang telah kita buat pada contoh 1. Ketika program pertama kali dipanggil, maka state berada pada Aktif, disini sebuah TextBox dan Command dibuat. Kemudian program menunggu respon dari user dengan mengimplementasikan CommandListener. Ketika user menekan Command cmdExit (baris 32-39), maka program memanggil metodh(destroyApp) untuk membunuh MIDlet.
25
10
User Interface
Dalam sebuah aplikasi seringkail membutuhkan user interface seperti misalnya dibutuhkan input pada aplikasi yang akan dibangun. Contoh di bawah ini mendemonstrasikan input dengan sebuah TextField dan output dengan StringItem.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: import javax.microedition.MIDlet.*; import javax.microedition.lcdui.*; public class converter extends MIDlet implements CommandListener{ private private private private private private private private Display display; Command cmdExit; Command cmdConvert; Command cmdOK; Form form1; Form form2; TextField input; StringItem hasil;
public void startApp() { display = Display.getDisplay(this); cmdConvert = new Command("Convert",Command.SCREEN,1); cmdExit = new Command("Exit",Command.SCREEN,1); cmdOK = new Command("OK",Command.SCREEN,1); form1 input = new Form("Converter"); = new TextField("Input:",null,256,TextField.ANY);
form1.addCommand(cmdConvert); form1.addCommand(cmdExit); form1.setCommandListener(this); form1.append(input); form2 = new Form("Hasil"); hasil = new StringItem(null,null); form2.append(hasil); form2.addCommand(cmdOK); form2.setCommandListener(this); display.setCurrent(form1); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command cmd,Displayable disp) {
26
Contoh diatas mendemonstrasikan penggunaan user interface dalam hal ini TextField yang digunakan sebagai media input dan input string tersebut diproses dalam fungsi untuk mengkonversi menjadi huruf kapital yakni dengan metodh String.toUpperCase() untuk kemudian dikeluarkan melalui StringItem. Dalam pengoperasian fungsi-fungsi diatas tentunya dilengkapi dengan Command-Command yang mengimplementasikan CommandListener.Output program diatas tampil pada gambar di bawah ini.
27
11
Pemrograman Database dengan RMS
J2ME CLDC menyediakan paket RMS (Record Management System) untuk penanganan database. Sedangkan dalam penulisan dan pembacaan data digunakan stream. Struktur RMS diilustrasikan dalam gambar berikut.
id record
data
Gambar 11.1. Struktur RMS Id record dapat dianalogikan sebagai primary key dan selebihnya adalah data. Untuk mempejelas penggunaan RMS, perhatikan program database kota, yakni menambahkan nama kota ke dalam database RMS.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: import import import import javax.microedition.rms.*; java.io.*; javax.microedition.MIDlet.*; javax.microedition.lcdui.*;
public class tambahData extends MIDlet implements CommandListener { private Display display; private private private private private public Command cmdExit = new Command("Exit",Command.EXIT,2); Command cmdAdd = new Command("Tambahkan",Command.OK,1); Form formTambahKota; TextField tKota; RecordStore myDb;
tambahData() { }
28
public void tambahData() { formTambahKota = new Form("Tambah Kota "); tKota = new TextField("",null,30,TextField.ANY); formTambahKota.append(tKota); formTambahKota.addCommand(cmdAdd); formTambahKota.addCommand(cmdExit); formTambahKota.setCommandListener(this); display.setCurrent(formTambahKota); } public void tambahkan() { try{ String kota = tKota.getString();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeUTF(tKota.getString()); byte[] b = baos.toByteArray(); myDb.addRecord(b, 0, b.length); display.setCurrent(formTambahKota); } catch(IOException e) { } catch(RecordStoreException e) { } } public void bukaDb() { try{ myDb = RecordStore.openRecordStore("kota",true); tambahData(); } catch(RecordStoreNotFoundException e) { } catch(RecordStoreException e) { } } public void Exit(){ try { myDb.closeRecordStore(); this.destroyApp(true); } catch(RecordStoreNotOpenException e) { } catch(RecordStoreException e) { }
29
Dalam program penambahan data diatas, awalnya program memanggil bukaDb() yang disitu terdapat inisialisasi database kota
myDb = RecordStore.openRecordStore("kota",true);
Jika database kota belum ada, maka RMS akan membuatkan database kota. Kemudian program memanggil tambahData() sebagai media input berupa textField, sehingga program akan menuju pengisian nama kota seperti pada gambar berikut.
Gambar 11.2. Form penambahan kota Ketika user menekan Command Tambahkan(cmdAdd), maka proses penambahan data dilakukan dengan stream.
String kota = tKota.getString();
ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeUTF(tKota.getString()); byte[] b = baos.toByteArray(); myDb.addRecord(b, 0, b.length);
30
Untuk menampilkan data, kita tambahkan program untuk menambahkan data. Untuk mempermudah, kedua MIDlet ini digabung dalam satu project dengan menambahkan MIDlet pada setting projectnya.
public class tampilData extends MIDlet implements CommandListener { private Display display; private Command cmdSelect = new Command("Select",Command.EXIT,1); private Command cmdExit = new Command("Exit",Command.EXIT,1); private Form formListKota; private TextField t2; private RecordStore rmsDbKota; private static class Record { String kota; } public tampilData() { } public void startApp() { display = Display.getDisplay(this); bukaDbTampil(); } public void tampilkanKota() { try{ formListKota = new Form("Kota"); ChoiceGroup ChoiceGrp = new ChoiceGroup("",Choice.EXCLUSIVE); formListKota.addCommand(cmdExit); formListKota.addCommand(cmdSelect); formListKota.setCommandListener(this); formListKota.append(ChoiceGrp); byte[] recData = new byte[150]; ByteArrayInputStream bais = new ByteArrayInputStream(recData); DataInputStream dis = new DataInputStream(bais);
31
RecordEnumeration enum = rmsDbKota.enumerateRecords(null,null, false); Record r=new Record(); while(enum.hasNextElement()) { int recId = enum.nextRecordId(); bais = new ByteArrayInputStream(rmsDbKota.getRecord(recId)); dis = new DataInputStream(bais); r.kota = dis.readUTF(); ChoiceGrp.append(r.kota,null); } display.setCurrent(formListKota); } catch(IOException e) { } catch(RecordStoreNotOpenException e) { } catch(RecordStoreException e) { } } public void Kembali() { display.setCurrent(formListKota); } public void bukaDbTampil() { try{ rmsDbKota = RecordStore.openRecordStore("kota",true); tampilkanKota(); } catch(RecordStoreNotFoundException e) { } catch(RecordStoreException e) { } } public void keluar() { try{ rmsDbKota.closeRecordStore(); this.destroyApp(true); } catch(RecordStoreNotOpenException e) { } catch(RecordStoreException e) { } catch(NullPointerException e) { this.destroyApp(true); } } public void commandAction(Command c, Displayable d) { String lbl = c.getLabel(); if(lbl.equals("Exit"))
32
Program diatas akan menampilkan semua data dengan stream dan menampilkannya dalam choice group.
bais = new ByteArrayInputStream(rmsDbKota.getRecord(recId)); dis = new DataInputStream(bais); r.kota = dis.readUTF(); ChoiceGrp.append(r.kota,null);
Output program diatas seperti pada gambar di bawah ini. Jika user menekan Command Exit maka program memannggil metodh untuk membunuh MIDlet
33
12
Pemrograman Client Server dengan Socket
Tiba saatnya kita masuk ke pembahasan inti, pemrograman client server. Perangkat wireless dapat berkomunikasi dengan perangkat lainya apakah PC atau antar perangkat wireless dapat dengan berbagai macam, seperti dengan infra merah, bluetooth atau koneksi GPRS (General Packet Radio Service). Koneksitas antara server dengan perangkat wireless pada aplikasi yang akan kita buat dengan menggunakan GPRS diilustrasikan pada gambar berikut di bawah ini.
Gambar 12.1. Koneksi server dengan perangkat wireless dengan GPRS Aplikasi yang akan kita buat berupa program untuk melihat status pengiriman pada sebuah perusahaan yang menerima delivery order. Program ditanam di server dan di client. Pada server digunakan MySQL sebagai databasenya dan JDBC sebagai koneksitasnya dengan aplikasi yang kita buat.
A. Sisi server
Pada sisi server kita membutuhkan database dalam hal ini kita gunakan MySQL. Database dan tabel yang kita pakai diberi nama status. Contoh query untuk menampilkan seluruh data pada tabel status adalah sebagai berikut.
Pemrograman aplikasi wireless dengan Java/J2ME mysql> select * from status; +-------+----------------+----------+--------------------+ | id | tanggal_datang | status | tanggal_pengiriman | +-------+----------------+----------+--------------------+ | 00001 | 2003-12-07 | terkirim | 2003-12-10 | | 00002 | 2003-12-07 | pending | 2003-12-11 | | 00003 | 2004-01-07 | terkirim | 2004-01-09 | | 00004 | 2004-01-08 | pending | 2004-01-09 | | 00005 | 2004-01-09 | pending | 2004-01-11 | +-------+----------------+----------+--------------------+ 5 rows in set (0.00 sec)
34
Program di sisi server menggunakan socket untuk membuat program yang siap menerima koneksi dari client.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: import java.io.*; import java.net.*; import java.sql.*; public class OrderStatusServer { private int port =2004; private ServerSocket serverSocket; static final String dbURL= "jdbc:mysql://localhost/status?"+ "user=root&password="; public OrderStatusServer() throws ClassNotFoundException { Class.forName("org.gjt.mm.mysql.Driver"); } public void acceptConnection() { try { serverSocket = new ServerSocket(2004); } catch(IOException e) { System.err.println("Gagal menginisialisasi Socket Server"); e.printStackTrace(); System.exit(0); } while(true) { try { Socket newConnection = serverSocket.accept(); System.out.println("koneksi diterima"); ServerThread st = new ServerThread(newConnection); new Thread(st).start(); } catch(IOException ioe) { System.err.println("gagal menerima koneksi"); } } }
Pemrograman aplikasi wireless dengan Java/J2ME 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: public static void main(String args[]) { OrderStatusServer server =null; try { server =new OrderStatusServer(); } catch ( ClassNotFoundException e) { System.out.println("Gagal meload driver JDBC"); e.printStackTrace(); System.exit(1); } server.acceptConnection(); } class ServerThread implements Runnable { private Socket socket; private DataInputStream datain; private DataOutputStream dataout; public ServerThread(Socket socket) { this.socket = socket; } public void run() { try { datain= new DataInputStream (new BufferedInputStream(socket.getInputStream())); dataout= new DataOutputStream (new BufferedOutputStream(socket.getOutputStream())); } catch(IOException e) { return; } byte[] ba =new byte[6]; boolean conversationActive=true; while(conversationActive) { String orderNumber=null; try { datain.read(ba,0,6); orderNumber=new String(ba); if(orderNumber.toUpperCase().charAt(0)=='C') { conversationActive=false; } else { System.out.println("order Number="+orderNumber); String status=getStatus(orderNumber); System.out.println("status:"+status);
35
Pemrograman aplikasi wireless dengan Java/J2ME 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: dataout.write(status.getBytes(),0,status.length()); dataout.write("\n".getBytes(),0,1); dataout.flush(); } } catch(IOException ioe) { conversationActive=false; } } try { System.out.println("closing socket"); datain.close(); dataout.close(); socket.close(); } catch(IOException e) { } } private String getStatus(String orderNumber) { String status="Not on file"; Connection conn=null; try { conn=DriverManager.getConnection(dbURL); Statement stmt=conn.createStatement(); String query= "SELECT status from status where id="+orderNumber; ResultSet rs =stmt.executeQuery(query); if(rs.next()) { status=rs.getString(1); } } catch(SQLException e) { status="server error"; } finally { if (conn!= null) { try { conn.close(); } catch (SQLException e) { } } } return status; } } }
36
37
Setelah dikompile dan dieksekusi, ceklah apakah program di server sudah siap menerima koneksi, perhatikan contoh output netstat berikut pada sisi server!
C:\>netstat /na Active Connections Proto TCP TCP TCP TCP TCP Local Address 0.0.0.0:21 0.0.0.0:42 0.0.0.0:80 0.0.0.0:2004 0.0.0.0:3306 Foreign Address 0.0.0.0:0 0.0.0.0:0 0.0.0.0:0 0.0.0.0:0 0.0.0.0:0 State LISTENING LISTENING LISTENING LISTENING LISTENING
Di sisi server berfungsi: Membuka port untuk menerima koneksi Menerima koneksi dari client Membaca nomor order Dengan JDBC mengeksekusi perintah SQL untuk menampilkan status order Mengirim hasilnya ke client
B. Sisi client
Di sisi client dibuat program untuk mengakses server, kode program sebagai berikut
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.microedition.io.*; import java.io.*; public class OrderStatusClient extends MIDlet implements CommandListener { Display display; private boolean commandAvailable; private byte[] xmit; CommandThread commandThread; List menu; Form inputForm; Form outputForm; TextField orderNumber; StringItem orderStatus; Command cmdBack; Command cmdExit; Command cmdOK; private static final String URL="socket://127.0.0.1:2004"; StreamConnection conn= null; InputStream is = null; OutputStream os = null; public void startApp(){ display = Display.getDisplay(this); inputForm=new Form ("Order Status"); orderNumber =new TextField("Order=", null,6, TextField.NUMERIC); inputForm.append(orderNumber); cmdOK= new Command("OK", Command.SCREEN,1);
38
cmdExit=new Command("Exit", Command.EXIT,1); inputForm.addCommand(cmdOK); inputForm.addCommand(cmdExit); inputForm.setCommandListener(this); outputForm=new Form("Order Status"); orderStatus=new StringItem(null,null); outputForm.append(orderStatus); cmdBack=new Command("Back", Command.BACK,1); outputForm.addCommand(cmdBack); outputForm.addCommand(cmdExit); outputForm.setCommandListener(this); try {
conn=(StreamConnection)Connector.open(URL,Connector.READ_WRITE,true); os=conn.openOutputStream(); is=conn.openInputStream(); } catch (Exception e) { destroyApp(false); notifyDestroyed(); } commandAvailable =false; commandThread=new CommandThread(this); commandThread.start(); display.setCurrent(inputForm); } public void pauseApp() { } public void destroyApp(boolean unconditional){ try{ os.write("Q".getBytes()); conn.close(); } catch (IOException e){ } } public void commandAction(Command cmd, Displayable d) { if(cmd==cmdExit){ destroyApp(false); notifyDestroyed(); } else if(cmd==cmdBack){ orderNumber.setString(null); display.setCurrent(inputForm); } else if (cmd==cmdOK) synchronized (this){ xmit=orderNumber.getString().getBytes(); commandAvailable =true; notify(); }
39
} class CommandThread extends Thread{ MIDlet parent; boolean exit=false; public CommandThread(MIDlet parent){ this.parent =parent; } public void run() { while(true) { synchronized (parent){ while(!commandAvailable){ try{ parent.wait(); } catch (InterruptedException e){ } } commandAvailable =false; } getStatus(); } } public void getStatus() { try { os.write(xmit); os.flush(); int ch; StringBuffer sb=new StringBuffer(); while ((ch =is.read())!=-1) { sb.append((char)ch); if((char)ch =='\n') { break; } } orderStatus.setText(sb.toString()); display.setCurrent(outputForm); } catch(Exception e) { }
} } }
Pada client digunakan connector.open() untuk membuat StreamConnection. Untuk komunikasi 2 arah digunakan getInputStream dan getOutputStream. Setelah dikompile dan dieksekusi maka pada sisi client akan tampil seperti sebagai berikut
40
41
13
Installasi Aplikasi pada Perangkat Wireless
Setelah aplikasi yang kita buat dapat berjalan dengan baik sesuai dengan yang kita inginkan, maka pada tahap akhir adalah menginstall aplikasi yang telah dibuat pada perangkat wireless.
A. Pembundelan aplikasi
Sebelum aplikasi diinstall ke perangkat wireless, file-file yang terkait dengan aplikasi selain file classnnya seperti file gambar, data dan file-file pendukung lainnya perlu dibundel dalam 1 file JAR. Dalam J2ME Toolkit sudah terdapat fasilitas untuk membundel aplikasi yang kita buat yaitu pada menu Project Package Create Package
Gambar 13.1. Pembundelan aplikasi Hasil pembundelan aplikasi ini berupa file JAR dan JAD, file JAR merupakan aplikasi yang kita buat sedangkan file JAD merupakan file yang berisi informasi aplikasi yang kita buat. Kedua file ini yang akan diinstall ke dalam perangkat wireless.
B. Installasi aplikasi
Ada 2 teknik installasi pada perangkat wireless yakni: OTA(Over The Air) dan Installasi langsung.
42
Pada OTA file JAD dan JAR disimpan di web server yang terhubung ke internet (dengan IP public tentunya). Pada web server perlu ditambahkan agar mendukung file JAD dan JAR yaitu pada konfigurasi file mime.types. Setelah file JAD dan JAR disimpan dalam web server, akseslah alamat url file JADnya sehingga perangkat wireless yang dalam keadaan terkoneksi mendownload file JARnya.
Gambar 13.2. Drive perangkat wireless dalam Windows Explorer Untuk menginstall aplikasi J2ME dengan metode ini hanya dengan mengkopikan file JAR dan JAD ke dalam direktori tempat program Java (dalam hal ini direktori /java/jam/direktori aplikasi kita.
43
14
Penutup
Untuk bisa menguasai pemrograman pada perangkat wireless tentunya tidak hanya mengandalkan buku ini. Buku ini sengaja disusun secara sederhana yang mencakup garis-garis besarnya saja. Untuk lebih lengkapnya Anda harus membuka dokumentasi API dari J2ME dan API tambahan vendor sesuai dengan perangkat wirelessnya. Selain itu Anda juga perlu membaca manual tentang teknik installasi sesuai vendor jika Anda ingin menggunakan teknik installasi langsung dari PC (bukan OTA). Untuk mempermudah belajar Anda bisa mengikuti berbagai milis serta aktif membukabuka arsip forum diskusi tentang aplikasi wireless.
44
DAFTAR PUSTAKA
1. Tremblet, Paul. Wireless Java with J2ME, McGraw-Hill/Osborne 2. Raka, Cokorda. Trik Pemrograman Java untuk Jaringan dan Internet, Elex Media Computindo 3. Hartono, Puji. Modul Praktikum Pemrograman Berorientasi Objek, Laboratorium Komputer STMIK-AMIKBANDUNG 4. Wicaksono, Ady. Pemrograman Aplikasi Wireless dengan Java, Elex Media Computindo 5. Sanjaya, Ridwan. Pemrograman di Linux dengan Java, Elex Media Computindo
Lampiran
A. Seting PATH
Agar program-program di direktori \bin\ bisa dieksekusi dari sembarang direktori, maka perlu di set PATHnya Contoh: Direktori \bin terletak di C:\java\j2se\bin maka seting pathnya
SET PATH=%PATH%;C:\Java\j2se\bin
B. Seting CLASSPATH
Agar class-class dapat menemukan class-class yang diimport-kan, maka perlu diset CLASSPATH nya. Contoh: Direktori \lib terletak di C:\java\j2se\lib maka seting classpathnya
SET CLASSPATH=C:\Java\j2se\lib;%CLASSPATH%
C. Seting JDBC
Agar class-class jdbc dapat diakses maka perlu ditambahkan seting CLASSPATH nya. Contoh: Direktori \jdbc terletak di C:\java\jdbc maka seting classpathnya
SET CLASSPATH=C:\Java\jdbc\;%CLASSPATH%