Menyimpan Objek Java ke dalam File

Minnaaaa~~~, akhirnya blog balita balik lagi. Sekarang, bakal dibahas caranya gimana buat nyimpan data dalam bentuk objek. Yap, emang kalo nyimpan data gampangnya pake database ajah. Tapi, dalam satu atau lain kesempatan, bisa ajah kita musti nyimpen bukan ke database, tapi bentuk lain. Kalo udah gini, cara paling gampang yaaa… pake penyimpanan file. Tapi, akses file sendiri biasanya yang disimpan adalah tulisan2.

Tulisan ini bisa aja dijadiin data tersendiri ke dalam file kalo ngegunain pake bahasa pemrograman Java. Tapi, pendekatan yang gw maksud gini… Pas kamu punya satu master data yang jumlahnya puluhan baris record, dan satu record-nya terdiri dari beberapa hal. Yaa.. contohnya aja kamu nyimpen data semua member JKT48 di aplikasi yang kamu bikin. Kali ajah, kan… Dan hal ini, gak bisa kamu simpan gitu aja dalam bentuk tulisan. Karena, kamu musti bikin parsing dari tulisan2 yang kamu simpan. Alternatif penyimpanan yang bisa kamu lakuin contohnya (paling gak yang kepikiran ma gw sekarang), yaitu nyimpen dalam format XML. Yap, kamu musti parsing lagi, tapi bentuknya kan dah standar. Jadi gampang… dan alternatif lainnya, merupakan hal yang bakal dibahas di postingan sekarang… yaitu nyimpen dalam bentuk objek.

Bahasa Java mengakomodir penyimpanan objek yang dibentuk ke dalam file. Untuk melakukan hal ini, kita butuh yang namanya package java.io. Bagian yang kita butuhkan nantinya yaitu “FileOutputStream” dan “ObjectOutputStream”. Dari namanya ajah dah jelas ya gunanya buat apa. Selain itu, yang kita butuhin juga, bentuk POJO dari class yang kita simpan objeknya. Gw agak gak yakin tentang POJO (yaaa, maaf2 ajah kalo gw salah ngejerumusin kamu semua ama info yang gak valid. Kalo ada yang musti diperbaikin tell2 yak), tapi intinya POJO itu kependekan dari “Plain Old Java Object”. Bentuk dari POJO itu standar… cuma satu class dengan atribut dan method set-get, ditambah meng-implements “Serializable” dari java.io.Serializable.

Okeh, kita langsung praktek yah… Pertama, bikin class POJO dari objek yang nantinya mau disimpen. Gw bikin class “Oshi”, dengan atribut nama, tim, plus tahun lahir. Konstruktornya mau ada ketiga-tiganya, trus override method toString jugak. Jadi, gw bikin 1 file java, dengan class diagram kayak gini:

Class Diagram Oshi

Class diagram di atas dibikin pake plugin EasyUML dari Netbeans, gak bikin sendiri. Jadi kalo dirasa gak sesuai ama UML yang kamu kenal, yaaa… silahkan disesuaikan ajah. Kode dari class diagram di atas ditulisin gini:

import java.io.Serializable;

/**
 *
 * @author arby
 */

public class Oshi implements Serializable{
    private String nama;
    private char tim;
    private int tahunLahir;

    public Oshi(String nama, char tim, int tahunLahir) {
        this.nama = nama;
        this.tim = tim;
        this.tahunLahir = tahunLahir;
    }

    public String getNama() {
        return nama;
    }

    public void setNama(String nama) {
        this.nama = nama;
    }

    public char getTim() {
        return tim;
    }

    public void setTim(char tim) {
        this.tim = tim;
    }

    public int getTahunLahir() {
        return tahunLahir;
    }

    public void setTahunLahir(int tahunLahir) {
        this.tahunLahir = tahunLahir;
    }

    @Override
    public String toString() {
        return "Oshi{" + "nama=" + nama + ", tim=" + tim + ", tahunLahir=" + tahunLahir + '}';
    }
}

Terus, buat nyimpen objeknya ke file, gw bikin class baru Main.java

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 *
 * @author arby
 */
public class Main {
    public static void main(String[] args) {
        //bentuk 1 objek Oshi
        Oshi o = new Oshi("Melody", 'J', 1992);
        
        //menyimpan objek oshi "o"
        try {
            FileOutputStream fos = new FileOutputStream("file_oshi.dat");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(o);
            oos.close();
            System.out.println("Tersimpan");
        } catch (IOException ex) {
            System.out.println("Gagal. Error: "+ex);
        }
    }
}

Keliatan kan urutannya… pertama, tentukan file-nya pake FileOutputStream, abis itu simpan objek ke dalam file pake ObjectOutputStream. Kalo udah ditulis, jangan lupa ditutup pake “close”. Untuk tipe data (ekstensi file), itu juga bebas c… gak dipakein ekstensi pun sebenernya gak masalah. Nanti, bakal ada file_oshi.dat yang kebentuk sesuai path class yang kamu punya. Kalo gw, berhubung pake netbeans, kebentuknya di dalam project Netbeans-nya langsung. Hirarkisnya gini:

Selection_005

Kalo kamu liat isinya pake text editor, bakal keluarnya gini:

Selection_006

Dan… selesai lah sudah. Objek kamu berhasil tersimpan. Tapi, yang perlu kamu perhatiin… cara di atas, gak cuma bisa nyimpen 1 objek per file lhoh yah.. kalo kamu bikin 2 objek, anggaplah o1 sama o2, terus kamu tulisin syntax “oos.writeObject(o1);” juga “oos.writeObject(o2);”, yang kesimpen 2 objek itu. Cara ngebuktiinnya?! Hmm… cara ngebuktiinnya, kamu musti baca file tersebut. Bisa liat di file-nya langsung pake editor semacam notepad atau wordpad (soalnya kalo gedit/netbeans langsung dah gw coba, dan berakhir dengan kegagalan buat nampilin isinya)…

O iya, yang perlu kamu perhatiin jugak, tentang konsep penyimpanannya. Konsepnya nimpa lhoh yah… bukan nambah2 data baru kayak penambahan row baris di database. Nimpa… alias replace. Jadi, tiap kamu jalanin kode di atas, isinya bakal nimpa sesuai yang kamu tulisin. Bukan nambah data di baris paling bawahnya.

Kalo buat ngebaca file-nya di program java… uhmmm… postingan berikutnya aja yak… Gw lagi males nulisin. Ditunggu ajah… 😀 Ja naaa… moga ngebantu yak…

Sumber: how-to-write-an-object-to-file-in-java/
Valid: Yap!
Kadaluarsa: Sampe method terkait dinyatain deprecated.

Advertisements

Menyelesaikan “Reading package lists… Error!” di Linux Mint

Jadi yah, setelah lama gak install2 via terminal (yang musti kehubung ke internet gitu), gw kemarin nyoba install sesuatu lagi. Biasanya, gw kan donlot dulu package-nya di kantor (yaaa… oportunis dikit gapapa lhah ya 😛 ), trus copy ke si eunji (nama laptop gw di rumah), trus baru dah install. Tapi sekarang ceritanya, gw lagi seneng2nya make ngabisin kuota dari nomer hape gw yang berujung pada kegiatan buat beli paket berkali2 T_T

Karena kegiatan gw yang gak lazim itu, jadilah pas butuh satu aplikasi, gw langsung pake cara standar ajah di terminal (pake apt-get install ___), dan kondisinya gw gak pake DVD repo. Di sinilah sebenernya tulisan ini bermula. Jadi, pas gw ketikin

sudo aptitude install amarok

Yang keluar malah gini:

Couldn’t find any package whose name or description matched “amarok”
Couldn’t find any package whose name or description matched “amarok”
No packages will be installed, upgraded, or removed.
0 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B of archives. After unpacking 0 B will be used.

Uhmm… ini gak banget, kan… jadi gw cobalah ketikin:

$ sudo apt-get update

sama

$ sudo apt-get upgrade

ternyata… hasilnya tuh gini:

