dimanche 29 novembre 2009

JavaFX Style Sheet with my custom component

Because my custom component doesn’t have a Mac look and feel (the rounded corners of the TextBox) and because I don’t want to change the code of my component, I decided to create a Mac Style Sheet.

Now, let us study the Mac style sheet and the code to use this style sheet

the Mac style sheet - mac.css

.searchTextBox {corner-radius: 25;padding-left: 10}

To have a rounded corners of the textbox, I use the CSS attribute corner-radius and to move the position of the input cursor (because of the rounded corners), I use the CSS attribute padding-left

To use this CSS just set the style sheets attribute of your Scene with the location of your CSS file.

    scene: Scene {
        stylesheets : ["{__DIR__}resources/mac.css"]

The code of the demo (the code of the custom component doesn’t change)

resources\mac.css
/* 
    Document   : style
    Created on : 3 oct. 2009, 00:34:05
    Author     : paddy
    Description:
        Purpose of the stylesheet follows.
*/

.searchTextBox {corner-radius: 25;padding-left: 10}
.searchTextBoxRed{corner-radius: 25;padding-left: 10;border-fill:#FF0000;}

Main.fx
/*
 * Main.fx
 *
 * Created on 3 oct. 2009, 00:44:05
 */

package customcomponentcssdemo;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton;

import javafx.scene.control.ToggleGroup;

/**
 * @author Patrick
 */

class ExtRadioButton extends RadioButton {
    public var action:function();

    override public var selected on replace {
        if (selected) {
            action();
        }
    }
}

def macStyleSheet="{__DIR__}resources/mac.css";
var stylesheets:String = macStyleSheet;

Stage {
    title: "Application title"
    width: 250
    height: 200

    var cssToggleGroup = ToggleGroup {};

    scene: Scene {
        //stylesheets : ["{__DIR__}resources/mac.css"]
        stylesheets : bind stylesheets
        content: [
            Text {
                font : Font {
                    size : 16
                }
                x: 10
                y: 30
                content: "Search "
            }
            SearchTextBox {
                    //styleClass : "searchTextBoxRed"
                    translateX :10
                    translateY :40
                    

                    onResetSearch:function(){
                        println("reset !");
                    }
                    onSearch:function(s: String){
                        println("Search of : {s}");
                    }
            }
            Button {
                    text: "just a button to change focus"
                    translateX :10
                    translateY :80
                    action: function() {
                        println("Hello !")
                   }
            }

            ExtRadioButton {
                            text: "do not use the CSS"
                            translateX :10
                            translateY :110
                            toggleGroup: cssToggleGroup
                           // selected: true

                            action: function() {
                                stylesheets = " ";
                            }
            }

            ExtRadioButton {
                            text: "use the CSS"
                            translateX :10
                            translateY :130
                            toggleGroup: cssToggleGroup
                            selected: true

                            action: function() {
                                stylesheets = macStyleSheet;
                            }
            }
        ]
    }
}

dimanche 15 novembre 2009

Les technologies RIA (Flex/Silvelight/JavaFX) hors et dans le navigateur

Toujours dans l'article sur les RIA du magazine Programmez n°124, il est dit que les 3 technologies RIA (Flex, Silverlight et JavaFX) peuvent fonctionner hors du navigateur et même que Silverlight hors du navigateur et équivalent à Adobe Air.
Que ces 3 technologies puissent fonctionner hors du navigateur est vrai, par contre dire que Silverlight hors du navigateur et équivalent à Adobe Air ce n'est pas vraiment exact.
Aussi, j'aimerais apporter quelques précisions (non exhaustives) sur ces technologies RIA hors du navigateur (et dans le navigateur aussi pour comparer ;) ).

Silverlight

Le mode hors du navigateur de Silverlight 3 est très limité, en effet une application Silverlight 3 s'exécutant hors du navigateur s'exécute aussi dans une sandbox, la même sandbox (et même runtime) que celle utilisé par le navigateur quand l'application s'exécute dans le navigateur.
L'application ne peut donc pas accéder aux ressources la machine ce qui est très limitant pour écrire une application desktop.
Pour écrire une vraie application desktop avec accès aux ressources de la machine, il faut utiliser WPF (uniquement Windows) qui diffère de Silverlight.
Microsoft propose d'ailleurs un très bon whitepaper comparant les WPF et Silverlight. http://wpfslguidance.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28278

Flex AIR et Browser

Flex étant à la base une technologie pour écrire des applications s'exécutant dans le navigateur, Adobe a dû créer AIR pour pouvoir écrire des applications hors du navigateur.
Adobe AIR permet d'utiliser les ressources de la machine, contrairement à Silverlight, et d'écrire de vraies applications desktop en Flex.
Pourtant, il ne faut pas croire qu'une application écrite en Flex pour le navigateur va pourvoir fonctionner directement sur le desktop (hors du navigateur) car :
  • Le runtime Air est différents du player Flash pour le navigateur
  • Une application Flex/AIR est différente d'une application Flex pour le navigateur comme le montre ces 2 petits exemples de l'application Hello World pour Flex/AIR et Flex/navigateur.
    (Air utilise le tag WindowedApplication pour créer sa fenêtre alors qu'une application Flex utilise le tag Application)
Application Flex/AIR
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" title="Hello World">

<mx:Script>
<![CDATA[
         private function hello():void{
              myText.text = "Hello world !";
         }
      ]]>

</mx:Script>

<mx:Text id="myText" x="10" y="10" text="..." width="209"/>
<mx:Button x="154" y="36" label="Click me" enabled="true" click="hello()"/>

</mx:WindowedApplication>



Application Flex Brower
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>
<![CDATA[
         private function hello():void{
              myText.text = "Hello world !";
         }
      ]]>

</mx:Script>

<mx:Text id="myText" x="10" y="10" text="..." width="209"/>
<mx:Button x="154" y="36" label="Click me" enabled="true" click="hello()"/>

</mx:Application>

  • La compilation se fait avec la commande mxmlc pour une application Flex navigateur, alors qu'il faut utiliser amxmlc pour une application AIR.
    En fait amxml n'est qu'un batch qui exécute mxmlc avec l'option +configname=air pour compiler une application Flex/AIR avec ses spécificités.

JavaFX

JavaFX est la technologie la plus en avance sur l'exécution dans le navigateur et hors du navigateur. En effet, JavaFX :
  • utilise le même runtime (JRE) que se soit pour une application desktop ou pour une application dans le navigateur.
  • peut accéder, pour une application desktop, aux ressources de la machine comme une application java classique (lors son exécution dans le navigateur, il utilise une sandbox comme une applet java classique)
  • utilise le même SDK et les mêmes APIs que l'on écrive une application desktop ou une application pour le navigateur web. (le code JavaFx est identique dans les 2 cas)
  • utilise le même compilateur pour compiler une application JavaFX desktop ou navigateur (javafxc)
Récapitulatif
Runtimes navigateur et hors navigateur identiques Accès aux ressources de la machine en mode hors du navigateur Code identique pour écrire une application navigateur web ou desktop Compilateur/ SDK identiques
Silverlight oui non oui oui
Flex non oui non non
JavaFX oui oui oui oui

jeudi 5 novembre 2009

A propos de l'article sur les RIA du magazine Programmez n° 124

Je viens de lire l'article du magazine Programmez n°124 sur les RIA...
Et il y a plein de choses avec lesquelles je ne suis pas d'accord …
Mais le plus gros problème est l'exemple Hello World en JavaFX
Je ne sais pas ce qu'a voulu faire l'auteur, mais c'est clair qu'il ne connait pas JavaFX !

Pour pouvoir comparer un minimum les technos, j'ai donc réécrit cet exemple de deux manières différentes :

  • en utilisant le biding
  • en utilisant une méthode proche des exemples Flex et Silverlight

Et bien sûr, ces 2 exemples fonctionnent aussi bien dans le browser que en en dehors du browser

Méthode utilisant le binding

Main.fx
package helloworldprogrammez;

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

/**
 * @author patrick
 */
var text="...";

Stage {
    title: "Hello World"
    width: 400
    height: 200
    scene: Scene {
        content: [
            Text {
                font : Font {
                    size : 12
                }
                x: 10
                y: 10
                content: bind text
            }
            Button {
                text: "Click me"
                translateX: 154
                translateY: 36
                action: function() {
                    text="Hello world !"
                }
            }
        ]
    }
}

Méthode proche des exemples Flex et Silverlight

Main2.fx
package helloworldprogrammez;

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

/**
 * @author patrick
 */

Stage {
    var t:Text;

    title: "Hello World"
    width: 400
    height: 200
    scene: Scene {
        content: [
            t = Text {
                font : Font {
                    size : 12
                }
                x: 10
                y: 10
                content: "..."
            }
            Button {
                text: "Click me"
                translateX: 154
                translateY: 36
                action: function() {
                    t.content="Hello world !"
                }
            }
        ]
    }
}