26 April 2008

JarMaker & j2Exe: Membuat Executable Aplikasi Java

Lupakan mitos java tidak bisa dijalankan secara langsung. Jangan percaya kalau ada yang bilang java tidak bisa dibuat menjadi aplikasi exe. Kuno kalo masih menggunakan file jar saja atau bahkan file class untuk hasil building aplikasi java. Cobalah untuk sedikit berimprovisasi membuat aplikasi java menjadi exe, hal yang tidak bisa dilakukan oleh tools yang disediakan jdk, bahkan netbeans 6 saat ini.
Hasil binary compiler java berupa file class, yang dijalankan dengan perintah java namaclass. Jadi paling tidak untuk menjalankannya harus melalui command prompt, atau yang sedikit kreatif dengan membuat shortcut yang diarahkan ke java.exe dengan parameter nama class yang dipanggil, lengkap dengan pengubahan icon sesuai dengan aplikasinya.

Sun sendiri mengembangkan file arsip kompresi jar, mirip dengan format zip, dengan tool yang disediakan di jdk-nya,untuk menghasilkan sebuah file yang berisi seluruh class yang dibutuhkan, sehingga dapat dilakukan pemanggilan dengan class yang pertama dipanggil ada dalam MANIFEST dengan konfigurasi Main-Class. File jar ini bisa dipanggil dari command prompt dengan java -jar namafile.jar atau langsung dari explorer seperti halnya memanggil aplikasi biasa, dengan syarat JRE terkonfigurasi tanpa masalah. Bagus, tapi kareana sifatnya yang arsip kompresi kadang asosiasi tipe file-nya kadang di-take over oleh archive extractor yang lebih kreatif semacam winrar. Jadi, apabila dijalankan dari explorer, yang terjadi bukan jalannya aplikasi, tetapi malah menampilkan isi dari jar lengkap dengan class dan file MANIFEST-nya.
Sekarang, cara pembuatan jar sendiri sangat menyulitkan kalau dengan tool standar dari jdk, dengan bentuk command dos. Pada netbeans versi lama, dibawah 4, file jar bisa dibuat dengan agak membingungkan bagi pemula. Sedangkan pada netbeans versi baru, jar dibuat secara otomatis setiap kali build aplikasi berbasis project, dengan sedikit kesulitan bagi yang tidak biasa membuild aplikasi dengan IDE selengkap ini. Jadi setelah memilih beberapa tools pembuat jar yang entah kenapa aneh semua, jarmaker adalah yang terbaik. Oh iya, di aplikasi ini ada tab Windows exe, tapi entah karena lupa atau apa, disini tidak ada control apapun untuk melakukan itu, jadi untuk pembuatan exe-nya diserahkan pada j2exe wizard, yang pada versi baru sudah harus bayar,sedangkan versi ini, 1.4, versi yang paling bagus, masih gratis.
Sekarang, proses pembuatan aplikasi exe dari java. Prinsip langkahnya adalah, compile aplikasi java dalam sebuah folder yang khusus untuk aplikasi itu lengkap dengan seluruh library yang dibutuhkan, Gunakan jarmaker untuk membuat file jar, setelah itu ubah menjadi jar tersebut menjadi exe dengan j2exe Wizard.

Langkah lengkapnya:
1. Compile source code javanya, jadikan semuanya dalam sebuah folder, apabila menghasilkan banyak class, taruh semua ditempat tersebut. Siap digoreng.

2. Jalankan JarMaker, hal yang harus diperhatikan:
- Gunakan hanya tab JAR Maker, untuk pembuatan jar.
- Output File, menentukan tempat dan nama file hasil konversi
- Input direktory, tempat asal semua class yang akan dijadikan Jar
- JAR compression Rate, semakin besar kompresi yang bisa dilakukan semakin efektif
- Abaikan Advanced Option kecuali tahu artinya
- Manifest Template, Penting harus memilih file Main-Class, sebagai class utama yang pertama kali dipanggil. Tuliskan nama class-nya tanpa akhiran class.
-----> Create jar! untuk menghasilkan file jarnya.
Apabila berjalan, jar siap dipanggang jadi exe

