Thursday, 17 June 2010

RGB colour mixer application

Couple of days ago I described the Hello World application. Today I'd like to describe something more complicated. It is a colour mixer application. There will be a rectangle which colour will be controlled by three sliders. They will represent Red Green Blue values making up the background. I aim at demonstrating some the important concepts of JavaFX. One of them is binding, second is mouse event and finally the layout manager. The application looks like this:


And that's the way it looks after the sliders have been moved:


and here is the code:


import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.control.Slider;
import javafx.scene.paint.Color;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.scene.input.MouseEvent;

var sceneRef: Scene;
var r: Number = 255;
var g: Number = 255;
var b: Number = 255;

Stage {
    title: "RGB colour mixer"
    width: 270
    height:250
    resizable: false
    scene: sceneRef = Scene {
        fill: Color.LIGHTGRAY
        content: [
            Rectangle {
                 layoutX: 190
                 layoutY: 20
                 width: 50
                 height: 180
                 arcWidth: 20
                 arcHeight: 20
                 fill : bind Color.rgb(r, g, b)
                 onMouseClicked: function(me: MouseEvent): Void {
                     r = g = b = 255;
                 }
            },
          
            VBox {
                spacing: 15
                layoutX: 20
                layoutY: 20
                content: [
                        Text {
                            content: bind "Red value: {r}"
                            font: Font.font("Sans Serif",FontWeight.BOLD, 14)
                        },

                        Slider {
                            min: 0
                            max: 255
                            vertical: false
                            value: bind r with inverse
                        },

                       Text {
                            content: bind "Green value: {g}"
                            font: Font.font("Sans Serif",FontWeight.BOLD, 14)
                        },

                       Slider {
                            min: 0
                            max: 255
                            vertical: false
                            value: bind g with inverse
                        },

                       Text {
                            content: bind "Blue value: {b}"
                            font: Font.font("Sans Serif",FontWeight.BOLD, 14)
                        }
                       Slider {
                            min: 0
                            max: 255
                            vertical: false
                            value: bind b with inverse
                        }
                    ]
            }
        ]
    }
}

Now, that you've studied the source code let me explain it. Like always we start with import directives. There are some new libraries that needed to be imported:


import javafx.scene.control.Slider; // slider
import javafx.scene.layout.VBox;  // VBox layout manager
import javafx.scene.shape.Rectangle; // allows us to draw rectangle
import javafx.scene.input.MouseEvent; // controls mouse events

I think it is straightforward why we need them. In case you need some more information on the classes imported refer to the JavaFX API documentation.
After the import there we have variable declaration. I described two posts ago how we define the variables. As you see we create variable sceneRef of the Scene class. I put it in there so that you can see that the we can create variables of Scene and Stage and then refer to them in the script. The following code: 

scene: sceneRef = Scene {
// code omitted
}

initialises the sceneRef object and assigns it to the scene variable of Stage class. Later in the program we can refer to the Scene using the name sceneRef. It might be the case when we want to change one of the Scene's variables like fill. Without it we would not be able to alter any properties of the Scene.
So far the space to draw has been created. Next step is to place graphical nodes on the surface. As I mentioned in the previous post all nodes are assigned to content variable of Scene. First of them is Rectangle:


Rectangle {
                 layoutX: 190
                 layoutY: 20
                 width: 50
                 height: 180
                 arcWidth: 20
                 arcHeight: 20
                 fill : bind Color.rgb(r, g, b)
                 onMouseClicked: function(me: MouseEvent): Void {
                     r = g = b = 255;
                 }
 }

Rectangle class provides us with facilities to draw a rectangle shape on the screen.As you can see from the object literal above it has number of variables, which allow us to manipulate the shape:

layoutX - x coordinate on the screen, where drawing should begin
layoutY - y coordinate on the screen, where drawing should begin
width - width of the shape
height - height of the shape
arcWidth - width of the rectangle's round corners
arcHeight - height of the rectangle's round corners
fill - colour of the rectangle. In this point we use bind expression. I will explain it below
onMouseClicked - action listener responsible for mouse events

JavaFX has something what is called bind expression. It is very simple but very useful tool. Basically what it does is to glue two variables together.If the variable that is bound to other variable changes the other variable's value is changed as well. In the example code above we've got:

fill : bind Color.rgb(r, g, b)

