w3hJava

What, Why, When and How of Java, JavaFX and related technologies


Published August 22nd, 2008

Gradient in Java FX - Shading and 3D effect !

One thing that makes life very easy in JavaFX is the effect of Gradient. There are two types of Gradient support in JavaFX - Linear and Radial.

Linear Gradient is good for shading like

So, you can see the gradient of Black and Red on ball.  Why 2 circle because in this code, I want to show you how to achieve same effect from proportional coordinate and from absolute coordinate :-). Here is the code:

package gradientexample;

import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.geometry.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.paint.*;
import javafx.scene.geometry.Circle;

Frame {
title: "MyApplication"
width: 500
height: 500
closeAction: function() { java.lang.System.exit( 0 );
}
visible: true

stage: Stage {
content: [

Circle {
centerX: 100, centerY: 100
radius: 40
fill: LinearGradient {
startX: 0.0
startY: 0.0
endX: 1.0
endY: 0.0
proportional: true
stops: [
Stop { offset: 0.0 color: Color.BLACK },
Stop { offset: 1.0 color: Color.RED }
]
}
},

Circle {
centerX: 200, centerY: 200
radius: 40
fill: LinearGradient {
startX:   160.0
startY:   0.0
endX: 240.0
endY: 0.0
proportional: false
stops: [
Stop { offset: 0.0 color: Color.BLACK },
Stop { offset: 1.0 color: Color.RED }
]
}
}

]
}
}

Now, Have a look of Radial Gradient, this can be used to generate 3D effect on a ball like :

Here is the code for 3D ball generator. Just click on the button on the top and it will keep on generating the random color, select the good for your application and just put it :)

Here goes the code:

package gradientexample;

import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.geometry.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.paint.*;
import javafx.scene.geometry.Circle;
import javafx.ext.swing.Button;
import java.util.Random;
import javafx.ext.swing.ComponentView;
import  javafx.scene.effect.*;

var color: Color = Color.RED;

var rnd : Random = new Random();

var button = Button {
text: "3D Ball Generator"
action: function() {
color = Color.rgb(rnd.nextInt(255),rnd.nextInt(255),rnd.nextInt(255))
}
}
Frame {
title: "3D Ball Generator"
width: 700
height: 700
closeAction: function() { java.lang.System.exit( 0 );
}
visible: true

stage: Stage {
fill: Color.GRAY
content: [
Circle {
centerX: 200, centerY: 200
radius: 70
fill: bind RadialGradient {
centerX: 170
centerY: 170
radius: 100
proportional: false
stops: [
Stop { offset: 0.0 color: Color.WHITE },
Stop { offset: 1.0 color: color },
]
}
effect: GaussianBlur   {
radius: 70
input: Flood {
paint: Color.BLACK
}
}
opacity: 0.6
},
ComponentView {
component: button
}

]
}
}

Lot of good examples on these gradient are available on net.

Published August 13th, 2008

Java + PDF !

Java is such a big language now, that we ofter need to handle all type of application with Java. You may end up with a situation where you want to call MS word from Java, or Open Document from Java. Now, months back, I got a situation where I need to call some PDF formats from Java and need to do some operation on its pages. At that time, I have explored the Project - PDF Renderer on java.net site. Its an awesome project and cool operations.

A complete viewer and render. API’s are strong and I have just check this code from site itself. This code put the first page of your PDF file inside PagePanel. No doubt PDF is one of the open format used worldwide across all OS. In such a case, support from Java is something like adding more flavor in sweet.

import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PagePanel;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import javax.swing.*;

/**
 * An example of using the PagePanel class to show PDFs. For more advanced
 * usage including navigation and zooming, look ad the
 * com.sun.pdfview.PDFViewer class.
 *
 * -AT-author joshua.marinacci@sun-DOT-com
 */
public class Main {

    public static void setup() throws IOException {

        //set up the frame and panel
        JFrame frame = new JFrame("PDF Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        PagePanel panel = new PagePanel();
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);

        //load a pdf from a byte buffer
        File file = new File("Amityform.pdf");
        RandomAccessFile raf = new RandomAccessFile(file, "r");
        FileChannel channel = raf.getChannel();
        ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY,
            0, channel.size());
        PDFFile pdffile = new PDFFile(buf);

        // show the first page
        PDFPage page = pdffile.getPage(0);
        panel.showPage(page);

    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                try {?
                    Main.setup();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }
}

Just download the jar file from project site. And then :

javac -cp PDFRenderer.jar Main.java

java -cp PDFRenderer.jar;. Main

It is pretty fast as well, because IO operation has been done by NIO and channels are superb.  Thanks guys for making such a great project.

Published August 1st, 2008

Rotating balls JavaFX in ease style

Here is again a small code of JavaFX. Rotating some colorful circle in ease style. It mean, it will stop in flash way, I mean slow at the end and the begining.

Check out the code:

package newfx;

import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.geometry.Circle;
import javafx.scene.paint.Color;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.application.*;

import javafx.scene.*;
import javafx.scene.geometry.*;
import javafx.animation.*;
import javafx.scene.transform.*;

var angle = 0.0;