[ ERR] Reading package lists
E: Encountered a section with no Package: header
E: Problem with MergeList /var/lib/apt/lists/packages.linuxmint.com_dists_rebecca_import_i18n_Translation-en
E: The package lists or status file could not be parsed or opened.
[ ERR] Reading package lists
E: Encountered a section with no Package: header
E: Problem with MergeList /var/lib/apt/lists/packages.linuxmint.com_dists_rebecca_import_i18n_Translation-en
E: The package lists or status file could not be parsed or opened.

Gw jugak gak tau apa yang gw bikin sebelumnya sampe keluar error gitu. Yah, sebenernya gak penting2 jugak c install amarok, toh dari awal, nih linux mint dah ke-install VLC ma Banshee. Tapi yaaa.. pengen aja cari alternatif lain. Karena penasaran, nemu lah satu thread ini.

Dari sana, dibilang cara nyeleseinnya pake 3 langkah ini:

$ sudo rm /var/lib/apt/lists/* -vf

Kode di atas, gw sebenernya juga gak tau artinya. Tapi, kalo rm buat nge-remove, yaaa… mungkin maksudnya buat ngehapus semua file di bawah direktori /var/lib/apt/lists, terus tulisin progres ngapusinnya (soalnya, -v itu pendekan dari “verbose” kalo gak salah). Abis itu, masukin ini:

$ sudo apt-get update

Kalo dah keluar macam2, brarti dah selese… tinggal dieksekusi kayak biasa… Dan, FYI… gw gak jadi install amarok. Tapi ya gapapa lhah… toh ujung2nya jadi 1 tulisan di mari 😛

Moga ngebantu yah, Guyz… 🙂

Mengakses Field Date pada Database Oracle

As always… ini tulisan rekues! Sebenernya udah lama c yah… dan orangnya yang ngerikues udah nerima jawabannya. Tinggal jawaban balik buat gw dibolehin apa enggak mosting yang dia tanyain di sini… Dan jawabannya, “terserah ajah”. Berhubung kemaren2 gw lagi di luar kota, nih tulisan baru jadi sekarang. 😀

Apapun prolog di atas, intinya si Aa’ nanya ke gw, gimana caranya kerja pake database Oracle, terus di database itu ada field yang tipe-nya Date. Kalo ajah dia nyari tutorialnya di stackoverflow, percayalah… itu jawaban bakal langsung nemu! Tapi, berhubung nih si Aa’ males ngeliat apapun, jadi dia tanya gw ajah. Katanya gw kan mantan asisten OOP. Hhhh… baiklah. (-_-)

Gimana caranya ngakses field itu? Gw tulisin jawabannya singkat ajah yak… Intinya, kalo insert, pake kuerinya gini:

String kueri = "INSERT INTO pergudangan (IDBARANG, NAMA, TGL_MASUK, STOK) VALUES (?,?,to_date(?,'DD-MM-YYYY','NLS_DATE_LANGUAGE = American'),?)";

Itu si Aa’ pake PreparedStatement, makanya ada tanda tanya gitu… intinya c pas masukin tanggal, bisa masukin pake format DD-MM-YYYY pas nulisinnya. Terus pas di ResultSet pake kode:

ps.setString(3,"27-05-2014");

Atau kalau kamu gak keberatan pake format “YYYY-DD-MM”, bisa pake java.sql.Date… caranya gini:

Date d = Date.valueOf("2014-11-15");
ps.setDate(3,d);

Yang paling penting dari hal di atas, kelas Date di sana diambil untuk class Date dari package java.sql… bukan java.util, yah. Si Aa’ berkali-kali gagal nyoba, gara2 dia ngira tipe Date di atas itu tipe Date dari java.util. Dan yang paling penting jugak buat kamu ketahui, kedua class ini walo namanya sama, mereka gak bisa di-casting gitu ajah. Boleh ajah kamu berhasil ngelakuin casting… tapi tolong kasi kodenya di kotak komentar yak. Gw jugak pengen tau… 😛

Teruuuuss… kalo kamu mau tau gimana caranya ngambil sysdate (tanggal dari system), kamu bisa pake bantuan dari class Date dari package java.util. Di sini, kamu bisa mengkolaborasikan kedua class Date itu. Caranya:

java.util.Date d1 = new java.util.Date();
Date d = new Date(d1.getTime());
ps.setDate(3,d);

Intinya, kamu bikin objek java.sql.Date dengan bantuan dari objek java.util.Date, tepatnya untuk memanggil method “getTime()”, yang bisa ngambil sysdate…

Dan…. trik terakhir, kalo kamu mau ngambil tipe Date dari ResultSet, dan kamu maunya nampilin pake format “dd-MM-YYYY”, ada class yang namanya “SimpleDateFormat”. Pake class itu, kamu bisa atur format tanggalnya. Caranya gini:

Date d = rs.getDate(3);
SimpleDateFormat sm = new SimpleDateFormat("dd-MM-YYYY");
System.out.println("Tanggal: "+sm.format(d));

Dan begitulah….

Kalau kamu mau tau penggalan kode di atas sebenernya lengkapnya tuh gimana… boleh disimak kode di bawah ini:

Untuk kelas Koneksi (KoneksiDB.java)… kelas ini buat ngecek JDBC ama ngembaliin objek class Connection. Kelas ini kebiasaan aja digunain pas kuliah dulu. Gak harus c, cuma ya itu… udah kebiasa… makanya adaan.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class KoneksiDB{
	private Connection conn;
	private final String DB_DRIVER="oracle.jdbc.driver.OracleDriver";
	private final String DB_URL="jdbc:oracle:thin:@localhost:1521/XE";
	private final String USERNAME="";
	private final String PASSWORD="";
	
	public void bukaKoneksi(){
		boolean flag = false;
		try{
			Class.forName(DB_DRIVER);
		}catch(ClassNotFoundException ex){
			System.out.println(ex.getMessage());
			flag = true;
		}
		if(!flag){
			try{
				conn = DriverManager.getConnection(DB_URL,USERNAME,PASSWORD);
			}catch(SQLException ex){
				System.out.println(ex.getMessage());
			}
		}
	}
	public Connection getConn(){
		return this.conn;
	}
}

Kelas Main yang digunain buat INSERT database:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Main{
	public static void main(String args[]){
		KoneksiDB k = new KoneksiDB();
		k.bukaKoneksi();
		Connection kon = k.getConn();
		String kueri = "INSERT INTO pergudangan (IDBARANG, NAMA, TGL_MASUK, STOK) VALUES (?,?,to_date(?,'DD-MM-YYYY','NLS_DATE_LANGUAGE = American'),?)";
		int rowAffect=0;
		try{
			PreparedStatement ps = kon.prepareStatement(kueri);
			ps.setString(1,"BRG04");
			ps.setString(2,"Tisu Kering");
			ps.setString(3,"27-05-2014");
			ps.setInt(4,20);
			rowAffect = ps.executeUpdate();
			ps.close();
		}catch(SQLException ex){
			System.out.println(ex);
		}
		if(rowAffect==0){
			System.out.println("Query Gagal");
		}else{
			System.out.println("Query Berhasil");
		}
		
	}
}

Kelas Main… contoh buat ngambil value dari string dengan format “YYYY-MM-DD”:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Date;

public class Main{
	public static void main(String args[]){
		KoneksiDB k = new KoneksiDB();
		k.bukaKoneksi();
		Connection kon = k.getConn();
		String kueri = "INSERT INTO pergudangan (IDBARANG, NAMA, TGL_MASUK, STOK) VALUES (?,?,?,?)";
		int rowAffect=0;
		try{
			PreparedStatement ps = kon.prepareStatement(kueri);
			ps.setString(1,"BRG03");
			ps.setString(2,"Sabun Cuci");
			Date d = Date.valueOf("2014-11-15");
			ps.setDate(3,d);
			ps.setInt(4,100);
			rowAffect = ps.executeUpdate();
			ps.close();
		}catch(SQLException ex){
			System.out.println(ex);
		}
		if(rowAffect==0){
			System.out.println("Query Gagal");
		}else{
			System.out.println("Query Berhasil");
		}
		
	}
}

Kelas Main yang dibikin buat ngambil sysdate:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Date;

public class Main{
	public static void main(String args[]){
		KoneksiDB k = new KoneksiDB();
		k.bukaKoneksi();
		Connection kon = k.getConn();
		String kueri = "INSERT INTO pergudangan (IDBARANG, NAMA, TGL_MASUK, STOK) VALUES (?,?,?,?)";
		int rowAffect=0;
		try{
			PreparedStatement ps = kon.prepareStatement(kueri);
			ps.setString(1,"BRG03");
			ps.setString(2,"Sabun Cuci");
			java.util.Date d1 = new java.util.Date();
			Date d = new Date(d1.getTime());
        	ps.setDate(3,d);
			ps.setInt(4,100);
			rowAffect = ps.executeUpdate();
			ps.close();
		}catch(SQLException ex){
			System.out.println(ex);
		}
		if(rowAffect==0){
			System.out.println("Query Gagal");
		}else{
			System.out.println("Query Berhasil");
		}
		
	}
}

dan terakhir…. kelas Main buat nampilin tanggal pake format “dd-MM-YYYY”:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Date;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;

public class Main{
	public static void main(String args[]){
		KoneksiDB k = new KoneksiDB();
		k.bukaKoneksi();
		Connection kon = k.getConn();
		
		String kueri="SELECT * FROM pergudangan";
		ResultSet rs = null;
		try{
			PreparedStatement ps = kon.prepareStatement(kueri);
			rs = ps.executeQuery();
			while(rs.next()){
				System.out.println("ID Barang: "+rs.getString(1));
				System.out.println("Nama Barang: "+rs.getString(2));
				Date d = rs.getDate(3);
				System.out.println("Tanggal Masuk: "+rs.getString(3));
				SimpleDateFormat sm = new SimpleDateFormat("dd-MM-YYYY");
				
				System.out.println("Tanggal: "+sm.format(d));
				System.out.println("Stok: "+rs.getInt(4)+"\n");
			}
		}catch(SQLException ex){
			System.out.println(ex);
		}
		
	}
}

Begitulaaahhh~~ moga ngebantu yah, guyz….

Valid?: Banget.
Masa Kadaluarsa: Gak tau.
Sumber: stackoverflow, pribadi.

Membuat .jar File dari Kode Java

Jadi gini… lagi2 ada yang nanya… Kalo diliat polanya, pas mosting yang agak serius, itu pasti karena requirement dari seseorang. Entah itu temen, si Aa’, atau sapa lhah… Seolah gw gak bisa bikin sesuatu yang serius, kecuali berupa tanggapan. Huweeee….

Apapun itu, intinya ada yang nanya ke gw, gimana cara bikin file berekstensi jar dari codingan java yang udah dia bikin. Hmmm, gimana yah… Kalo gw biasanya nyuruh dia pake IDE, terus coding pake Netbeans, trus kalo dah selesai, klik kanan di project Netbeans-nya, pilih “Build”. Ntar bakal ada folder “dist” kebentuk dalam folder project, dan itu bisa dijalanin gitu ajah, asal mesinnya keinstal JRE. Tapi, requirement-nya dia lagi gak make Netbeans dan emang cuma pake editor sederhana, yang gak bisa generate IDE-nya langsung.

Okeh… permintaan di atas, mirip2 sama tugas kuliah… Tapi baiklah, berhubung gw baik… jadi gw jelasin aja di mari. Buat yang gak tau apa itu file berekstensi jar, gw jugak bakal jelasin di mari. Ekstensi jar merupakan file java archive. Jadi kayak kamu ngegabungin beberapa file menjadi sebuah file lain. Pernah nge-compress beberapa file jadi 1 file zip/rar? Kalo pernah, yaaa yang kamu lakuin mirip2 ama compress itu. Bedanya, file jar ini bukan berfungsi buat nge-compress, tapi buat ngegabungin semua file class (hasil compile file java) yang udah kamu buat supaya bisa jalan dan jadi sistem yang utuh, walau kesebar di beberapa file codingan. Intinya, file .jar itu merupakan executable file yang terdiri dari satu atau beberapa file yang kamu gunakan untuk membuat sebuah aplikasi berbasis java.

Cara gampang untuk meng-generate file jar yaitu dengan menggunakan editor IDE kayak Eclipse atau Netbeans. Caranya kayak yang udah gw jelasin di atas. Ada cara gampang, ada juga cara native pastinya… Cara native ini kemungkinan yang dilakukan banyak programmer sebelum IDE diciptakan oleh mereka. Cara native-nya pake command “jar” di terminal/console/command prompt. Berhubung sekarang lagi ngetik di komputer berbasis  Windows, jadi gw praktekkin di windows, yak. Yang linux sama ajah… gak ada beda.

Sebelumnya, gw bakal ngasi tau kalo command jar punya beberapa opsi, diantaranya c, m, f, x, t dll. Penjelasannya gini:

  1. c: buat “create” file jar
  2. m: buat memodifikasi file MANIFEST.MF yang ada di folder META-INF
  3. f: untuk merujuk ke sebuah file yang diberikan, jadi keluarannya bukan stdout gitu
  4. x: buat nge”eXtract” file jar
  5. t: buat melihat isi dari file jar yang dimaksud

Contoh? Oke.. gini, pertama, bikin dulu file java yang ada “public static void main(String args[])”-nya biar bisa di-running.

public class Main{
	public static void main(String args[]){
		System.out.println("Hello World");
	}
}

Kompile dan run file java itu…

1. Eksekusi dan Jalankan

Yang perlu kamu ketahui, setiap kamu nge-running java, sebenernya yang kamu jalanin adalah file .class-nya, dan bukan file java-nya. Jadi, dalam jar, kamu cukup masukin file .class yang kamu butuhin… gak usah semuanya jugak. Tapi kalo kamu mau masukin semuanya, juga gak masalah. Kamu tinggal pake command “*” ajah… Gak usah pilih2…

Jadi… langkah selanjutnya, kamu masukin file Main.class ke dalam sebuah file jar, pake command jar

2. Bentuk Jar

Command itu gak usah gw jelasin yah maksud “cf”-nya. Kan udah di atas… Kalo hai.jar, itu nama file jar yang kamu mau, dan setelahnya ada Main.class… itu file class yang mau dimasukin ke file jar-nya. File jar ini, seharusnya udah bisa kamu jalanin… tapi biasanya, yang terjadi c belum bisa dijalanin. Cobain deh gini:

3. Jalankan Jar

Bilangnya, belum ada “main” di manifest sebagai atribut. Mungkin kamu bingung, dan gw lebih bingung lagi ngejelasinnya. Tapi intinya, pas kamu bikin file jar tersebut, ada file MANIFEST.MF dari folder META-INF yang di-generate secara default oleh sistemnya, karena file ini emang dibutuhin sama si file jar-nya. Bentuk default-nya kayak gini:

Manifest-Version: 1.0
Created-By: 1.7.0_55 (Oracle Corporation)

Isi dari file MANIFEST.MF itu belum lengkap, karena kita gak specified class yang punya “public static void main(String args[])” tuh yang mana. Makanya error-nya gitu. Uhhmmm… nangkep kan maksud gw?! Okeh, nangkep atau enggak, gw bakal kasi tau solusinya. Kamu extract dulu file jar yang tadi pake command gini:

4. Jar Salah

Dan nanti, ada file tambahan di folder tempat kamu nge-ekstract file hai.jar.

5. Struktur File

Ada folder META-INF. Di dalamnya ada MANIFEST.MF. Ubah isi file MANIFEST.MF pake editor favorit kamu (bisa gedit/notepad++/notepad) jadi kayak gini:

Manifest-Version: 1.0
Created-By: 1.7.0_55 (Oracle Corporation)
Main-Class: Main

Yang gw merahin merupakan nama Class yang bisa di-running (ada public static void main(String args[])). Kalo Class gw kan namanya Main.class, jadi gw bikinnya “Main”. Save, dan tutup editornya. Gak ditutup juga gak papa c. Terus, kamu bikin lagi file jar pake MANIFEST yang udah kamu ubah isinya tadi dan running. Caranya gini:

6. Bentuk Jar

Yang perlu kamu perhatiin, kamu harus nambahin satu karakter kosong sehabis kamu ngubah file MANIFEST.MF, jangan kayak gini:

7. Manifest Salah

Kenapa?! karena kalo gak, yaaa bakal jadi kayak gini kalo kamu running, hal ini lah yang bakal kamu temuin:

8. Jar Salah

Jadi bikinnya, paling gak ada karakter space kayak gini (space lhoh yah… whitespace juga gak ngaruh):

9. Manifest Benar

Dan buat kamu yang bertanya-tanya, kenapa ngejalaninnya pake “java -jar”, bukannya klik dua kali… kan executable?? Gak ada yang bisa gw jawab kecuali “yaaa.. karena tipe aplikasi yang dibikin itu sifatnya console-based”. Jadi jalaninnya tetap di console/terminal/command prompt/cmd. Kalo kamu bikin aplikasi GUI, ntar juga bisa dijalanin pake klik 2x. Dan begitulaaahhhh…. Pertanyaan dan saran, boleh langsung di kotak komentar, yak…

PS: kalo ada yang nanya, buat library eksternal kayak JDBC kalo mau di-running, daftarinnya gimana… Jawabannya gini: “tinggal kamu tambahin atribut Class-Path di file MANIFEST.MF”. Contohnya gini:

10. Manifest dengan Path

Dan struktur folder-nya gini:

11. Bentuk Jar

Kalo library lain ada lagi yang mau ditambahin, tinggal dikasi spasi ajah kayak gini:

Manifest-Version: 1.0
Created-By: 1.7.0_55 (Oracle Corporation)
Main-Class: Main
Class-Path: lib1.jar lib2.jar lib3.jar

PPS: Kalo ada yang nanya lagi, “itu… file MANIFEST.MF sebenernya buat apa dan harus kayak di atas bikinnya? Generate dulu, extract, baru pake yang ada?” sebenernya enggak. Jawabannya: “gw gak tau yah buat apa sebenernya, tapi kayaknya buat spesifikasi pas nge-running java…kan ada atribut Main-Class gitu, terus kalo harus gitu bikinnya… enggak c yah. Kamu bisa bikin sendiri file MANIFEST.MF itu pake editor biasa, asalkan encoding-nya pake UTF-8”. Contohnya, gini.. gw bikin sendiri MANIFEST.MF kayak di atas, terus gw generate lagi kayak gini:

12. Akhir

Dan selesai… Begitulah caranya.. Moga membantu…

Valid: Iyap!
Kadaluarsa: Gak tau
Sumber: situs oracle, stackoverflow.com sama dok pribadi

Menyimpan Username & Password di Option Panel

Kemarin udah ngebahas tentang form login yang muncul sebelum aplikasi dijalanin kan yah… Tapi username sama passwordnya kesimpan di sistem. Sebenernya, kamu bisa ubah2 supaya uname ma passwordnya kesimpen di database. Tapi, kalo kamu gak niat bikin aplikasi yang pake database, uname ma passwordnya, bisa kamu simpan di variable global. Yang pake NbPreferences gitu… Dan biasanya kalo gak pake bantuan Wizard, pake bantuan dari Option Panel.

Tapi berhubung adanya tutorial buat nyimpen dari Option Panel, kita ngikutin ajah yah…

Uhmmm… sebelum ngikutin tutorial ini, pastiin ikutin tutorial sebelumnya yah… Kan nyambung ceritanya.

Pertama, dari NPA sebelumnya, kita buat satu module buat nampung Option Panel. Sebenernya boleh aja kalo mau gabung sama module “LoginModule” sebelumnya, tapi gw pisah… biar mirip sama tutorialnya 😀 Jadi… bikin satu module baru lagi, infonya gini:

1. Identitas Module2. Code Name Base Module

Di module “Pengguna”, buat satu option panel. Klik kanan di module, pilih New →  Other. Muncul 1 window baru, di sebelah kiri pilih “Module Development”, di bagian kanan pilih “Options Panel”.

3. New Option Panel

Bikin Primary Panel ajah kita. Gak usah ada secondary panel-nya… Untuk icon, kalo gak punya, pake ini ajah… User-icon Bukan punya gw jugak c sebenernya… ngambil secara semena-mena dari internet itu… :p

4. Primary Panel

5. Option Panel Name

Klik “Finish”. Perhatikan, ada 3 file kebentuk… Cuma yang kebaca 2 ajah (ekstensi java ajah yang bakal muncul). Yang satu (ManajemenPenggunaOptionsPanelController) buat controller, yang satu lagi (ManajemenPenggunaPanel) buat desain tampilannya.

Di bagian pengaturan tampilan, atur tampilannya jadi kayak gini:

6. Desain Option Panel

Ada 2 label, 1 text field di sebelah “Pengguna” dengan nama variable “username”, 1 text field bernama “password” di sebelah “Kata Sandi”. Dan layoutnya pake Flow Layout.

Kondisi yang kita mau, tiap nutup panel itu, perubahan disimpan, dan tiap dibuka, pengguna ama kata sandi-nya muncul. Artinya, kita bakal kerja dengan method “load” dan “store”. Method ini ada di kelas “ManajemenPenggunaPanel”. Kalo kamu Cuma liat bagian design, coba ubah ke bagian Source. Ntar keliatan tuh yang begituan.

7. Source-Design

8. Method Load-Store

 Kalo load dijalanin pas option panel dibuka, store dijalanin pas ditutup. Sekarang, gw c mau bikin buat “store” dulu. Jadi, kalo mau nyimpen variable, bisa pake kode gini kan yah:

NbPreferences.forModule(REFERENSI_KELAS_YG_DIGUNAKAN).put
     ("NAMA_VAR_YG_DIMAU", "TEXT");

Tinggal diganti nama variable yang diinginkan, terus ganti text sesuai isi yang disimpan. Jadi kalo mau username disimpan di variable bernama “nama” dan isinya “arby”, terus referensi kelasnya itu c option panel tadi, kode di atas bisa diganti jadi:

NbPreferences.forModule(ManajemenPenggunaPanel.class).
     put("nama", "arby");

Dan kode di atas, gak ada hubungannya sama nama variable text field atau apapun yang sebelumnya udah kita buat. Hubungannya, isi dari variable itu kan seharusnya dari text field yang udah kita buat sebelumnya, jadi musti kita ganti pake:

 NbPreferences.forModule(ManajemenPenggunaPanel.class).put
      ("nama", username.getText());

Kalo “nama” di atas, gak usah diganti… itu jadi nama variable global kalo mau ngakses username. Kalo kamu mau ganti yaaa silakan. Tapi kamu musti tau, referensi rujukan variable global-nya jadi berubah. Kalo yang di-store udah selesai diubek2, selanjutnya di method load yang diubah2… Di method ini, kita ubah kode sebelumnya, dari “put” jadi “get”.

NbPreferences.forModule(ManajemenPenggunaPanel.class).get("nama", "")

Kalo kamu liat, isinya jugak ada 2, “nama” dan string kosong. Untuk “nama”, ini merupakan referensi global yang udah kita tentuin tadi. Untuk store ama load, ini harus sesuai. Sedangkan string kosong, itu merupakan default yang dikirimkan kalo si variable global “nama” itu gak ditemuin ama sistem.

Singkat cerita, isi dari method store sama load itu bisa dibikin kayak gini:

    void load() {
        NbPreferences.forModule(ManajemenPenggunaPanel.class).get("nama", "");
        NbPreferences.forModule(ManajemenPenggunaPanel.class).get("sandi", "");
    }

    void store() {
        NbPreferences.forModule(ManajemenPenggunaPanel.class).put("nama", username.getText());
        NbPreferences.forModule(ManajemenPenggunaPanel.class).put("sandi", password.getText());
    }

Dan jangan lupa buat meng-import package terkait:

import org.openide.util.NbPreferences;

Udah?? Coba dijalanin…

Di bagian Tools → Option, ada satu menu “Manajemen Pengguna”. Di sana ada 2 buah text field gini. Dan itu bisa diisi sesukanya…

9. Hasil

Tekan OK, terus tutup aplikasi NPA-nya. Aplikasi lhoh ya… Bukan sekedar Option Panel-nya. Jalanin lagi, lihat di bagian “Manajemen Pengguna”, isi dari “Pengguna” dan “Kata Sandi” bakal tetap ada. Tapi kamu heran… coz yang kamu temuin adalah field kosong… Padahal udah ngikutin langkah2 yang gw tulis dengan baik dan benar.

Oke, kamu gak usah pusing, coz variable itu tetap ada isinya. Cuma emang gak nampil. Itu ajah… Kalo kamu isinya tampil, kamu musti ubah dikit kodingan di method load jadi gini:

    void load() {
        String nama = NbPreferences.forModule(ManajemenPenggunaPanel.class).get("nama", "");
        String sandi = NbPreferences.forModule(ManajemenPenggunaPanel.class).get("sandi", "");
        
        username.setText(nama);
        password.setText(sandi);
    }

Jalanin lagi deh.. Ntar text di sebelah “Pengguna” sama “Kata Sandi” bakal ada isinya…

Oke… Tapi isi yang kesimpen di option panel ini belum ada hubungannya sama modul login. Jadi… kita ubah codingan di modul “LoginModule”. Karena kemarin dibikin bagian pengecekan username sama sandi ada di method “authenticate” dari class Installer, jadi kita liat lagi method tersebut.

    private void authenticate(){
        String uname = lf.getUsername();
        char[] pwd = lf.getPass();
        if(uname.equals("Arby")){
           if(cekPwd(pwd)){
               
           }else{
               exit();
           }
        }else{
            exit();
        }
        
    }
    
    private boolean cekPwd(char[] input){
        boolean benar;
        char[] pass = {'p','e','s','a','n'};
        if(input.length != pass.length){
            benar = false;
        }else{
            benar = Arrays.equals(pass, input);
        }
        Arrays.fill(pass,'0');
        return benar;
    }

Bagian krusial ada di bagian warna merah. Kalo yang warna biru, itu method yang dipanggil sama baris kode warna merah kedua.

Di bagian merah pertama, ada pengecekan username. Dibandingin sama kata “Arby”. Karena kita udah punya pembanding lain, yaitu variable global yang kita simpen di kelas referensi “ManajemenPenggunaPanel” dengan nama “nama”. Sayangnya, “Installer” sama “ManajemenPenggunaPanel” ada di 2 module yang berbeda. Mereka harus dihubungin satu sama lain. Biar terhubung, ada yang nge-publish isinya, ada yang make isi module yang di-publish itu. Dan kalo kita liat lagi, module “Pengguna” yang ada kelas “ManajemenPenggunaPanel” ini lebih bersifat publisher, dan module “LoginModule” yang ada “Installer” cocok buat jadi pengguna sesuatu yang di-publish.

Jadi, klik kanan di module “Pengguna”. Pilih “Properties”, pilih API Versioning, dan centang di bagian “Public Packages”. Tekan OK.

10. Public Package Option Panel

Abis itu, klik kanan di bagian module “LoginModule”, Pilih Bagian “Libraries”. Di tab “Module Dependencies”, pilih “Add Dependency” (Langkah ini bisa kamu lakukan di bagian “Libraries” dari module di window tree project).

11. Module Dependency

Pilih module “Pengguna” dan tekan OK.

12. Dependency Pengguna

12. Dependency Pengguna-2

Kalo udah kayak di atas Module Dependencies dari LoginModule, artinya mereka udah saling mengenal. Yang LoginModule bisa pake module Pengguna. Tapi ada satu masalah lagi… class “ManajemenPenggunaPanel” gak bersifat public. Jadi class itu gak mungkin digunain di luar package terkait. Solusinya, tambahin keyword “public” pas ngedeklarasiin class “ManajemenPenggunaPanel”.

public final class ManajemenPenggunaPanel extends javax.swing.JPanel {

Kalo udah gini…. di method authenticate, bisa diubah jadi:

    private void authenticate(){
        String sNama = NbPreferences.forModule(ManajemenPenggunaPanel.class).get("nama","");
        String uname = lf.getUsername();
        char[] pwd = lf.getPass();
        if(uname.equals(sNama)){
           if(cekPwd(pwd)){
               
           }else{
               exit();
           }
        }else{
            exit();
        }
        
    }

Lihat kan??! Logikanya gampang… Ambil variable global yang udah tersimpan, cek username inputan user sama username dari variable global. Coba jalanin deh… Pasti kalo kamu masukin kayak gambar di bawah, aplikasinya gak bakal jalan.

13. Hasil Akhir

Karena username-nya udah berubah… Jadi “system”… sesuai yang diinput di option panel sebelumnya. Username udah berubah, berikutnya password. Pengecekan password, ada di method “cekPwd”. Jadi oprek2 ajah method itu. Gw ubah method nya jadi kayak gini:

    private boolean cekPwd(char[] input){
        boolean benar;
        String pwd = NbPreferences.forModule(ManajemenPenggunaPanel.class).get("sandi", "");
        char[] pass = pwd.toCharArray();
        if(input.length != pass.length){
            benar = false;
        }else{
            benar = Arrays.equals(pass, input);
        }
        Arrays.fill(pass,'0');
        return benar;
    }

Coba jalanin lagi… Pasti password yang benar udah bukan “pesan” lagi, tapi “arby”. Sesuai yang tersimpan di variable global.

Selesaaaaaiii~~~~

Valid: Hu um….
Kadaluarsa: Cuma dibuktiin buat netbeans 8.0
Sumber: Link di atas + dok. pribadi

Menambahkan window Login pada Netbeans Platform

Pertanyaan yang sering gw denger terkait netbeans platform yaitu… “bisa gak dikasi security aplikasinya?” Dan jawaban gw… “Tergantung!”… Yuhu~~~ tergantung ama jenis security apa yang kamu maksud. Kalo maksudnya biar ada halaman login sebelum aplikasinya dijalanin… yaaa bisa banget! Yang perlu kamu lakuin ngikutin tutorial dari netbeans platform tentang installer.

Buat 1 netbeans module di 1 NPA (Netbeans Platform Application) kayak gini (Untuk NPA-nya, bikin sendiri yak… pake yang ada jugak boleh, gak musti bikin NPA baru dari awal. Module jugak sama, Cuma gw bikin module baru khusus Installer)…

Klik kanan bagian module di NPA, pilih “Add New…”.

1. Module Baru

Masukin “LoginModule” buat namanya…

2. Nama Module Baru

Buat code name base-nya terserah… Cuma kamu bisa masukin kayak gw (“org.login”)

3. Code Base Module baru

Bakal muncul 1 netbeans module yang baru bernama “LoginModule”, breakdown ajah (tekan tanda tambah-nya) terus di package “org.login” klik kanan pilih “Other”.

4. Login Module

Bakal muncul 1 window baru, pilih “Module Development” di sebelah kiri, pilih “Installer/Activator” di sebelah kanan.

5. Installer

Installer ini merupakan hal yang pertama kali dijalankan ama NPA. Kalo gak salah, Cuma ada 1 Installer per netbeans module. Kalo gak salah lhoh yah… Jadi, kamu bakal nemuin error kalo punya lebih dari 1 installer per module. Tapi… 1 NPA boleh punya lebih 1 module kan yah… Kalo kamu mau letakin 1 Installer untuk tiap module-nya, yaaa boleh2 ajah…  Cuma pastiin kalo tiap Installer itu gak bentrok algoritmanya satu sama lain…

Intinya, bakal kebentuk 1 Installer… dan isinya tuh gini:

package org.login;

import org.openide.modules.ModuleInstall;

public class Installer extends ModuleInstall {

    @Override
    public void restored() {
        // TODO
        
    }

}

Yup! Simple yah…. Di bagian body method restored(), kamu bisa tambahin apapun yang bakal ngejalanin kode itu pertama kali pas NPA dijalanin. Coba ajah tambahin gini:

package org.login;

import org.openide.modules.ModuleInstall;

public class Installer extends ModuleInstall {

    @Override
    public void restored() {
        System.out.println("Hello World");
    }

}

Dan nanti, pas NPA dijalanin… jadinya gini:

6. Eksekusi Installer

Muncul “Hello World” gitu…

Hal ini yang bakal kita manfaatin buat munculin login window pas ngejalanin NPA. Jadi… udah nangkep yah apa yang mau kita bikin… Minimal, tempat untuk pertama kali modul dijalanin udah ada.. Sekarang, bikin form login-nya.

Masih di module yang pertama kita bikin tadi, klik kanan di package org.login, pilih New → Other.

7. New Panel

Di sebelah kiri pilih “Swing GUI Forms”, di sebelah kanan pilih “JPanel Form”. Di bagian nama, masukin ajah “LoginForm”. Bebas c yah… Suka2 kamu ajah.

Kenapa pilih JPanel bukan JFrame Form?! Coz kita gak bikin satu aplikasi sendiri teman2… kita bikin sebuah panel yang jadi bagian dari NPA-nya. Jadi, GUI dasar tetap dari NPA. Makanya pake JPanel. Mungkin itulah yang dibilang Netbeans di tutorialnya kalo kamu bertanya2 kenapa gak bikin JFrame Form sekalian.

8. New Panel-2

Sekarang, bisa design panel-nya suka2 kamu. Mau pake layout apapun boleh. Gw c gini:

9. Design Panel

Tambahkan method untuk me-return isi dari text field username sama password:

    public String getUsername(){
        return this.jTextField1.getText();
    }
    
    public char[] getPass(){
        return this.jPasswordField1.getPassword();
    }

Ada 2 label, 1 text field sama 1 password field. Di sini, GUI tempat nampung username sama password udah muncul. Tinggal dipanggil ajah di bagian Installer. Tapi… seperti yang kamu tau, JPanel bukanlah komponen yang biasa ditampilkan secara langsung. JPanel kan sifatnya lebih ke container, bukan sebagai pane. Kalo gak salah c yah. Atau gw kebalik?

Tapi bukan itu intinya… Intinya adalah gimana cara nampilin si JPanel di NPA. Kita bisa pake NotifyDescriptor yang ada di module “Dialogs API”. Jadi, caranya… klik kanan di bagian “Libraries”, pilih “Add Module Dependency”. Di bagian Filter tulis “NotifyDescriptor” atau “Dialogs API”.

10. Dependency

Dan nantinya, ada 1 library tambahan di bagian “LoginModule”.

11. Libraries

Ubah isi dari Installer dengan memanggi si JPanel yang sudah dibuat sebelumnya:

import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.modules.ModuleInstall;

public class Installer extends ModuleInstall {

    LoginForm lf = new LoginForm();
    @Override
    public void restored() {
        NotifyDescriptor nd = new NotifyDescriptor.Confirmation(lf, "Login");
        DialogDisplayer.getDefault().notifyLater(nd);
    }
}

Dan… setelah clean & build, terus di-run, NPA kamu bakal ngehasilin tampilan kayak gini:

12. Login Window

Ada login-nya sodara2!! Hohohoho…

Tapi… sayangnya, kamu mau tekan tombol apapun, hasilnya sama ajah.. pasti ngeluarin aplikasi NPA-nya gak pake kendala.

Untuk melakukan pengecekan username dan password yang sesuai, ubah codingan di Installer kayak gini:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import javax.swing.JButton;
import org.openide.DialogDisplayer;
import org.openide.LifecycleManager;
import org.openide.NotifyDescriptor;
import org.openide.modules.ModuleInstall;

public class Installer extends ModuleInstall {

    LoginForm lf = new LoginForm();

    @Override
    public void restored() {
        bikinForm();
    }

    private void bikinForm() {
        JButton ok = new JButton();
        ok.setText("OK");

        JButton cancel = new JButton();
        cancel.setText("Cancel");

        cancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                exit();
            }
        });

        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                authenticate();
            }
        });
        
        NotifyDescriptor nd = new NotifyDescriptor.Confirmation(lf, "Login");
        DialogDisplayer.getDefault().notifyLater(nd);
        nd.setOptions(new Object[] {ok,cancel});
        
        nd.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent pce) {
                if (NotifyDescriptor.CLOSED_OPTION.equals(pce.getNewValue())) {
                    exit();
                }
            }
        });
    }

    private void exit() {
        LifecycleManager.getDefault().exit();
    }
    
    private void authenticate(){
        String uname = lf.getUsername();
        char[] pwd = lf.getPass();
        if(uname.equals("Arby")){
           if(cekPwd(pwd)){
               
           }else{
               exit();
           }
        }else{
            exit();
        }
        
    }
    
    private boolean cekPwd(char[] input){
        boolean benar;
        char[] pass = {'p','e','s','a','n'};
        if(input.length != pass.length){
            benar = false;
        }else{
            benar = Arrays.equals(pass, input);
        }
        Arrays.fill(pass,'0');
        return benar;
    }
}

Moga kamu gak bingung c yah ama kode di atas… Intinya, kode warna biru untuk ngebikin panel-nya. Jadi yang awalnya ada 3 tombol, sekarang ada 2 tombol. Masing2 tombol punya action sendiri… yaitu exit() sama authenticate(). Itu kode yang gw tandain pake warna merah. Terus ada method “cekPwd()” yang digunain buat ngecek password. Method itu dipanggil di method authenticate().

Yah… gitu lah…

Sekarang, kalo di-run udah jalan mintak uname ama password. Uname-nya “Arby” passwordnya “pesan”. Itu case sensitive lhoh yah… Kalo salah masukin, yaaa… selesai… Kalo kamu bingung mau ngubah uname ama password ada di mana, yaaa… itu masalah kamu! Hehehe 😀

Eh… enggak kok, gw gak kejam. Adanya di baris yang gw pakein bold ama underline…

Begitulaaahhh~~ moga bantu yak.

Valid: Yap
Kadaluarsa: Sejauh ini teruji mulai 7.2 sampe nb 8
Sumber: Situs netpla+dok pribadi

Menggunakan MD5 di Java

Kamu tau fungsi hash?? Hmmm.. mustinya tau yah, jadi gw gak usah nulisin lagi di mari. Intinya, fungsi hash itu fungsi satu arah buat ngubah suatu string. Fungsi ini banyak digunain buat nyimpen password di database. Jadi, sebelum passwordnya dimasukin ke database, diubah dulu bentuknya pake fungsi hash, baru disimpen. Jadi… bahkan orang yang punya akses database-nya gak bakal tau password dari user terkait. Dan fungsi hash paling dikenal itu… MD5! Kenapa?? Gak ngerti jugak deh. Mungkin ada hubungannya sama pemanggilannya yang gampang di php. Kamu tinggal gunain:

string md5 ( string $str [, bool $raw_output = false ] )

Contohnya,

<?php
$str = 'apple';

if (md5($str) === '1f3870be274f6c49b3e31a0c6728957f') {
    echo "Would you like a green or red apple?";
}
?>

Tapi… berhubung gw lagi gak bicarain php, jadi… kita ganti bahasa! Di postingan ini, gw bakal tulisin contoh pemakaian md5 di java. Di java sendiri, pemakaiannya jugak gak sulit2 amat coz kamu gak usah bikin fungsi md5 dari awal. Ada class MessageDigest dari package “java.security”yang bisa kamu gunain di sini. Sayangnya, masukan dari fungsi md5 bukan string… jadi musti convert dulu ke dalam bentuk array of byte.

Dan pemakaiannya kira2 pake kode gini:

import java.security.MessageDigest;
…
String pesan = “pesan kamu”;
byte[] bytePesan = pesan.getBytes();
MessageDigest md = null;
try {
      md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException ex) {
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] hasil = md.digest(bytePesan);

Dan “hasil” merupakan bentuk md5 dari pesan kamu. Cuma ajah, masih dalam bentuk byte. Hasil ini bisa kamu ubah ke dalam bentuk String pake method “toString” yang (kemungkinan) bakal nampilin alamat dari si array of byte. Atau kamu bisa ubah ke dalam bentuk string lagi pake kode:

byte[] hasil = md.digest(bytePesan);
String pwd = new String(hasil);

Tapi… sayangnya, ini gak bisa kamu lakuin… coz hasilnya bakal jadi gini:

1. Hasil Password

Jadi… gimana caranya supaya string dari hasil fungsi md5 itu muncul?? Caranya ngerubah bentuk byte itu ke dalam format hexa. Gampangnya, sediain 1 fungsi dengan masukan byte dan keluaran String:

    private static String byteArrToString(byte[] b) {
        
        StringBuilder sb = new StringBuilder(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            int j = b[i] & 0xff;
            if (j < 16) {
                sb.append('0');
            }
            sb.append(Integer.toHexString(j));
        }
        String res = sb.toString();
        return res.toUpperCase();
    }

Dan bisa digunain gini:

        byte[] hasil = md.digest(bytePesan);
        String password = byteArrToString(hasil);

2. Hasil Fungsi Hash

Lengkapnya:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Arby
 */
