the world is a pixel
Posts tagged RIA
FootprintFX
Jun 2nd

Footprint is a publisher and distributor of certificates of participation in conferences – signed PDF documents that prove you attended a conference or a course.
This is a little JavaFX application that shows how to create a interface that displays data provided by services. This version uses three services: one that counts the number of users, other that counts the number of events and one that list these events. Check out the source code here. Try the application as a draggable JavaFX applet here.
JavaFX 1.1 for Linux workaround
May 16th
Download
javafx4linux.tar.bz2 (~ 36Mb).
Installing
1) Extract the javafx4linux.tar.bz2 file. In this example I’m placing it on my Desktop. After the installing process you can remove it.
2) Open your NetBeans 6.5 and go at Tools → Plugins and go to Downloaded tab. In a plain and new NetBeans installation there will be no plugin in this tab yet.
3) Click on the Add Plugins button and head to the directory you extracted the file and select all .nbm files.
4) You will see a list of 22 plugins selected. Click on the Install button.
5) Just keep clicking on the Next button.
6) Check the license agreement accept box.
7) You’ll see a warning because the Linux pluggin is not signed. Don’t worry, just click Continue.
8) Click on Finish to restart NetBeans.
9) Now we can test it. Go at File → New Project, select the JavaFX on Categories and JavaFX Script Application on Projects.
10) Put some code and run it. There is. JavaFX on Linux.
Considerations
This is not a official of JavaFX for Linux! This solution was tested on Ubuntu 9.04 “Jaunty Jackalope” with Java 6 update 13 and NetBeans 6.5.1, but should also work with others Linux distributions and Java versions greater than 5.
Known bugs
As a non official workaround for JavaFX for Linux you may notice some drawbacks. Some parts of the JavaFX runtime rely on native implementations on the specific operational system. You may not use some multimedia capabilities as video playback, JavaFX Mobile emulator and some performance issues in some effects. Despite that, is perfectly possible to develop applications using JavaFX on NetBeans.
Thanks
I’d like to thanks some guys around the world. Weiqi Gao’s original post on JavaFX on Linux, HuaSong Liu article on DZone and Kaesar Alnijres post.
JavaFX, easy use of tiles
Jan 6th
Continuing my little JavaFX framework for game development, right now focused on use those tiles I’m drawing and posting here in my blog. This framework will be a group of classes for simplify and hide some complexities of common game development. Right now I wrote just a few of them.
Use
We create a tileset from the files.png file that way
var tileset = Tileset { cols: 15 rows: 10 height: 32 width: 32 image: Image { url: "{__DIR__}tiles.png" } }

Tileset are orthogonal, distributed into a grid of cols columns and rows rows. Each tile have dimensions height x width.
A Tileset is used into a Tilemap
var bg = Tilemap { set:tileset cols:5 rows:5 map: [8,8,8,8,8,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3] }
That shows

Each number in the map represents a tile in the tilemap. Number 0 means the first tile at the upper left corner, numbers keep growing from left to right columns, from top to bottom rows.
Another example
var things = Tilemap { set:tileset cols:5 rows:5 map: [80,55,56,145,145,96,71,72,61,62,0,0,0,77,78,122,0,0,93,94,138,0,0,0,0] }

A tilemap can also contains more than one layer
var room = Tilemap { set:tileset cols:5 rows:5 layers:2 map: [ [8,8,8,8,8,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3], [80,55,56,145,145,96,71,72,61,62,0,0,0,77,78,122,0,0,93,94,138,0,0,0,0] ] }

