Latest Eclipse Plugin for JavaFX 1.2.1

Posted: under JavaFX News, JavaFX Technology.
Tags: , , ,

Last week, the Eclipse plugin for JavaFX 1.2.1 was released. This is an important update since June 2009 and it is a good news to Eclipse users. Because Sun is the development force behind NetBeans, NetBeans naturally becomes the “default” IDE of JavaFX. This is why JavaFX SDK is usually bundled with NetBeans for download.


I think Eclipse and NetBeans both are excellent open source IDEs for Java developers. They provide comparable features and functions. The only sad thing is that their plug-ins are not compatible with each other. Therefore, the JavaFX plug-ins must be developed separately for Eclipse and NetBeans. I personally do not have much preference from one over the other. For people who get used to the Eclipse environment have been longing for a nice JavaFX IDE without being forced to switch to NetBeans. This newly released JavaFX plug-in not only provides the support of the latest SDK 1.2.1, but also can import NetBeans projects directly. You know this helps a lot because many sample codes are coming as a NetBeans project.


If you are a fan of Eclipse( and javaFX ), you should definitely check out this plug-in here:


http://javafx.com/docs/gettingstarted/eclipse-plugin/release-notes.jsp


Other links:

JavaFX Used in Vancouver Olympics

UK Citizenship Test for Britain Applicant
Australian Citizenship Test Practice Question

British UK Australian Citizenship test on iphone
US Citizenship Test Practise

Citizenship iPhone Apps


Comments (0) Jan 16 2010

JavaFX Online Game Prototype: Wish Tree (1)

Posted: under JavaFX Technology, Wish Tree.
Tags: , , , ,

I finished a JavaFX prototype of an online game, it is called “Wish Tree”. Strictly speaking, this prototype is not a game. Instead, it is an online multi-user application of fun (esp. for kids). However, it embodys all the essential elements of an online game: a JavaFX rich client for user interaction, a server handling communication among multiple clients, and a database for data persistence. Though it is still relatively simple, it lays a foundation of building an online multi-user game. I am going to demostrate in two posts how to design and write such an application in JavaFX, PHP and MySQL.


Not long ago, I wrote a JavaFX program for fun. You may have heard of the song “Tie a Yellow Ribon on an Old Oak Tree”, my program was called “Hang a Lucky Star on a Wish Tree“. It allowed people hang colorful stars on a tree to keep their wishes. The program was running as a standalone application. Recently, I added in some code to make it an online version. People all over the world now can share their wishes on the same tree.


This online version is a true RIA(Rich Internet Application) now. After a person leaves a lucky star on the tree, he/she can see the star next time she/he runs the program. People can see others’ wishes as well ( sorry, no privacy for now ^_^ ). However, an email address is needed to modify an existing wish.


The main architecture of the whole system is depicted in the below figure. First, the program gets started from a browser by Java Web Start technology. Then the program connects back to the server to obtain data and draws the wish tree hanging with stars. The server component retrieves data from the database and returns to the client. If the client makes a new wish, the data of the wish is sent to the server for persistence.


The requirements of the system are listed below:


1) On the client side, we need a browser that supports JavaFX 1.2. Basically, on our client machine we need JRE 1.5 +, or better with JRE 1.6 U13 later.

2) On the server side, we need a web server that supports PHP and MySQL. We can choose the popular “LAMP” stack (Linux, Apache web server, MySQL and PHP), but the two required things are ‘MySQL’ and ‘PHP’ only. In fact, in my development environment, I use Windows XP, Sun Java Web Server 7.0, MySQL and PHP plugin for JWS.


Before we get into any technical details, you can click on the below screenshot to start the JavaFX
client to see how it works. You can click on existing stars to see others’ wishes, or click on the tree
to leave your wish. Be sure to leave your email address so that you can modify your wish later. After you save your wish, you can check your wish next time you start the program. For testing purpose, please do not leave more than 2 wishes(stars).


click to start wish tree online program


Since this is a typical client/server application, let’s look at the JavaFX client first. A GUI is presented to the user for interaction. The Main.fx contains the main Windows(a Stage instance) of the application. We put in some images of trees and clouds on the stage. To make them look more realistic, the clouds are applied with the GaussianBlur effect.