public class Main {

    public static void main(String[] args) {
        Scanner x = new Scanner(System.in);
        System.out.print("Masukkan kata: ");
        String pesan = x.nextLine();

        byte[] bytePesan = pesan.getBytes();
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        byte[] hasil = md.digest(bytePesan);
        
        String password = byteArrToString(hasil);
        System.out.println(password);
    }

    private static String byteArrToString(byte[] b) {
        
        StringBuilder sb = new StringBuilder(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            int j = b[i] & 0xff;
            if (j < 16) {
                sb.append('0');
            }
            sb.append(Integer.toHexString(j));
        }
        String res = sb.toString();
        return res.toUpperCase();
    }
}

Sumber:
http://stackoverflow.com/questions/415953/generate-md5-hash-in-java
https://platform.netbeans.org/tutorials/60/nbm-login.html

Valid: Yap…
Kadaluarsa: Sampe method dari class MessageDigest dinyatain deprecated

Membuka Window dari Node Bean Tree pada Netbeans Platform

Pengen buka window dari suatu node?! Simple, pake ajah kode:

TopComponent tc = new NamaTopComponentYangDibuka();

Atau, karena top component udah di-set sebagai suatu singleton ama netbeans platform, manggilnya bisa gini:

TopComponent tc = WindowManager.getDefault().findTopComponent("NamaTopComponentYangDibuka ");

