Thursday, 9 February 2012

How to close child windows when closing parent window in javascript?

In many instances we want to close all child windows when main parent window is closed. This can be easily achieved using javascript.

To achieve this we need to do three thing

1) Create an array. This array is required for storing references of all child windows.


var childwindows = new Array();

2) Open child window using window.open and then store references of child window into an array

function openPopup(){
 try{
  var d = new Date();
  var win = window.open("Test.html",'test'+d.getMilliseconds(),'width=200,height=100')
  childwindows[childwindows.length] = win;
  win.focus();
 }catch(e){
  alert(e);
 }
}

3) Finally close all child windows on window.onunload event.

window.onunload = function closeChildWin(){
 for(var i=0; i<childwindows.length; i++){
  try{
     childwindows[i].close()
  }catch(e){
   alert(e);
  }
 }
}



To test this you can copy and paste following code into the file and save it as a Test.html. Let me know if it has helped you.

<html>
 <body>
        <input type="submit" onclick="openPopup()" value="Open new Window">
 </body>
</html>

<script>

var childwindows = new Array();

function openPopup(){
 try{
  var d = new Date();
  var win = window.open("Test.html",'test'+d.getMilliseconds(),'width=200,height=100')
  childwindows[childwindows.length] = win;
  win.focus();
 }catch(e){
  alert(e);
 }
}

window.onunload = function closeChildWin(){
 for(var i=0; i<childwindows.length; i++){
  try{
     childwindows[i].close()
  }catch(e){
   alert(e);
  }
 }
}

</script>

Friday, 3 February 2012

JBox2D with JavaFX 2.0 Tutorial: Attaching an image to body

In Write your first JBox2D with JavaFX 2 program posts we have seen how to create a ball and its GUI representation using JavaFX Circle shape. We can also use images for GUI representation. Following code snippet shows how to attach an image to the body.

import javafx.scene.Parent;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;

/**
 *
 * @author dilip
 */
public class Ball extends Parent{

    
    //X and Y position of the ball in JBox2D world
    private float posX;
    private float posY;
    
    //Ball radius in pixels
    private int radius;
    
    public Ball(float posX, float posY, int radius){
        this.posX = posX;
        this.posY = posY;
        this.radius = radius;
        create();
    }

    
    private void create(){
        
        /**
         * Set ball position on JavaFX scene. We need to convert JBox2D coordinates 
         * to JavaFX coordinates which are in pixels.
         */
        this.setLayoutX(Utils.toPixelPosX(posX)); 
        this.setLayoutY(Utils.toPixelPosY(posY));
        
        //Create an JBox2D body defination for ball.
        BodyDef bd = new BodyDef();
        bd.type = BodyType.DYNAMIC;;
        bd.position.set(posX, posY);
        
        CircleShape cs = new CircleShape();
        cs.m_radius = radius * 0.1f;  //We need to convert radius to JBox2D equivalent
        
        // Create a fixture for ball
        FixtureDef fd = new FixtureDef();
        fd.shape = cs;
        fd.density = 0.5f;
        fd.friction = 0.3f;        
        fd.restitution = 0.5f;

        /**
        * Virtual invisible JBox2D body of ball. Bodies have velocity and position. 
        * Forces, torques, and impulses can be applied to these bodies.
        */
        Body body = Utils.world.createBody(bd);
        body.createFixture(fd);
        this.setUserData(body);

        //Attach an image.
        ImageView iv = new ImageView();
        iv.setSmooth(true);
        iv.setImage(new Image(Ball.class.getResourceAsStream("images/ball.png")));
        getChildren().add(iv);
    }
}

Friday, 20 January 2012

How to calculate an age in Java?

Can we calculate an age in java without worrying about number of leap years between birth date and current date? Is there simple way to calculate it? …. The answer is yes. When we calculate somebody’s age manually, we do not think about number of leap year or number of days in each year. Same logic can be applies for calculating age programmatically.

