Showing posts with label Java Tech. Show all posts
Showing posts with label Java Tech. Show all posts

Thursday, October 29, 2009

Menambahkan Offline Recitation pada Zekr

Pada posting sebelumnya ane sudah membahas sekelumit tentang aplikasi zekr, lalu bagaimana jika kita ingin mendengarkan bacaan Al Qur'an sekaligus ingin menyimak ayat2 yang sedang dibacakan secara offline ??. tidak usah bingung karena dari developer zekr sudah menyediakan offline recitation kita tinggal download saja dari situs resmi zekr, di situs resminya sendiri tidak menyediakan keseluruhan recitation yang dicantumkan tetapi hanya beberapa saja yaitu dari Al-Minshawi, Al-Ghamdi, Al-Huzaifi, dan Al-Afas. Hehe jujur saja kalo saya lebih cenderung download yang Al Afasi, tapi tergantung selera juga sih... lain ladang kan lain belalang. Lalu  pertanyaannya bagaimana menambahkan offline receitation-nya?? akhi, ukhti begini caranya..

  1. download recitation file audio dan file propertiesnya, misalnya ane ingin menambahkan Al Afasi maka ane download afasy.zip dan afasy-offline.properties
  2. unzip afasy.zip ke [lokasi instalasi zekr]/res/audio/afasy (sebagai contoh C:\Program Files\Zekr\res\audio\zekr di Windows). Setelah langkah ini, maka akan didapatkan file *.mp3 didalam folder afasy; 
  3. tambahkan afasy-offline.properties melalui Tools > Add > Recitation;
  4. restart Zekr dan akan ada tambahan item recitation baru dengan pengenal (offline) di menu Audio > Recitation menu.
setelah ditambahkan tinggal dijalankan saja, pilih surah apa yang akan di baca dan klik 2 kali (pake mouse lho! :D).


Panduan

Zekr - Qur'an For Linux

Mungkin sudah agak telat posting tentang aplikasi zekr karena aplikasi ini sudah ada secara default pada distribusi Ubuntu muslim edition (UbuntuME), aplikasi ini merupakan aplikasi layaknya digital Al Qur'an lengkap dengan terjemahannya. Selain itu masih banyak lagi fungsionalitas dari aplikasi ini seperti fungsi pencarian, fungsi language translation, bahkan ada recitation (pembaca Al Qur'an) tergantung mau pilih siapa yang mau membawakan bisa online maupun offline, dan masih banyak lagi. so far sih aplikasi ini sangat membantu ketika ane lupa bawa mushaf. Silahkan saja download aplikasinya dari situs resminya disini atau yang sudah pake ubuntu tinggal pake perintah
sudo apt-get install zekr

Splash screen saat loading



 Antarmuka Aplikasi

Saturday, October 10, 2009

render farm project on progress

in this year i hope i can finish my study in Gadjah Mada University might be many people known as UGM where it place in Yogyakarta. my first project is create render farm, i initiate it as my final exam or in my university called TA (Tugas Akhir), i build it using java RMI collaborate with blender render engine the idea is using java RMI for communicate between client and node through the server then the node will process render task from client using blender, in each node must have blender engine installed. there are three kind of application one will place in the client, second will place in the sever and third application will place in node, and i use master slave architecture for building the infrastructure.

this is illustration of my idea, may be it familiar to you:



there are three main application in the architecture picture AddJob class, JobManager class and JobProcessor class. Bellow picture will illustrate my final exam project work flow.











that’s my idea and had been implementing and work in progress. :D

Tuesday, February 10, 2009

Setting Jasper Report on Eclipse then use it!

JasperRepots merupakan project open source yang sangat powerfull untuk menampilkan rich content baik ke printer maupun kedalam bentuk file PDF, HTML, XLS, RTF, ODT, CSV, TXT dan XML. Oke tidak usah panjang lebar langsung saja download resourcenya dari official site-nya : http://jasperforge.org/, kemudian extract dan akan terdapat beberapa folder diantaranya :build, demo, dist, docs, lib, dan src.
*untuk yang menggunakan netbeans, bisa langsung import project lalu buka folder yang memuat forlder diatas.

Sebenarnya yang kita butuhkan untuk diimport kedalam classpathnya eclipse adalah yang berada didalam folder dist dan lib, untuk yang berada didalam folder dist yang digunakan adalah file jasperreports-3.1.3.jar sedangkan untuk yang didalam folder lib adalah commons-beanutils-1.7.jar, commons-collections-2.1.jar, commons-digester-1.7.jar, commons-javaflow-20060411.jar, commons-logging-1.0.2.jar, dan iText-2.1.0.jar.

1. Buka editor eclipse lalu buat project java dengan nama jreport (File -> New -> Java Project)
2. Import file2 yang disebutkan diatas kedalam classpath project jreport dengan cara, klik kanan pada nama project pilih properties maka akan muncul jendela berikut :


untuk menambahkan classpath bisa langsung tekan tombol [Add External JARs], masukkan file2 jasperreports-3.1.3.jar, commons-beanutils-1.7.jar, commons-collections-2.1.jar, commons-digester-1.7.jar, commons-javaflow-20060411.jar, commons-logging-1.0.2.jar, dan iText-2.1.0.jar.
3. Karena file2 yang dibutuhkan sudah masuk kedalam classpath project jreport, langkah selanjutnya adalah membuat code untuk melakukan test. Buat folder reports pada project jreport dengan cara klik kanan pada project jreport - > new -> folder.



4. Buat java class pada jreport dan beri nama JasperReportsIntro.java dan isi dengan kode2 sebagai berikut :
public class JasperReportsIntro
{
public static void main(String[] args)
{
JasperReport jasperReport;
JasperPrint jasperPrint;
try
{
jasperReport = JasperCompileManager.compileReport(
"reports/jasperreports_demo.jrxml");
jasperPrint = JasperFillManager.fillReport(
jasperReport, new HashMap(), new JREmptyDataSource());
JasperExportManager.exportReportToPdfFile(
jasperPrint, "reports/simple_report.pdf");
System.out.println("Successfully created PDF file");
}
catch (JRException e)
{
e.printStackTrace();
}
}
}

lalu buat file didalam folder reports dengan nama jasperreports_demo.jrxml dan isikan kode berikut :

5. Jalankan file JasperReportsIntro.java (klik kanan -> Run As -> Java Application). Setelah proses selesai file pdf akan terbentuk didalam folder reports.

Untuk melihat contoh2 penggunaan lainnya bisa dilihat dalam folder demo, didalamnya terdapat sample2 JasperReport yang siap dignakan.

Tuesday, January 13, 2009

Swing Layout in Action



Rehat dulu ah dari bahas games engineering, capek... refreshing dulu..., kemaren lagi iseng2 main2 layout swing sambil nginget2 sama mau optimasi dengan layout2 yang ada di java, enaknya sih emang klo kita pake visual swing desainer kayak punyanya netbeans tiggal drag n drop (what you see is what you get) tapi ga papalah buat iseng2 main2 layout biar ngerti konsep layout. sebenarnya java awt punya beberapa layout sebagai berikut:
  • CardLayout ---> Merupakan model seperti stack kartu yang dapat ditampilkan secara berurutan biasanya diaplikasikan pada waktu kita ingin membuat model interface seperti wizard2 atau model interface seperti kalo kita menginstall applikasi dengan next/previous.
  • BorderLayout ---> Akan membagi area menjadi 5 wilayah yaitu North, West, East, South, dan Center.
  • FlowLayout ---> FlowLayout merupakan default layout yang digunakan oleh swing, layout ini akan menampilkan komponen secara berurutan dari kiri ke kanan.
  • GridLayout ---> GridLayout merupakan layout yang akan membagi sebuah frama/panel kedalam baris dan kolom dengan ukuran yang sama. Misalnya ketika kita ingin membuat tombol2 kalkulator dengan ukuran tombol yang sama.
  • GridBagLayout ---> Layout yang sangat fleksibel yang akan membagi area menjadi grid2 sehingga komponen dapat ditempatkan secara fleksibel, dalam tulisan ini kita akan memanfaatkan layout ini.
  • GroupLayout ---> Layout yang fleksibel yang dipakai oleh netbeans dan dikembangkan oleh third party yaitu apache.