Dan jangan lupa nambahin kode:

tc.open();

Begitulaaahh~~ gampang kan?! Tambahin kode2 di atas di aksi yang udah dibikin sebelumnya.

Tulisan Terkait:

  1. Bean Tree View
  2. Aksi Bean Tree View

Valid: Yap!
Kadaluarsa: Teruji efektif di versi 7.4-8.0; Diyakinkan jalan di versi 6.9 ke atas.
Sumber:
Milis Netbeans
Situs Geertjan

Menambahkan Open File pada Netbeans Platform

Yang namanya ngegunain framewok emang menyenangkan… Ada banyak alasan buat itu. Salah satu alasan yang paling sering digunain buat alasan pas sidang TA yaitu tentang pengembangan lebih lanjut. Well, gw menganggap itu bukan keuntungan sama sekali. Yang jelas, kalo gw, seperti ajaran senpai… nganggap kalo framework itu kerangka kerja. Setiap orang punya cara kerja dan pola pikirnya masing-masing. Dan framework menyamaratakan persepsi dan pikiran itu. Simple! Dan yang paling penting, framework itu memudahkan segalanya. Ada beberapa modul yang gak harus dibuat ulang dari awal. Tinggal make fungsi yang udah disediakan… dan jadi!

Hal itu juga kejadian di Netbeans Platform. Ada modul yang bisa kamu gunain gitu ajah buat hal2 tertentu dan umum. Salah satunya modul buat ngebuka file. Di sini, kamu bisa langsung pilih file, dan ngebuka file itu. Gampang!