Following is a code snippet for calculating the age. Please leave comment if it has helped you. Also please let me know if you feel this can be further optimized or this can be achieved by more simpler way...

  int years = 0;
  int months = 0;
  int days = 0;
  
  //create calendar object for birth day
  Calendar birthDay = Calendar.getInstance();
  birthDay.set(Calendar.YEAR, 2005);
  birthDay.set(Calendar.MONTH, Calendar.SEPTEMBER);
  birthDay.set(Calendar.DATE, 29);
  
  //create calendar object for current day
  long currentTime = System.currentTimeMillis();
  Calendar currentDay = Calendar.getInstance();
  currentDay.setTimeInMillis(currentTime);

  //Get difference between years
  years = currentDay.get(Calendar.YEAR) - birthDay.get(Calendar.YEAR);

  
  int currMonth = currentDay.get(Calendar.MONTH)+1;
  int birthMonth = birthDay.get(Calendar.MONTH)+1;
  
  //Get difference between months
  months = currMonth - birthMonth;
  
  //if month difference is in negative then reduce years by one and calculate the number of months. 
  if(months < 0)
  {
   years--;
   months = 12 - birthMonth + currMonth;
   
   if(currentDay.get(Calendar.DATE)<birthDay.get(Calendar.DATE))
    months--;
   
  }else if(months == 0 && currentDay.get(Calendar.DATE) < birthDay.get(Calendar.DATE)){
   years--;
   months = 11;
  }
  
  
  //Calculate the days
  if(currentDay.get(Calendar.DATE)>birthDay.get(Calendar.DATE))
   days = currentDay.get(Calendar.DATE) -  birthDay.get(Calendar.DATE);
  else if(currentDay.get(Calendar.DATE)<birthDay.get(Calendar.DATE)){
   int today = currentDay.get(Calendar.DAY_OF_MONTH); 
   currentDay.add(Calendar.MONTH, -1);
   days = currentDay.getActualMaximum(Calendar.DAY_OF_MONTH)-birthDay.get(Calendar.DAY_OF_MONTH)+today;
  }else{
   days=0;
   
   if(months == 12){
    years++;
    months = 0;
   }
  }
  
  System.out.println("The age is : "+years+" years, "+months+" months and "+days+" days" );


Tuesday, 10 January 2012

JBox2D with JavaFX tutorial: Applying Force and Impulse on body

Many times there will be situation when in JBox2D world we want to move bodies manually. So how do we do it? In real world we apply force to move anything. It holds good in JBox2D world too. To move bodies in JBox2D world we have to apply Force or Impulse.

There is a difference between force and Impulse. Force act gradually on bodies’ velocity. Imagine in real world if we wants to move one big box from one location to other then we will start pushing it. It means we will gradually apply force on that box; as a result box will start moving. Force in JBox2D world also works in similar fashion.

Following is a code snippet for applying force on body.
Body body = (Body)ball.getUserData();
Vec2 force  = new Vec2(0, 150.0f);
Vec2 point = body.getWorldPoint(body.getWorldCenter());
body.applyForce(force ,point);

Impulse act instantaneously, in a fraction of time step. Impulse is like we strike snooker ball with a cue or move objects with the help of explosives. Applying impulse is similar to applying force. We need to use applyLinearImpulse() function in place of applyForce()

Following sample code snippet is for applying the impulse.
Body body = (Body)ball.getUserData();
Vec2 force  = new Vec2(0, 50.0f);
Vec2 point = body.getWorldPoint(body.getWorldCenter());
body. applyLinearImpulse (force ,point);

The applyForce() and applyLinearImpulse() function takes two parameters force and point. Force parameter defines a direction and magnitude of the force. And second parameter defines on which point of the body force should be applied. In above snippet, we are applying force/impulse on center of the body.

<<JBox2D With JavaFX : Write your first JBox2D with JavaFX 2 program

Thursday, 29 December 2011

JBox2D With JavaFX : Write your first JBox2D with JavaFX 2 program

