Go back to JavaFX

In a previous post i said JavaFX lack was a design tool to promote a good relationship between developers and designers, essential for membership of the community around this technology. Knowing that designers will not change tools easily the best approach would be to make a bridge between the existing design tools and JavaFX. That is the purpose of Project NILE by offering a Illustrator and Photoshop plugin to export a FXD or a FX file but also a SVG converter and a graphic viewer.
It’s the good strategy i think, so I realized a test.

To enhance collaboration designer / developer I went looking for graphic work on the net, I found « glossy » buttons proposed in .ai and .svg.
alphabet_glass_bars
The SVG test was not good, the conversion did not include the effects and a lot of corrections were needed to compile. I continued with a conversion via Illustrator. The first shot will not compile because I am european ;). In the second time it compiles and the result is almost identical to the .ai document. Just a slight color problem quickly corrected.
The FX script is composed of a set of SVGPath, each character of the keyboard is also defined in a SVGPath. A little difficult to operate as it would be more practical to extract a component and to apply behavior as typically a mouse click and passing it in setting its position and character to display.
I extract in script the definition of a button I replace the SVGPath character by a Text component. I add a click event on the mouse and I change the effect when the mouse button is pressed.

GlassButton.fx

package testfx1;

import javafx.scene.*;
import javafx.scene.geometry.*;
import javafx.scene.image.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import javafx.scene.effect.*;
import javafx.input.MouseEvent;
import javafx.scene.transform.*; 
public class GlassButton extends CustomNode {
    public attribute letter:String;
    public attribute onClick:function(t:String):Void;
    public attribute x:Integer;
    public attribute y:Integer;
    protected function create() : Node {
        var effect = DropShadow { offsetX:0.0,offsetY:1.0,color:Color.BLACK,radius:8.0};
        return Group {
            translateX: x
            translateY: y
            content: [
                SVGPath {
                    effect: bind effect
                    fill: LinearGradient{proportional: false startX: 21.00 startY:35.00 endX: 21.00 endY: 5.00 stops: [
                            Stop {offset: 0.000 color: Color.rgb(0xd2,0xd2,0xd2,1.0)},
                            Stop {offset: 0.500 color: Color.rgb(0x4e,0x4e,0x4e,1.0)},
                            Stop {offset: 1.000 color: Color.BLACK},
                        ]}
                    content: "M36.00,27.00 C36.00,31.42 32.42,35.00 28.00,35.00 L14.00,35.00 C9.58,35.00 6.00,31.42 6.00,27.00 L6.00,13.00 C6.00,8.59 9.58,5.00 14.00,5.00 L28.00,5.00 C32.42,5.00 36.00,8.59 36.00,13.00 Z "
                },
                SVGPath {
                    fill: Color.GRAY
                    content: "M34.00,22.77 L8.00,22.77 L8.00,14.00 C8.00,9.86 11.55,6.50 15.92,6.50 L26.08,6.50 C30.46,6.50 34.00,9.86 34.00,14.00 Z "
                },
                Text {
                    fill: Color.WHITE
                    font: Font { 
                        size: 18 
                        style: FontStyle.BOLD
                    }
                    x: 14, y: 27
                    content : letter
                }
            ]
            onMouseClicked: function( e: MouseEvent ):Void {
                onClick(letter);
            }
            onMousePressed: function( e: MouseEvent ):Void {
                effect = null;
            }
            onMouseReleased: function( e: MouseEvent ):Void {
                effect = DropShadow { offsetX:0.0,offsetY:1.0,color:Color.BLACK,radius:8.0};
            }
        };
    }
}

Then I create a second class will manage the position of keys looping over an array of characters.

Keyboard.fx

package testfx1;
import javafx.scene.*;
import javafx.scene.text.*;
import javafx.scene.paint.*;

public class Keyboard extends CustomNode {
    public function create():Node {
        java.lang.System.out.println("BuildLetters …");
        var t:String;
        var letters = [
            "A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R",
            "S", "T", "U", "V", "W", "X", "Y", "Z", "@"
        ];
        var buttons:Node[] = [
            Text {
                font: Font { 
                    size: 14 
                    style: FontStyle.PLAIN
                }
                x: 5, y: 16
                content: bind t;
            
            }
        ];
        var posX:Integer = 0;
        var posY:Integer = 0;
        var incI:Integer = 0;
        var incJ:Integer = 0;
        for (i in letters) {
        if (
            incI mod 9 == 0) {
                posY = 35 * (incJ ++ ); 
                posX = 0;
                incI = 0;
            } else {
                posX = 35 * incI;
            }
        insert GlassButton {
                x: posX
                y: bind 45 + posY
                letter : i
                onClick : function(s:String) {
                    t += s;
                }
            } into buttons;
        incI++;
        }
        java.lang.System.out.println("OK.");
        return Group {
            content : buttons
        }
    }
}

And then I put it all into an Applet following James Weaver advise.

GlassButtonApplet.fx

package testfx1;
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.text.*;
import javafx.scene.paint.*;

Application {
    stage: Stage {
        content: Keyboard {}
    }
}

Below the result, click on the keys and put the Applet out of the browser by pressing the Alt key and dragging the Applet. The launch time is long be patient (30s), I don’ t know why right now, I will ask Sun.

Note: being able to put the Applet off the browser, it require to create a JNLP and therefore to sign all jars depending on the applet. A little boring, it is necessary to automate this task:

  1. certificate creation: keytool-genkey [-keystore ]-alias
  2. JAR signing: jarsigner [-keystore ] . jar

Conclusion
By putting all the time spent in developing it take about 4 hours, including learning of JavaFX. This is correct but it would be nice to further reduce this time. I believe that it is difficult to manipulate JavaFX without at least one real-time viewer. One provided in NetBeans 6.1 is a little slow.
Finally, the idea is there and it is promising because with the Java Plugin to 4MB will finally have rich full Java apps that take advantage of being able to do more than the competition: access to serial devices, Bluetooth, … on the client, using existing Java APIs (eg JMS), switch to desktop app…

Une réflexion sur « Go back to JavaFX »

Les commentaires sont fermés.