The Bubble.fx defines a Bubble class which draws a bubble rising from the bottom of the stage. Animation is used to let the bubble eventually vanish into the tree. The Main class has a few instances of Bubble to create a boiling effect.


When the tree is clicked, a star is shown and a dialog is popup for the user to enter a wish. The
Star is a subclass of the Polyon class. It has a few pre-defined color schemes. The part of drawing a star is achieved by the following few lines, a little bit of geometry knowledge here:

  def r1 : Double = 15;
  def r2 : Double = r1 / 1.6;
  var r = [r1, r2];
  ... ...

    points = for ( i in [0..9] ) [
      r[i mod 2] * cos( toRadians(i*36) ),
      r[i mod 2] * sin( toRadians(i*36) )
    ];


The Dialog is a subclass of CustomNode which contains a few buttons and text fields. When the “OK” button of the dialog is pressed, the user’s wish is saved on the server. The user can also click on a star that’s already on the tree to view its content. If the user is the owner of the wish( based on the email address), the user can modify the content of the wish and then save it.


Finally, the class ServerConnector uses HttpRequest to communicate with the server and store wishes in the server’s database. We will walk through the server code next week and illustrate the data interaction between the server and the client.


If you are interested in the source code, you can visit the download page of this site. As shown in the architectural figure, there are source code of server side(Mysql and PHP) and client side(JavaFX), respectively. Be sure to read the file README.txt before you try the code.


If you have any questions, please leave your comments.


Next Article: JavaFX Online Game Prototype: Wish Tree (2)



Other articles on JavaFX:

JavaFX Scene in Swing       JavaFX API for Java

JavaFX Menu       How Java Code Calls JavaFX APIs ?

Review on Book “Essential JavaFX”


Comments (3) Aug 16 2009

Building Menu in JavaFX

Posted: under JavaFX Technology.
Tags: , , ,

The JavaFX APIs do not come with a menu GUI component. Perhaps the JavaFX team in Sun does not think it is an important thing in RIA. However, from time to time, developers are asking questions on how to build a menu bar from JavaFX. So I decided to write an example of the menu bar in JavaFX.

JavaFX provides us a class javafx.ext.swing.SwingComponent, which can wrap a SWING component into a JavaFX node. We know that we can build complicated menus in SWING. Therefore, we can wrap up the SWING menu items and put them into a JavaFX Stage. Let’s take a look at the below code:

/*
 * Main.fx
 * @author Henry Zhang   http://www.javafxgame.com
 */
package menutest;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;

import java.awt.event.*;
import javax.swing.*;
import javafx.ext.swing.SwingComponent;

var w : Number = 480 on replace { fxMenuBar.width = w ; } ;
var h = 300;
var selected = "";

var handler = ActionListener {
  public override function actionPerformed( e: ActionEvent ) {
    selected = e.getActionCommand() ;
  }
};

var menuBar = new JMenuBar();

var menu = new JMenu("Menu A");
menu.setMnemonic(KeyEvent.VK_A);
menuBar.add(menu);

var menuItem = new JMenuItem("Item A-1");
menuItem.setAccelerator(
    KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.ALT_MASK));
menuItem.addActionListener(handler);
menu.add(menuItem);

menuItem = new JMenuItem("Item A-2");
menuItem.setAccelerator(
    KeyStroke.getKeyStroke(KeyEvent.VK_2, ActionEvent.ALT_MASK));
menuItem.addActionListener(handler);
menu.add(menuItem);

menu = new JMenu("Menu B");
menu.setMnemonic(KeyEvent.VK_B);
menuBar.add(menu);

menuItem = new JMenuItem("Item B-1");
menuItem.setAccelerator(
    KeyStroke.getKeyStroke(KeyEvent.VK_3, ActionEvent.ALT_MASK));
menuItem.addActionListener(handler);
menu.add(menuItem);

menuItem = new JMenuItem("Item B-2");
menuItem.setAccelerator(
    KeyStroke.getKeyStroke(KeyEvent.VK_4, ActionEvent.ALT_MASK));
menuItem.addActionListener(handler);
menu.add(menuItem);

var fxMenuBar : SwingComponent = SwingComponent.wrap(menuBar);
fxMenuBar.width = w;
fxMenuBar.layoutX=0;
fxMenuBar.layoutY=0;

