Jim has posted 66 posts at DZone. You can read more from them at their website. View Full User Profile

Setting the "Stage" for the JavaFX SDK

07.10.2008
| 8136 views |
  • submit to reddit

As I mentioned in the JavaFX SDK Packages are Taking Shape post, the JavaFX SDK will have a "node-centric" UI approach.  This approach will make it easier to create UIs that have an "iPhone look and feel" that users will increasingly expect.  The first step that the JavaFX team took in implementing this was to create a javafx.application package and put classes in it (e.g. a new version of the Frame class) that adopt this node-centric philosophy.

Today, in the JavaFX SDK Technology Preview branch, an attribute named stage was introduced into the Window class from which Frame and Dialog are derived, and it was also introduced into the Application class.  This stage attribute holds a reference to a Stage instance, which is also located in the javafx.application package.  According to the JavaFXdocs (shown below), the Stage class is the root area for all scene content, and it contains a sequence of one or more graphical Node instances.

Stagedocs

Also shown in the JavaFXdoc screenshot above is a fill attribute so that you can control the background of the stage, and find out its current height and width.  The stage expands to the area of its container, so the stage contained within a Frame, for example, will expand to the size of the usable area of the frame (e.g. minus the title bar).

An Example of Using the Stage Class, and the HBox/VBox Layout Classes

In keeping with the node-centric approach, today's example uses classes from the javafx.scene.layout package, namely HBox and VBox.  I expect that we'll see more classes in this package soon, and these classes will be for the purpose of providing cross-platform layout management of graphical nodes.  These layout classes are graphical nodes, so the entire UI containment hierarchy will (as I understand it) evolve to a frame or applet that contains a stage, that in turn contains a hierarchy of graphical nodes.  My understanding is that components such as buttons and text fields will be "nodified" so that they can be used as nodes, a side benefit of which is having a more consistent API between graphical nodes and components.  Here's a screenshot of today's example, in which resizing the Frame causes the Stage to be resized, which in turn (because of the bind operators) causes the Rectangle instances contained in the HBox and VBox layout nodes to be resized:

Stageexample

Here's the code for this example:

/*
* StageExample.fx -
* An example of using the new Stage class in JavaFX Script
*
* Developed 2008 by James L. Weaver (jim.weaver at lat-inc.com)
*/

import javafx.application.*;
import javafx.scene.*;
import javafx.scene.text.*;
import javafx.scene.geometry.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;

Frame {
var stageRef:Stage
var rows:Integer = 4;
var columns:Integer = 3;
title: "Example of Using the New Stage Class"
width: 350
height: 400
visible: true
stage:
stageRef = Stage {
fill: Color.WHITE
content:
VBox {
spacing: bind stageRef.height / (rows) * .10
content:
for (row in [1..rows])
HBox {
spacing: bind stageRef.width / (columns) * .10
content:
for (column in [1..columns])
Group {
var rectRef:Rectangle
var textRef:Text
translateX: bind stageRef.width / (rows) * .10
translateY: bind stageRef.height / (columns) * .10
content: [
rectRef = Rectangle {
fill: Color.BLUE
stroke: Color.WHITE
width: bind stageRef.width / (columns) * .85
height: bind stageRef.height / (rows) * .85
},
textRef = Text {
content: "{row},{column}"
fill: Color.WHITE
textOrigin: TextOrigin.TOP
x: bind (rectRef.getWidth() / 2) - (textRef.getWidth() / 2)
y: bind (rectRef.getHeight() / 2) - (textRef.getHeight() / 2)
font:
Font {
size: 24
style: FontStyle.BOLD
}
}
]
}
}
}
}
}

 


Running this Example

The JavaFX SDK Technology Preview branch of the compiler build may be downloaded here.  This branch is what will become the JavaFX SDK Preview Release.  After adding the openjfx-compiler-tp1/dist/bin directory to your PATH environment variable, and verifying that you have the Java Runtime Environment (JRE) 6 installed, use the following command at your operating system prompt to compile the program:

javafxc StageExample.fx

To run the program, use the following command:

javafx StageExample

Alternatively, you can take the easy way out and run this application via Java Web Start.  As mentioned in previous posts, installing Java SE 6 Update 10 will cause this application to deploy more quickly.  Also, keep in mind that JRE 6 is required regardless of your platform.  Regarding running this on a Mac, here's a tip that Ken Russell of Sun and Thom Theriault of MaldenLabs passed on to me after the Java Web Start link didn't successfully invoke the program:

  • Launch Applications > Utilitiies > Java > Java Preferences
  • Under Java Application Runtime Settings, drag Java SE 6 (64-bit) to the top of the box as shown below.
  • Save the configuration.

Snapz_pro_xscreensnapz053

Have fun, and please post a comment if you have any questions!

Published at DZone with permission of its author, Jim Weaver.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Jacek Furmankiewicz replied on Thu, 2008/07/10 - 4:42am

I don't want to sound like a broken record, but could you post a sample of how to accomplish the same thing by calling the underlying JavaFX APIs from pure Java instead? I am actually really interested in seeing that and so is probably a lot of people who have invested a lot into Java and are thinking maybe of enhancing existing Swing apps to have this sort of functionality.

 Thank you

Peter Thomas replied on Thu, 2008/07/10 - 10:01am

+1

Collin Fagan replied on Thu, 2008/07/10 - 10:58am

Interesting, it reminds me of my Macromedia Director days. It seems to me that layout mangers and a dynamic node based system would be at odds with each other. One is designed to rigidly define the position of components/nodes and the other is designed to allow arbitrary placement of components/nodes. how do these mesh? What happens when you manually move a node currently managed by a layout manager, say for a bouncing animation?

Jim Weaver replied on Thu, 2008/07/10 - 12:07pm

I don't want to sound like a broken record, but could you post a sample of how to accomplish the same thing by calling the underlying JavaFX APIs from pure Java instead? I am actually really interested in seeing that and so is probably a lot of people who have invested a lot into Java and are thinking maybe of enhancing existing Swing apps to have this sort of functionality.

 Jacek.  No problem on sounding like a broken record.  I *really* have valued your input!  I fully expect a version of GridPanel, for example, that contains graphics nodes and *is* a graphical node (like HBox is, for example).  It would be located in the javafx.scene.layout package.  Does that address your concern?

Thanks,

Jim Weaver

 

Jacek Furmankiewicz replied on Thu, 2008/07/10 - 12:20pm in response to: Jim Weaver

Are there any docs how to use any of the internal JavaFX APIs from Java in general? It would be *great* if all the funky JavaFX examples were accompanied by the equivalent pure Java example.