fill variable is bound to the product of Color.rgb() method. Furthermore, the product depends on r,g and b variables which correspond to values hold by sliders. Every time any of the sliders is moved the corresponding value is updated, this results in the function Color.rgb() being invoked and fill variable updated. At the end what we see is that colour of the rectangle changes. I hope you more or less understand what binding is. If not do not worry as there will be simpler examples in the future (I think).
In the example above we also have action listener, which is assigned to onMouseClicked variable:


onMouseClicked: function(me: MouseEvent): Void {
        r = g = b = 255;
 }

Here we have anonymous function, which return type is Void and which takes parameter me of type MouseEvent. If you have ever worked with UML you should notice that declaration of types of variables are the same in JavaFX as in UML. The mentioned anonymous method is invoked every time we click on the rectangle. The result of its action is to bring the values of the sliders back to 255. Binding is responsible for the sliders to move back to the position where they were when program was first started up and changing the fill colour of the shape to white.

Another object on the scene is VBox:

VBox {
                spacing: 15
                layoutX: 20
                layoutY: 20
                content: [
                            // code omitted
                 ]
}

VBox is on of the JavaFX layout managers. It is responsible for placing elements in vertical manner. As you can guess there is also manager to place nodes on horizontal manner called HBox. There is couple more layout managers, which you can find by studying JavaFX API. Let's have a look on the variables in the example:

spacing - sets the space in pixels between two nodes
layoutX - x coordinate of the beginning of the layout manager
layoutY - y coordinate of the beginning of the layout manager
content - here we place all the nodes that we require to be place in vertical manner

We can place nodes and other layout managers inside the content sequence. As I mentioned in the previous post content is sequence of type Node, which in turn is the grandfather of every class in JavaFX. This allows us to assign any object to the content.

Inside the VBox object we have text and sliders. I will discuss one example of slider as they are all the same. I will skip the Text class as it was already discussed in the Hello World application post.

Here we go, the Slider object:

 Slider {
         min: 0
         max: 255
         vertical: false
         value: bind r with inverse
 }

The variables represent:

min - minimum value of slider's range
max - maximum value of slider's range
vertival - is the slider to be drawn verticality
value - holds value of the slider

As you can see incorporating slider in the program is very simple task. In the above listing you can see that the value of slider is bound with the variable r. As you noticed we added "with inverse" after the variable name. It means that the variables will change if any of them is changed. We can amend the variable r somewhere in the program and at the same time the slider value will be changed and the point on the slider moved to correct position.

There is one more thing I would like to mention. In the Text objects there is the following line:

content: bind "Red value: {r}"

The signs{} are used when we want to display the value of the variable within the string of characters.

That's all for now. I've got some interesting examples coming up next, so stay tuned. Remember that the best way to learn language is to write programs in it. You should try to experiment!! Good luck:)


Friday, 28 May 2010

Hello World!!

 It is almost a tradition in programming that first application you write is Hello World.  According to it here we go, our first application:



It is possible to print the Hello World in the console, but as I mentioned before JavaFX is designed to produce quality GUI. Based on that the decision on moving straight to graphics. Below is the listing of source code:

// Imports
import javafx.stage.Stage; 
import javafx.scene.Scene; 
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.StageStyle;

Stage {
    title: "Helo world"
    width: 200
    height: 200
    scene: Scene {
        fill: Color.ORANGE
        content: [
            Text {
                layoutY: 80
                layoutX: 20
                fill: Color.BLACK
                font: Font.font("Serif", FontWeight.BOLD, 20);
                content: "HELLO WORLD"
            } // Text end
        ] // content end
    } // Scene end
} // Stage end

Let's start the description of the code. The first couple of lines starting with keyword import are responsible for importing needed library classes. There is many classes available for you in the JavaFX API. The number of them still grows as it is fairly fresh language. It is important to have JavaFX API handy while programming. You can find all needed information in there.

After the import there is Stage:

Stage {
    title: "Helo world"
    width: 200
    height: 200

 // code omitted
}
 It is object of class Stage. This class provides us with the window for our application. It can have different styles. It can provide us with basic window buttons like close button or it can be completely undecorated. If you have experience in Java GUI programming, the easiest way to think about Stage is as Java's Window class. In the listing above we can see three variables:

title - which sets the title of the application in the caption bar
height - sets the height of the window in pixels
width - sets the width of window in pixels

Again, there is many variables available in Stage class that are not used in this example. Some of the will be encountered in the future. I want to draw you attention to the way we assign the values to the variables. We use the ":" sign. We use it when we deal with object literals. The above declaration is an object literal. It is similar to the constructor in Java. On the other hand we use "=" sign when we are assigning values to variables we declared in the application.