Stage {
    title: "JavaFX Menu Test"
    width: bind w with inverse
    height: h
    scene: Scene {
        content: [
          fxMenuBar,
          Text {
                font : Font {
                    size : 16
                }
                translateX: 50
                translateY: 100
                x: 10
                y: 30
                content: bind if ( selected == "" ) "Ready"
                         else "Menu clicked: {selected}"
            }
        ]
    }
}


In the code, we first constructed a menu bar with two menus. Each menu contained two menu items. This is the standard way in SWING to show a menu bar. The line below created a SwingComponent instance which acted as a wrapper of the SWING menu bar:

var fxMenuBar : SwingComponent = SwingComponent.wrap(menuBar);

The below 3 lines were used to keep the menu bar on the top of the window(Stage).

fxMenuBar.width = w;
fxMenuBar.layoutX=0;
fxMenuBar.layoutY=0;

In the Stage class, we can see that fxMenuBar was used like a normal JavaFX node. Since the window is resizable, we need to adjust the width of the menu bar so that it changes with the window. A trigger has been added on the variable w to adjust the width of the menu bar.

var w : Number = 480 on replace { fxMenuBar.width = w ; };

The actual binding to the window’s width was achieved by this statement:

Stage {
 ...
    width: bind w with inverse
 ...
}

Below is a screenshot of the program. You can use accelerators like Alt+1,2,3,4 to activate the menu items.


Related Articles:

JavaFX Scene Displayed in a Swing JFrame Window

Calling JavaFX Classes from Java Code

Comments (2) Jul 27 2009

JavaFX Scene Embedded in a Swing Window

Posted: under JavaFX Technology.
Tags: , , ,

In Stephen Chin’s open source project JFXtras, a JavaFX wrapper for Swing is included in the current release(V0.5). This wrapper allows us to put JavaFX GUI components into a SWING application. It is very useful for developers to integrate JavaFX GUI features with their Java Swing applications.


The JFXtras project comes with a sample test program( refer to SceneToJComponentScene.fx and SceneToJComponentTest.java). I suppose that Swing developers are probably interested in this topic, so I modified the code a bit and created the below example for better illustration purposes.


First we create a subclass of the Scene. Since the Scene class is the top level container in JavaFX , we can virtually place any GUI components in it and then make a reference to it from the java side. Let’s look at the code:

/*
 * MyScene.fx     http://www.javafxgame.com
 * @author Henry Zhang
 */

package swingtest;

import javafx.scene.Scene;
import javafx.scene.text.*;
import javafx.scene.paint.*;
import javafx.scene.shape.Rectangle;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;

def w = 500;
def h = 400;

public class MyScene extends Scene {
    var xx = w / 3;
    var yy = h / 2;
    var rotate = 0;
    var text = "";

    var tl = Timeline {

      repeatCount: Timeline.INDEFINITE
      keyFrames : [
        KeyFrame {
          time: 70ms
          action: function() {
             text = JavaFXToSwingTest.tf.getText();
             rotate = (rotate+5) mod 360;
          }
        }
      ]
     }

     override var content= [
        Rectangle {
            width: w, height: h
            fill: Color.BLUE
        },
        Text {
            font : Font {
                    size: 24
                   }
            layoutX: bind  xx
            layoutY: bind yy
            rotate: bind rotate
            content: bind text
            fill: Color.YELLOW
        }
    ];

    init { tl.play(); }
}


In the above MyScene.fx, we define a Timeline object to play an animation of a Text instance. Every 70ms, the text will be rotated by an angle of 5 degree. To demostrate the data exchange between JavaFX and java, we update the content of the text for each cycle of the animation. The line shown below is used to get data from a Java static variable:

text = JavaFXToSwingTest.tf.getText();


Though this is not an elegant approach to update data, we use it here for its simplicity. We will discuss more about this issue later. Now that we have a Scene class, we can work on the java class. The code of JavaFXToSwingTest.java is listed below:


package swingtest;

/**
 * JavaFXToSwingTest.java     http://www.javafxgame.com
 * @author Henry Zhang
 */
import java.awt.*;
import javax.swing.*;
import org.jfxtras.scene.SceneToJComponent;

public class JavaFXToSwingTest extends JFrame {

  public static JTextField tf = new JTextField("JavaFX for SWING");