3. Jalankan j2exe Wizard, ikuti wizard yang ada:
- Pilih nama file jar yang sudah dibuat tadi
- Pilih jenis aplikasinya. Gunakan Windows GUI Application apabila menggunakan aplikasi berbasis Frame. sedangkan Console akan menampilkan command prompt, pilih jenis ini untuk aplikasi dos atau aplikasi frame tapi membutuhkan penampilan diagnosa error dan trace jalannya aplikasi pada command prompt.
- Tentukan nama file main class-nya tanpa ekstensi class. Biasanya langsung disebutkan oleh aplikasi dengan membaca file Manifest yang ada dalam jar, jadi tinggal next saja.
- Tentukan tempat hasil exe-nya.
- Udah Finisih, aplikasi siap dibakar.

Tentukan Main-Class

Buat Jar-nya

Buat Exe-nya

Download:
JarMaker
J2EWizard 1.4
N3XT...arrow

10 April 2008

Start from the basic: Java input & Graphic2D

Cuma sedikit protes dengan beberapa buku java dari Indonesia yang agak sedikit ngawur, dari segi pemrograman. Tentu karena bahasanya yang lebih sesuai dibandingkan dengan buku buku terjemahan buatan orang asing, yang dengan isi yang sangat berbobot, harga lebih mahal, tapi karena terjemahan, ada beberapa hal yang agak sulit dimengerti. Dimulai dengan buku java 2 - AK yang sangat banyak digunakan untuk panduan belajar di kampus.

Start from the basic!
Membaca input dari keyboard
Pada C ada scanf, pada C++ ada cin, pada pascal ada readln, pada basic ada input, tapi di java tidak ada perintah khusus untuk melakukan input data dari keyboard. Padahal, perintah ini sangat berguna untuk melakukan trial and error terutama pada saat proses awal belajar java. Sun sendiri tidak pernah memberikan caranya secara official, paling tidak saya belum pernah menemuainya di dokumentasi resmi java. Bahkan di ebook yang lain. Mungkin cuma karena saya belum pernah punya buku java, dan jarang lihat ebook java dasar.
Tapi, yang ada di buku ini sudah jelas ngawur, bagaimana bisa mengajarkan java dasar tapi sudah harus membuat object bacaKeyboard dari class di file yang berbeda untuk mendapatkan input data, padahal konsep OOP sangat menyulitkan untuk proses awal belajar. Menurut versi bukunya dengan membuat kelas baru khusus untuk input,

public class BacaKeyboard{ public static String bacaString(){ perintah...; } }

sehingga cara pemanggilannya karena berjenis static function:

String nama = BacaKeyboard.bacaString;

Dan selalu diperlukan file class aslinya untuk bisa dicoba di program lain, yang sebetulnya sangat sederhana misalkan tentang kondisi if dan perulangan for, tapi sudah disulitkan dengan hal dasar seperti ini.
Supaya tidak membutuhkan file lain, dan cuma membutuhkan satu file tanpa perlu konsep OOP, tinggal gunakan saja class BufferedReader:

String nama="";
try{
java.io.BufferedReader br=new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
nama=br.readLn();
System.out.println("Hasil input:\""+nama+"\"");
}catch(java.io.IOException e){}

Perintah ini bisa diterapkan dimana saja dalam program, sehingga memudahkan proses input data tanpa perlu kelas tambahan. atau kalau dalam fungsi main yang bisa langsung jalan:

import java.io.*;
public class contoh{
public static void main(String[]a)throws IOException{
BufferedReader br=new BufferedReader(InputStreamReader(System.in));
String nama=br.readLn();
System.out.println("Hasil input:\""+nama+"\"");
}
}