Hasil akhirnya kira2 gini:

1. Hasil Akhir

Ada satu module “Open File” ama “Open Recent File” di sana. Defaultnya hal ini gak ada c yah… Defaultnya kan kayak gini:

2. Hasil Sebelumnya

Jadi… nambahin hal itu… caranya gampang ajah. Kamu gak usah nambahin 1 action buat menu yang bakal nampil “Open File” terus ngebikin objek File Chooser. Gak usaaaaahh…

Cara nambahinnya gini, klik kanan di NPA yang kamu mau ada Netbeans Platform-nya. NPA lhoh yah. NPA! Bukan module NPA. Pilih Properties, muncul 1 window, di bagian “Categories”, pilih “Libraries”.

3. Module NPA

Di bagian “Node”, ada beberapa module udah jadi yang bisa kamu gunain. Karena fokusnya buat nambahin “Open File” tadi, jadi coba pilih/breakdown bagian “ide”, cari module “User Utilities”. Dan langsung ajah centang…

4. Module NPA-2

Klik OK, dan hasilnya seperti yang udah kamu liat sebelumnya. Sekarang, kalo kamu berniat buat nambahin filter, kayak gini:

5. Filter

Bisa banget! Caranya jugak gampang… tinggal pake annotasi dari MIMEResolver.Registration. Bikin 1 top component (Window). Kalo belum tau caranya, liat postingan gw sebelumnya yak. Terus, tambahin 1 buat file Java. Yap! File java biasa.