  public JavaFXToSwingTest() {
    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("JavaFX in SWING Test");

    Container container = getContentPane();
    container.setLayout(new BorderLayout());

    String sceneClass = "swingtest.MyScene";
    JComponent myScene = SceneToJComponent.loadScene(sceneClass);

    JLabel label = new JLabel(" Below is a JavaFX Animation: ");
    container.add(label, BorderLayout.NORTH);
    container.add(myScene, BorderLayout.CENTER);

    JPanel p = new JPanel();
    p.setLayout(new FlowLayout());

    tf.setColumns(28);
    p.add(tf);
    p.add(new JButton("SWING Button"));

    container.add(p, BorderLayout.SOUTH);
    pack();
  }

  public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(
      new Runnable() {
        public void run() {
          new JavaFXToSwingTest().setVisible(true);
        }
      });
  }
}


The code should be quite straightforward for most Java(Swing) programmers. We used BorderLayout and FlowLayout to arrange a few Swing widgets inside a JFrame. There are two lines to create the JavaFX scene to be loaded into a JFrame:

    String sceneClass = "swingtest.MyScene";
    JComponent myScene = SceneToJComponent.loadScene(sceneClass);


The SceneToJComponent class comes from the JFXtras project. Its loadScene() method loads a JavaFX Scene class and returns a JComponent object, which can be used as a normal Swing JComponent. Running the program you will see a text “JavaFX for SWING” rotating in a window(JFrame). If you change the sentence in the input box, you will see the rotating text changes as well. If you have Windows media player installed on your machine, you can click on the below screenshot to watch a video on how the program runs.


DISCUSSION

1) In the above program, we use the JavaFX code actively poll the data from a Java variable. This may waste quite some processing cycles. We can let the Java code notify JavaFX object instead. This requires a technique of invoking JavaFX classes from Java code. Interested readers can refer to this article for details: Java Code to Call JavaFX Classes.


2) Some people may ask how we should compile and run the code. There are basically two approaches for compiling the code. The first is to use javafxc to compile both the Java and JavaFX code. The second is to use javafxc to compile the JavaFX code into a jar file and javac for the java code. To run the program, you can choose either the javafx or java command. You can refer to my article Calling JavaFX Classes from Java Code for more explanations.


3) The last thing I need to point out is that the JFXtras project uses some internal APIs of JavaFX to implement the loadScene() method. This implies that the code may break in future releases of JavaFX. However, as pointed out by Steve, using the JFXtras Swing wrapper could insulate you from the changes of JavaFX APIs (i.e. he will take care of the changes for you). I think Steve is the one we can bank on, because he always acts fast to keep up with the latest JavaFX version. :)


Please leave comments if you have any questions.


Comments (4) Jul 08 2009

Calling JavaFX Classes from Pure Java Code

Posted: under JavaFX Technology.
Tags: , , , ,

Just after the release of JavaFX 1.0, in one of my posts JavaFX and Java Interoperability, I discussed three possible approaches to invoke JavaFX features from the Java side. These approaches were:

1. The ScriptEngineManager class. It is based on JSR-223, the java scripting API, which allows a java program to call a script(such as JavaFX Script, javascript, perl).
2. The JavaFX reflection API. It can probably call any classes in JavaFX.
3. The JavaFX class implements a Java interface so that a Java program can invoke the JavaFX class via the interface.


The third one seems the most elegant way to call JavaFX from Java. However, there is a drawback: the program should start from the JavaFX side. The reason is that it is simpler to use JavaFX code to instantiate the JavaFX classes which can be passed to Java code. Nevertheless, in some scenario, it would be better to start the program from the java side. For example, if you want to add in some JavaFX features to an existing large java application, it is better to have java code as the entry point. To solve this issue, I am combining the essence of Approach 2 and 3 to create the below example.


Let’s say we want to invoke the latest charting functions of JavaFX 1.2 from the java code. We will first use the JavaFX reflection API to instantiate the JavaFX class. We then use it via its java interface. So we define a Java interface first.

/*
 * JavaInterface.java
 *
 * @author Henry Zhang      http://www.javafxgame.com
 */
package javatest;
public interface JavaInterface {
  public void addData(String name, float data);
  public void showChart();
}

The next step is to create a JavaFX class MyChart to implements this interface:

/*
 * MyChart.fx
 *
 * @author Henry Zhang     http://www.javafxgame.com
 */
package javatest;

import javafx.scene.chart.PieChart;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.scene.chart.PieChart3D;