Graphic2D untuk menggambar
Graphic2D digunakan untuk menggambar obyek garis atau gambar kotak dan semacamnya dalam bentuk dua dimensi dengan cepat.
Entah kenapa di buku ini prosesnya begitu rumit. Buat object Canvas atau Applet, setelah itu di-add-kan ke Container, baru bisa digambar. Padahal sederhananya, inheritance dari Frame, sebuah container, juga menurunkan fungsi paint() yang bisa langsung digunakan. Perintah yang ada di class java.awt.Graphics bisa langsung dipanggil disini. Contoh penggunaannya ada di program jam analog, yang menggunakan package Graphic2D untuk menggambar jarum jam dan lingkarannya.

public class Ana extends Frame {
public void paint(Graphics G){
G.drawOval(100,100,300,300);
}
public Ana(){
super("om_agus Klok_klok");
setSize(800,600);
}
public static void main(String[]a){
new Ana().setVisible(true);
}
}

Karena tidak pernah menggunakan bukunya sebagai panduan, mungkin cuma ini saja yang sering ditemui oleh penggunanya. Ini berdasarkan pertanyaan yang paling sering keluar saja. Mungkin masih banyak yang lainnya, selain juga ingin membahas habis bukunya janet--, tapi sepertinya tidak terlalu penting juga.
N3XT...arrow

AppQuery: Java Source Code

Source code dari program AppQuery di posting sebelumnya.

//********* (c) 2008 om4gus(tm) ***********//
//********* om4gus.blogspot.com ***********//
import javax.swing.table.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
public class lihatTabel extends javax.swing.JFrame {
public lihatTabel() throws Exception{
initComponents();
tabel.setModel(model=new DefaultTableModel());
}



private void initComponents() {//GEN-BEGIN:initComponents
buttonGroup1 = new javax.swing.ButtonGroup();
cbTabel = new javax.swing.JComboBox();
jScrollPane1 = new javax.swing.JScrollPane();
tabel = new javax.swing.JTable();
tUser = new javax.swing.JTextField();
tPass = new javax.swing.JPasswordField();
tDb = new javax.swing.JTextField();
bUpdateDb = new javax.swing.JButton();
bUpdateTable = new javax.swing.JButton();
jPanel1 = new javax.swing.JPanel();
jLabel6 = new javax.swing.JLabel();
rSqlServer = new javax.swing.JRadioButton();
rMySql = new javax.swing.JRadioButton();
rOdbc = new javax.swing.JRadioButton();
rCustom = new javax.swing.JRadioButton();
tKoneksi = new javax.swing.JTextField();
tDriver = new javax.swing.JTextField();
lDriver = new javax.swing.JLabel();
lKoneksi = new javax.swing.JLabel();
lQuery = new javax.swing.JLabel();
tQuery = new javax.swing.JTextField();
lUser = new javax.swing.JLabel();
lDb = new javax.swing.JLabel();
tCopy = new javax.swing.JButton();
lStatus1 = new javax.swing.JLabel();
bRun = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
lStatus = new javax.swing.JTextArea();

getContentPane().setLayout(null);

setTitle("MyTabel om4gus");
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
exitForm(evt);
}
});

cbTabel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cbTabelActionPerformed(evt);
}
});

getContentPane().add(cbTabel);
cbTabel.setBounds(230, 100, 150, 19);

tabel.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
jScrollPane1.setViewportView(tabel);

getContentPane().add(jScrollPane1);
jScrollPane1.setBounds(0, 210, 380, 130);

getContentPane().add(tUser);
tUser.setBounds(70, 70, 130, 20);

getContentPane().add(tPass);
tPass.setBounds(230, 70, 150, 20);

tDb.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tDbActionPerformed(evt);
}
});

getContentPane().add(tDb);
tDb.setBounds(70, 100, 130, 20);

bUpdateDb.setText("update DB");
bUpdateDb.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bUpdateDbActionPerformed(evt);
}
});

getContentPane().add(bUpdateDb);
bUpdateDb.setBounds(70, 120, 130, 23);