Implementation
The Tileset class basically stores a Image and a collection of Rectangle2D objects, for be used as viewports in ImageView classes.
import javafx.scene.image.ImageView; import javafx.scene.image.Image; import javafx.geometry.Rectangle2D; public class Tileset { public-init var image: Image; public-init var width: Integer = 32; public-init var height: Integer = 32; public-init var rows: Integer = 10; public-init var cols: Integer = 15; protected var tile: Rectangle2D[]; init { tile = for (row in [0..rows]) { for (col in [0..cols]) { Rectangle2D{ minX: col * width, minY: row * height height: width, width: height } } } } }
The Tilemap is a CustomNode with a Group of ImageViews in a grid. The grid is mounted by iterating over the map as many layers was defined.
public class Tilemap extends CustomNode { public-init var rows: Integer = 10; public-init var cols: Integer = 10; public-init var set: Tileset; public-init var layers: Integer = 1; public-init var map: Integer[]; public override function create(): Node { var tilesperlayer = rows * cols; return Group { content: for (layer in [0..layers]) { for (row in [0..rows-1]) { for (col in [0..cols-1]) { ImageView { image: set.image x: col * set.width y: row * set.height viewport: set.tile[map[tilesperlayer*layer + row*rows+col]] } } } } }; } }
Next steps
- Integrate to a map editor
- Support some XML map format
- Sprite classes for animation
- Integrate those collision detection classes I posted before
Download
- Source code and NetBeans project, tileworld.tar.bz2.
Reading Twitter with JavaFX
Jan 4th

Twitter is a social network and micro-blogging service that allow you to create and read tweets, 140 characters text-based posts. It’s becoming a popular tool to keep in touch with your friends, coworkers, bloggers, etc. Here we’ll create a very simple application that show us tweets related with a given word.
Twitter offers a very simple and powerfull REST API which supports XML, JSON, and the RSS and Atom formats. As we are aiming just to read tweets we’ll use just the Search API.
We do that in three steps:
- Query Tweets
- Parser the Atom result
- Show tweets into a GUI
Let’s see them in the order of dependence beetween them.
Displaying a Tweet
var gradient = LinearGradient { startX: 0.0, startY: 0.0, endX: 0.0, endY: 150.0 proportional: false stops: [Stop {offset: 0.0 color: Color.DARKGRAY }, Stop { offset: 1.0 color: Color.BLACK }] } public class Tweet extends CustomNode { public var image: Image; public var username: String; public var message: String; public override function create(): Node { var txt = Text { x: 65 y: 35 wrappingWidth: 150 fill: Color.WHITE content: "{message}" } return Group { content: [ Rectangle { width: 220 height: txt.boundsInLocal.height + 40 arcHeight: 10 arcWidth: 10 fill: gradient }, ImageView { x: 5 y: 20 image: image }, Text { x: 65 y: 20 fill: Color.BLACK content: "{username} said" }, txt ] }; } }
For example, this tweet would become:

Parsing ATOM result
In my last post about JavaFX I showed how to parse XML documents (and make sandwiches) with JavaFX. Here we’ll use the Atom format, but use any other would be almost the same. Parsing XML or JSON documents with JavaFX is both very simple using the javafx.data.pull.PullParser class.
A query output is a Atom XML document with several information. We are interested only in the fields that holds the avatar image, the message and the user name.
var tweets = VBox {} def parser = PullParser { var avatar; var firstname; var text; documentType: PullParser.XML; onEvent: function(event: Event) { if(event.type == PullParser.START_ELEMENT){ if(event.qname.name.equals("link")){ if(event.getAttributeValue(QName{name: "rel"}) == "image"){ avatar = event.getAttributeValue(QName{name:"href"}); } } } if(event.type == PullParser.END_ELEMENT) { if(event.qname.name == "title"){ text = event.text; } if((event.qname.name == "name")and(event.level==3)){ var names: String[] = event.text.split(" "); firstname = names[0]; insert Tweet { image: Image { url: avatar } message: text username: firstname } into tweets.content; } } } }
Querying Tweets
We can get Atom results through url queries like that:
- Tweets containing the word Beatles http://search.twitter.com/search.atom?q=Beatles
- Tweets from the user Silveira http://search.twitter.com/search.atom?q=from%3ASilveira
- Tweets to the user Silveira http://search.twitter.com/search.atom?q=to%3ASilveira
- Tweets containing the hashtag #CEJUG http://search.twitter.com/search.atom?q=to%23CEJUG
Notice that queries should be URL encoded. We will use a additional parameters &rpp=4 to receive only 4 results per page. To know more about search queries read the Search API Documentation. We get these results as InputStreams making asynchronous HTTP requests using the javafx.io.http.HttpRequest class, which it’s perfect to invoke RESTful Web Services.
word = "Beatles"; var request = HttpRequest { location: "http://search.twitter.com/search.atom?q={word}&rpp=4"; onInput: function(stream: java.io.InputStream) { parser.input = stream; parser.parse(); } } request.enqueue();
Conclusion
Here is the application running for the word “House”.

