Monday, June 8, 2009

Why can't I import javafx.ui.*?

The Answer for the Impatient (like me!)

Short answer for those who are impatient... see javafx.scene.layout.* and use something like HBox. Reason you ask? JavaFX 1.1 vs 1.2 had many non-backwards compatible changes.

Background

So I was trying out JavaFX with NetBeans 6.5.1 while I was waiting for a software build to complete. I created a simple project then wanted to do a more advanced component layout. I Googled "javafx positioning elements side by side" and noticed that many of the tutorials were importing javafx.ui.* to get BorderLayout. Looks great!

Absolute Positioning

Before I continue, here is my code which has a simple Text and an ImageView component:

/*
* Main.fx
*
* Created on Jun 8, 2009, 9:50:23 AM
*/

package javafxapplication1;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.image.Image;

import javafx.scene.image.ImageView;
import javafx.scene.text.Text;


/**
* @author graeme
*/

Stage {
title: "Flask"
width: 800
height: 600
scene: Scene {
content: [
Text {
font : Font {
size : 16
}
x: 10
y: 30
content: "Flask 0.01"
}
ImageView {
x: 10
y: 50
image: Image {
url: "{__DIR__}flask-2.jpg"
}
}
]
}

Adding the Infamous BorderLayout

I simply added BorderLayout inside of my scene content and did the old CTRL+SHIFT+I to fix imports and... nothing. Confused++

So I typed the import in manually and noticed it was not there. Confused++

I figured I had an old version of NetBeans. So I went to get NetBeans 6.7 RC2 and JavaFX is not available for it... Confused++

Maybe my Plugin was old...? I checked - nope! Brand new. Confused++

Here is the code that will not work in JavaFX 1.2 - I have bolded the reasons why:

/*
* Main.fx
*
* Created on Jun 8, 2009, 9:50:23 AM
*/

package javafxapplication1;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.image.Image;


import javafx.ui.*;

import javafx.scene.image.ImageView;
import javafx.scene.text.Text;


/**
* @author graeme
*/

Stage {
title: "Flask"
width: 800
height: 600
scene: Scene {
content: [
BorderLayout {
content: [
Text {
font : Font {
size : 16
}
content: "Flask 0.01"
}
ImageView {
image: Image {
url: "{__DIR__}flask-2.jpg"
}
}
]
}
]
}
}

Breaking Through the Confusion

So now that Confused = 4, I Googled once more. (Rhyming not intentional)

I read that many classes moved from javafx.ui.* to javafx.application.* then distributed somewhere inside to javafx.scene. This makes more sense!

So I found HBox and VBox (which are quite familiar to me in the Flex world) and gave those a shot. Worked like a charm!

Here is the code that will work in JavaFX 1.2:

/*
* Main.fx
*
* Created on Jun 8, 2009, 9:50:23 AM
*/

package javafxapplication1;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Font;
import javafx.scene.image.Image;


import javafx.scene.layout.HBox;

import javafx.scene.image.ImageView;
import javafx.scene.text.Text;


/**
* @author graeme
*/

Stage {
title: "Flask"
width: 800
height: 600
scene: Scene {
content: [
HBox {
content: [
Text {
font : Font {
size : 16
}
content: "Flask 0.01"
}
ImageView {
image: Image {
url: "{__DIR__}flask-2.jpg"
}
}
]
}
]
}
}
Screenshot of NetBeans 6.5.1 Flask Example















References

Good ones:

http://java.sun.com/javafx/1/tutorials/ui/layout/index.html#hbox
http://java.sun.com/javafx/1/tutorials/ui/

Old ones:

http://www.ibm.com/developerworks/java/library/j-javafx/
http://www.informit.com/guides/content.aspx?g=java&seqNum=418