bUpdateTable.setText("update Table");
bUpdateTable.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bUpdateTableActionPerformed(evt);
}
});

getContentPane().add(bUpdateTable);
bUpdateTable.setBounds(230, 120, 150, 23);

jLabel6.setFont(new java.awt.Font("Arial", 1, 12));
jLabel6.setText("Driver Type");
jPanel1.add(jLabel6);

rSqlServer.setText("SQL Server");
buttonGroup1.add(rSqlServer);
rSqlServer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
rSqlServerActionPerformed(evt);
}
});

jPanel1.add(rSqlServer);

rMySql.setText("MySQL");
buttonGroup1.add(rMySql);
rMySql.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
rMySqlActionPerformed(evt);
}
});

jPanel1.add(rMySql);

rOdbc.setText("ODBC");
buttonGroup1.add(rOdbc);
rOdbc.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
rOdbcActionPerformed(evt);
}
});

jPanel1.add(rOdbc);

rCustom.setText("Custom");
buttonGroup1.add(rCustom);
rCustom.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
rCustomActionPerformed(evt);
}
});

jPanel1.add(rCustom);

getContentPane().add(jPanel1);
jPanel1.setBounds(0, 10, 400, 30);

getContentPane().add(tKoneksi);
tKoneksi.setBounds(70, 150, 310, 20);

getContentPane().add(tDriver);
tDriver.setBounds(70, 40, 310, 20);

lDriver.setFont(new java.awt.Font("Arial", 1, 12));
lDriver.setText("Driver");
getContentPane().add(lDriver);
lDriver.setBounds(4, 40, 50, 15);

lKoneksi.setFont(new java.awt.Font("Arial", 1, 12));
lKoneksi.setText("Connect.");
getContentPane().add(lKoneksi);
lKoneksi.setBounds(0, 150, 70, 15);

lQuery.setFont(new java.awt.Font("Arial", 1, 12));
lQuery.setText("Query");
getContentPane().add(lQuery);
lQuery.setBounds(0, 180, 50, 15);

getContentPane().add(tQuery);
tQuery.setBounds(70, 180, 200, 20);

lUser.setFont(new java.awt.Font("Arial", 1, 12));
lUser.setText("User");
getContentPane().add(lUser);
lUser.setBounds(4, 70, 50, 20);

lDb.setFont(new java.awt.Font("Arial", 1, 12));
lDb.setText("DB/Table");
getContentPane().add(lDb);
lDb.setBounds(4, 100, 70, 20);

tCopy.setText("Copy selected data to clipboard");
tCopy.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tCopyActionPerformed(evt);
}
});

getContentPane().add(tCopy);
tCopy.setBounds(1, 340, 380, 23);

lStatus1.setFont(new java.awt.Font("Arial", 1, 12));
lStatus1.setText("Status: ");
getContentPane().add(lStatus1);
lStatus1.setBounds(0, 370, 50, 20);

bRun.setText("Run Query");
bRun.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bRunActionPerformed(evt);
}
});

getContentPane().add(bRun);
bRun.setBounds(270, 180, 110, 23);

lStatus.setEditable(false);
jScrollPane2.setViewportView(lStatus);

getContentPane().add(jScrollPane2);
jScrollPane2.setBounds(52, 372, 330, 40);

java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-403)/2, (screenSize.height-447)/2, 403, 447);
}//GEN-END:initComponents

private void tDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tDbActionPerformed
bUpdateDbActionPerformed(evt);
}//GEN-LAST:event_tDbActionPerformed

private void tCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tCopyActionPerformed
Clipboard c = this.getToolkit( ).getSystemClipboard( );
c.setContents(new copyData((String)tabel.getValueAt(tabel.getSelectedRow(),tabel.getSelectedColumn())),
new ClipboardOwner( ) { public void lostOwnership(Clipboard c,Transferable t){}
});

}//GEN-LAST:event_tCopyActionPerformed