var anim = Timeline { keyFrames: [
KeyFrame { time: 5s values: angle => 360 tween Interpolator.EASEBOTH },
]
autoReverse: true
repeatCount: Timeline.INDEFINITE
};
anim.start();

Frame {
title: “MyApplication”
width: 900
height: 900
closeAction: function() { java.lang.System.exit( 0 );
}
visible: true
stage: Stage {
fill: Color.BLACK;
content: Group {
translateX: 400 translateY: 400
content: for(i in [0..5]) {
Circle {
centerX: bind(i*60), centerY: 50
radius: 40
fill: Color.rgb(255 - i*40,i*40,0)
strokeWidth:2
stroke:Color.BLACK
transform:bind[
Transform.rotate(angle,50,50),
]
}
}
}
}
}

Here is one snap shot:

Published July 29th, 2008

Use default client for mailing - JDK6

Sending mails or messaging from Java is never been a tough process but still most of us has to write Java Messaging API or Java Mail API to do this, which is a cumbersome process in itself.

JDK6 came with a new Desktop class in which you can give user the option to work on the default mail client, do whatever you want to do and after closing the default client the control will go back to the java code. Here is a small code to do that:

import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;

public class DefaultMail {
public static void main(String[] a)throws Exception {
Desktop desktop = null;
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
}

desktop.mail(”mailto”, “vaibhav.choudhary@sun.com”, null);
}
}

The idea is clean I guess, the default client will give more option than Java mail API or anything else. Desktop class give lot more other functionality as well, which we will discuss later.

Published June 21st, 2008

How to use JDK 6 to solve memory issues?

Take care of disk space when you are writing a big program :). Use JDK 6 features:

import java.io.File;

public class DiskSpaceCheck {
public DiskSpaceCheck() {
File file = new File("E:");
System.out.println("E:");
System.out.println("Total:  " + file.getTotalSpace());
System.out.println("Free:   " + file.getFreeSpace());
System.out.println("Usable: " + file.getUsableSpace());

file = new File("E://movie");
System.out.println("E://movie");
System.out.println("Total:  " + file.getTotalSpace());
System.out.println("Free:   " + file.getFreeSpace());
System.out.println("Usable: " + file.getUsableSpace());

file = new File("/");
System.out.println("n/");
System.out.println("Total:  " + file.getTotalSpace());
System.out.println("Free:   " + file.getFreeSpace());
System.out.println("Usable: " + file.getUsableSpace());
}

public static void main(String[] args) {
new DiskSpaceCheck();
}
}

I was actually very suprised that why this feature came so late.

Published June 17th, 2008

Test your applet on different JRE’s

In last post on StringBuffer, Dimitris Andreou commented that it was an old thing. ;-). So, I decided to write something new which is currently going on in Sun Microsystems. Finally I zeroed down on Java SE 6u10 features. Some of them I blogged on my Sun site but here are some more.

Very often this happens. You made a UI in applet and want to check whether the application is working fine on all JRE’s or not. If you are not, then please do it :).?I have seen people still using JDK 1.3. I, myself use jdk1.4.2 for many reasons and it still survive somewhere in the company standards. Now, if you want to check the applet on all JRE’s, welcome to the world of JRE 6u10 features.

Here is the demo:

Write a normal applet code, say Hello World.

import java.awt.*;
import java.applet.Applet;

public class HelloWorld extends Applet {
public void paint(Graphics g) {
g.drawString("Hello World",50,50);
} // end of paint
} // end of applet

And now the interesting part, write the HTML file like:

<APPLET CODE="HelloWorld.class" WIDTH=200 HEIGHT=100>
<PARAM name="java_version" value="1.5.0_20">
</APPLET>

It will run the applet on JRE 1.5.0_20(if exists on machine). For more generic once, write:

<APPLET CODE="HelloWorld.class" WIDTH=200 HEIGHT=100>
<PARAM name="java_version" value="1.4*">
</APPLET>

It will check any flavor of 1.4 like 1.4.2_01 or 1.4.2_10 on your machine. 6u10 rocks ! Remember it will work in IE6 or + and FF3 or +. Ah, I remember, today is FF3 download day. So, please don’t forget to download FF3.

Published June 15th, 2008

String goes StringBuffer

Let me first tell you what is StringBuilder. StringBuilder is a class analogous to StringBuffer added in JDK 1.5. This class is designed to use in place where StringBuffer is used by single thread(like in most
of the cases). According to documentation, StringBuilder should work faster than StringBuffer. So ” thread unsafe, fast”.

I was reading one of the posts of orkut Java community asking “what is this capacity in StringBuffer and even we can add two strings from String class why to go for StringBuffer”. Valid question ! GC need to work little more in case of String, but thats fair.

No don’t use String class for concatenation operation, always use StringBuffer / StringBuilder and let me tell you why ?

This is a simple Java code for string addition in String and StringBuffer:

class StringTest {
    public static void main(String[] args)
   {
       String s = “just a string”;
       s = s + “add me too”;
       System.out.println(s);
       /*
       StringBuffer s = new StringBuffer(”just a string”);
      //StringBuilder s = new StringBuilder(”just a string”);
      s = s.append(”add me too”);
      System.out.println(s);
      */
     }
}