So far we have learned about JBox2D world, Bodies and world Simulation. With this we are ready to try our hands on JBox2D.

Today we will write one simple JBox2D application. In this application we will create one bouncy ball and release it into the JBox2D world. We will use JavaFX 2 for UI.

Our first step is to create JavaFX project. We will use NetBeans 7.1 for this. If you have not installed JavaFX SDK and NetBeans then you can download and install it form here. Once installed, open NetBeans IDE and follow the following steps

Click on File>New Project… menu. This will open “New Project” dialog box.
Select “JavaFX” under categories and then select JavaFX Application under projects
Click on “Next“ button.

In next window, type project name as “BouncyBallApp”.
Select project location.
Select “Create Application class” checkbox.
Select “Set as main project”
Click on finish.


This will create a project with main class “BouncyBallApp.java”

We will create two more class in this project – Utility.java and BouncyBall.java

Utility.Java – We will add all required constants and utility methods to this class.

We will add following constants to the Utility.java class
//Create a JBox2D world. 
    public static final World world = new World(new Vec2(0.0f, -10.0f), true);
    
    //Screen width and height
    public static final int WIDTH = 600;
    public static final int HEIGHT = 600;
    
    //Ball radius in pixel
    public static final int BALL_RADIUS = 8;


We will add method “addGround” to Utility class. This method will help us to add ground/platform for our JBox2D world. Ground is an essential component of our application. This is where our bouncy ball will land and bounce back. If we do not add ground ball will move infinitely downwards.

//This method adds a ground to the screen. 
public static void addGround(float width, float height){
    PolygonShape ps = new PolygonShape();
    ps.setAsBox(width,height);
        
    FixtureDef fd = new FixtureDef();
    fd.shape = ps;

    BodyDef bd = new BodyDef();
    bd.position= new Vec2(0.0f,-10f);

    world.createBody(bd).createFixture(fd);
}

As you can see we are using polygon shape for creating the ground. I will cover JBox2D shapes in detail in future post.

Next we will add method “addWall” to utility class. This method will allow us to add walls to our JBox2D world. Walls are required because we don’t want our bouncy ball to go outside the application viewable area.
//This method creates a walls. 
public static void addWall(float posX, float posY, float width, float height){
    PolygonShape ps = new PolygonShape();
    ps.setAsBox(width,height);
        
    FixtureDef fd = new FixtureDef();
    fd.shape = ps;
    fd.density = 1.0f;
    fd.friction = 0.3f;    

    BodyDef bd = new BodyDef();
    bd.position.set(posX, posY);
        
    Utils.world.createBody(bd).createFixture(fd);
}

Next we will add few utility methods which will allow us to convert JBox2D world coordinates to pixel coordinates and vise versa.
//Convert a JBox2D x coordinate to a JavaFX pixel x coordinate
public static float toPixelPosX(float posX) {
    float x = WIDTH*posX / 100.0f;
    return x;
}

//Convert a JavaFX pixel x coordinate to a JBox2D x coordinate
public static float toPosX(float posX) {
    float x =   (posX*100.0f*1.0f)/WIDTH;
    return x;
}

//Convert a JBox2D y coordinate to a JavaFX pixel y coordinate
public static float toPixelPosY(float posY) {
    float y = HEIGHT - (1.0f*HEIGHT) * posY / 100.0f;
    return y;
}

//Convert a JavaFX pixel y coordinate to a JBox2D y coordinate
public static float toPosY(float posY) {
    float y = 100.0f - ((posY * 100*1.0f) /HEIGHT) ;
    return y;
}

//Convert a JBox2D width to pixel width
public static float toPixelWidth(float width) {
    return WIDTH*width / 100.0f;
}

//Convert a JBox2D height to pixel height
public static float toPixelHeight(float height) {
    return HEIGHT*height/100.0f;
}