private void bRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bRunActionPerformed
updateTabel();
}//GEN-LAST:event_bRunActionPerformed

private void cbTabelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbTabelActionPerformed
tQuery.setText("SELECT * FROM "+cbTabel.getSelectedItem());
updateTabel();
}//GEN-LAST:event_cbTabelActionPerformed

private void rCustomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rCustomActionPerformed
setType();
}//GEN-LAST:event_rCustomActionPerformed

private void rOdbcActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rOdbcActionPerformed
setType();
}//GEN-LAST:event_rOdbcActionPerformed

private void rMySqlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rMySqlActionPerformed
setType();
}//GEN-LAST:event_rMySqlActionPerformed

private void rSqlServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rSqlServerActionPerformed
setType();
}//GEN-LAST:event_rSqlServerActionPerformed

private void bUpdateTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bUpdateTableActionPerformed
tQuery.setText("SELECT * FROM "+cbTabel.getSelectedItem());
updateTabel();
}//GEN-LAST:event_bUpdateTableActionPerformed

private void bUpdateDbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bUpdateDbActionPerformed
setType();
}//GEN-LAST:event_bUpdateDbActionPerformed

/** Exit the Application */
private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
System.exit(0);
}//GEN-LAST:event_exitForm

/**
* @param args the command line arguments
*/
public static void main(String args[]) throws Exception{
new lihatTabel().show();
}
private void updateDb(){
// if(tUser.getText().length()>0){
try{
testDriver();
ResultSet rsTabel=con.getMetaData().getTables(null, null, null, null);
cbTabel.setModel(new javax.swing.DefaultComboBoxModel());
for(;rsTabel.next();)
cbTabel.addItem(rsTabel.getString("TABLE_NAME"));
cbTabel.setSelectedIndex(-1);
lStatus.setText(lStatus.getText()+"\nChange Database success");
}catch(Exception e){
System.err.println(e.toString());
lStatus.setText(lStatus.getText()+"\n"+e.toString());
}
// }
}
private void updateTabel(){
tabel.setModel(model=new DefaultTableModel());
tabel.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// if(cbTabel.getSelectedIndex()>0){
try{
perintah=tQuery.getText();
ResultSet hasil=stmt.executeQuery(perintah);
ResultSetMetaData rsKolom=hasil.getMetaData();
for(int I=1;I<=rsKolom.getColumnCount();I++)
model.addColumn(rsKolom.getColumnName(I).trim());
Vector V=null;
for(int I=0;hasil.next();I++){
V=new Vector();
for(int J=1;J<=hasil.getMetaData().getColumnCount();J++){
V.add(hasil.getObject(J));
}
model.addRow(V);
}
lStatus.setText(lStatus.getText()+"\nUpdate Table success");
}catch(Exception e){
System.err.println(e.getMessage()+"2");
lStatus.setText(lStatus.getText()+"\n"+e.toString());
}
//}
}
public void testDriver(){
//String dbDrv = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
//String dbUrl = "jdbc:microsoft:sqlserver://localhost;DatabaseName="+db;
try{
Class.forName(tDriver.getText());
con = DriverManager.getConnection(tKoneksi.getText(),tUser.getText(),tPass.getText());
stmt=con.createStatement();
lStatus.setText("Driver Connected");
}catch(Exception ce){
System.out.println(ce.toString()+"1");
lStatus.setText(ce.toString());//lStatus.getText()+"\n"+
cbTabel.setModel(new DefaultComboBoxModel());
}
}
private void setType(){
lDb.setText("DB/Table");
tDriver.setEnabled(false);
tKoneksi.setEnabled(false);
tPass.setEnabled(true);
if(rSqlServer.isSelected()){
tDriver.setText(this.sqlServerDriver);
tKoneksi.setText(this.sqlServerUrl+"//localhost;DatabaseName="+tDb.getText());
}else if(rMySql.isSelected()){
tDriver.setText(this.mySqlDriver);
tKoneksi.setText(this.mySqlUrl+"//localhost/"+tDb.getText());
}else if(rOdbc.isSelected()){
tDriver.setText(this.odbcDriver);
tKoneksi.setText(this.odbcUrl+""+tDb.getText());
tPass.setText("");
lDb.setText("DS Name");
}else{
tDriver.setEnabled(true);
tKoneksi.setEnabled(true);
}
updateDb();
}
Connection con;
Statement stmt;
String perintah;
DefaultTableModel model;
private static final String sqlServerDriver="com.microsoft.jdbc.sqlserver.SQLServerDriver";
private static final String sqlServerUrl="jdbc:microsoft:sqlserver:"; //jdbc:microsoft:sqlserver://localhost;DatabaseName="+db;
private static final String mySqlDriver="com.mysql.jdbc.Driver";
private static final String mySqlUrl="jdbc:mysql:";//jdbc:mysql://localhost/dbme
private static final String odbcDriver="sun.jdbc.odbc.JdbcOdbcDriver";
private static final String odbcUrl="jdbc:odbc:"; //jdbc:odbc:sqlKuliah
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bRun;
private javax.swing.JButton bUpdateDb;
private javax.swing.JButton bUpdateTable;
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JComboBox cbTabel;
private javax.swing.JLabel jLabel6;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JLabel lDb;
private javax.swing.JLabel lDriver;
private javax.swing.JLabel lKoneksi;
private javax.swing.JLabel lQuery;
private javax.swing.JTextArea lStatus;
private javax.swing.JLabel lStatus1;
private javax.swing.JLabel lUser;
private javax.swing.JRadioButton rCustom;
private javax.swing.JRadioButton rMySql;
private javax.swing.JRadioButton rOdbc;
private javax.swing.JRadioButton rSqlServer;
private javax.swing.JButton tCopy;
private javax.swing.JTextField tDb;
private javax.swing.JTextField tDriver;
private javax.swing.JTextField tKoneksi;
private javax.swing.JPasswordField tPass;
private javax.swing.JTextField tQuery;
private javax.swing.JTextField tUser;
private javax.swing.JTable tabel;
// End of variables declaration//GEN-END:variables
class copyData implements Transferable {
DataFlavor FLAVOR= new DataFlavor("application/x-java-serialized-object; class=java.lang.String","String");
DataFlavor[ ] FLAVORS = new DataFlavor[ ] { FLAVOR };
String str;
public copyData(String str) {
this.str = str;
}
public DataFlavor[ ] getTransferDataFlavors( ) { return FLAVORS; }
public boolean isDataFlavorSupported(DataFlavor f){return f.equals(FLAVOR);}
public Object getTransferData(DataFlavor f)
throws UnsupportedFlavorException {
if (!f.equals(FLAVOR)) throw new UnsupportedFlavorException(f);
return str;
}
}
}