I think it would go a long way to disspelling some of the negativity many Java developers have towards JavaFX (or to be more precise, how it seems to be getting all the features we've wanted in Java for years, e.g. easy data binding).

Thank you, I appreciate your response.

 

Tom Ball replied on Thu, 2008/07/10 - 2:53pm

it seems to be getting all the features we've wanted in Java for years, e.g. easy data binding

For that you want Beans Binding (JSR 295), which has been around for (a few) years:  https://beansbinding.dev.java.net/.  You won't find any "internal FX API" that is easier to use.  As for access to Nodes and the like, the FX runtime relies on the Scene Graph Project at https://scenegraph.dev.java.net/.

Not everything written in JavaFX Script gets converted into Java calls, however.  There is no API to build an object literal declaritively like Jim's Frame example above, for example; instead, the compiler generates all the necessary code to create and initialize each element it contains.

GeekyCoder coder replied on Thu, 2008/07/10 - 3:27pm

Hi Tom,

I understand that you are openjfx compiler lead (http://www.javalobby.org/java/forums/t101855.html), and I have question to ask pertaining tosome developers' need to know and learn the underlying Swing code correspond to JavaFX.

I thought that initial version of JavaFX compiler interpret and translate the JavaFX code to Java Swing which then compile to standard Java class. Now the JavaFX compiler is a true compiler that compile JavaFX code directly to class file. Is there a flag that can be set to allow output to Java Swing source then ?

I remember that I using Flex in FlexBuilder, and Flex compiler has the capability to generate the underlying ActionScript code from the MXML declarative programming language which is useful as a learning tool. So I wonder if JavaFX could provide similar capability.

 

 

 

 

 

Tom Ball replied on Thu, 2008/07/10 - 3:40pm

Have you actually used Beans Binding on its own (i.e. without Netbeans generating all the code for you?).

Sure, its architect and I are teammates.  Binding is hard to do in Java because the language doesn't hide any of the necessary plumbing -- that's one of the major reasons why JavaFX Script was created.  FX doesn't call some "internal JFX API" to handle all binding, it generates a lot of code and relies on a small runtime, similar to what Beans Binding involves.  The difference is that with Beans Binding you write the glue code, with JFX its compiler does, and with Flex it's done by the JavaScript interpreter using reflection. 

There is no magic bullet for binding; the glue code has to come from somewhere. Chris Oliver (JavaFX Script's creator) has stated that he never set out to create a new language, he just wanted to write Swing apps much more quickly.  If there was a way to write a binding library that didn't require all the client code you hate, he'd have written that library instead of a new language.

BTW, it should be possible to access Flex from Java, using the scripting API. This should reduce the glue code overhead, as long as performance isn't an issue.

Tom Ball replied on Thu, 2008/07/10 - 4:02pm

I thought that initial version of JavaFX compiler interpret and translate the JavaFX code to Java Swing which then compile to standard Java class. Now the JavaFX compiler is a true compiler that compile JavaFX code directly to class file. Is there a flag that can be set to allow output to Java Swing source then ?

Not quite:  Chris Oliver wrote a true interpreter, not a compiler.  This interpreter made Java calls, just like any other Java application. The JavaFX compiler doesn't output Java, it outputs JVM class files; while it can create pseudo-Java files useful for debugging (as I mentioned earlier), JFX cannot map directly to Java because it needs things like block expressions.  In theory it's possible to take a pseudo-Java dump file and turn it into a Java file (just like early C++ compilers output C intermediate files), but that's a lot of work compared to just writing JFX directly.

I remember that I using Flex in FlexBuilder, and Flex compiler has the capability to generate the underlying ActionScript code from the MXML declarative programming language which is useful as a learning tool. So I wonder if JavaFX could provide similar capability.

The Flex compiler generates JavaScript to be run by an interpreter that supports things like first-class functions, so it's more of a code generator than a traditional compiler (it's still a great piece of engineering work, of course).  We compiler directly to the JVM without any interpretation, reflection, or other features available from JavaScript; that's great for performance and lower footprint (eventually), but makes intermediate code reuse impossible.

Tom

Jim Weaver replied on Thu, 2008/07/10 - 10:45pm

It seems to me that layout mangers and a dynamic node based system would be at odds with each other. One is designed to rigidly define the position of components/nodes and the other is designed to allow arbitrary placement of components/nodes. how do these mesh? What happens when you manually move a node currently managed by a layout manager, say for a bouncing animation?

cfagan,

I think that layout managers and a dynamic node based system can work well together.  IMO the primary reasons for layout managers are:

  1. the ability to create cross-platform UIs that automatically take into account differences in native components.
  2. the ease of adjusting portions of the UI according to predefined rules when the overall size change.

An example of the latter point is the Tetris game shown in the Watch for Falling Blocks: Take TetrisJFX for a Spin! post.  It is handy to use the BorderPanel and FlowPanel to place those image buttons, as well as using other layout panels to place the playing field (where the blocks fall) next to the components to the right of it.  When the application is resized, things are adjusted accordingly.  See the the Game Over: Improving upon the Compiled JavaFX Tetris Program post for JavaFX code that illustrates this.  Within the layout panels, nodes for the playing field, next piece in play, etc. are graphical nodes that have strict positioning requirements (for example locations of tetrominoes as they are falling).  In that code example, whenever a node is placed within a layout panel, a Canvas must be used to adapt between the component and the node "worlds".  On the other hand, when JavaFX completes the migration to a node-centric approach, adapting between the two worlds won't be necessary.

Thanks!

Jim Weaver

Peter Thomas replied on Fri, 2008/07/11 - 1:25am

I'm not sure I follow most of the detailed discussion above but:

Not everything written in JavaFX Script gets converted into Java calls, however.  There is no API to build an object literal declaritively like Jim's Frame example above, for example; instead, the compiler generates all the necessary code to create and initialize each element it contains.

FX doesn't call some "internal JFX API" to handle all binding, it generates a lot of code and relies on a small runtime, similar to what Beans Binding involves.

The JavaFX compiler doesn't output Java, it outputs JVM class files; while it can create pseudo-Java files useful for debugging (as I mentioned earlier), JFX cannot map directly to Java because it needs things like block expressions.  In theory it's possible to take a pseudo-Java dump file and turn it into a Java file (just like early C++ compilers output C intermediate files), but that's a lot of work compared to just writing JFX directly.

 So what I understand is I *have* to learn a new language if I want to use JavaFX.  Not that I'm complaining, but hmm.

Tom Ball replied on Fri, 2008/07/11 - 1:53am

You only need to learn JavaFX Script if you want its compiler to generate the necessary plumbing code instead of writing it by hand (similar to the Beans Binding example Jacek wrote above).  The same is true for Flex, which outputs JavaScript which could have been written by hand.  It's much easier to use the JavaFX platform using JavaFX Script, but all the platform requires is JVM classfiles making the right calls to it.

 

 

Jacek Furmankiewicz replied on Fri, 2008/07/11 - 3:51am in response to: Tom Ball

Tom, I think you guys did a great job with Beans Binding...it's not the library that's the issue, but the fact that the JavaBean standard is woefully verbose compared to more modern languages.

This cannot be fixed by a library...it needs to be fixed via changes to the language itself to bring its features into the 21st century and compete more with its more nimble, recent competitors

 

Kevin Daly replied on Fri, 2008/07/11 - 9:05am

Leave Java alone!

Why all of this "change the language" bs!

We need to consider the JVM as the crown jewel of the "Platform", with things such as Java, JavaFX, JRuby, Groovy, JPython and whatever other  language runtime they want to squeeze into the JVM.

Java has it's place, and if you want all of the syntatic sugar use Groovey or FX, it's no different to learning Flex & Actionscript, just you have access to the richness of the Java Platform, instead of Adobes limited API. It's the best of both worlds.

It always amazes me that people will complain that language xxx has this and language yyy has that, and they are going to leave Java for Language xxx or yyy, but they seem upset that they have to learn a new JVM language that has the features they want. I don't get it, if you are going to learn something new anyways, why not a language in the environment that you are familiar with.

Jacek Furmankiewicz replied on Fri, 2008/07/11 - 9:10am in response to: Kevin Daly

It's called being realistic. In the comfort of my home I like to learn any language there is.

But any corporations prefers to have one standard language that they know can do it all and they don't have to keep retraining people.

Moving people off one language to learn another is a huge investment for any employer and it better be worth it.

And let's be honest here...if Java can't do RIA, I think it is MUCH MORE likely that a corporation would look at Flex rather than JavaFX. It's called first-mover advantage and existing developer mindshare.

So there is a lot of benefit to take advantage of the massive number of Java developers who know the language inside out and make sure they can do RIAs in the tool they already know.

There's nothing stopping you from learning Groovy, Jython or JRuby at home. But try convincing your employer to re-train let's say 500 or a 1000 developers in a new language and you'd better have a damn good convincing business case. And as I said...they're probably more likely to look at Flex at that point, such is the reality of Java being so behind everyone else in the RIA space.

 

Kevin Daly replied on Fri, 2008/07/11 - 9:40am in response to: Jacek Furmankiewicz

I agree with you as far as Jython & JRuby training, but FX and Groovy are very tightly bound to Java almost to the point that they are simply extensions to the Java Language that should be part of any competent developers toolbox.

Groovy is trivial to learn since it is so close to Java & FX is not any different than a Microsoft developer having to learn XAML. I don't think that it is unreasonable to expect developers to learn these technologies as part of the "keeping current" part of learning a platform.

We as developers need to stop thinking in terms of languages, we need to have a broad based toolset that can be used to solve business problems, and we need to apply the correct tools to the problems at hand.

I acknowledge that people will look at Flex instead of FX or Java 6 Update 10 applets due to the fact that that is where the current mindshare rests, but the point I'm trying to make is that retraining is going to occur anyways, so why not choose technologies that are closer to the skill sets of Java developers such as FX / Groovy SwingBuilder or even just plain Swing Applets.

As to the common cry of "Java can't do RIA", I think that's bullshit, java applets were the original RIA tools, and although they've had a rough ride (somtimes unfairly), Java 6 Update 10 will re-juvinate applets and exceed what is possible with Flash/Flex. Take a look at pivot as well it's new, but it shows huge promise.

Jacek Furmankiewicz replied on Fri, 2008/07/11 - 9:54am in response to: Kevin Daly

I hope you are right...but from what I am seeing the RIA train has taken off and neither Java nor JavaFX are even on it.

And to be frank with you...I've seen Microsoft Expression Blend on the desks of some .net guys here...and nothing I've seen from JavaFX comes even close in terms of a graphical dev environment. I hope Sun can deliver some serious tooling for this and not only for NetBeans, but for Eclipse too.

And as for Java6u10...my first experiences with it were so so...it prompted me for proxy passwords on Firefox3 (unlike Flex or Silverlight) and on IE the Scenegraph applets would not even load...they were getting ActiveX errors!

So, I am happy for your optimism...but right now we are way behind both Flash and Silverlight. I hope JavaFX/Java6u10 can turn the tide, but they're so late already the window of opportunity may be closing.

 

Kevin Daly replied on Fri, 2008/07/11 - 10:41am

Last post, i've got tons of code to write.

I agree that expression blend is awsome, but It's not cross platform, so it's a non starter for me.

As far as being "behind", its all a matter of perspective, once Update 10 is out Java will be "ahead" in many ways. I'd love to see an OpenGL game such as the one based on Quake that was presented at JavaOne (don't remember the name), run in Flash or Silverlight. I'd love to see  someone drag and drop an applet out of the browser like was demonstrated at JavaOne.

The JRE is much more compete than the Flex API & much more mature than Silverlight (it is also cross platform as well), so we're ahead there now.

Java has a vibrant open source community for components/frameworks such as Hibernate/Echo/Spring/Pivot etc etc etc. so we're ahead there as well.

etc etc.

Michael Bien replied on Fri, 2008/07/11 - 12:59pm in response to: Kevin Daly

[quote=kedaly]I'd love to see an OpenGL game such as the one based on Quake that was presented at JavaOne (don't remember the name), run in Flash or Silverlight.[/quote]

its called Jake2 and is a 1:1 port of Quake2 to java using JOGL (or LWJGL) as OpenGL binding.

original website:

http://bytonic.de/html/jake2.html

 the demo applet you saw @ J1 is here:

http://download.java.net/javadesktop/plugin2/jake2/

hassen karkar replied on Sun, 2008/08/03 - 8:30am

I'am working with javafx using javafx plugin for eclipse. i don't know how can i use the javafx compiler to run applications.

i used "javafx.ui" package and now when i import "javafx.ext.swing" there are errors even i had added the jars from "openjfx-compiler-tp1\dist\lib" to my project source path.

code :

import javafx.ext.swing.*;

SwingFrame {
    height: 600
    width: 500
    visible: true
   }

error : incompatible types: expected com.sun.javafx.runtime.location.IntVariable, found Integer in width: 500

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.