BouncyBall.java – Now we will create main actor of our application i.e. bouncy ball. First we will add class called as BouncyBall.java. We will add following attributes to this class.
//JavaFX UI for ball
    public Node node;
    
    //X and Y position of the ball in JBox2D world
    private float posX;
    private float posY;
    
    //Ball radius in pixels
    private int radius;

Then we will add method “private Node create()” to this class. The return type of method is set to javafx.scene.Node. We will use this method to create a ball. To create ball we will have to:

Create graphical representation of the ball and set its x,y position
//Create an UI for ball - JavaFX code
        Circle ball = new Circle();
        ball.setRadius(radius);
        ball.setFill(color); //set look and feel

        /**
         * Set ball position on JavaFX scene. We need to convert JBox2D coordinates 
         * to JavaFX coordinates which are in pixels.
         */
        ball.setLayoutX(Utils.toPixelPosX(posX)); 
        ball.setLayoutY(Utils.toPixelPosY(posY));

Create body definition of the ball i.e. ball body type (Dynamic in this case) & body position
//Create an JBox2D body defination for ball.
        BodyDef bd = new BodyDef();
        bd.type = BodyType.DYNAMIC;
        bd.position.set(posX, posY);

Create ball shape
CircleShape cs = new CircleShape();
        cs.m_radius = radius * 0.1f;  //We need to convert radius to JBox2D equivalent

Create fixture for ball
// Create a fixture for ball
        FixtureDef fd = new FixtureDef();
        fd.shape = cs;
        fd.density = 0.6f;
        fd.friction = 0.3f;        
        fd.restitution = 0.8f;
And finally we will create body, associate it with its graphical representation and return it.
/**
        * Virtual invisible JBox2D body of ball. Bodies have velocity and position. 
        * Forces, torques, and impulses can be applied to these bodies.
        */
        Body body = Utils.world.createBody(bd);
        body.createFixture(fd);
        ball.setUserData(body);
        return ball;

We will call this method from class constructor.
public BouncyBall(float posX, float posY, int radius, Color color){
        this.posX = posX;
        this.posY = posY;
        this.radius = radius;
        this.color = color;
        node = create();
    }

Finally BouncyBall.java should look like this:

package bouncyballapp;

import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;

/**
 *
 * @author dilip
 */
public class BouncyBall{

    //JavaFX UI for ball
    public Node node;
    
    //X and Y position of the ball in JBox2D world
    private float posX;
    private float posY;
    
    //Ball radius in pixels
    private int radius;
    
   
    private Color color;
    public BouncyBall(float posX, float posY, int radius, Color color){
        this.posX = posX;
        this.posY = posY;
        this.radius = radius;
        this.color = color;
        node = create();
    }
    
    /**
     * This method creates a ball by using Circle object from JavaFX and CircleShape from JBox2D
     */
    private Node create(){
        //Create an UI for ball - JavaFX code
        Circle ball = new Circle();
        ball.setRadius(radius);
        ball.setFill(color); //set look and feel 
        
        /**
         * Set ball position on JavaFX scene. We need to convert JBox2D coordinates 
         * to JavaFX coordinates which are in pixels.
         */
        ball.setLayoutX(Utils.toPixelPosX(posX)); 
        ball.setLayoutY(Utils.toPixelPosY(posY));
       
        //Create an JBox2D body defination for ball.
        BodyDef bd = new BodyDef();
        bd.type = BodyType.DYNAMIC;
        bd.position.set(posX, posY);
        
        CircleShape cs = new CircleShape();
        cs.m_radius = radius * 0.1f;  //We need to convert radius to JBox2D equivalent
        
        // Create a fixture for ball
        FixtureDef fd = new FixtureDef();
        fd.shape = cs;
        fd.density = 0.6f;
        fd.friction = 0.3f;        
        fd.restitution = 0.8f;

        /**
        * Virtual invisible JBox2D body of ball. Bodies have velocity and position. 
        * Forces, torques, and impulses can be applied to these bodies.
        */
        Body body = Utils.world.createBody(bd);
        body.createFixture(fd);
        ball.setUserData(body);
        return ball;
    }
    
}