N3XT...arrow

AppQuery: Akses Java ke semua jenis Database



Sistem baru, dimulai dengan menyelesaikan ini.
Sebenarnya banyak hal yang ingin dituliskan dan dijelaskan, karena agak kompleksnya aplikasi ini, tapi malah bingung. Jadi ingat apa yang dikatakan Budi Rahardjo, kalo penulisan orang teknik Indonesia tidak menarik, lebih mirip laporan praktikum daripada sebuah karya ilmiah, dengan hal teknis tapi dengan bahasa mirip bahasa mesin, cuma berisi beberapa kata tentang fungsinya, setelah itu disambung dengan kodenya. Padahal 50% dari pengerjaan proyek seharusnya digunakan untuk pembuatan dokumentasi dan help yang menarik dan mudah dimengerti. Dan konsultan luar negeri dibayar mahal karena penulisan mereka yang rapi disesuikan dengan target pembacanya, orang teknis, konsumen pemakai, atau investor. Satu lagi, kalo membuat blog, yang penting kuantitas, baru kulaitas. Buat tulisan yang banyak dulu, baru memikirkan kualitasnya. Blog ini juga begitu, sering update, kalo perlu sehari dua kali, sebulan sampai puluhan, sekarang baru mulai agak serius, dan efeknya langsung terasa. Trafik dari google langsung meningkat, seperti untuk pembahasan ozeki. Tapi biarkan saja, namanya juga belajar.