Is not a complete Twitter client, as it’s not intended to be, but can show you how to handle a simple asynchronous call and handle Twitter documents. There’s already a few beta JavaFX Twitter clients like Tweetbox and Twitterfx and certanly others will appears.
Download
Sources and Netbeans project, fxtwitter.tar.bz2.
Parsing a XML Sandwich with JavaFX
Dec 25th

Let sandwich.xml be a file at /tmp directory with the content above.
<?xml version="1.0" encoding="UTF-8"?> <bread sesame="true"> <catchup/> <hamburguer/> <cheese type="chedar"/> <maionese/> <lettuce/> </bread>
We can open it using java.io.FileInputStream and so use it on a javafx.data.pull.PullParser. A PullParser is a event oriented parser that works with XML and YAML files. Above a general and simple parser with a GUI that show the list of events during the parse process.
import java.io.FileInputStream; import javafx.data.pull.Event; import javafx.data.pull.PullParser; import javafx.ext.swing.SwingList; import javafx.ext.swing.SwingListItem; import javafx.scene.Scene; import javafx.stage.Stage; var list = SwingList { width: 600 height: 300 } var myparser = PullParser { documentType: PullParser.XML; onEvent: function (e: Event) { var item = SwingListItem { text: "event {e}" }; insert item into list.items; } input: new FileInputStream("/tmp/sandwich.xml"); } myparser.parse(); Stage { title: "XML Sandwich" scene: Scene { content: list } }

The XML cheese element produce two the outputs.
type:1 typeName:START_ELEMENT level:1 qname:cheese text:” namespaces:{} attributes:{type=chedar}
type:2 typeName:END_ELEMENT level:1 qname:cheese text:” namespaces:{} attributes:{type=chedar}
Notice that white spaces like tab and escape characters like new line also produced events from type TEXT. We are not interested on them. Above a parser that looks only those events of type START_ELEMENT or END_ELEMENT, look into it’s contents, building a sandwich at runtime based on the XML file.
import java.io.FileInputStream; import javafx.data.pull.Event; import javafx.data.pull.PullParser; import javafx.data.xml.QName; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.VBox; import javafx.scene.Scene; import javafx.stage.Stage; // my sandwich starts as an empty VBox var mysandwich = VBox {} // give a name and returns a ImageView with a png image like the name function ingredient(name){ return ImageView { image: Image { url: "{__DIR__}{name}.png" } } } // basicaly, look the event and put a ingredient at mysandwich var myparser = PullParser { documentType: PullParser.XML; onEvent: function (e: Event) { // starter xml elements if(e.type == PullParser.START_ELEMENT){ // bread if(e.qname.name.equals("bread")){ insert ingredient("bread_top") into mysandwich.content; } // hamburguer if(e.qname.name.equals("hamburguer")){ insert ingredient("hamburguer") into mysandwich.content; } // catchup if(e.qname.name.equals("catchup")){ insert ingredient("catchup") into mysandwich.content; } // maionese if(e.qname.name.equals("maionese")){ insert ingredient("maionese") into mysandwich.content; } // lettuce if(e.qname.name.equals("lettuce")){ insert ingredient("lettuce") into mysandwich.content; } // cheese if(e.qname.name.equals("cheese")){ var type= e.getAttributeValue(QName{name:"type"}); if(type.equals("cheedar")){ insert ingredient("cheedar") into mysandwich.content; } else { insert ingredient("cheese") into mysandwich.content; } } } // ending xml elements (just bread) if(e.type == PullParser.END_ELEMENT){ if(e.qname.name.equals("bread")){ insert ingredient("bread_botton") into mysandwich.content; } } } input: new FileInputStream("/tmp/sandwich.xml"); } myparser.parse(); Stage { title: "XML Sandwich" scene: Scene { height: 300 content: mysandwich } }
Here’s our sandwich.