Oke dalam tulisan ini akan dibatasi untuk membahas GridbagLayout, karena layout ini cukup menarik untuk dibahas sedangkan untuk layout2 yang lain bisa tutorialnya di situs resminya java atau resource2 yang lain.

Untuk membuat layout ini cukup simple kita bisa mengkonstruksi dengan :
GridBagLayout gbl = new GridBagLayout();
kemudian dari situ kita bisa melakukan set layout pada JFrame/JPanel yang akan kita gunakan cukup menambahkan object gbl pada parameter, misalnya:
JFrame frame = new JFrame(); // jika layout diimplementasikan pada JFrame
frame.serLayout(gbl);
JPanel panel = new JPanel(); // jika layout diimplementasikan pada JPanel
panel.setLayout(gbl);
Untuk mengatur tataletak komponen tadi pada frame/panel kita memanfaatkan GridBagConstraints, class ini mempunyai properti2 yang penting untuk mengatur tataletak sebagai berikut :
*Note: properti dibawah ini diassignkan dengan nilai defaultnya
  • fill = GridBagConstrains.NONE; ----> properti ini digunakan untuk setting arah resize dari komponen, Nilainya bisa GridBagConstrains.NONE, GridBagConstrains.HORIZONTAL, dan GridBagConstrains.VERTICAL
  • gridx = GridBagConstrains.CENTER; ----> untuk meletakkan komponen pada grid tertentu terhadap posisi x
  • gridy = GridBagConstrains.RELATIVE; ----> untuk meletakkan komponen pada grid tertentu pada posisi y
  • gridheight = 1; ----> untuk menentukan span yang digunakan oleh komponen, misalkan kita isi dengan nilai 2 berarti komponen akan menempati area sebesar 2 grid searah sumbu y
  • gridwidth = 1; ----> sama seperti gridheight hanya saja span gridnya searah sumbu x
  • insets = new Insets(0, 0, 0, 0); ----> digunakan untuk menentukan jarak antar komponen Insets(top, left, bottom, right)
  • ipadx = 0; ----> digunakan untuk menentukan padding dari dalam komponen searah sumbu x
  • ipady = 0; ----> digunakan untuk menentukan padding dari dalam komponen searah sumbu y
  • weightx = 0; ----> digunakan untuk menentukan ukuran maksimum resize dari komponen searah sumbu x
  • weighty = 0; ----> digunakan untuk menentukan ukuran maksimum resize dari komponen searah sumbu x
  • anchor = GridBagConstrains.CENTER; digunakan untuk menentukan perataan letak komponen, bisa CENTER, EAST, WEST, SOUTH, NORTH ...
Untuk memyederhanakan dalam pembuatan GridBagConstrains yang digunakan, saya membuat class GBCHelper.java yang merupakan subclass dari GridBagCondtrains sehingga kita cukup menggunaka sekali konstruksi object GridBagConstrains untuk semua komponen, listing programnya sebagai berikut:
package brain.left.swingtest;

import java.awt.GridBagConstraints;
import java.awt.Insets;

/**
* This class for simplifies using GridbagConstrains copyleft by amru rosyada,
* you can redistribute with any change to this code license GPLV3
*
* @version = 1.00 12 Jan 2009
* @author amru rosyada, amrurosyada.blogspot.com, taka86[AT]gmail.com
*/

public class GBCHelper extends GridBagConstraints {
private static final long serialVersionUID = 582260222458228387L;

public GBCHelper() {

}

/**
* Set GridbagConstrains to default value
*/
public GBCHelper clear() {
this.fill = GBCHelper.NONE;
this.gridx = GBCHelper.CENTER;
this.gridy = GBCHelper.RELATIVE;
this.gridheight = 1;
this.gridwidth = 1;
this.insets = new Insets(0, 0, 0, 0);
this.ipadx = 0;
this.ipady = 0;
this.weightx = 0;
this.weighty = 0;
this.anchor = GBCHelper.CENTER;
return this;
}

/**
* set gridy gridx position
*
* @param gridx
* set gridx position
* @param gridy
* set gridy position
*/
public GBCHelper setGrid(int gridx, int gridy) {
this.gridx = gridx;
this.gridy = gridy;
return this;
}

/**
* Sets the fill direction.
*
* @param fill
* the fill direction
* @return this object for further modification
*/
public GBCHelper setFill(int fill) {
this.fill = fill;
return this;
}

/**
* set value for gridx, gridy, gridwidth, gridheight
*
* @param gridx
* the gridx position
* @param gridy
* the gridy position
* @param gridwidth
* the cell span in x-direction
* @param gridheight
* the cell span in y-direction
*/
public GBCHelper setGrid(int gridx, int gridy, int gridwidth, int gridheight) {
this.gridx = gridx;
this.gridy = gridy;
this.gridwidth = gridwidth;
this.gridheight = gridheight;
return this;
}

/**
* Sets the insets of this cell.
*
* @param distance
* the spacing to use in all directions
* @return this object for further modification
*/
public GBCHelper setInsets(int distance) {
this.insets = new Insets(distance, distance, distance, distance);
return this;
}

/**
* Sets the insets of this cell.
*
* @param top
* the spacing to use on top
* @param left
* the spacing to use to the left
* @param bottom
* the spacing to use on the bottom
* @param right
* the spacing to use to the right
* @return this object for further modification
*/
public GBCHelper setInsets(int top, int left, int bottom, int right) {
this.insets = new Insets(top, left, bottom, right);
return this;
}

/**
* Sets the internal padding
*
* @param ipadx
* the internal padding in x-direction
* @param ipady
* the internal padding in y-direction
* @return this object for further modification
*/
public GBCHelper setIpad(int ipadx, int ipady) {
this.ipadx = ipadx;
this.ipady = ipady;
return this;
}

/**
* Sets the anchor.
*
* @param anchor
* the anchor value
* @return this object for further modification
*/
public GBCHelper setAnchor(int anchor) {
this.anchor = anchor;
return this;
}

/**
* Sets the cell weights.
*
* @param weightx
* the cell weight in x-direction
* @param weighty
* the cell weight in y-direction
* @return this object for further modification
*/
public GBCHelper setWeight(double weightx, double weighty) {
this.weightx = weightx;
this.weighty = weighty;
return this;
}
}

Pada listing GBCHelper diatas telah terdokumentasikan setiap methodnya, perlu dicatat untuk setiap kali kita akan menggunakan kembali object ini harus memanggil terlebih dahulu method clear() sebelum method yang lain, sekarang kita akan buat class GridBagTester.java untuk melakukan tes menggunakan class GBCHelper. Listing programnya sebagai berikut :
package brain.left.swingtest;

import java.awt.EventQueue;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.SoftBevelBorder;

public class GridbagTester extends JFrame {
/**
*
*/
private static final long serialVersionUID = -2094745569627207471L;
private JPanel panel = new JPanel();
private JLabel label1 = new JLabel("Label 1");
private JTextField jtext1 = new JTextField(20);
private JLabel label2 = new JLabel("Label 2");
private JTextField jtext2 = new JTextField(20);
private JButton button1 = new JButton("Tombol 1");
private GBCHelper GBCH = new GBCHelper();
private JTextArea jta = new JTextArea();
JScrollPane pane = new JScrollPane(jta);

public GridbagTester() {
jta.setRows(5);
Border br = BorderFactory.createBevelBorder(SoftBevelBorder.LOWERED);
panel.setBorder(br);
panel.setLayout(new GridBagLayout());
//menambahkan komponen pada layout
//jangan lupa untuk memanggil method clear sebelum method2 yang lain
panel.add(label1, GBCH.clear().setGrid(0, 0).setAnchor(GBCHelper.EAST));
panel.add(jtext1, GBCH.clear().setGrid(1, 0).setFill(
GBCHelper.HORIZONTAL).setInsets(1, 5, 2, 1));
panel.add(label2, GBCH.clear().setGrid(0, 1).setAnchor(GBCHelper.EAST));
panel.add(jtext2, GBCH.clear().setGrid(1, 1).setFill(
GBCHelper.HORIZONTAL).setInsets(1, 5, 2, 1));
panel.add(pane, GBCH.clear().setGrid(0, 3, 4, 1).setAnchor(
GBCHelper.WEST).setFill(GBCHelper.BOTH));
panel.add(button1, GBCH.clear().setGrid(1, 4).setAnchor(GBCHelper.EAST)
.setInsets(10, 1, 5, 2));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(panel);
pack();
setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
new GridbagTester();
}

});
}
}