public class MyChart extends JavaInterface {
  var chartData :  PieChart.Data[] = [];

  public override function addData( l:String, v: Number):Void {
    var labelString = l;

    var data =  PieChart.Data {
      label : l
      value : v
      action: function() {
        println("{labelString} clicked!");
      }
     } ;

    insert data into chartData;
  }

  public override function showChart() : Void {
    var chart =
      PieChart3D {
        data : chartData
        pieThickness: 25
        pieLabelFont: Font{ size: 9 };
        pieToLabelLineOneLength: 10
        pieToLabelLineTwoLength : 20
        pieLabelVisible: true
        pieValueVisible: true
        translateY: -50
     };

    Stage {
      title: "PieChart Window"
      width: 520
      height: 300
      scene: Scene {
        content: [
          Text {
            font : Font {
                    size : 16
                   }
            x: 200
            y: 20
            content: "Pie Chart"
          },
          chart
        ]
      }
    }
  }
}

The last thing is to write the java main class JavaTest.

/*
 * JavaTest.java
 * @author Henry Zhang    http://www.javafxgame.com
 */
package javatest;

import javafx.reflect.FXClassType;
import javafx.reflect.FXLocal;
import javafx.reflect.FXLocal.Context;
import javafx.reflect.FXLocal.ObjectValue;

public class JavaTest {
  public static void main(String args[]) {
    Context context = FXLocal.getContext();
    FXClassType instance = context.findClass("javatest.MyChart");
    ObjectValue obj = (ObjectValue)instance.newInstance();

    JavaInterface ji = (JavaInterface)obj.asObject();

    String [] labels = {"January", "Febuary", "March", "April"};
    int [] values = { 18, 20, 25, 37 };

    for ( int i=0; i < values.length; i++ ) {
      ji.addData(labels[i], values[i]);
    }

    ji.showChart();
  }
}



There are three lines in the above code to instantiate a JavaFX class via reflection:

    Context context = FXLocal.getContext();
    FXClassType instance = context.findClass("javatest.MyChart");
    ObjectValue obj = (ObjectValue)instance.newInstance();



The next line is to convert the JavaFX instance into a java interface so that it can be used by Java side:

    JavaInterface ji = (JavaInterface)obj.asObject();



If you are using NetBeans IDE, you can set javatest.JavaTest as the main class in your project properties. This makes sure that the entry point of your program is a java class. Build this project you will get a javatest.jar. Running this program produces the below screenshot:

Java PieChart via JavaFX


To run it from the command line, use the below command:

   javafx -jar javatest.jar


Actually, you could do it in the purest java style by including all the JavaFX runtime stuffs, the command would look like this:

 java -Djava.library.path="<path to javafx sdk lib>"
     -classpath "<all javafx sdk jars>" -jar javatest.jar



Since there are many jar files used by the JavaFX, this purest java approach turns out to be very troublesome. I would rather use the javafx command, which is a wrapper of the above java command.


Please leave comments if you have any questions.

This article is cross-posted at Pure Java Code to Call JavaFX Class. The Chinese translation can be found at http://www.javafxblogs.com.


P.S. Stephen Chin has released the JFXtras 0.5 version. In this project, a class SceneToJComponent is provided to load a JavaFX scence as a SWING component. Though it uses the internal method of the Scence class, it can insulate your code from future JavaFX change(i.e. Steve will take care of the changes for you. :) )


Comments (4) Jun 21 2009

How to Write Pac-Man Game in JavaFX(5)

Posted: under JavaFX Technology, pac-man.
Tags: , , ,

Yesterday, my last article of a series, “Writing the Pac-Man Game in JavaFX Part 5“, had been published on insiderRIA.com. This final article detailed the chasing algorithms of the ghosts. I think it is probably one of the most interesting things in the code.


When writing the game, there are a few points we need to consider before designing an algorithm of the ghosts, such as effectiveness, randomness, simplicity. You can refer to the article about considerations on these aspects. An excerpt from the article is listed below in blue text. It discussed the choice of a proper algorithm. This algorithm not only serves as the chasing logic, it can also control the escaping behavior of the ghosts.


. . . . . .
After some thinking, I found that the distance between a ghost and the Pac-Man is a good ranking metric. The shorter the distance is, the higher the score is given to a particular choice. The advantages of using the distance as a metric are obvious. It is very simple and can be caculated easily. Besides, this algorithm makes a ghost move in the direction that has the shortest distance to thePac-Man. To illustrate this algorithm, let’s look at the below figure.