Bikin file-nya jadi kayak gini:

import org.openide.filesystems.MIMEResolver;

@MIMEResolver.Registration(
        displayName = "Nama",
        resource = "mime-resolver-html.xml",
        showInFileChooser ={"Web Page"}
)

public class WebFilter{

}

Yuhuuuu~~ isinya emang gak ada. Tapi kamu nambahin satu annotasi “@MIMEResolver.Registration”. Annotasi ini sebenernya bisa ditambahin di top component tadi. Tapi gw pisahin ke kelas lain. Di kelas ini, kamu bisa lakukan beberapa logika… Contohnya, apa yang mau kamu lakuin terhadap file yang kamu buka. Pastinya gak plain kayak di atas. Kamu jugak musti make module lain dari netbeans platform buat itu. Karena sulit, jadi gw gak nulisin dah di mari :p

Balik lagi ke kelas tadi, kemungkinan kamu bakal dapat error di baris “resource”. Ini kejadian, coz XML tempat ngatur filternya gak ada. Jadi kamu bikin 1 file dulu… namanya “mime-resolver-html.xml”. Yap! Lagi2 kamu benar… itu file XML emang. Isinya gini:

<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE MIME-resolver PUBLIC
          "-//NetBeans//DTD MIME Resolver 1.0//EN" 
          "http://www.netbeans.org/dtds/mime-resolver-1_0.dtd">