screenshoot hasil running programmnya sebagai berikut :



oke done!

Friday, January 9, 2009

JAVA 2D Graphics dan Animation (Part 1) - Games Engineering

Key topics pada pembahasan:
  • Full-screen Graphics
  • Images
  • Getting Rid of Flicker and Tearing
  • Simple Effects
  • Summary
Full-screen Graphics
Pembuatan games akan lebih interaktif dan menarik ketika kita menambahkan adanya user interface(graphic) dan animation. Tetapi dalam pembuatannya kita perlu membuat spesifikasi2 seperti berapa resolusi yang digunakan dan juga jangan sampai mengabaikan masalah refresh rate pada monitor.
Oke sekarang kita akan langsung melihat bagaimana hardware displai bekerja sebelum menginjak ke masalah programming. Secara garis besar ada dua bagian pada display hardware : video card dan monitor. Video card merepresentasikan apa yang ada di memorinya dan mempunyai fungsi2 untuk melakukan modifikasi pada apa yang ditampilkan. Memori card juga bekerja dibackground untuk mempush memorinya ke monitor. Sedangkan monitor akan menampilkan informasi yang diberikan oleh video card.

Screen Layout
Screen pada monitor sebenarnya akan dibagi dalan pixel warna kecil2 yang mempunyai ukuran sama. Perkalian dari pixel horizontal dan vertikal akan membuat sebuah ukuran screen yang kita sebut sebagai resolusi.
Screen akan dimulai dari pojok kiri atas, yang diperlihatkan pada gambar 1 dibawah ini. Pixel akan dimasukkan mulai dari pojok kiri atas, kemudian ke kanan dan seterusnya samapi ke pojok paling kiri bawah. Area pada screen bisa kita akses perdasarkan posisi koordinat (x, y), x merepresentasikan horizontal pixel dan y merepresentasikan vertical pixel.

gambar 1 ilustrasi pixel dalam screen 800x600.

Resolusi yang kita manipulasi sangat bergantung pada kemampuan video card dan monitor. Umumnya resolusi yang sering di pakai adalah 640x480, 800x600, 1024x768, 1280x1024.
Secara umum monitor dan televisi mempunyai size ratio 4:3. Yang berarti tinggi dari monitor adalah 3/4 dari ukuran lebarnya. Beberapa monitor yang baru dibuat dalam wides creen dengan display size retio 3:2 atau 16:10 dan 16:9(untuk wide screen movie).

Warna Pixel dan Kedalaman Bit
Warna primer ada tiga merah, kuning, dan biru. Mungkin kita masih ingat dengan percampuran warna, "kuning + biru = hijau." Idenya adalah kita bisa memanipulasi warna-warna tersebut menjadi warna yang lain yang kita inginkan. Model semacam ini sering disebut sebagai subtractive color model, dan percampuran semua warna akan mejadi putih.
Ini sama sebagaimana monitor komputer dan televisi bekerja. Monitor mengkombinasikan merah, biru dan hijau untuk membuat banyak warna lain.
Warna2 pada monitor dapat ditampilkan tergantung pada kedalaman bit-nya. Secara umum kedalaman bit yang sering digunakan adalah 8,15, 16, 24, dan 32 bit.
  • Warna 8-bit mempunyai 2^8=256 warna. Hanya 256 warna yang bisa ditampilkan pada suatu waktu.
  • Warna 15-bit mempunyai 5 bit untuk merah, biru dan hijau, totalnya ada 2^15=32,768 warna.
  • Warna 16-bit mempunyai 5 bit untuk merah dan biru, dan 6 bit untuk hijau, totalnya ada 2^16=65,536 warna.
  • Waran 24-bit mempunyai 8 bit untuk merah, hijau dan biru, total ada 2^24=16,777,216 warna.
  • Warna 32-bit mempunyai warna sama dengan 24 bit, tetapi ditambah dengan extra 8 bit sebagai padding.
Video card saat ini sudah mendukung 8-, 16-, dan 32-bit. Karena disesuikan dengan mata manusia dapat melihat sampai 10 miliar warna, 24-bit ideal digunakan. 16-bit sedikit lebih cepat dari pada 24-bit karena data yang ditransfer juga lebih sedikit, tetapi kualitas warnanya tidak akurat.

Refresh Rate
Bagaimana monitor bisa menampilkan pixel seperti gambar beneran ?, sebenarnya setiap pixel akan menghilang setelah beberapa milisecond. Untuk tetap menjaga agar bisa tetap ditampilkan, maka monitor akan secara berkelanjutan melakukan refresh pada display biar tidak menghilang. Kecepatan melakukan refresh ini yang disebut sebagai refresh rate. Refresh rate mempunyai satuan Hertz (Hz), yang berarti cycles per second. Refresh rate antara 75Hz dan 85Hz sesuai untuk mata manusia.

Switching Display ke Mode Full-Screen
Sekarang kita sudah mengetahui tentang konsep resolusi, kedalaman warna, dan refresh rate, sekarang tinggal masuk koding. Di dalam java kita membutuhkan beberapa object untuk merubah ke mode full-screen, sebagai berikut:
  • Window object. Window object adalah abstraksi dari apa yang ditampilkan ke layar, anggaplah sebuah kanvas untuk menggambar. Kita akan memanfaatkan JFrame, yang merupakan subclass dari Windows class dan dapat juga digunakan untuk membuat applikasi windowed.
  • DisplayMode object. DisplayMode object digunakan untuk spesifikasi resolusi, kedalaman bit, dan refresh rate untuk switch display.
  • GraphicsDisplay object. GraphicsDislay object digunakan untuk merubah display mode dan melihat display properti. Bayangkan saja ini sebagai video card. GraphicsDisplay object diperoleh dari GraphicsEnvironment object.

Berikut adalah contoh untuk melakukan switch ke mode full-screen:
JFrame window = new JFrame();
DisplayMode displayMode = new DisplayMode(800, 600, 16, 75);

// mendapatkan GraphicsDevice
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = environment.getDefaultScreenDevice();
// menggunakan JFrame untuk full screen window
device.setFullScreenWindow(window);
// mengubah display mode
device.setDisplayMode(displayMode);
Setelah itu jika ingin mengembalikan pada resolusi semula, set full-screen window dengan nilai null:
device.setFullScreenWindow(null);
Kadang pada sistem tertentu tidak mengijinkan kita untuk mengubah mode display, dan saat kita melakukan pemanggilan pada setDisplayMode() akan menampilakan IllegalArgumentException.

Oke sekarang kita akan membuat class wrapper untuk memudahkan dalam pembuatan mode full-screen simpan dengan nama SimpleScreenManager.java, listing programmnya sebagai berikut:
import java.awt.*;
import javax.swing.JFrame;
/**
SimpleScreenManager class menangani inisialisasi dan
menampilkan mode full-screen.
*/
public class SimpleScreenManager {
private GraphicsDevice device;
/**
Membuat SimpleScreenManager object.
*/
public SimpleScreenManager() {
GraphicsEnvironment environment =
GraphicsEnvironment.getLocalGraphicsEnvironment();
device = environment.getDefaultScreenDevice();
}
/**
Memasukkan full screen mode and mengubah display mode.
*/
public void setFullScreen(DisplayMode displayMode,
JFrame window)
{
window.setUndecorated(true); // menghilangkan border
window.setResizable(false);
device.setFullScreenWindow(window);
if (displayMode != null &&
device.isDisplayChangeSupported())
{
try {
device.setDisplayMode(displayMode);
}
catch (IllegalArgumentException ex) {
// illegal mode untuk device
}
}
}
/**
Mengembalikan window yang sedang digunakan pada full screen mode.
*/
public Window getFullScreenWindow() {
return device.getFullScreenWindow();
}
/**
Mengembalikan display mode semula.
*/
public void restoreScreen() {
Window window = device.getFullScreenWindow();
if (window != null) {
window.dispose();
}
device.setFullScreenWindow(null);
}
}
Selanjutnya kita akan membuat kode untuk melakukan test menggunakan SimpleScreenManager, yang menerima parameter berupa ukuran resolusi yang digunakan dan kedalaman bit. Untuk menjalankannya dengan cara sebagai berikut :
java FullScreenTest 1024 768 32 ------> berarti merubah ke fullscreen mode menjadi 1024x768 dengan kedalaman bit 32-bit.