Our final step is to modify main class i.e. BouncyBallApp.java class.

We will have to do following changes to “start()” method.

Set application title and application window size. Also set full screen and resizable properties to false so user will not be able to resize application window.
primaryStage.setTitle("Bouncy Ball");
        primaryStage.setFullScreen(false);
        primaryStage.setResizable(false);
        Group root = new Group(); //Create a group for holding all objects on the screen
        Scene scene = new Scene(root, Utils.WIDTH, Utils.HEIGHT);

Add ball, ground and walls
//create ball   
        final BouncyBall ball = new BouncyBall(45, 90, Utils.BALL_RADIUS, Color.RED);
         
        //Add ground to the application, this is where balls will land
        Utils.addGround(100, 10);
        
        //Add left and right walls so balls will not move outside the viewing area.
        Utils.addWall(0,100,1,100); //Left wall
        Utils.addWall(99,100,1,100); //Right wall

Add code for simulating the world.
final Timeline timeline = new Timeline();
        timeline.setCycleCount(Timeline.INDEFINITE);

        Duration duration = Duration.seconds(1.0/60.0); // Set duration for frame.
        
        //Create an ActionEvent, on trigger it executes a world time step and moves the balls to new position 
        EventHandler<actionevent> ae = new EventHandler<actionevent>() {
            public void handle(ActionEvent t) {
                        //Create time step. Set Iteration count 8 for velocity and 3 for positions
                        Utils.world.step(1.0f/60.f, 8, 3); 
                       
                        //Move balls to the new position computed by JBox2D
                        Body body = (Body)ball.node.getUserData();
                        float xpos = Utils.toPixelPosX(body.getPosition().x);
                        float ypos = Utils.toPixelPosY(body.getPosition().y);
                        ball.node.setLayoutX(xpos);
                        ball.node.setLayoutY(ypos);
           }
        };

                
         /**
         * Set ActionEvent and duration to the KeyFrame. 
         * The ActionEvent is trigged when KeyFrame execution is over. 
         */
        KeyFrame frame = new KeyFrame(duration, ae, null,null);

        timeline.getKeyFrames().add(frame);

Add code to start simulating the world on click of the button
//Create button to start simulation.
        final Button btn = new Button();
        btn.setLayoutX((Utils.WIDTH/2) -15);
        btn.setLayoutY((Utils.HEIGHT-30));
        btn.setText("Start");
        btn.setOnAction(new EventHandler<actionevent>() {
            public void handle(ActionEvent event) {
                        timeline.playFromStart(); 
                        btn.setVisible(false);
            }
        });

Finally add button and ball to the root group
root.getChildren().add(btn);
        root.getChildren().add(ball.node);
        primaryStage.setScene(scene);
        primaryStage.show();


Finally hit the “F6” to run the application.

<<Simulating JBox2D world                         Applying Force and Impulse on body>>

Wednesday, 21 December 2011

JBox2D Tutorial : Simulating JBox2D world

In previous post we have learned how to create JBox2D world. We also learned how to create bodies and add them to the world. Now next step is to simulate the JBox2D world.

To simulate the world, we need to call step method of the world.

float timeStep = 1.0f / 60.f;
int velocityIterations = 6;
int positionIterations = 2;

for (int i = 0; i < 60; ++i) {
world.step(timeStep, velocityIterations, positionIterations);
      Vec2 position = body.getPosition();
      float angle = body.getAngle();
      System.out.printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);
}
As you can see in above snippet, we are passing three arguments to the world.step

timeStep - This defines how much simulation should advance in one second. In above example simulation will advance by 1/60th second on every call to the step method.

velocityIterations – This define how accurately velocity will be simulated. Higher iteration value increases the accuracy of velocity simulation but decreases the performance. The recommended velocity iteration value is 6.

 positionIterations – This is similar to velocity iteration, higher value means more accurate position simulation but lesser performance. The recommended position iteration value is 3.