In the figure, the ghost Blinky is moving into an intersection from the right to the left. When it reaches the intersection, it has three possible choices of its next movement: to go up, to go down and to continue heading left. Going down is not a valid move because it hits the border of the maze. So we need to compare the other two options. The below table shows the computation of the distance of the two possible moves:

Choice X distance Y distance Total
Intersection 3 10 13
Up 3 9 12
Left 4 10 14

As shown in the table, the distance from the intersection to the Pac-Man character is 13 (The distance between two adjacent dots is 1). If Blinky goes up, the distance is reduced to 12. If it heads left, the distance becomes 14. Therefore, going up seems a better choice for Blinky. In this way, Blinky should be able to get closer and closer to the Pac-Man and eventually catches him.


Of course, this simple algorithm does not take into consideration for the walls in the maze. For this reason, sometimes the calculated score does not in fact represent the shortest path. However, this inaccuracy makes the ghosts appear “stupid” in the game, which is the randomness we want to achieve in the behavior. So we are going to implement it in our code. We rewrite the class MoveDecision. When the function evaluate() calculates a score, it takes in two arguments: the reference to Pac-Man instance and whether the ghost is in a hollow state. The variable distance is used to compute the score. If the ghost is going after the Pac-Man character, the score is 500-distance, which means a shorter distance yields a higher score. If the Pac-Man is hunting the ghosts(when they are hollow), the score is caculated as 500+distance. This makes the ghosts running away from the Pac-Man.
. . . . . .


Now that all the articles had been published and I hope you enjoyed reading them. The game was originally written in JavaFX 1.0, and was compatible with JavaFX 1.1. Because multi-inheritance has been removed in JavaFX 1.2, I made some minor changes to the code. The abstract class MovingObject had been changed to mixin class. The code for JavaFX 1.2 can be download from JavaFX Game Download Page.


You can now click on the below image to play the completed Pac-Man game, it is based on the newly released JavaFX 1.2 . With the improved performance, the game runs very smoothly.


click to run

click to run

Related Articles:

Develop Games in JavaFX

JavaFX MineSweeper Demo Game

JavaFX Demo Game: LinkUP

WidgetFX Game Widgets: Pac-Man

My First JavaFX Game Demo

JavaFX Discussion Blogs

JavaFX Game Article

The Featured Articles on insideRIA.com:

May 14, 2009: Writing the Pac-Man Game in JavaFX - Part 1

May 21, 2009: Writing the Pac-Man Game in JavaFX - Part 2

May 28, 2009: Writing the Pac-Man Game in JavaFX - Part 3

June 4, 2009: Writing the Pac-Man Game in JavaFX - Part 4

June 11, 2009:Writing the Pac-Man Game in JavaFX - Part 5

Comments (0) Jun 13 2009

Pac-Man Widget for WidgetFX 1.2

Posted: under JavaFX News, JavaFX Technology, pac-man.
Tags: , , ,

To fully take advantage of the power of JavaFX 1.2, Stephen Chin just released the WidgetFX 1.2 API beta version. There is even a widget contest running until the end of July. [Update: Steve had released the WidgetFX 1.2 version on June 29. ]


Just before the JavaOne 2009, Jim Weaver asked me to write a widget for my JavaFX Pac-man game. The WidgetFX API was quite simple to use, so I finished it pretty soon. The game widget later got demo-ed on Jim and Steve’s JavaOne sessions. There was a small problem of the pac-man widget: it run relatively slow due to the performance issue of JavaFX 1.1. Since JavaFX 1.2 and WidgetFX 1.2 are ready now, I am modifying the code to see the improvement on performance.


First, the JavaFX code of the Pac-Man game needs to be modified a little bit for JavaFX 1.2. Since multi inheritance is gone, we need to use mixin classes now. You can refer to my articles on insideRIA.com for details of the code. Changes for JavaFX 1.2 were given on comments of Article 4 by Patrick Webster. I also added in a pausing key(”P” button) handling for the game. I compiled the game into a pacman.jar file.


The next step is to write the widget. Actually, the code is quite simple if you do not have stuffs like configuartion etc. Let’s look at the code below:

/*
 * PacManWidget.fx
 * http://www.javafxgame.com
 */

package pacmanwidget;

import org.widgetfx.Widget;

/**
 * @author Henry Zhang
 */

def defaultWidth = 528.0;
def defaultHeight = 576.0;

def maze =  pacman.Maze {};

var widget:Widget = Widget {
    width: defaultWidth
    height: defaultHeight
    aspectRatio: defaultWidth / defaultHeight
    content: maze
    resizable: false

    onDock: function():Void {
       maze.pauseGame();
    }
}

return widget;

In the standalone game, an instance of the Maze class was put into the content variable of a Stage. Now, instead of putting it into a Stage, we add it into a Widget. To do this, we can just set the content variable of a Widget instance. Other attributes of the Widget class are quite straightforward, mostly for resizing purposes. The next thing is to write a onDock() function to pause the game when the widget gets docked. The game can be resumed after pressing the “p” button when it is undocked.


The last thing is to deploy it on a web server. We need a JNLP file. Be sure to write the jnlp file of the JavaFX 1.2 style. Netbeans can generate the JNLP file which we can modify for deployment. I listed below part of my jnlp file. Besides the widget code PacManWidget.jar, there are supporting jar files( pacman.jar and WidgetFX-API.jar) under the /lib folder as well. Notice that there is a bug in the generated JNLP file by NetBeans 6.5.1: the <update> tag is missing a slash(/) at the end of the tag.


 . . . . . .
 <resources>
     <j2se version="1.5+" />
     <extension name="JavaFX Runtime"
        href="http://dl.javafx.com/1.2/javafx-rt.jnlp"/>
     <jar href="PacManWidget.jar" main="true"/>
     <jar href="lib/pacman.jar"/>
     <jar href="lib/WidgetFX-API.jar"/>
 </resources>
 <application-desc main-class="com.sun.javafx.runtime.main.Main">
    <argument>MainJavaFXScript=pacmanwidget.PacManWidget</argument>
 </application-desc>
 <update check="background" />
 . . . . . .


Now, you can click on the below button to start the Pac-man widget for JavaFX 1.2. Enjoy!


Pac-Man Widget 1.2



Comments (3) Jun 08 2009

How to Write the Pac-Man Game with JavaFX

Posted: under JavaFX Games, JavaFX Technology, pac-man.
Tags: ,

After the official announcement of JavaFX 1.0, I wrote a JavaFX program for the Pac-Man game. People were interested in the game. They either enjoyed playing or asked me for the details fo the JavaFX code. JavaFX expert Jim Weaver asked me to write some articles about the process of building the game. After a few weeks’ hard work, with Jim’s constructive ideas and great help in proofreading, I finished the articles. Now they are published on nsideRIA.com, an O’Reilly’s web site, as featured articles. There will be 5 articles in total and they will run through the coming 5 weeks.  

In each of the articles, there are web start links that you can click to start a JavaFX program to see how it works. If you follow the 5 articles, you will find out how the game is written bit by bit. I hope the articles can help people who want to learn JavaFX or want to develop games in JavaFX. Thanks Jim for making these articles possible.


Here are the links for the articles:


May 14, 2009:
Writing the Pac-Man Game in JavaFX - Part 1
May 21, 2009:
Writing the Pac-Man Game in JavaFX - Part 2
May 28, 2009:
Writing the Pac-Man Game in JavaFX - Part 3
June 4, 2009:
Writing the Pac-Man Game in JavaFX - Part 4
June 11, 2009:
Writing the Pac-Man Game in JavaFX - Part 5


Related Posts:
First JavaFX Demo Game: PACMAN

Articles on Writing JavaFX Pac-Man Game

JavaFX Demo Game: PAC-MAN

Comments (1) May 17 2009

JavaFX SyntaxHighlighter

Posted: under JavaFX Technology.
Tags: , , , , ,

In a modern IDE(Integrated Development Environment), such as NetBeans or Eclipse, syntax elements of a programming language are usually shown in different colors and styles. On a web page, there are tools for highlighting the keywords. They are either client side or server side tools. The SyntaxHighlighter is a client side(javascript) tool to display keywords of a programming language in a particular style(bold, different color etc). It supports quite a few languages such as Java, C, C#, VB, Ruby, javascript. While I was recently writing articles on JavaFX, I found it necessary to come up with a syntax highlighter for JavaFX.