Perlu diingat jangan menggunakan resolusi yang tidak disupport oleh system, karen program tidak akan jalan. Berikut adalah kode program untuk melakukan test FullScreenTest.java :
import java.awt.*;
import javax.swing.JFrame;
public class FullScreenTest extends JFrame {
public static void main(String[] args) {
DisplayMode displayMode;
if (args.length == 3) {
displayMode = new DisplayMode(
Integer.parseInt(args[0]),
Integer.parseInt(args[1]),
Integer.parseInt(args[2]),
DisplayMode.REFRESH_RATE_UNKNOWN);
}
else {
displayMode = new DisplayMode(800, 600, 16,
DisplayMode.REFRESH_RATE_UNKNOWN);
}
FullScreenTest test = new FullScreenTest();
test.run(displayMode);
}
private static final long DEMO_TIME = 5000;
public void run(DisplayMode displayMode) {
setBackground(Color.blue);
setForeground(Color.white);
setFont(new Font("Dialog", Font.PLAIN, 24));
SimpleScreenManager screen = new SimpleScreenManager();
try {
screen.setFullScreen(displayMode, this);
try {
Thread.sleep(DEMO_TIME);
}
catch (InterruptedException ex) { }
}
finally {
screen.restoreScreen();
}
}
public void paint(Graphics g) {
g.drawString("Hello World!", 20, 50);
}
}
Berikut adalah hasil screenshot running programnya :


Anti Aliasing
Kita bisa memanfaatkan anti aliasing untuk membuat tulisan "Hello World!" menjadi lebih smooth, karena dengan anti aliasing kita bisa melakukan blending antara text dengan background. Ubah kode menjadi sebagai berikut:
public void paint(Graphics g) {
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
g.drawString("Hello World!", 20, 50);
}
Mode Mana yang Sebaiknya digunakan?
Banyak pilihan resolusi yang dapat digunakan, tetapi yang mana yang seharusnya digunakan untuk running game yang kita buat?
Oke, sebaiknya game yang kita develop berjalan minimal pada dua resolusi, sehingga player akan menentukan sendiri resolusi mana yang cocok digunakan.
Jika memungkinkan, inisialisasi game yang kita develop sesuai dengan resolusi monitor yang digunakan, sehingga game display akan ditampilkan dengan bagus. Penggunaan kedalaman warna 16-, 24-, atau 32-bit warna adalah ide yang bagus. 16-bit warna akan berjalan sedikit lebih cepat, tetapi gunakanlah resolusi yang lebih besar jika menginginkan representasi warna yang akurat. Gunakan refresh rate antara 75Hz dan 85Hz karena sesuai dengan mata manusia.

Reference :
  • http://java.sun.com
  • David Brackeen, Bret Barker, Laurence Vanhelsuwé, Developing Games in Java, 2003, New Riders Publishing

Wednesday, January 7, 2009

Java Thread - Games Engineering


original image link http://static.howstuffworks.com/gif/best-games-never-made-6.jpg

Games engineering sangatlah menarik untuk dibahas, karena dalam pembuatan games sendiri diperlukan gabungan dari berbagai disiplin ilmu mulai dari aspek sosial sampai aspek eksak. Multithreading sangat diperlukan dalam games engineering, karena dalam sebuah games diperlukan adanya pemrosesan yang berjalan bersama2 misalnya ketika kita membuat games realtime strategi seperti red alert, berapa banyak thread yang dibutuhkan ??, apalagi kalo membuat games seperti football manager (my favourite) dimana setiap club bahkan setiap pemain akan mempunyai perubahan perilaku, skill, usia, mood, technique dll dalam siklus tertentu. Dalam dunia nyata-pun tak dapat dipisahkan, simpelnya saja nih ... ketika kita browsing browser membuka banyak tab dan tiap2 tab mengkses halaman web yang berbeda itu juga merupakan proses multithreading, sedangkan disisi server seperti webserver akan membuat thread jika ada request yang masuk.
Dalam java untuk membuat thread ada 3 cara :

1. Menurunkan class Thread (Extends)
2. Mengimplementasikan interface Runnable
3. Menggunakan anonymous inner class

Download artikel dalam pdf

Sekarang kita akan bahas satu persatu bagaimana ketiga cara itu digunakan :
ex, dengan menurunkan class thread :

public class MyThread extends Thread {
public void run() { System.out.println("Ini threading lho !!!");
}
}
Thread mythread = new MyThread();
mythread.start();


ex, dengan mengimplementasikan interface Runnable:
dengan menggunakan cara ini mempunyai keuntungan class yang kita buat masih bisa menurunkan class yang lain, karena java tidak mengijinkan multiple inharitance
public class MyThread extends SomeOthersClass implements Runnable {
public MyThread() {

}
public void run() {
System.out.println("threading pake implementd Runnable");
}
}

Thread mythread = new Thread(new MyThread);
mythread.start();


ex, menggunakan anonymous class:
dengan ini kita tidak perlu untuk menurunkan class Thread dan mengimplementasikan interface Runnable.

new Thread() {
public void run() {
System.out.println("menggunakan anonymous class");
}
}.start();


kerugian menggunakan cara ini adalah membuat code yang kita bikin menjadi sulit untuk dibaca dan dipahami.
gunakan method join agar thread yang kita gunakan masuk keantrian dan mengunggu sampai thread yang lain selesai.

myhtread.join();

method ini sangat berguna ketika kita membuat games dan player ingin keluar dari permainan, untuk memastikan bahwa semua thread telah selesai sebelum menjalankan cleanup. Kita juga melakukan sleep untuk thread yang sedang berjalan dengan presisi waktu dalam milidetik.
mythread.sleep(1000);


Sinkronisasi
Misalkan kita mau membuat maze game (games untuk mencari jalan keluar). Thread manapun bisa mengubah posisi pemain/player, dan thread manapun bisa melakukan pemeriksaan apakah ada pemain yang sudah menemukan pintu keluar. Untuk mempermudah mari kita lihat pada ilustrasi berikut, kita asumsikan bahwa jalan keluar/exit berada di x=0, y=0 :
public class Maze {
private int playerX;
private int playerY;

public boolean isAtExit() {
return (playerX==0 && playerY==0);
}

public void setPosition(int x, int y) {
playerX=x;
playerY=y;
}
}

secara garis besar code diatas tidak akan bermasalah, tapi bagai mana jika terjadi preemtive (banyak thread yang mengakses dan mana yang didahulukan untuk dapat mengubah resource). Misalkan kita ambil sekenario sebagai berikut, pamain berpindah tempat dari (1,0) ke (0,1):
1.Dimulai dari posisi (1,0), variabel playerX=1 dan playerY=0
2.Thread A memanggil setPosition(0,1)
3.Ketika line playerX=x dieksekusi maka playerX bernilai 0
4.Tiba-tiba Thread B melakukan pengecekan pada isAtExit() sebelum A sempat mengubah nilai playerY maka B akan mendapatkan kembalian bernilai true, karena playerX dan playerY sedang dalam keadaan yang sama yaitu bernilai 0.

sekarang kita akan melakukan sinkronisasi untuk mencegah terjadinya hal diatas. Kodenya akan berubah menjadi sebagai berikut :

public class Maze {
private int playerX;
private int playerY;
public synchronized boolean isAtExit() {
return (playerX == 0 && playerY == 0);
}
public synchronized void setPosition(int x, int y) {
playerX = x;
playerY = y;
}
}