Mulai aja deh.
Ini cuma sebuah program pribadi yang tadinya cuma untuk mengetes koneksi java dengan sql server pada saat beberapa tahun lalu (Siapa aja ya, yang dulu minta, kayaknya banyak yang ngaku deh.....), akhirnya ditambahkan dengan beberapa keunikan. Aplikasi ini bisa digunakan untuk mengambil data dari berbagai macam database dengan cara yang mudah dan terstandardisasi, karena prinsipnya yang sama....
+ Driver SQL Server 2000 dan Driver mysql
Berbasis driver, sehingga cuma perlu tahu user dan password di database tanpa perlu ada konfigurasi tambahan. Bahkan drivernya sendiri sudah ada dalam bentuk class di aplikasi ini. Tinggal masukkan username, password, ketik nama database-nya, klik update database. Kalo koneksi berhasil, langsung ada pilihan tabel yang akan dilihat dari combobox dan perintah query yang bisa dijalankan.
sqlServerDriver="com.microsoft.jdbc.sqlserver.SQLServerDriver";
String sqlServerUrl="jdbc:microsoft:sqlserver:"; //jdbc:microsoft:sqlserver://localhost;DatabaseName="+db;

mySqlDriver="com.mysql.jdbc.Driver";
mySqlUrl="jdbc:mysql:";//jdbc:mysql://localhost/dbme

+ ODBC
Menggunakan fasilitas dari windows Data source yang bisa digunakan untuk menghubungkan berbagai jenis database, dari oracle sampai file teks biasa. Yang harus dilakukan adalah membuat datasource dari Administrative tools di control panel, pilih jenis database yang akan dikoneksikan, lakukan konfigurasi sampai selesai. Setelah itu masukkan nama Datasource-nya di aplikasi ini, langsung update database. Apabila koneksi berhasil, pilihan tabel yang bisa dipilih langsung keluar.
odbcDriver="sun.jdbc.odbc.JdbcOdbcDriver";
odbcUrl="jdbc:odbc:"; //jdbc:odbc:sqlKuliah


+ koneksi lainnya.
Bisa dengan mengubah setting yang disediakan, atau dengan driver yang bernar-benar baru. Misalkan, untuk koneksi mysql tapi dengan server di komputer yang berbeda, bukan di localhost, atau dengan port yang berbeda. Bisa juga misalkan dengan menambahkan driver oracle dengan setting path-nya, kemudian mengetikkan setting koneksi, database url, username dan password, di aplikasi ini.