<MIME-resolver>
    <!-- Skip anything marked as definitely not ours. -->
    <file>
        <fattr name="known-ant-project-file" text="false"/>
        <exit/>
    </file>
    <!-- Accept immediately anything known as definitely ours. -->
    <file>
        <fattr name="known-ant-project-file" text="true"/>
        <resolver mime="text/x-ant+txt"/>
    </file>
    <!-- For other XML, look for <project default="..."/> -->
    <file>
        <ext name="htm"/>
        <resolver mime="text/x-ant+htm">
            <xml-rule>
                <element name="project">
                    <attr name="default"/>
                </element>
            </xml-rule>
        </resolver>
    </file>
    <file>
        <ext name="html"/>
        <resolver mime="text/x-ant+html">
            <xml-rule>
                <element name="project">
                    <attr name="default"/>
                </element>
            </xml-rule>
        </resolver>
    </file>
    <file>
        <ext name="shtml"/>
        <resolver mime="text/x-ant+shtml">
            <xml-rule>
                <element name="project">
                    <attr name="default"/>
                </element>
            </xml-rule>
        </resolver>
    </file>
    <file>
        <ext name="xhtml"/>
        <resolver mime="text/x-ant+xhtml">
            <xml-rule>
                <element name="project">
                    <attr name="default"/>
                </element>
            </xml-rule>
        </resolver>
    </file>
</MIME-resolver>

Gw gak bakal jelasin apapun terkait hal diatas, tapi gw Cuma mau bilang… perhatiin kode warna biru.

Yang bakal kamu dapatin dari kelas di atas, yaaa… Cuma filter buat web page. Kalo mau filter buat XML jugak kayak di contoh awal, kamu musti tambah 1 kelas lagi. Ulangi lagi kayak hal di atas. Sebenernya ada cara lain, Cuma gw gak ngerti. Jadi yaaa sudah… Yang penting jadi kan 😀

6. Filter Akhir

Jadi gw tambahin 1 file XML gini:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE MIME-resolver PUBLIC
          "-//NetBeans//DTD MIME Resolver 1.0//EN" 
          "http://www.netbeans.org/dtds/mime-resolver-1_0.dtd">