Ok, so far we've got window. Next thing we need is the surface to draw on. Class Scene provides us with the container for the graphical nodes we want to draw:

scene: Scene {
        fill: Color.ORANGE
        content: [
           // code omitted
           ]
     }

What we've got here is pretty simple. There is another object literal of class Scene, which is assigned to Stage's variable scene. There are two variables used:
fill -  which is responsible for painting the background of the node, we used the Color class to paint the        background in the orange color
content - this hold nodes which are to be painted within the scene.

As you probably noticed the variable content has a square brackets [ ]. This means that content is a sequence. Sequences are very similar to arrays in Java and C++. If you look at the JavaFX API you will notice that content is a sequence of type Node[]. Well , the question is what is Node[ ]. The Node is a father of everything. All classes subclass Node. It is the same case as Object in Java language. It ensures that every node can be stored within content variable.The [ ] denotes that the sequence is expected. 


Are you following so far? It is really not difficult once you get a grasp on it. Let's move on. The only node within content is Text node:

Text {
     layoutY: 80
     layoutX: 20
     fill: Color.BLACK
     font: Font.font("Serif", FontWeight.BOLD, 20);
     content: "HELLO WORLD"
}

This object allows us to paint text on the scene. In here we have couple of variables:
layoutY - y coordinate of the place where the drawing should begin
layoutX - x coordinate of the place where the drawing should begin
fill - responsible for the colour of the text
font - sets the font of the text. In here we used the Font.font() syntax. I specifies the family of the font ot be used, its style and the size.
content - which is the text we want to be displayed

There is many more variables available in every of the mentioned class. If you want to know more please refer to the language API.

One more note. We specified the height and width of the Stage to be 200px. The Scene can also have this values assigned. Remember that the variables should be greater for Stage as it holds caption bar and borders of the window. It is a good practice to set these variables only for Scene, therefore forcing JVM to calculate the values for height and weight of the Stage.


Enjoy!

Cheers

Thursday, 27 May 2010

JavaFX introduction to variables

JavaFX variables are a bit different from other languages e.g. Java and C++. They are more like in PHP. You do not need declare the type of the variable. The compiler is clever enough to do it for you. So there are two ways in which you declare variables.
First of them, which allows you to declare variable that you will be able to change during the course of application:

var myVar;
var myVar = 0;

Second of them, which allows you to declare the variables that cannot be changed (something like final in Java):

def myVar;
def myVar = 0;

Above I sad that variables with def cannot be changed. It is not entirely true. JavaFX provides mechanism called binding, which allows two variables to be connected. I'll not discuss it in here. It'll be described soon in the future.

At the beginning I wrote that you do not need to declare the type of the variable. You can do it if you want. Here is the way you do it:

var myInteger: Integer;
def myInteger: Integer = 0;

In that case the myInteger is declared to hold Integer value.
Similarly to other languages JavaFX has the following data types:
Boolean
Short
Byte
Integer
Number
Double
String
Character
Duration
etc.

If you want in depth description of them, you should consult JavaFX API:

http://java.sun.com/javafx/1.3/docs/api/

I would point your attention to the Number type. In the current version of the language this type behaves the same as Java's Float. The other type is Duration, which stores values like:
60s
5m
1h
They represent the time duration. Once again it is wise to search the API for in depth description.

The same as Java, JavaFX assigns default values to variables which haven't been initialized with a value. Number gets 0.0, String "", Integer 0 and any reference type is initialized with null.

Cheers

JavaFX scripting Welcome

Hello everybody,
Recently I started learning the JavaFX scripting language, the new kid  of Sun Microsystem. I decided that I will set up this blog in which I will present concepts of JavaFX in simple way. I'll describe syntax and logic behind the language as well as post simple JavaFX applications. Each of the will be accompanied by description of what the code do. Hopefully, we all will learn something new.

So what is JavaFX you might ask. Simply saying is scripting language that allows us to build Rich Internet Applications. It provides programmers with facilities to build really fancy UI. In addition applications written in this language can be run stand-alone on the desktop, they might be run in the browser and to surprise you, in the mobile phone. You do not need to change too much as most of the processing is handled by JavaFX engine. If you wish to get more information, you should have a look in here:


You'll find many interesting information on that site. 
Anyway, that's all for now. Watch out for new posts!

Cheers.