Wednesday 1 December 2010

London Tube Lines application. Developed using JavaFX

Hello everybody.
As it could be noticed I haven't been posting for a while. It is due to my university courseworks, which keep me busy all the time, and my private project. This is the part I wanted to discuss. I don't know how many of you lives in London and is familiar with London Underground, but it should not be a problem in understanding my project.

In the past weeks I was working on developing desktop application that will show the current status of the underground lines in London. The application is not yet finished, but major part is codded already. Have a look at the main window:


The rectangle with grey shadow indicates that you can click on it and view information about the line (somehow my hand cursor didn't get caught on that shot...). The information is presented in the window which slides from the top and looks like that:



As you can see it does not show any information yet. It is the part to be yet implemented. It is worth to mention that data is updated from the TFL server through Tubeupdates API. The information to be displayed in the second screen shot is to be fetched straight from TFL through their feeds. And finally the application is purely implemented using JavaFX, I don't use any Java classes.

Once the application is finished, I'm planning to turn it to desktop widget using WidgetFX framework and release to the public:)

Please comment!!!

Thanks

JavaFX layout managers part I - HBox and VBox

After long absence from here I'm back again. This time I would like to talk about layout managers available in JavaFX. For starters, for those not familiar with layout managers, layout manager is responsible for laying out components of GUI in specified fashion. There are many of them available in JavaFX and each of them organises the content in different manner. In this post will describe HBox and VBox, which are very simple end basic. Even though they are very powerful tool in building layout of the application.


Lets start with HBox. This layout manager places the nodes on HORIZONTAL MANNER. Please take a minut consulting the API page for HBox, this will make it easier to understand the following example.
Link to API page: http://download.oracle.com/docs/cd/E17802_01/javafx/javafx/1.3/docs/api/javafx.scene.layout/javafx.scene.layout.HBox.html


As you saw, hopefully, in the API layout manager reside in javafx.scene.layout.* package. Do not forget to import it otherwise your application will not compile and you'll get an error.


Ok, now we are ready to see an example:






Code:


Stage {
    title: "HBox example"
    scene: Scene {
        width: 200
        height: 200
        content: HBox{
            padding: Insets { top: 20 bottom: 20 left: 20 right: 20 }
            spacing: 20
            content: [
                Text { content: "one" },
                Text { content: "two" },
                Text { content: "three"}
             ]
        } // HBox finish
    } // Scene finish
} // Stage finish


No a bit of explanation. As you can see from the code above the HBox has several variables that can be initialized in object literal, while creating an object of this class. The ones that are visible are:


padding - adds padding to the HBox. In the code above another class Insets is used that specifies the padding  at the top, bottom, left and right of the HBox instance


spacing - specifies the distance by which elements will be separated


content - contains the nodes to be positioned


There are many more available:

hpos - lets you specify the horizontal position of all nodes in a row, by default set to HPox.LEFT
vpos - same as above but in vertical manner, by default set to VPos.TOP
nodeVPos -  lets you specify the vertical position of the node, by default set to VPos.TOP
nodeHPos -  lets you specify the horizontal position of the node, by default set to HPox.LEFT




VBox is very simillar to HBox. In essence it contains exactly the same variables as HBox. Therefore slight change in code:


Stage {
    title: "HBox example"
    scene: Scene {
        width: 200
        height: 200
        content: VBox{
            padding: Insets { top: 20 bottom: 20 left: 20 right: 20 }
            spacing: 20
            content: [
                Text { content: "one" },
                Text { content: "two" },
                Text { content: "three"}
             ]
        } // VBox finish
    } // Scene finish
} // Stage finish


Will produce the following:




As you can see the HBox an VBox are very simple to use, but while combined can make powerful GUI. Of course there are many more which will be discussed in part I and part II.

That's all for now.

Cheers



Saturday 18 September 2010

How to position nodes using layoutInfo?

Hi guys,
Hope you all are doing ok. Today I’d like to describe another method of positioning nodes within a container. This time we will have a look at the layoutInfo variable and LayoutInfo class. Mentioned variable is accessible in any node in javafx. To be more specific layoutInfo is inherited from the “big daddy” Node class. The information stored in layoutInfo tell the container how to position the particular node within its bounds. Objects of LayoutInfo are used to describe what exactly we want to do with the node to position.

Before reading further it would be a great idea if you checked LayoutInfo class description in javafxdoc:



As always let’s have a look at the example:



From the picture above you can see that the application consists of two red rectangles one positioned in top left corner and the other in bottom right corner. They are exactly half of the width and height of the window. They also connected in the exact middle.  In addition, when we resize the window they keep the proportion:



I hope you more or less understand what the application does. The next step is to have a look at the code for this example:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Stack;
import javafx.geometry.VPos;
import javafx.geometry.HPos;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.layout.LayoutInfo;

var scene: Scene;

Stage {
    title: "Stack and LayoutInfo"
    scene: scene = Scene {
        width: 200
        height: 200
        content: [

            Stack {
                height: bind scene.height;
                width: bind scene.width;
                content: [

                    Rectangle {
                        width: bind scene.width / 2
                        height: bind scene.height / 2
                        fill: Color.RED;

                        layoutInfo: LayoutInfo {
                            vpos: VPos.TOP
                            hpos: HPos.LEFT
                        } // end LayoutInfo
                    } // end Rectangle

                    Rectangle {
                        width: bind scene.width / 2
                        height: bind scene.height / 2
                        fill: Color.RED;

                        layoutInfo: LayoutInfo {
                            vpos: VPos.BOTTOM
                            hpos: HPos.RIGHT
                        } // end LayoutInfo
                    } // end Rectangle
                ] // end Stack content
            } // end Stack
        ] // end Scene content
    } // end Scene
} // end Stage

From the listing above you can see that as a container I used Stack (discussed in previous post). I did it from one reason. Stack centres all of the nodes by default. It gives me perfect opportunity to demonstrate the power of layoutInfo. If we didn’t use this variable the application would look as follows:


I would also like you too notice that the height and width is calculated using bind statement. It assures that the rectangle will have half of the scene's height and width. 

Let’s concentrate on the one of the rectangles (one in top left corner):

Rectangle {
width: bind scene.width / 2
height: bind scene.height / 2
fill: Color.RED;

layoutInfo: LayoutInfo {
vpos: VPos.TOP
hpos: HPos.LEFT
} // end LayoutInfo
} // end Rectangle

In here you can see the variable layoutInfo with object of LayoutInfo class assigned to it. This class consists of many variables, which allow container to manipulate the node. The ones seen above are:

vpos – sets the vertical position of the node (in this example top). Expects constant value from VPos     class.
hpos – sets horizontal position of the node(in this example left). Expects constant value from HPos class.

In order to assign proper values we need to import two library classes:

javafx.geometry.VPos
javafx.geometry.HPos

Possible constant values for HPos ( from JavaFX API documentation ):

CENTER - Indicates centered horizontal position
LEADING - Indicates leading horizontal position, which means left in left-to-right context and right in a right-to-left context.
LEFT - Indicates left horizontal position.
RIGHT - Indicates left horizontal position.
TRAILING - Indicates trailing horizontal position, which means right in left-to-right context and left in a right-to-left context

On the other hand VPos provides following constants:

BASELINE - Indicates baseline vertical position.
BOTTOM - Indicates bottom vertical position.
CENTER - Indicates centered vertical position.
PAGE_END - Indicates vertical position at the end of the page, which means bottom in a top-to-bottom context and top in a bottom-to-top context.
PAGE_START - Indicates vertical position at the start of the page, which means top in a top-to-bottom context and bottom in a bottom-to-top context.
TOP - Indicates top vertical position.

Using these two variables gives us free choice of where to position particular node within container. 

Apart from the vpos and hpos LayoutInfo class consists of the following properties, which will allow further manipulation of the node:

minWidth – sets minimal allowed width of the node
minHeight – sets minimal allowed height of the node
maxWidth – sets maximal allowed width of the node
maxHeight – sets maximal allowed height of the node
height – sets height of the node
width – sets width of the node

There are more variables, but I’ll leave them for you to exploreJ

That would be all from me today. Hope you enjoyed the read.

Cheers

Wednesday 8 September 2010

How to centre nodes using Stack??

Hi guys,
Hope that your experience with Java FX is growing... Today I’m going to describe another way of centering  nodes in a container or Scene. This time I’ll describe the use of Stack using simple example. Stack class allows us to stack nodes on top of each other. It would be good if at this point you consult JavaFX API in order to better understand the example below. Here is the link:


Let’s begin with example. The outcome of the program looks as follows:


As you can or not see it consists of two elements. First one is Java FX text and second is the address of this very blog, positioned on top of the first element. It suggests that the Stack positions the nodes in back-to-front manner.

Now let’s look what happens when we resize the window:



The elements are still positioned in the centre and on top of each other. Have a look at the source code:
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Stack;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.paint.Color;
import javafx.scene.effect.DropShadow;

Stage {
    title: "Centering nodes - Stack"
    var scene: Scene;

    scene: scene = Scene {
        width: 500
        height: 200
        content: Stack {
           width: bind scene.width
           height: bind scene.height
           content: [
              Text {
                  font: Font.font(null, FontWeight.BOLD, 96)
                  fill: Color.LIGHTGREY
                  content: "JAVA FX"
              } // end Text

              Text {
                  font: Font.font(null, FontWeight.BOLD, 25)
                  fill: Color.LIGHTBLUE
                  effect: DropShadow {
                      color: Color.BLUE
                      radius: 5
                  } // end DropShadow
                  content: "www.javafxscripting.blogspot.com"
              } // end Text
           ] // end Stact content
        } // end Stack
    } // end Scene
} // end Stage


As you can see from the source code the object literal for Stack class is as follows:

Stack {
           width: bind scene.width
           height: bind scene.height
           content: [
                ....CODE OMMITED.....
                ]
}

There is nothing unusual about the code, so how the magic happens?? It is simple, Stack has two variables called nodeVPos and nodeHPos which are set to CENTER by default. Lets modify the code above and include the following:

Stack {
           width: bind scene.width
           height: bind scene.height
           nodeVPos: VPos.BOTTOM
           nodeHPos: HPos.RIGHT
           content: [
                ....CODE OMMITED.....
                ]
}

The outcome would be:



In order for the code to work the following libraries must be included:
import javafx.geometry.HPos;
import javafx.geometry.VPos;

I will not describe those at the moment, but you are free to explore them yourselfJ

The order in which the nodes are going to appear is dependent on how they are coded. The first one in the content variable of Stack will be displayed on the bottom. The rest will be displayed on top of the ones that are before them in content. Hope it made some sense;)
The width and height of the Stack is also bound to the scene. It is done so, because we want the Stack to resize with the window and keep the items in the correct position. You can set the variables to other values in order to position the stack whenever you want in the program