Just changing the XML file you got a new sandwich.
<?xml version="1.0" encoding="UTF-8"?> <!-- double burger --> <bread sesame="true"> <maionese/> <lettuce/> <hamburguer/> <cheese type="chedar"/> <catchup/> <hamburguer/> <lettuce/> </bread>

Bon appétit.
For more details on XML and JSON parsing see the JavaFX API.
- ps: Sandwich image from commons.wikimedia.org
- ps2: We’re out of sesame.
- ps3: Sources, xmlsandwich.tar.bz2.
Gravatar with JavaFX
Dec 21st
Gravatar is easy way to put global recognized avatar images into any Internet application. Gravatar would stands for globally recognized avatar.
Below, the Java class that I got from the Gravatar Java reference. Here is a static class called md5 that applies a MD5Sum algorithm over a string. Is a little complex code but all behavior keeps encapsulated and who uses it don’t need to know how it works. Just gives a string and receives a encrypted string. Those two codes are also a good example of how calling Java classes inside a JavaFX code.
package gravatarexample; import java.security.MessageDigest; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; public class MD5 { public static String toHex(String message) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte array[] = md.digest(message.getBytes("CP1252")); StringBuffer sb = new StringBuffer(); for (int i = 0; i < array.length; ++i) { sb.append(Integer.toHexString((array[i]&0xFF)|0x100).substring(1, 3)); } return sb.toString(); } catch (NoSuchAlgorithmException e) { } catch (UnsupportedEncodingException e) { } return null; } }
As a Java class in the same package, any JavaFX (or Java) code can call it without any problem. Just to keep the code more clear I’m importing it explicitly. Is this example I also create some Swing interface to give user the option to put his mail, adjust the image size and get a output direct link or html image tag.
package gravatarexample; import gravatarexample.MD5; import javafx.ext.swing.SwingButton; import javafx.ext.swing.SwingSlider; import javafx.ext.swing.SwingTextField; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.VBox; import javafx.scene.Scene; import javafx.stage.Stage; var mail = "Email"; var key = ""; function gravatalize(mail:String, size: Integer): String { return "http://www.gravatar.com/avatar/{MD5.toHex(mail)}?s={size}" } var inputtxt = SwingTextField { columns: 20 text: mail } var slider = SwingSlider { minimum: 10 maximum: 128 value: 100 vertical: false } var button = SwingButton { text: "Get Gravatar" action: function() { key = gravatalize(inputtxt.text, slider.value); directoutput.text = key; htmloutput.text = "<img src="{key}" alt="\"gravatar\"" />"; photo.image = Image { backgroundLoading: true, url: key}; } } var photo:ImageView = ImageView { image: null } var directoutput = SwingTextField { columns: 20 text: "direct link image" } var htmloutput = SwingTextField { columns: 20 text: "html tag image" } Stage { title: "Gravatar" width: 300 height: 340 scene: Scene { content: [ VBox { spacing: 10 content: [inputtxt, slider, button, directoutput, htmloutput, photo] }, ] } }
The string itself is assembled in the gravatalize function. You give a mail and it’s returns a Gravatar direct link to the image. There’s many cool ways to use together Gravatar and a JavaFX Internet application.
