I did some search and found the reserved keywords, then modified the shBrushJava.js to be shBrushJavaFX.js. Now my articles can have highlighted JavaFX syntax. For example:

package pacman;
import java.lang.Math;
import pacman.MazeData;
import pacman.PacMan;

/**
 * @author Henry Zhang  http://www.javafxgame.com
 */

public class MoveDecision {

  // x and y of an intended move
  public var x: Number;
  public var y: Number;

  // evaluate if the move is valid and its score if it's valid
  public function evaluate(pacMan:PacMan, isHollow:Boolean): Void {
    if ( x < 1 or y < 1 or y >= MazeData.GRID_SIZE
         or x >= MazeData.GRID_SIZE){
      score = -1;
      return ;
    }
  }
 . . .
}


If you are interested in using this JavaFX highlighter, you can download the brush file: shBrushJavaFX.js and the CSS file: SyntaxHighlighter.css. Information about the original SyntaxHighlighter 1.5.1 can be found here: SyntaxHighlighter .


For those who are intersted in the reserved words (keywords) of JavaFX, you can find it here. For your convience, I list them below:

abstract after and as assert at attribute before bind bound break
catch class continue def delete else exclusive extends false finally
first for from function if import indexof in init insert instanceof
into inverse last lazy mixin mod new not null on or override
package postinit private protected public-init public public-read
replace return reverse sizeof static step super then this throw
trigger true try tween typeof var where while with



Comments (0) May 02 2009

JavaFX and Java Interoperability

Posted: under JavaFX Technology.
Tags: , , , ,

[ 2009/06/22 Update: My latest article discussed how to use
Pure Java Code to Call JavaFX Class]



From the JavaFX blog, an article discussed the possiblity of invoking methods of JavaFX classes from Java. JavaFX can call Java code without any problem, however, the reverse is not supported by JavaFX. Doing some googling shows that programmers are trying all kinds of hacks to invoke a JavaFX class method from Java. You can check out an interesting article on reverse engineering of JavaFX classes. Even the example on JavaFX blog provided a hack to work around this.

 

So do we have the need of such kind of interaction between Java and JavaFX? I say it is a “YES”. If Java and JavaFX can be used interchangeably(when possible), this could give more life to JavaFX in the long run. Just consider the MVC design pattern, we can write an application by using Java and JavaFX together. The “M” and “C” part can be implemented in Java while the “V” can be done by JavaFX. It would be very interesting to see this.

 

Right now, there are a few “standard” ways to call JavaFX from Java:

1) Using the ScriptEngineManager class. From Geertjan Wielenga’s article, we can do it in this way:

package calc; 

import java.io.InputStreamReader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException; 

public class CalculatorLauncher { 

public static void main(String[] args) {
 try {
 ScriptEngineManager manager=new ScriptEngineManager();
 ScriptEngine engine = manager.getEngineByExtension("fx");
 InputStreamReader reader = new InputStreamReader
 (CalculatorLauncher.class.getResourceAsStream
 ("Calculator.fx"));
 engine.eval(reader);
   } catch (ScriptException ex) {
  }
 }
}

However, this is just like System.exec(”calc”) as pointed out by cronseaux. I agree with him. A even simpler way is to use System.exec(”javafx Calculator.fx”) to complete the above code. So this is not a good solution.

 

2) Manage to use java reflection to call JavaFX class methods. This one should work because JavaFX classes are compiled into Java classes and byte code. However, the complexity makes it almost unusable and code written in this way has no readability.

 

3) A third approach is to define an interface in Java and implement it in JavaFX. For example,

public interface JavaInterface
{ ... }

In MyJavaFXClass.fx, do something like:

public class MyJavaFXClass extends JavaInterface
{ ... }

In you java code, just invoke the JavaFX object directly using the interface. This approach can solve most of the interoperation issues. Just that an interface is needed for every JavaFX class which is going to be called from Java. Though it is very cumbersome, at least it is the best workaround I can find so far.

 

Since this is the first release of JavaFX, I don’t criticize much on this given the strong powerful features of JavaFX. I do hope the future releases of JavaFX can improve on this.

[ 2009/06/22 Update: Please refer to my latest article for discussion on: Pure Java Code to Call JavaFX Class ]

Comments (2) Dec 26 2008