Those days I received my box of free Ubuntu CDs and sticks, free of charges. Courtesy of Canonical throught the Ubuntu Shipit project, thanks guys! I love those Internet free stuff. It’s essential having a few CDs distros always with me.
Those days I received my box of free Ubuntu CDs and sticks, free of charges. Courtesy of Canonical throught the Ubuntu Shipit project, thanks guys! I love those Internet free stuff. It’s essential having a few CDs distros always with me.
In this demo Roman Strobl shows the new functionality available from OpenSolaris 2008.11 . Time Slider allows users get instant rollback and point in time snapshots. This is possible the thought the ZFS Snapshots and now can be easily used by users thought the Time Slider in the Gnome interface.
More about news functionalities in OpenSolaris 2008.11 in the live demo “What’s new in OpenSolaris 2008.111” also with Roman.
Let sandwich.xml be a file at /tmp directory with the content above.
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.
Bon appétit.
For more details on XML and JSON parsing see the JavaFX API.
A pizza party que o CEJUG ganhou por ter atingido mais de 100 usuários no OSUM em apenas dois dias é essa sexta-feira, à s 18hrs no restaurante Florence L’Escale. As pizzas ficam por nossa conta e as bebidas por conta dos participantes.
Se você vai:
Lembre-se, é nessa sexta-feira, dia 26 de Dezembro, às 18 horas. Preencha o espaço na sua agenda entre as festas de natal e a farra de ano novo. ;D Maiores detalhes no site do evento dentro do OSUM.
Now is possible to create a tiny mall. With a few more ambients will be possible to create a entire little town.
And here the last entire tile set.
Booth, made with Gimp.
Happy holidays in a JavaFX Style.
It’s a application to put a Santa’s hat on a picture from web. To test it obviously I used my picture with John Hall “Maddog”, the closest person I know to Santa Claus. ;D
I tried the approach from Chris Campbell’s Effect Playground application but I needed get both photo image and hat at the same time. In this application I used the Jean-Francois Screenshot Maker approach, taking a screenshot of the desired area. Maybe not the best solution, but it works very well. I also used his Screencapture.java and Util.java codes.
package santahat;
import javafx.ext.swing.SwingTextField;
import javafx.scene.CustomNode;
import javafx.scene.input.MouseEvent;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.ext.swing.SwingButton;
var imgview = ImageView {
image: Image {
url: "{__DIR__}help.png"
}
}
var txtfield:SwingTextField = SwingTextField {
columns: 45
text: "your image url"
editable: true
action: function(){
println(txtfield.text);
imgview.image = Image {
url: txtfield.text;
}
}
};
var santahat:ImageView = ImageView {
x: 240 y: -5
var startX = 0.0
var startY = 0.0
var zoom = 1.0
var angle = 0.0
scaleX: bind zoom
scaleY: bind zoom
rotate: bind angle
onMousePressed: function( e: MouseEvent ):Void {
startX = e.sceneX - santahat.translateX;
startY = e.sceneY - santahat.translateY;
}
onMouseDragged: function( e: MouseEvent ):Void {
santahat.translateX = e.sceneX - startX;
santahat.translateY = e.sceneY - startY;
}
onMouseWheelMoved: function( e: MouseEvent ):Void {
if(e.controlDown) {
angle +=
e.wheelRotation * 10;
} else {
zoom +=
e.wheelRotation / 20;
}
}
image: Image {
url: "{__DIR__}santahat.png"
}
}
// Based on the Jean's ScreenshotMaker
// http://javafx.com/samples/ScreenshotMaker/index.html
var stage:Stage = Stage {
title: "Santa Hat"
width: 510 height: 480
scene: Scene {
content: [
VBox {
content: [ txtfield, imgview,
SwingButton {
text: "Save"
action: function() {
// Ugly. See the entire source at through the link in the blog post
}
}]
}, santahat]
}
}
Downloads:
For those who uses Eclipse IDE: there’s already a JavaFX plugin for you. Check out here. To try out, Paul Bakker wrote a post introduction showing how to create a cool first application.
Is a another big free organism in our JavaFX ecosystem!
Changelog:
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 = "
";
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.
Tile sets are a very simple way to draw scenarios with repeated elements. From simple to complex ones using a very low footprint.
First step, load the png file that stores the tileset into a Image. The file tiles.png shoud be in the same directory of the source code. I adjusted some tiles from those tile set I’ve blogged here before into a grid of 10×10 tiles.
var tileset = Image {
url: "{__DIR__}tiles.png"
}
Notice that each tile have 32 of height and 32 of width. We will assume this and use theses numbers when performing calculations to find a single tile in our tile set.
def w = 32;
def h = 32;
To display a Image in the screen we use a ImageView node. A ImageView can have a viewport property to create crop or zoom effect. A viewport is just a Rectangle2D, a object with position (minX and minY), height and width. If we want to display the first tile in the tileset we do
ImageView {
image: tileset
viewport: Rectangle2D{
minX: 0, minY: 0, height: 32, width: 32
}
}
Notice that the minX determines the column and minY the row in the tileset. The first row is 0*32, the second row is 1*32 and so on. If we want to display the tile at the second line and third column of the tileset we do
ImageView {
image: tileset
viewport: Rectangle2D{
minX: 2 * 32 , minY: 1*32, height: 32, width: 32
}
}
Those properties in a Rectangle2D are for init and read only. So I created a list with all Rectangles I can need for use as a viewport.
def viewports = for (row in [0..9]) {
for (col in [0..9]) {
Rectangle2D{
minX: col * w, minY: row * h, height: w, width: h
}
}
}
The scenario map is stored in another list. The first element of the list is 7, that is, the first tile in the scenario is the 7th tile from the tile set.
var map = [
7, 3, 3, 3, 3, 3, 3, 3, 3, 8,
19, 26, 40, 41, 24, 13, 13, 23, 24, 19,
19, 36, 50, 51, 34, 2, 2, 2, 34, 19,
19, 2, 2, 2, 2, 2, 2, 2, 25, 19,
19, 57, 58, 44, 45, 46, 2, 2, 35, 19,
27, 3, 3, 6, 55, 56, 5, 3, 3, 38,
19, 60, 13, 16, 47, 48, 15, 13, 61, 19,
19, 70, 1, 33, 1, 1, 1, 1, 71, 19,
19, 1, 1, 1, 1, 1, 1, 1, 49, 19,
17, 9, 9, 9, 9, 9, 9, 9, 9, 18,
];
Finally to create a scenario with 100 tiles, 10 per row and with 10 rows, in a list called tiles. Each iteration of this loop creates a ImageView. Each ImageView will store a single tile. We get the tile number in the map list and so use it to index the viewports list.
var tiles = for (row in [0..9]) {
for (col in [0..9]) {
ImageView {
x: col * w, y: row * h,
viewport: bind viewports[map[row * 10 + col]]
image: tileset
}
}
}
Additionally I added two things to transform this program also in a (extremely)Â simple map editor. At each ImageView I added a callback for onMouseClicked event. When you click on a tile, it changes its map position, ie, the tile. The next tile for the left button and the last tile for any other button.
onMouseClicked: function( e: MouseEvent ):Void {
var amount = if(e.button == MouseButton.PRIMARY) { 1 } else { -1 };
map[row * 10 + col] = (map[row * 10 + col] + amount) mod 100;
}
The other thing is to print the map list when the program is over. There is the full program:
package tileeditor;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.geometry.Rectangle2D;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.MouseButton;
def w = 32;
def h = 32;
var map = [
7, 3, 3, 3, 3, 3, 3, 3, 3, 8,
19, 26, 40, 41, 24, 13, 13, 23, 24, 19,
19, 36, 50, 51, 34, 2, 2, 2, 34, 19,
19, 2, 2, 2, 2, 2, 2, 2, 25, 19,
19, 57, 58, 44, 45, 46, 2, 2, 35, 19,
27, 3, 3, 6, 55, 56, 5, 3, 3, 38,
19, 60, 13, 16, 47, 48, 15, 13, 61, 19,
19, 70, 1, 33, 1, 1, 1, 1, 71, 19,
19, 1, 1, 1, 1, 1, 1, 1, 49, 19,
17, 9, 9, 9, 9, 9, 9, 9, 9, 18,
];
var tileset = Image {
url: "{__DIR__}tiles.png"
}
def viewports = for (row in [0..9]) {
for (col in [0..9]) {
Rectangle2D{
minX: col * w, minY: row * h, height: w, width: h
}
}
}
var tiles = for (row in [0..9]) {
for (col in [0..9]) {
ImageView {
x: col * w, y: row * h,
viewport: bind viewports[map[row * 10 + col]]
image: tileset
onMouseClicked: function( e: MouseEvent ):Void {
var amount = if(e.button == MouseButton.PRIMARY) { 1 } else { -1 };
map[row * 10 + col] = (map[row * 10 + col] + amount) mod 100;
}
}
}
}
Stage {
title: "JavaFX Simple Tile Editor"
scene: Scene {
content: [ tiles ]
}
onClose: function() {
println(map);
}
}
Here is the result for that map
And you can try it yourself in your browser. Play it online now.
Here is a video of it working
[youtube]lxuBEoItB5E[/youtube]
Downloads:
Possibilities
We are using just a image that can handle 100 tiles, tiles.png with less than 30Kb. The map is also composed with 100 tiles. Each tile we can choose between 100 different tiles, so we can compose 10100 different maps (one googol10 ). Most of them are useless and without any sense, but some are cool. 🙂