An example of JavaFX

· JavaFX

This is a really simple thing I wrapped up in a couple of minutes. It doesn't show much, and certainly isn't very flashy, but it does show some main points I wanted to share about my 5-minutes experience with JFX. By the way, this code can be just taken as is and put directly into the JavaFX Pad.


import javafx.ui.*;
import javafx.ui.canvas.*;

class Person {
    attribute name:String ;
    attribute parent:Person inverse Person.children;
    attribute children:Person* inverse Person.parent;
    attribute gender:String;
}

Canvas {
    var father = Person { name:"George", gender:"Male" }
    var jen = Person {name:"Jennifer", parent:father, gender: "Female" }
    var matt = Person { name:"Matt", parent:father, gender:"Male" }
    var lara = Person {name:"Lara", parent:father, gender: "Female" }
    
    content: select Text {content: p.name y:indexof p * 15} 
                    from p in father.children 
                    where p.gender == "Female"
}
The points I want to show off:
  • No need to update the "children" attribute: Notice that I do not update the children attribute of dad. Since children and parent are defined to be inverse to one another, just specifying who the parent is is enough.
  • Creating graphical elements is easy: I can create graphical elements using a select statement on the array of items I have in my data model, and use their attributes as values to the elements. It's that simple - I create three elements here with one line of code, and I could create complex queries using joins and where clauses.
The annoying part was when I tried to give some behavior to the generated Text elements. I changed the creation to be like this:

Text {
        var x1:Number = 0
        var y1:Number = indexof p * 15 + 20
        content: p.name
        x:bind x1
        y:bind y1
        cursor:HAND
        onMouseDragged:operation(e:CanvasMouseEvent) {
            x1 += e.localDragTranslation.x;
            y1 += e.localDragTranslation.y;
        }
But, it didn't work! It did change the cursor to "Hand" when the mouse was over an element, but it didn't make the drag work. I can't imagine why - In an example on the openjfx.org site something similar was made, but there they used subclassing and adding attributes instead of adding variables dynamically like I chose to do here. Maybe that's the case; but it really isn't clear. If anyone has an idea, please let me know!

Comments (11)

Avah
I don't know how to help except for you making sure that you are really running using 1.6, meaning: Going to the Java Preferences console (look it up using Spotlight) and also making sure by going to Terminal and running "java -version".
Hari Jayaram
Hi I had a problem launching the java webstart link on my mac running the 1.6 jdk. The error I get is.. n error occurred while launching/running the application. Title: JavaFX Demos:JavaFX Pad Vendor: Sun Microsystems Category: Launch File Error Unsupported JNLP version in launch file: 1.5+. Only version 1.0 is supported with this version. Please contact the application vendor to report this problem.
JavaFX articles at “Chaotic Java” blog | JavaFX site
[...] An example of JavaFX [...]
Avah
Here's a working version of what I tried to achieve:

import javafx.ui.*;
import javafx.ui.canvas.*;

class Person {
    attribute name:String ;
    attribute parent:Person inverse Person.children;
    attribute children:Person* inverse Person.parent;
    attribute gender:String;
}

class MyText extends CompositeNode {
    attribute text: String;
    attribute x: Number;
    attribute y: Number;
}

function MyText.composeNode() = Text {
    content: bind text
    x: bind x
    y: bind y
    cursor: HAND
    onMouseDragged: operation(e:CanvasMouseEvent) {
        x += e.localDragTranslation.x;
        y += e.localDragTranslation.y;
    }
};

Canvas {
    var father = Person { name:"George", gender:"Male" }
    var jen = Person {name:"Jennifer", parent:father, gender: "Female" }
    var matt = Person { name:"Matt", parent:father, gender:"Male" }
    var lara = Person {name:"Lara", parent:father, gender: "Female" }
    
    content: select MyText {
        text: p.name y: indexof p * 15
    }
    from p in father.children
    where p.gender == "Female"
}
Still, I had to use a CompositeNode and it wasn't at all clear that this was the requirement.
Kjus
Hi, I saw your code, it work beautiful. And now a question for you, is it also possible to move or resize an TextField or TextArea? Thanks for your answers Kjus
Avah
Kjus: Essentially, yes. Since both TextField and TextArea derive from Widget, they both have the "width" and "height" attributes to bind to.
Aviad
@jos: I didn't try, to be honest.. :) I was only working with JavaFX pad.. But it should work - inverse is a keyword, and netbeans should accept it.. right? :)
jos
Nice, everything works fine within JavaFX pad. But ... after copying the source to netbeans i get a compiler error ... grrrrr ;-) On line: attribute parent:Person inverse Person.children; Netbeans got confused when he saw "inverse" which is a keyword. I.have tried lib javaFX SDK on Java 1.6.(0.10) and JavaFX SDK on Java 1.7 (both preview of JavaFX and little bit older version). You don't get an compilor error on that line in Netbeans 6.1 ?
Amith
what is JavaFX means?ie what is FX stand for?
Aviad
@Amith: I think it's not really an acronym, but just means "Effects". Like SFX - "Sound Effects".
Josh W
For JavaFX Pad, try this: http://download.java.net/javadesktop/scenario/demos/demo-12-10-07/fxpad-0.41/fxpad.jnlp