<MIME-resolver>
    <!-- Skip anything marked as definitely not ours. -->
    <file>
        <fattr name="known-ant-project-file" text="false"/>
        <exit/>
    </file>
    <!-- Accept immediately anything known as definitely ours. -->
    <file>
        <fattr name="known-ant-project-file" text="true"/>
        <resolver mime="text/x-ant+xml"/>
    </file>
    <!-- For other XML, look for <project default="..."/> -->
    <file>
        <ext name="xml"/>
        <resolver mime="text/x-ant+xml">
            <xml-rule>
                <element name="project">
                    <attr name="default"/>
                </element>
            </xml-rule>
        </resolver>
    </file>
</MIME-resolver>

Terus 1 kelas lagi gini:

import org.openide.filesystems.MIMEResolver;

@MIMEResolver.Registration(
        displayName = "Nama",
        resource = "mime-resolver-xml.xml",
        showInFileChooser ={"XML Document"}
)

public class XMLFilter {
    
}

Struktur direktori:

7. Direktori

Begitulaaaahhh~~ gampang, kan?! 😀

Valid: Banget!
Kadaluarsa: Paling gak, teruji dari versi 7.4 sampe 8.0
Sumber:
https://blogs.oracle.com/geertjan/entry/open_file_dialog_in_the
– Javadoc MIMERegistration.

Menggunakan BeanTreeView pada Netbeans Platform

Buat sebuah NPA baru, tambah 1 modul (name-nya kalo gak ada ide, bikin aja “SeleksiSimpul”, base “org.seleksi.view”).

1. Modul-NPA

Trus tambahin sebuah top component (Window). Kalo belum tau, caranya…. Klik kanan di package “org.seleksi.view”, pilih “New –> Other”. Muncul 1 window, pilih “Window”.

2. BeanTree

3. Bean Tree-Next

4. Bean Tree-Next-1

Muncul  sebuah form, atur di form kemunculan BeanTreeView. Ambil BeanTreeView dari Palette. Kalo belum ada, di Palette, klik kanan pilih “Palette Manager”.

5. Palette Manager

Pilih “Add From JAR”.

5. Add From JAR

Cari jar “org-openide-explorer.jar” di folder /platform/modules dari direktori tempat nginstall netbeans. Kalo yang windows, kemungkinan alamatnya: “C:\Program Files\NetBeans 8.0\platform\modules”, kalo linux kemungkinan “/home/ NetBeans 8.0/platform/modules”.

6. Jar Explorer

Pilih “BeanTreeView”, masukkan kemunculannya ke kategori yang kamu mau.

6. Category

6. Category Place

Nanti bakal muncul gini:

7. Palette Bean Tree View

Tarik BeanTreeView ke form… sebelumnya layout kalo mau diatur jugak boleh.

8. Panel

 Kalo gw pake border layout, naruh BeanTreeView di bagian center. Class-nya bakal ada merah2 tanda error. Itu wajar, coz defaultnya Cuma ada 5 modul dependency yang dipakai di sini (kalo udah bikin Window):

  1. Lookup API
  2. Settings API
  3. UI Utilities API
  4. Utilities API
  5. Window System API

Liat ajah di bagian library dari module terkait. Bakal muncul gini:

9. Error Dependency

Dependency BeanTreeView ada di “Explorer & Property Sheet API”. Trus buat bikin simpul/node-nya pake dependency dari “Nodes API”. Jadi, sekalian kita tambahin ajah. Di bagian “Libraries”, klik kanan, pilih “Add Module Dependency…” Cari 2 module tadi. Bisa kamu masukin nama, atau komponen yang kamu perluin.

10. Explorer Dependency

11. Nodes Dependency

Buat sebuah class untuk membuat child atau node2 yang bisa dieksplor nanti. Bentuk dasar yang tampil, gw bikinnya String ajah. Kamu bisa ganti pake class bentukan sendiri.

Jadi, di package yang sama (org.seleksi.view), bikin sebuah class gini:

import java.util.List;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Node;
public class SimpulAnak extends ChildFactory<String>{

    @Override
    protected boolean createKeys(List toPopulate) {
        return true;
    }

    @Override
    protected Node createNodeForKey(String key) {
        return null
    }   
}

Berhubung di atas Cuma outline, kita isi masing2 method yang ada. Udah tau ya maksut kode di atas. Cuma 1 method abstract dari kelas “ChildFactory” (<String>, bisa kamu ganti kelas lain), yaitu createKeys(). Method yang ini gunanya buat mem-populate data yang bakal ditampilin. Terus method yang satu lagi buat bikin node-nya.

Jadi… ganti methodnya jadi gini:

    @Override
    protected boolean createKeys(List toPopulate) {
        ArrayList al = new ArrayList();
        al.add("Menu 1"); al.add("Menu 2"); al.add("Menu 3");
        toPopulate.addAll(al);
        return true;
    }

    @Override
    protected Node createNodeForKey(String key) {
        try {
            BeanNode bn = new BeanNode(key);
            bn.setDisplayName(key);
            System.out.println();
            return bn;
        } catch (IntrospectionException ex) {
            Exceptions.printStackTrace(ex);
            return null;
        }
    }

Pastikan import-nya gini:

import java.beans.IntrospectionException;
import java.util.ArrayList;
import java.util.List;
import org.openide.nodes.BeanNode;
import org.openide.nodes.ChildFactory;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;

Sekarang, karena node bakal ditampilin di window, buka window yang tadi (SimpulExplorerTopComponent), tambahkan signature gini di bagian class:

public final class SimpulExplorerTopComponent extends TopComponent implements ExplorerManager.Provider{

Nanti, bakal ada error, ikutin suggestion-nya (implement all abstract method) yang artinya harus ada 1 method yang ditambahin. Kita bikin gini:

    private final ExplorerManager mgr = new ExplorerManager();
    @Override
    public ExplorerManager getExplorerManager() {
        return mgr;
    }

Yap, memang ada 1 atribut “mgr” yang gw tambahin di sana. Terus gw ubah isi method-nya. Dan masih di window yang tadi, ubah konstruktornya jadi gini:

    public SimpulExplorerTopComponent() {
        initComponents();
        setName(Bundle.CTL_SimpulExplorerTopComponent());
        setToolTipText(Bundle.HINT_SimpulExplorerTopComponent());

        associateLookup(ExplorerUtils.createLookup(mgr, getActionMap()));
        SimpulAnak ecv = new SimpulAnak();
        AbstractNode an = new AbstractNode(Children.create(ecv, true));
        mgr.setRootContext(an);
    }

Di sana, emang kita pake yang namanya “Lookup”, gw gak tau kenapa… tapi kalo pake explorer manager emang pake create2 lookup gitu… Yah begitulah… Dan hasil akhirnya:

12. Hasil

Kamu bisa ganti icon dan lain2 di bagian deklarasi abstract node (buat parent) atau di bagian pengembalian node buat child…

Contoh:

@Override
    protected Node createNodeForKey(String key) {
        try {
            BeanNode bn = new BeanNode(key);
            bn.setIconBaseWithExtension("/org/seleksi/view/right-rectangle.png");
            bn.setDisplayName(key);
            System.out.println();
            return bn;
        } catch (IntrospectionException ex) {
            Exceptions.printStackTrace(ex);
            return null;
        }
    }
    public SimpulExplorerTopComponent() {
        initComponents();
        setName(Bundle.CTL_SimpulExplorerTopComponent());
        setToolTipText(Bundle.HINT_SimpulExplorerTopComponent());

        associateLookup(ExplorerUtils.createLookup(mgr, getActionMap()));
        SimpulAnak ecv = new SimpulAnak();
        AbstractNode an = new AbstractNode(Children.create(ecv, true));
        an.setIconBaseWithExtension("/org/seleksi/view/down-rectangle.png");
        mgr.setRootContext(an);
        
    }

Path:

13. Path

Hasil:

14. Hasil Akhir

Gambar bisa diambil di situs tutorial netbeans

Valid: Yap!
Versi non-Kadaluarsa: Netbeans 7.2-8.0
Sumber:
https://platform.netbeans.org/tutorials/nbm-selection-2.html
https://platform.netbeans.org/tutorials/nbm-crud.html