ketika JVM mengeksekusi method yang beratribut sinchronized, maka akan terjadi ackquire lock pada method tersebut dan hanya akan mengijinkan untuk dieksekusi oleh satu object pada suatu waktu.
Jadi jika suatu sinchronized method belum selesai dieksekusi maka method sinchronized lain tidak akan bisa dieksekusi.

public synchronized void setPosition(int x, int y) {
playerX = x;
playerY = y;
}


code diatas bisa juga ditulis dalam bentuk berikut:
public void setPosition(int x, int y) {
synchronized(this) {
playerX = x;
playerY = y;
}
}


pada code mempunyai jumlah bytecode yang lebih banyak. Sinkronisasi object seperti kode kedua diatas berguna jika kita mengijinkan lebih dari satu lock, dan tidak membutuhkan untuk sinkronisasi untuk methodnya.

Lock bisa dilakukan pada object apapun kecuali pada tipe primitive, berikut adalah contoh bagaimana lock dilakukan pada object :

Object myLock = new Object();
...
synchronized (myLock) {
...
}


Saat bagaimanakah diperlukan sinkronisasi ?
Jawabannya adalah setiap waktu ketika ada dua atau lebih thread melakukan akses pada suatu object/field.

Hal yang perlu diingat jangan pernah melakukan oversinkronisasi (melakukan sinkronisasi pada object/method/field yang telah disinkronisasi). Sebagai contoh jangan lakukan sinkronisasi pada sebuah method jika hanya field tertentu saja yang akan disinkronisasi dalam method tersebut. Sebagai contoh method berikut, lakukan sinkronisasi pada block yang diperlukan saja.

public void myMethod() {
synchronized(this) {
// code that needs to be synchronized
}
// code that is already thread-safe
}


jangan lakukan sinkronisasi pada method yang hanya menggunakan local variable, karena local variable akan ditaruh di stack, sedangkan thread punya stack untuk tiap2 thread, jadi tidak perlu untuk dilakukan sinkronisasi. Berikut adalah contoh method yang tidak perlu dilakukan sinkronisasi karena hanya menggunakan variable local.

public int square(int n) {
int s = n * n;
return s;
}


jika kita tidak yakin thread mana yang sedang mengakses kode kita, kita bisa mendapatkan nama dari thread tersebut dengan :
Thread.currentThread().getName();

Perlu diwaspadai juga adanya deadlock, deadlock adalah adanya thread yang tidak bisa melanjutkan proses karena thread saling menunggu thread lain sampai melepaskan resource. Misalkan pada contoh berikut :
1. Thread A acquire lock 1.
2. Thread B acquire lock 2.
3. Thread B menunggu sampai lock 1 dilepaskan.
4. Thread A menunggu sampai lock 2 dilepaskan.

Dapat kita lihat dari process diatas kedua thread saling menunggu samapai suatu waktu yang tidak bisa ditentukan. Kita bisa mengatasinya dengan cara melakukan sinkronisasi yang tepat sesuai dengan urutannya.

Menggunakan wait() dan notify()
Misalkan kita ambil sekenario sebagai berikut, ada dua thread yang akan saling berkomunikasi satu sama lain, sebagai contoh ada thread A menunggu sampai thread B mengirimkan pesan :

// Thread A
public void waitForMessage() {
while (hasMessage == false) {
Thread.sleep(100);
}
}
// Thread B
public void setMessage(String message) {
...
hasMessage = true;
}


kode diatas bukan suatu contoh yang baik, karena thread A melakukan pengecekan setiap 100 milisecond atau 10 kali dalam satu detik. Thread A dapat oversleep dan terlambat dalam mendapatkan pesan.
Alangkah lebih baik jika A idle sampai ada notifikasi dari B bahwa pesan sudah bisa dikonsumsi, dan ini bisa dilakukan dengan pasangan method wait() dan notify().

Method wait() digunakan didalam blok synchronized. Ketika method wait() dieksekusi, lock akan dilepaskan dan menunggu sampai ada notifikasi.
Method notify() juga digunakan didalam block synchronized. Method notify akan memberikan notifikasi pada thread yang menunggu pada lock yang sama. Jika ada banyak thread yang menunggu maka hanya akan ada satu notifikasi dan akan dipilih satu thread secara acak. Berikut adalah kode yang telah diperbaiki :

// Thread A
public synchronized void waitForMessage() {
try {
wait();
}
catch (InterruptedException ex) { }
}
// Thread B
public synchronized void setMessage(String message) {
...
notify();
}

jika kita ingin memberika notifikasi untuk semua thread yang sendang menunggu kita bisa menggunakan notifyAll(), method wait() juga menerima parameter dalam milisecond sebagai waktu tunggu, misalnya kita ingin memberikan timeout sampai 100milisecond maka kita bisa menggunakan wait(100).
Method wait(), notify(), dan notifyAll() merupakan method dari class object, sehingga semua java object mempunyai method2 tersebut.

Kapan kita seharusnya menggunakan thread ?
Jadi begini dari pendekatan games, ketika games play loading untuk kenyamanan pengguna sebaiknya ketika loading dibuatkan thread sendiri sehingga player tidak menyangka bahwa gamesnya sedang ngehang. Kalo dari pendekatan lain sebenarnya juga untuk kenyamanan dan optimasi, nyaman untuk pengguna karena pengguna merasa menggunakan program yang cepet loadingnya (tricky), optimal karena bisa memanfaatkan resource CPU yang belum termanfaatkan.

Sum it up
Oke dengan informasi thread yang telah dibahas sebelumnya, mari kita buat sesuatu yang berguna yaitu thread pool. Thread pool merupakan sebuah group dari thread yang didesain untuk mengeksekursi tugas yang bermacam-macam. Pada thread pool kita bisa memilih jumlah dari thread didalam pool dan menjalankan task yang didefinisikan sebagai Runnable. Berikut adalah contoh menggunakan ThreadPool dengan membuat 8 thread dalam pool, menjalankan task sederhana dan kemudian menunggu samapai task selesai dijalankan.

ThreadPool myThreadPool = new ThreadPool(8); myThreadPool.runTask(new Runnable() {
public void run() {
System.out.println("Do something cool here.");
}
});
myThreadPool.join();


Method runTask() akan dijalankan. Jika semua thread di dalam pool sedang sibuk menproses task, ketika memanggil runTask() akan memasukkan task kedalam antrian sampai ada thread yang mengeksekusinya. Berikut adalah kode ThreadPool.java :

import java.util.LinkedList;
/**
A thread pool is a group of a limited number of threads that are used to execute tasks.
*/