Alright, now have a look on the bytecode of this program.

>> javac StringTest.java
>> javap -c StringTest

Compiled from “StringTest.java”
class StringTest extends java.lang.Object{
StringTest();
Code:
0:   aload_0
1:   invokespecial   #1; //Method java/lang/Object.“:()V
4:   return

public static void main(java.lang.String[]);
Code:
0:   ldc     #2; //String just a string
2:   astore_1
3:   new     #3; //class java/lang/StringBuilder
6:   dup
7:   invokespecial   #4; //Method java/lang/StringBuilder.“:()V
10:  aload_1
 11:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
14:  ldc     #6; //String add me too
16:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)
Ljava/lang/StringBuilder;
19:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22:  astore_1
23:  getstatic       #8; //Field java/lang/System.out:Ljava/io/PrintStream;
26:  aload_1
27:  invokevirtual   #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
30:  return
}

Just see line no. 11. Interesting, the plus sign we used for addition is not as innocent as it looks. String itself use StringBuffer(StringBuilder) to add two strings and hence taking much more time than normal append operation done by StringBuffer. Let me give you more evidence, run verbose option and check the time

>> javac -verbose StringTest.java

and check the other one, that is, with StringBuffer one.

You can clearly figure out the time difference and make a try with StringBuilder, time should reduce furthermore.

Published May 28th, 2008

Multi-threading in Java

One of the greatest features in Java is support for multi-threading. Generally we have misconceptions about the concepts of threading. We tend to think it more as a part of coding and hence take it only at coding time. Threading is all about designing and not about coding. If you want to write a good threading code, think of it before writing the code. Sometime back, I had made a presentation on multi-threading in Java with some demos. Have a look here :)

here

Presentation is very basic and talk simple things. Your comments are most welcome.

Published May 23rd, 2008

Java - Pass by Reference(Not possible)

I had a big time fight on my Orkut community with the concept that Java do things with Pass by Reference. Here is the one for Orkut users :

Here

But for non-orkut users let me recap the point again, its very important for a person who is new in java:

There is NO CONCEPT OF CALL BY REFERENCE IN JAVA, ONLY CALL BY VALUE IS POSSIBLE. We generally get confused in pass the object reference by value and passing by reference. Both are completely different.

Here is a small code, to get a more clear picture:

class MyClass {

String name;
int nameCode;

public MyClass(String name, int nameCode) {
this.name = name;
this.nameCode = nameCode;
}

public String toString() {
System.out.println(name + " : " + nameCode);
return (name + nameCode);
}
}

public class NoCallByReference {

public static void swap(MyClass a, MyClass b) {
MyClass temp = a;
a = b;
b = temp;
}

public static void main(String[] args) {
MyClass myclass = new MyClass(”Ramu”, 7);
MyClass yourclass = new MyClass(”Mohan”, 1);
swap(myclass, yourclass);
myclass.toString();
yourclass.toString();
}
}

A very simple code where I tried to swap two object of myClass. But you will surprise to see the output because after swapping even the value of myclass and yourclass will remain the same. Because the copy of myclass and yourclass has been created and get swapped rather than actual myclass and yourclass. It’s like

myclass — copyofmyclass
yourclass — copyofyourclass

Swapping is done on copyofmyclass and copyofyourclass. Better to go for a homework and run the command

javap -c NoCallByReference and try to figure our how assemble is going on :-).

Published May 16th, 2008

Is Compiler Optimization always good?

Last week, I made a presentation on Multi-threading in Java. Although I had covered this aspect in presentation but still wanted to blog more on the same. In multi-threading world, compiler optimization can cause serious problems. Check out this small piece of code

public class NonVolatileProblem extends Thread {

    ChangeFlag cf;

    public static void main(String[] args) {
        ChangeFlag cf = new ChangeFlag();
        NonVolatileProblem th1 = new NonVolatileProblem(cf);
        NonVolatileProblem th2 = new NonVolatileProblem(cf);
        th1.start();
        th2.start();
    }

    public void run() {
        cf.method1();
        cf.method2();
    }

    public NonVolatileProblem(ChangeFlag cf) {
        this.cf = cf;
    }
}

class ChangeFlag {

    boolean flag = false;

    public void method1() {
        flag = false;
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            System.out.println(”Don’t want to be here”);
        }
        if (flag) {
            System.out.println(”This can be reached “);
        }
        System.out.println(”Value of flag” + flag);
    }

    public void method2() {
        flag = true;
    }
}

Check out the reason in bold. Now if compiler optimizes the code and remove the part of if(flag), thinking that flag value will always be false. Then we have a situation here(FBI style of speaking :-D), because other thread can change its value and can make the flag value true.

Try to run this code 5-6 may be 10 times, you will be able to see the SOP statement “This can be reached“. Just for te sake of getting that, I have added sleep statement. Here what I got on my 3rd run of the code :)

Value of flag:false
This can be reached
Value of flag:true

Handling such type of situation is not difficult, specification says to add a word volatile before the variable flag which will tell the compiler not to optimize its code just by seeing some initial value or declaration.