Khusus untuk pembelajaran, aplikasi untuk membuat saya belajar tentang banyak hal, diantaranya:
+ koneksi ke odbc
Bisa melakukan koneksi ke odbc dengan berbagai macam jenis database yang berbeda, dengan kelemahan harus menambahkan datasource di setiap komputer untuk koneksi database. Selain itu juga lebih lambat dari driver biasa, karena adanya bantuan sistem operasi sebagai penghubung ke database.
+ koneksi ke driver database
Aplikasi ini membuktikan koneksi java ke database apapun, memiliki cara pemanggilan yang sama persis, dengan driver yang dibuat oleh vendor yang berbeda sesuai kebutuhan aplikasi. Jadi bisa saja Sebuah aplikasi java tidak dikhususkan untuk database tertentu, dengan konfigurasi berasal dari file teks atau registry, dan bisa di-setting secara runtime.
melakukan operasi database
Disediakan sebuah teksboks untuk mencoba perintah query berjenis execute query, bukan update query. yaitu perintah query yang menghasilkan record untuk ditampilkan di jtable, dengan perintah select dan variasinya.
+ manipulasi JTabel
Sekali lagi, sangat mudah. Untuk membuat object dari JTable dan melakukan manipulasi bentuk dan isinya secara runtime. Untuk aplikasi ini, JTable bisa menyesuaikan dengan kebutuhan query, berapapun kolom dari tabel dan record yang akan ditampilkan, bisa langsung ditampilkan.
+ copy data ke clipboard sistem operasi
Cuma sebuah contoh paling sederhana dari copy-paste. Dengan mengkopikan data di JTable yang dipilih untuk kemudian bisa dipastekan di aplikasi yang lain misalkan notepad. Sebenarnya di Java bisa saja data yang dikopikan berupa obyek dengan tipe data lain misalkan gambar untuk dipastekan di mspaint.Untuk kebutuhan aplikasi ini cuma perlu tipe data string saja karena berupa teks biasa.
Clipboard c = this.getToolkit( ).getSystemClipboard( );
c.setContents(new copyData((String)tabel.getValueAt(tabel.getSelectedRow(),tabel.getSelectedColumn())),
new ClipboardOwner( ) { public void lostOwnership(Clipboard c,Transferable t){}

dari kelas copyData:
class copyData implements Transferable {
DataFlavor FLAVOR= new DataFlavor("application/x-java-serialized-object; class=java.lang.String","String");
DataFlavor[ ] FLAVORS = new DataFlavor[ ] { FLAVOR };
String str;
public copyData(String str) {
this.str = str;
}
public DataFlavor[ ] getTransferDataFlavors( ) { return FLAVORS; }
public boolean isDataFlavorSupported(DataFlavor f){return f.equals(FLAVOR);}
public Object getTransferData(DataFlavor f)
throws UnsupportedFlavorException {
if (!f.equals(FLAVOR)) throw new UnsupportedFlavorException(f);
return str;
}
}


+ Aplikasi yang bersifat portable, bebas sistem operasi
Bukan jamannya lagi aplikasi portable yang jalan dari flashdisk, tapi cuma jalan di os tertentu (xixixixi, sebenarnya malah sangat tergantung di aplikasi seperti ini). Untuk java, apabila sudah dibentuk dalam bentuk jar, maka bisa dijalankan dimanapun yang tersedia JRE, Windows, Linux, Mac OS. Khusus untuk aplikasi ini, karena di-compile dengan JDK versi lama, 1.4.2, maka bisa dijalankan di semua versi JDK terbaru. Selain itu semua library dan driver SQL Server dan My SQL sudah ada dalam satu paket tanpa perlu setting path segala macam. Jadi, dengan syarat JRE yang beres beserta konfigurasi asosiasi file dengan tipe jar yang benar, maka tinggal diklik dua kali, langsung jalan dan siap bekerja, tanpa setting apapun, tanpa melihat sistem operasi dia berjalan. Dengan cuma satu buah file jar, selain itu ada versi exe untuk windows, maka file java bisa langsung dijalankan tanpa masalah. Karena class java cuma tergantung pada JRE, bukan sistem operasi maupun hardware komputer.

Susunan file utama di jar:
File name Ext
------------------------------------------------------------------------------------------
appQuery jarContent
lihatTabel class
lihatTabel form
lihatTabel java
lihatTabel$copyData class
com\
com\microsoft\
com\microsoft\jdbc\
com\microsoft\jdbc\sqlserver\
SQLServerDriver class
com\mysql\
com\mysql\jdbc\
Driver class
org\
org\gjt\
org\gjt\mm\
org\gjt\mm\mysql\
Driver class

versi jar, didalamnya sudah termasuk sourcecode java dan form netbeans, driver mysql dan sql server, bisa dibongkar dengan 7zip dan sejenisnya, karena kompresi yang mirip antara jar dan zip. selain itu bisa jalan dengan berbagai os.

versi exe, bisa langsung dijalankan di windows, dibuat dengan j2exe.

Sedangkan untuk source codenya, ada di posting selanjutnya.....
N3XT...arrow