I used some effect with the second Text node in order to display the shadow. The class I used is DropShadow. It is one of many effects provided by JavaFX. I will not describe it in this post as I thing it is easy to understand. However, I would really advise you to explore the effect package of JavaFX. If you decide to do so, check the link below to JavaFX API:


I hope you will make use of the information above. If not, you can always ask?
Cheers

Thursday 2 September 2010

How to centre nodes using bind ??

Hi guys,
Haven't been here for a while... Fortunately I came back and I will drop some knowledge today.
I would like to describe one of the techniques used to centre nodes within the scene. In the following application I will use only bind statements, which enables me to keep the text centred even when the window has been resized.

Here you have the window before resizing:


... and here after the window has been resized:




As you can see the text is still in the centre position. It is achieved through using the bind statement. Below I'll reveal the "magic" in the source code:


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

Stage {
    title: "Centering Nodes"
    var scene: Scene;
    scene: scene = Scene {
        width: 400
        height: 100
        var textNode: Text;
        content: textNode = Text {
                layoutX: bind (scene.width - textNode.layoutBounds.width) / 2
                layoutY: bind (scene.height - textNode.layoutBounds.height) / 2
                textOrigin: TextOrigin.TOP
                font : Font.font(null, FontWeight.BOLD, 16)
                content: "www.javafxscripting.blogspot.com"
            } // end Text
    } // end Scene
} // end Stage