public class ThreadPool extends ThreadGroup {
private boolean isAlive;
private LinkedList taskQueue;
private int threadID;
private static int threadPoolID;

/**
Creates a new ThreadPool.
@param numThreads The number of threads in the pool.
*/

public ThreadPool(int numThreads) {
super("ThreadPool-" + (threadPoolID++));
setDaemon(true);
isAlive = true;
taskQueue = new LinkedList();
for (int i=0; i

Tasks start execution in the order they are received.
@param task The task to run. If null, no action is taken.
@throws IllegalStateException if this ThreadPool is already closed.
*/

public synchronized void runTask(Runnable task) {
if (!isAlive) {
throw new IllegalStateException();
}
if (task != null) {
taskQueue.add(task);
notify();
}
}

protected synchronized Runnable getTask() throws InterruptedException
{
while (taskQueue.size() == 0) {
if (!isAlive) {
return null;
}
wait();
}
return (Runnable)taskQueue.removeFirst();
}

/**
Closes this ThreadPool and returns immediately.
All threads are stopped, and any waiting tasks are not executed.
Once a ThreadPool is closed, no more tasks can be run on this ThreadPool.
*/

public synchronized void close() {
if (isAlive) {
isAlive = false;
taskQueue.clear();
interrupt();
}
}

/**
Closes this ThreadPool and waits for all running threads to finish.
Any waiting tasks are executed.
*/

public void join() {
// notify all waiting threads that this ThreadPool is no
// longer alive
synchronized (this) {
isAlive = false;
notifyAll();
}

// wait for all threads to finish
Thread[] threads = new Thread[activeCount()];
int count = enumerate(threads);
for (int i=0; i



Sekarang kita akan mencoba untuk melakukan test pada ThreadPool class, berikut adalah kode untuk melakukan test yaitu ThreadPoolTest class.
Berikut adalah cara untuku menjalankan ThreadPoolTest :
java ThreadPoolTest 8 4

8 merupakan jumlah task yang akan dijalankan, 4 adalah jumlah thread yang akan dijalankan. Berikut kode ThreadPoolTest.java :

public class ThreadPoolTest {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println("Tests the ThreadPool task.");
System.out.println(
"Usage: java ThreadPoolTest numTasks numThreads");
System.out.println(
" numTasks - integer: number of task to run.");
System.out.println(
" numThreads - integer: number of threads " +
"in the thread pool.");
return;
}
int numTasks = Integer.parseInt(args[0]);
int numThreads = Integer.parseInt(args[1]);
// create the thread pool
ThreadPool threadPool = new ThreadPool(numThreads);
// run example tasks
for (int i=0; i


oke all thing are finished.

Tuesday, December 30, 2008

Java Regular Expressions



Huehuehue ... kalo denger regex(regular expression) jadi inget sama matakuliah teori bahasa dan automata yang bahas2 regular expression dan berkutat pada NDFA, DFA, NFA, PDA, !@#^$#*&^!*&@%*@^# gak ngertilah pokoknya cukup bikin kita pusing, yah lupain dulu deh masalah kuliah ... now lets focus to java regex. Regular expression tak lain adalah cara untuk mendeskripsikan suatu set string berdasarkan karakteristik tertentu. Regex dapat dimanfaatkan untuk melakukan search, edit atau manipulasi text/data. Regex di java hampir mirip dengan regex di perl tidak hanya java/perl hampir semua bahasa mempunyai regex untuk pengolahan text/data. Jadi apapun bahasanya minumnya tetep teh botol sossro.
Java regex sebenarnya cuman berkutat pada package java.util.regex yang mempunyai tiga class yaitu Pattern, Matcher dan PatternSintaxException. Object Pattern mempunyai dua method utama untuk melakukan manipulsi text/data yaitu compile dan matcher, compile digunakan untuk menerima masukan pattern dari regex sedangkan matcher digunakan untuk menerima masukan berupa string yang akan dicocokkan berdasarkan karakteristik regex yang dimasukkan pada method compile.

contoh penggunaan Class Pattern pada java, kode berikut akan digunakan untuk percobaan-percobaan regex pada tulisan ini :
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import java.io.Console;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegexTestHarness {

public static void main(String[] args){
Console console = System.console();
if (console == null) {
System.err.println("No console.");
System.exit(1);
}
while (true) {

Pattern pattern =
Pattern.compile(console.readLine("%nEnter your regex: "));

Matcher matcher =
pattern.matcher(console.readLine("Enter input string to search: "));

boolean found = false;
while (matcher.find()) {
console.format("I found the text \"%s\" starting at " +
"index %d and ending at index %d.%n",
matcher.group(), matcher.start(), matcher.end());
found = true;
}
if(!found){
console.format("No match found.%n");
}
}
}
}

Setelah compile dan jalankan program untuk melakukan test regex pada posting ini.
amru@bl4ckcub3:~/MyJava/learn/regex$ javac RegexTestHarness.java

jalankan program
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex:


jika program dijalankan akan muncul promt yang meminta kita untuk memasukkan regex. Contoh sederhana dalam menggunakan program adalah untuk mencari kata dalam sebuah kalimat sebagai berikut :
Enter your regex: foo
Enter input string to search: foo bukanlah bar
I found the text "foo" starting at index 0 and ending at index 3.

Enter your regex:


Dari spesifikasi class Pattern dapat rangkum dalam tabel berikut regular expression yang digunakan pada java.

Character Classes
[abc] a, b, atau c (simple class)
[^abc] Semua karakter a, b, atau c (negation)
[a-zA-Z] a sampai z, atau A sampai Z, inclusive (range)
[a-d[m-p]] a sampai d, atau m sampai p: [a-dm-p] (union)
[a-z&&[def]] d, e, atau f (intersection)
[a-z&&[^bc]] a sampai z, kecuali untuk b dan c: [ad-z] (subtraction)
[a-z&&[^m-p]] a sampai z, dan tidak m sampai p: [a-lq-z] (subtraction)


Berikut adalah penjelasan dari table diatas pada applikasinya :
Simple class digunakan untuk melakukan pencocokan satu persatu dari karakter yang ada didalam tandakurung, misal [bcr]at, maka regex tersebut akan cocok dengan pattern berikut "bat", "cat" dan "rat". Dapat dilihat bahwa regex tersebut akan menerima semua urutan karakter dengan awalan karakter "b","c" dan "r" serta diakhiri dengan pattern "at".
ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: [bcr]at
Enter input string to search: bat
I found the text "bat" starting at index 0 and ending at index 3.

Enter your regex: [bcr]at
Enter input string to search: cat
I found the text "cat" starting at index 0 and ending at index 3.

Enter your regex: [bcr]at
Enter input string to search: rat
I found the text "rat" starting at index 0 and ending at index 3.

Negation
Digunakan untuk mencocokkan semua karakter kecuali yang ada didalam tandakurung ditandai dengan "^", misal [^bcr]at akan mencari pattern untuk semua karakter kecuali yang diawali dengan karakter "b", "c" dan "r".
ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: [^bcr]at
Enter input string to search: bat
No match found.

Enter your regex: [^bcr]at
Enter input string to search: cat
No match found.

Enter your regex: [^bcr]at
Enter input string to search: rat
No match found.

Enter your regex: [^bcr]at
Enter input string to search: hat
I found the text "hat" starting at index 0 and ending at index 3.


Ranges
Untuk menampilkan range pada suatu pattern tertentu ditandai dengan "-". Misal untuk mengenali pattern "a" sampai "c" maka bisa kita gunakan expresi sebagai berikut [a-b].
ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: [a-c]
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.

Enter your regex: [a-c]
Enter input string to search: b
I found the text "b" starting at index 0 and ending at index 1.

Enter your regex: [a-c]
Enter input string to search: c
I found the text "c" starting at index 0 and ending at index 1.

Enter your regex: [a-c]
Enter input string to search: d
No match found.

Enter your regex: foo[1-5]
Enter input string to search: foo1
I found the text "foo1" starting at index 0 and ending at index 4.

Enter your regex: foo[1-5]
Enter input string to search: foo5
I found the text "foo5" starting at index 0 and ending at index 4.

Enter your regex: foo[1-5]
Enter input string to search: foo6
No match found.

Enter your regex: foo[^1-5]
Enter input string to search: foo1
No match found.

Enter your regex: foo[^1-5]
Enter input string to search: foo6
I found the text "foo6" starting at index 0 and ending at index 4.

Union
Misalnya kita akan melakukan pengenalan pattern gabungan antara 0 sampai 4 dan 6 sampai 8 bisa kita lakukan dengan cara [0-4[6-8]], maka selain dari union/gabungan range antara 0 sampai 4 dan 6 sampai 8 tidak akan dikenali.
Ex:
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: [0-4[6-8]]
Enter input string to search: 0
I found the text "0" starting at index 0 and ending at index 1.

Enter your regex: [0-4[6-8]]
Enter input string to search: 5
No match found.

Enter your regex: [0-4[6-8]]
Enter input string to search: 6
I found the text "6" starting at index 0 and ending at index 1.

Enter your regex: [0-4[6-8]]
Enter input string to search: 8
I found the text "8" starting at index 0 and ending at index 1.

Enter your regex: [0-4[6-8]]
Enter input string to search: 9
No match found.


Intersection
Digunakan untuk melakukan pengenalan pattern yang berupa irisan atau ingin mengenali suatu pattern pada range tertentu, bisa menggunakan key &&. Misal ingin mengenali pattern 3, 4 dan 5 pada range 0 sampai 9 maka bisa kita kontruksi regex sebagai berikut [0-9&&[345]]
Ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: [0-9&&[345]]
Enter input string to search: 3
I found the text "3" starting at index 0 and ending at index 1.

Enter your regex: [0-9&&[345]]
Enter input string to search: 4
I found the text "4" starting at index 0 and ending at index 1.

Enter your regex: [0-9&&[345]]
Enter input string to search: 5
I found the text "5" starting at index 0 and ending at index 1.

Enter your regex: [0-9&&[345]]
Enter input string to search: 2
No match found.

Enter your regex: [0-9&&[345]]
Enter input string to search: 6
No match found.

Enter your regex: [2-8&&[4-6]]
Enter input string to search: 3
No match found.

Enter your regex: [2-8&&[4-6]]
Enter input string to search: 4
I found the text "4" starting at index 0 and ending at index 1.

Enter your regex: [2-8&&[4-6]]
Enter input string to search: 5
I found the text "5" starting at index 0 and ending at index 1.

Enter your regex: [2-8&&[4-6]]
Enter input string to search: 6
I found the text "6" starting at index 0 and ending at index 1.

Enter your regex: [2-8&&[4-6]]
Enter input string to search: 7
No match found.


Substraction
Digunakan untuk melakukan pengenalan pada negasi yang berada pada karakter yang bersarang, misal [0-9&&[^345]] berarti melakukan pencarian pada range 0 sampai 9 kecuali 3, 4 dan 5.

Oke lanjut, setelah kita melakukan percobaan pada class2 karakter ada baiknya jika kita kenali juga predifined charakter class, class Pattern telah mendefinisikan pattern2 diatas sehingga kita bisa memanfaatkannya sebagai shorthands.
Predefined Character Classes
. cocok dengan karakter apapun (may or may not match line terminators)
\d digit: [0-9]
\D non digit: [^0-9]
\s karakter whitespace: [ \t\n\x0B\f\r]
\S karakter non-whitespace: [^\s]
\w karakter kata: [a-zA-Z_0-9]
\W karakter non-word: [^\w]


ex:
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: .
Enter input string to search: @
I found the text "@" starting at index 0 and ending at index 1.

Enter your regex: .
Enter input string to search: 1
I found the text "1" starting at index 0 and ending at index 1.

Enter your regex: .
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.

Enter your regex: \d
Enter input string to search: 1
I found the text "1" starting at index 0 and ending at index 1.

Enter your regex: \d
Enter input string to search: a
No match found.

Enter your regex: \D
Enter input string to search: 1
No match found.

Enter your regex: \D
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.

Enter your regex: \s
Enter input string to search:
I found the text " " starting at index 0 and ending at index 1.

Enter your regex: \s
Enter input string to search: a
No match found.

Enter your regex: \S
Enter input string to search:
No match found.

Enter your regex: \S
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.

Enter your regex: \w
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.

Enter your regex: \w
Enter input string to search: !
No match found.

Enter your regex: \W
Enter input string to search: a
No match found.

Enter your regex: \W
Enter input string to search: !
I found the text "!" starting at index 0 and ending at index 1.


Oke dari predifined class bisa kita simpulkan :
Huruf bukan kapital berarti :
\d cocok untuk semua digit
\s cocok untuk whitespace
\w cocok untuk semua karakter penyusun kata

Sedangkan hurus kapital :

\D cocok untuk non-digits
\S cocok untuk non-spaces
\W cocok untuk semua non karakter penyusun kata

Quantifiers
Dengan menggunakan quantifiers kita bisa melakukan pencocokan berdasarkan berapa kali kita akan melakukan pengenalan pattern pada suatu urutan karakter, spesifikasi class Pattern mempunyai 3 quantifiers yaitu greedy, Reluctant dan Possessive. Berikut adalah tabel quantifiers :

Quantifiers
Meaning
Greedy Reluctant Possessive
X? X?? X?+ X, once or not at all
X* X*? X*+ X, zero or more times
X+ X+? X++ X, one or more times
X{n} X{n}? X{n}+ X, exactly n times
X{n,} X{n,}? X{n,}+ X, at least n times
X{n,m} X{n,m}? X{n,m}+ X, at least n but not more than m times


Sekarang kita akan melakukan percobaan dengan quantifiers greedy menggunakan huruf "a" dengan diikuti ?, *, + kita akan lihat perbedaannya. Input yang digunakan adalah string kosong "".
ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: a?
Enter input string to search:
I found the text "" starting at index 0 and ending at index 0.

Enter your regex: a*
Enter input string to search:
I found the text "" starting at index 0 and ending at index 0.

Enter your regex: a+
Enter input string to search:
No match found.


Pada contoh diatas untuk a? dan a* akan mengijinkan adanya pattern "", karena pattern "" ada pada input string kosong, awal dari input string, akhir dari input string atau diantara huruf pada input string.

kita lakukan percobaan lagi untuk melihat perbedaan dari ketiganya dengan memberikan input masukan berupa karakter "a":
ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: a?
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.

Enter your regex: a*
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.

Enter your regex: a+
Enter input string to search: a
I found the text "a" starting at index 0 and ending at index 1.


dari hasil diatas dapat kita lihat bahwa pada a? dan a* tetap menemukan pattern "" pada akhir karakter, karena pada index 0 ditempati oleh karakter "a" sedang pattern "" akan dikenali pada index ke 1 dan diakhiri pada index 1 juga.

oke sekarang kita coba lagi bagaimana jika masukannya berupa string "aaaaa" ?
ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: a?
Enter input string to search: aaaaa
I found the text "a" starting at index 0 and ending at index 1.
I found the text "a" starting at index 1 and ending at index 2.
I found the text "a" starting at index 2 and ending at index 3.
I found the text "a" starting at index 3 and ending at index 4.
I found the text "a" starting at index 4 and ending at index 5.
I found the text "" starting at index 5 and ending at index 5.

Enter your regex: a*
Enter input string to search: aaaaa
I found the text "aaaaa" starting at index 0 and ending at index 5.
I found the text "" starting at index 5 and ending at index 5.

Enter your regex: a+
Enter input string to search: aaaaa
I found the text "aaaaa" starting at index 0 and ending at index 5.

Nah sekarang dah katahuan kan bedanya huehuehue ..., tapi kita akan coba sekali lagi untuk memastikannya dengan mengubah string masukan menjadi "ababaaaab".
ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: a?
Enter input string to search: ababaaaab
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.
I found the text "a" starting at index 2 and ending at index 3.
I found the text "" starting at index 3 and ending at index 3.
I found the text "a" starting at index 4 and ending at index 5.
I found the text "a" starting at index 5 and ending at index 6.
I found the text "a" starting at index 6 and ending at index 7.
I found the text "a" starting at index 7 and ending at index 8.
I found the text "" starting at index 8 and ending at index 8.
I found the text "" starting at index 9 and ending at index 9.

Enter your regex: a*
Enter input string to search: ababaaaab
I found the text "a" starting at index 0 and ending at index 1.
I found the text "" starting at index 1 and ending at index 1.
I found the text "a" starting at index 2 and ending at index 3.
I found the text "" starting at index 3 and ending at index 3.
I found the text "aaaa" starting at index 4 and ending at index 8.
I found the text "" starting at index 8 and ending at index 8.
I found the text "" starting at index 9 and ending at index 9.

Enter your regex: a+
Enter input string to search: ababaaaab
I found the text "a" starting at index 0 and ending at index 1.
I found the text "a" starting at index 2 and ending at index 3.
I found the text "aaaa" starting at index 4 and ending at index 8.


oke jadi kesimpulannya begini untuk a? akan melakukan pencocokan karakter satu persatu dan akan menggantikan pattern yang tidak cocok dengan ""(string kosong), a* akan melakukan pencocokan karakter yang sama dengan a tetapi tidak satu persatu karakter tapi jika ada pattern yang sama misalnya "aaaa" akan dianggap sebagai sebuah kesatuan dan aka mengganti pattern yang tidak sama dengan "" dan pada a+ bertindak seperti a* tetapi langsung mengabaikan pattern yang tidak cocok.

lalu bagaimana jika kita ingin mencocokkan pattern karakter dengan jumlah tertentu ??, the answer is use the curly braces {n} oke!!
ex :
Enter your regex: a{3}
Enter input string to search: aa
No match found.

Enter your regex: a{3}
Enter input string to search: aaa
I found the text "aaa" starting at index 0 and ending at index 3.

Enter your regex: a{3}
Enter input string to search: aaaa
I found the text "aaa" starting at index 0 and ending at index 3.


dari contoh diatas dapat dilihat pemanfaatan dari {n}, n adalah jumlah karakter yang akan dicocokkan.Tapi kenapa yang pertama gagal ?? itu karena string yang dicocokkan jumlahnya lebih sedikit jika dibadingkan dengan jumlah regex yang akan dikenali meskipun string inputnya sama yaitu "aa". Nah kita lanjut lagi masih seputar {n}, lets look bellow :
Ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: a{3}
Enter input string to search: aaaaaaaaa
I found the text "aaa" starting at index 0 and ending at index 3.
I found the text "aaa" starting at index 3 and ending at index 6.
I found the text "aaa" starting at index 6 and ending at index 9.

Enter your regex: a{3,}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaaaaa" starting at index 0 and ending at index 9.

Enter your regex: a{3,6}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaa" starting at index 0 and ending at index 6.
I found the text "aaa" starting at index 6 and ending at index 9.


oke penjelasan untuk output diatas adalah sebagai berikut, untuk yang pertama dengan a{3} akan mengenali 3 kali karena input string "aaaaaaaaa" sejumlah 3 kali pattern a{3}, untuk yang kedua dengan {3,} maksudnya akan mengenali pattern minimal dengan panjang karakter "aaa" dengan pangjang maksimal tak terbatas, untuk yang terakhir dengan {3,6} sebenarnya sama dengan yang kedua hanya bedanya ada batas pengenalan panjang pattern yaitu sepanjang 6 karakter.

Sekarang perbadaan antara regex (dog){3} dengan dog{3} ??, look bellow agains ...
Ex :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: (dog){3}
Enter input string to search: dogdogdogdogdogdog
I found the text "dogdogdog" starting at index 0 and ending at index 9.
I found the text "dogdogdog" starting at index 9 and ending at index 18.

Enter your regex: dog{3}
Enter input string to search: dogdogdogdogdogdog
No match found.

terlihat bahwa yang pertama akan mengenali pattern berupa group karakter yaitu "dog" dengan panjang 3, sedangkan yang kedua hanya akan mengenali "dog" dimana yang dihitung jumlahnya bukan "dog" tetapi karakter "g". Untuk melakukan grouping seperti (dog){3} tetapi tidak mementingkan urutan bisa kita gunakan pattern [x]{n}, contoh :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: [abc]{3}
Enter input string to search: abccabaaaccbbbc
I found the text "abc" starting at index 0 and ending at index 3.
I found the text "cab" starting at index 3 and ending at index 6.
I found the text "aaa" starting at index 6 and ending at index 9.
I found the text "ccb" starting at index 9 and ending at index 12.
I found the text "bbc" starting at index 12 and ending at index 15.


Perbedaan antara greedy, reluctant dan possessive ??, okeh kita lihat saja contoh berikut ini :
amru@bl4ckcub3:~/MyJava/learn/regex$ java RegexTestHarness

Enter your regex: .*foo // greedy quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Enter your regex: .*?foo // reluctant quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.

Enter your regex: .*+foo // possessive quantifier
Enter input string to search: xfooxxxxxxfoo
No match found.

proses pada gredy adalah pertama dia akan mengkonsumsi semua input dengan menggunakan (.*) termasuk pattern "foo" yang terakhir, perlu diingat pencocokan pada gredy dimulai dari belakang sampai diketemukan pattern "foo" yang terakhir. Itulah kenapa setelah diketemukan pattern "foo" yang terakhir pencocokan akan berhenti.
proses pada reluctant adalah pertama dia tidak akan mengkonsumsi apapun dari input, pencocokannya akan dilakukan dari depan dengan mencocokkan satu persatu sampai diketemukan pattern "foo", jika diketemukan maka akan menghentikan pencocokan dan memulai kembali pencocokan dari index dimana dia berhenti.
proses pada possessive sama dengan greedy tetapi dia tidak akan mengulang lagi jika tidak diketemukan, pencocokan hanya dilakukan sekali saja.

reference : http://java.sun.com/docs/books/tutorial

Monday, December 15, 2008

Mengenal Tipe Enum



Definisi : Tipe enum merupakan tipe yang terdiri dari sekumpulan field constan. Misalkan bisa saja digunakan untuk mendefinisikan empat arah mata angin (NORTH, SOUTH, EAST, dan WEST) atau bisa jug digunakan untuk menyimpan nilai hari-hari dalam seminggu.

Note : enum sendiri mulai ada pada Java 1.5


pada java kita bisa menggunakan keyword enum untuk mendefinisikan tipe enum, contoh pada kode berikut :

/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}


Kapan enum cocok untuk digunakan ?, ketika kita ingin merepresentasikan set konstanta yang tetap. Misalkan saja kita ingin merepresentasikan data set planet yang ada pada susunan tatasurya kita (ya kalo ngga ditemukan planet baru hehehe...).

Kode program di bawah ini merupakan contoh penggunaan tipe enum Day yang telah kita buat sebelumnya.

/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

public class EnumTest {
Day day;

public EnumTest(Day day) {
this.day = day;
}

public void tellItLikeItIs() {
switch (day) {
case MONDAY: System.out.println("Mondays are bad.");
break;

case FRIDAY: System.out.println("Fridays are better.");
break;

case SATURDAY:
case SUNDAY: System.out.println("Weekends are best.");
break;

default: System.out.println("Midweek days are so-so.");
break;
}
}

public static void main(String[] args) {
EnumTest firstDay = new EnumTest(Day.MONDAY);
firstDay.tellItLikeItIs();
EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
thirdDay.tellItLikeItIs();
EnumTest fifthDay = new EnumTest(Day.FRIDAY);
fifthDay.tellItLikeItIs();
EnumTest sixthDay = new EnumTest(Day.SATURDAY);
sixthDay.tellItLikeItIs();
EnumTest seventhDay = new EnumTest(Day.SUNDAY);
seventhDay.tellItLikeItIs();


}
}


Output program :
Mondays are bad.
Midweek days are so-so.
Fridays are better.
Weekends are best.
Weekends are best.


Tipe enum tidak hanya bisa menyimpan konstanta saja, tetapi juga bisa mempunyai konstruktor dan juga field2 inilah yang membuat tipe enum menjadi powerfull. Untuk melakukan iterasi pada tipe enum kita bisa memanfaatkan for-each loop pada java :

for (Planet p : Planet.values()) {
System.out.printf("Your weight on %s is %f%n",
p, p.surfaceWeight(mass));
}


Note : ketika kita mendefinisikan tipe enum secara otomatis akan menurunkan class java.lang.Enum. Karena java tidak mengijinkan multiple inheritance sehingga tipe enum tidak bisa menurunkan/extends dari class lain.


Tipe enum dapat mempunyai parameter, yang akan dilewatkan pada konstruktornya ketika konstruktor dipanggil. Berikut adalah contoh kode enum yang merepresentasikan planet dalam susunan tatasurya kita, yang outputnya akan menghitung bobot kita di planet2 yang lain.

* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7);

private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
private double mass() { return mass; }
private double radius() { return radius; }

// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;

double surfaceGravity() {
return G * mass / (radius * radius);
}
double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
public static void main(String[] args) {
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight/EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Your weight on %s is %f%n",
p, p.surfaceWeight(mass));
}
}


Output program (dimana program menerima parameter masukan berupa bobot kita) :
$ java Planet 175
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
Your weight on EARTH is 175.000000
Your weight on MARS is 66.279007
Your weight on JUPITER is 442.847567
Your weight on SATURN is 186.552719
Your weight on URANUS is 158.397260
Your weight on NEPTUNE is 199.207413


referensi :
http://java.sun.com/docs/books/tutorial