In above sample code snippet on every simulation step we are getting body’s new position and angle details and printing them to the console. So far we have learned about world, bodies and world simulation. In next post we will write our first JBox2D program with JavaFX 2.0

<<Creating Body                                      Writing first JBox2D program>>

Monday, 19 December 2011

JBox2D Tutorial : Creating an object body

In last post we have learned how to create the JBox2D WorldNow our next step will be to create an object body and add it to the world. 

To create bodies in JBox2D world we need to first create:

  • Body definition
  • Body shape and
  • Body fixtures.


Body Definition

Body definition is created as below.

BodyDef bd = new BodyDef();
bd.position.set(50, 50);  
bd.type = BodyType.DYNAMIC;

Main properties of the body definition are

  • Position - position of the body in JBox2d world i.e. x and y coordinates.
  • Body type – type of the 
Body can be static, dynamic or kinematic.


Static Body

  • Static bodies have zero velocity.
  • Static bodies do not move under simulations.
  • Static bodies can be moved manually by user.
  • Static bodies have infinite mass.
  • Static bodies do not collide with other static and kinematic bodies.
  • Examples - Ground, Walls.


Dynamic Body –

  • Dynamic bodies move under simulation.
  • Dynamic bodies respond to the forces and they move accordingly.
  • Dynamic bodies can be moved manually.
  • Dynamic bodies always have non-zero mass. If mass is set to zero then it acquires 1Kg mass.
  • Dynamic bodies collide with dynamic, kinematic and static body types.
  • Examples – Ball, Box,


Kinematic Body –

  • Under simulation, kinematic bodies move according to its velocity.
  • Kinematic bodies do not move according to forces.
  • Kinematic bodies can be moved manually by user.
  • Kinematic bodies have infinite mass.
  • Kinematic bodies do not collide with static or kinematic bodies.
  • Kinematic body’s movement does not get affected by gravity.
  • Kinematic body’s movement does not get affected when dynamic bodies are collided with it.
  • Example – moving platforms in games.


Body Shape

Next we need to define the body shape. JBox2D support Circle shape, Polygon Shape, Edge Shape and Chain Shape. We will discuss each shape in details in future tutorials.

Following code snippet shows how to create a circle shape.

CircleShape cs = new CircleShape();
cs.m_radius = 0.5f;  

Fixtures

Fixture defines the material properties of the body. Fixtures are also used for attaching shape to the body. These material properties describe how two bodies should react when they collide with each other.

FixtureDef fd = new FixtureDef();
fd.shape = cs;
fd.density = 0.5f;
fd.friction = 0.3f;        
fd.restitution = 0.5f;

Density – This defines the heaviness of the body with respect to its area.

Friction - This defines how bodies slide when they come in contact with each other. Friction value can be set between 0 and 1. Lower value means more slippery bodies.

Restitution – This define how bouncy is the body. Restitution values can be set between 0 and 1. Here higher value means more bouncy body.

There are some more properties of fixture, will cover them in future post.

Creating body

Now final step is to create a body and add fixture to it. The bodies are created using World class.

Body body =  world.createBody(bd);
body.createFixture(fd);

The complete code snippet would look like:
//body definition
BodyDef bd = new BodyDef();
bd.position.set(50, 50);  
bd.type = BodyType.DYNAMIC;

//define shape of the body.
CircleShape cs = new CircleShape();
cs.m_radius = 0.5f;  

//define fixture of the body.
FixtureDef fd = new FixtureDef();
fd.shape = cs;
fd.density = 0.5f;
fd.friction = 0.3f;        
fd.restitution = 0.5f;

//create the body and add fixture to it
Body body =  world.createBody(bd);
body.createFixture(fd);
In next post we will learn how to simulate the JBox2D World.

<<JBox2D World                                                Simulating the JBox2D world>>
There was an error in this gadget