Most of the code should be clear for you guys as it was described in previous posts. If you cannot understand scroll below and read the posts. I will concentrate on the following piece of code, which keeps the text centred:


Text {
                layoutX: bind (scene.width - textNode.layoutBounds.width) / 2
                layoutY: bind (scene.height - textNode.layoutBounds.height) / 2
                textOrigin: TextOrigin.TOP
                font : Font.font(null, FontWeight.BOLD, 16)
                content: "www.javafxscripting.blogspot.com"
} // end Text


layoutX and layoutY is responsible for positioning the node at the proper coordinates. In this case  they are both calculated. As you can remember bind "glues" two variables together. In the listing both layoutX and layoutY is dependent on the product of:

 (scene.width - textNode.layoutBounds.width) / 2

and

(scene.height - textNode.layoutBounds.height) / 2.

Those are in turn dependent on the width and height of the scene. Therefore, every time the we resize the window the values change and the position of the text is calculated again and text moved to the appropriate position. Simple...

I know what you wan to ask now. What the hell is textNode.layoutBounds.height and textNode.layoutBounds.width??  
The answer is very simple as well. textNode is a reference to the text node(see listing above). layoutBounds is responsible for holding information about the borders of the particular node. This example uses the width and height in order to calculate the position in which drawing should begin.

That's all for now. Hope you all can work something out from the example above. If not.... why not ask a question?

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