This entry is just an attempt to start rolling something useful with JavaFX. I wanted to create a simple list of the most recent blog entries on OnJava using JavaFX. Starting simple, I wrote a very simple JavaFX application that parses the OnJava ATOM feed and just draws an array JavaFX Script Groups containing a Rect an two Text nodes.
Impressions after a few days
Pay attention to this technology. It’s at a very early stage, but, from what I see if could become very useful, very quickly with some minor improvements. It is very easy to dismiss JavaFX as hype, or to say that Sun will never compete with Adobe’s Flex, but I’m less interested in the horse race and more interested in the technology. While there are a few people out there blogging about initial experiences with JavaFX coding, the vast majority of commentary on JavaFX is being written by developers who haven’t bothered to use it. I’m not going to render judgement on this technology for another few weeks. In the meantime, I’m going to get involved, get my hands on the technology and use it.
A little buggy? Anyone else having issues running a JavaFX script via the ScriptEngine? I’m getting concurrent modification exceptions every other time I try to run this application from NetBeans 6. Either I’m doing something terribly wrong or the JavaFX runtime is an early stage alpha.Update: JavaFX isn’t buggy as I had previously suggested. Any exceptions that were being thrown were a problem in my Main class. I was trying to execute the FX script in the EDT. For an update to this post, read Correcting a Swing Mistake.- Not nearly as capable as Adobe Flex, but I can see the potential for easier integration with existing Java libraries.
JavaFX is so new there’s little documentation. (Actually that’s not fair, there’s a good deal of reference and some tutorials, but there is very little “here’s how you do X” documentation yet.) I’ve assembled a sample JavaFX application that includes a JavaFX component as a JComponent in a Swing application, but don’t view this application as a blueprint for your own application. There’s a good reason this isn’t an article - it is not a tutorial but my attempt to capture the first few hours of my experience with the technology. (Read: experimental)
Now on to the code…Application Output
I’m going to write this blog entry backwards - first, here is what the following application produces. A simple list of blog entries on the OnJava site. Each entry consists of a rounded rectangle which contains the title and the author. Here’s a screenshot:
No super-sexy rich media here, just some boxes. Eventually this application might grow to include some animations and interactivity, but my primary goal for this “first step” was to integrate a GUI written in JavaFX script with some existing Java classes that can parse an Atom feed. Maybe the next step will include some interesting visual effects.
The Code
First things first. I used Netbeans to write this application, and I followed the tutorial from the OpenJFX.org site to set up my project. The project depends on two external dependencies: JDOM 1.0 and ROME 0.8. There are two Java classes: Main and FeedReader, and one JavaFX file Ticker.fx. If you want to try to recreate this code, please feel free to copy and past the code into your project. Now to the code:
Main.java
Here are the contents of my Main class. (Thanks to Chris Oliver for quickly answering a question on the javafx-user mailing list - he gets credit for most of this main function). The line “String script = ‘import….” is the one that executes the script in Ticker.fx. If you want to know what the code does, just follow along in the comments…
IMPORTANT UPDATE: There is a problem in the following class. I was trying to execute the FX script in the EDT. For an update to this post and to see the new Main class source code, read Correcting a Swing Mistake. I made a newbie Swing mistake, which is expected I gave up on Swing a few years ago, and only now do I have a reason to pay attention to GUI programming.
package com.oreilly.onjava.feedticker;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Date;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
import javax.swing.JFrame;
public class Main {
public Main() {
}
public static void main(String[] args) throws Exception {
// Constructs a FeedReader that reads the OnJava blog Atom feed
FeedReader reader = new FeedReader(new URL("http://www.oreillynet.com/onjava/blog/atom.xml"));
reader.read();
JFrame frame = new JFrame("Ticker");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize( 500, 400 );
// WARNING THIS IS WRONG, SEE THE UPDATE POST...
// Get the fx scripting engine - javafxrt.jar in classpath...
ClassLoader loader =
Thread.currentThread().getContextClassLoader();
ScriptEngineManager manager = new ScriptEngineManager(loader);
ScriptEngine engine = manager.getEngineByExtension("fx");
// Bind the feed reader to the script's bindings...
Bindings bindings = engine.createBindings();
bindings.put("READER:com.oreilly.onjava.feedticker.FeedReader", reader);
// Bind a JComponent to the script's bindings... the JavaFX script creates a canvas and adds
// itself to this component.
bindings.put("MY_CONTAINER:javax.swing.JComponent", frame.getContentPane());
ScriptContext context = new SimpleScriptContext();
// Bug workaround (don't ask me, I have no idea what this means...TO)
context.setBindings(bindings, ScriptContext.GLOBAL_SCOPE);
context.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
engine.setContext(context);
// Evaluate the Script
String script = "import com.oreilly.onjava.feedticker.Ticker;";
engine.eval(script);
// Show the frame
frame.setVisible(true);
}
}
Ticker.fx
Ignore the FeedReader class, just accept that it reads an Atom feed using the ROME API. We’ll get to that next. What should be more interesting is the contents of the Ticker.fx file. Some things to notice - it’s pretty lightweight compared to what you’d need to do in a regular Swing application. Also, note that the last line adds the var canvas to the JComponent that was set as a binding.
package com.oreilly.onjava.feedticker;
import javafx.ui.*;
import javafx.ui.canvas.*;
import javax.swing.JComponent;
import com.oreilly.onjava.feedticker.FeedReader;
import javafx.ui.filter.*;
var reader:FeedReader = READER;
var canvas = Canvas {
height: 500
width: 445
content:
VBox {
content:
foreach (i in reader.entries)
Group {
content:
[Rect {
x: 5
y: 5
height: 40
width: 435
arcHeight: 20
arcWidth: 20
fill: lightgrey
stroke: black
strokeWidth: 1
filter: [ShadowFilter]
},
Text {
content: bind i.title
font: Font {face: VERDANA, style: [ITALIC, BOLD], size: 14}
transform: translate(10, 10)
},
Text {
content: bind i.author,
font: Font {face: VERDANA, size: 12}
transform: translate(310, 30)
}]
}
}
};
MY_CONTAINER:JComponent.add(canvas.getComponent());
FeedReader.java
And, finally, here are the contents of my FeedReader class:
package com.oreilly.onjava.feedticker;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;
import java.io.IOException;
import java.net.URL;
public class FeedReader {
private URL url;
private SyndEntry[] entries;
private Integer titleLength = 50;
public FeedReader(URL url) {
this.url = url;
}
public void read() throws IOException, IllegalArgumentException, FeedException {
SyndFeedInput input = new SyndFeedInput();
SyndFeed feed = input.build(new XmlReader(url));
entries = (SyndEntry[]) feed.getEntries().toArray(new SyndEntry[0]);
// Abbreviate Titles
for( SyndEntry entry : entries ) {
entry.setTitle( entry.getTitle().length() > titleLength ? entry.getTitle().substring(0, titleLength - 3 ) + "..." : entry.getTitle() );
}
}
public SyndEntry[] getEntries() {
return entries;
}
public void setEntries(SyndEntry[] entries) {
this.entries = entries;
}
}



HI Tim,
informative one to get started learning JavaFX.
nice post.
I like these
@Krishna and @Tony, thanks, expect more like this in the future. I'm starting to use the blog as a place for rough technology writing.
The one thing I'm amazed about with this particular example is how it fits in a few pages. I'm still skeptical about JavaFX as a practical technology, but I'll have to say that the script definitely saved some me from writing some very annoying Swing code.
Also, it is rare that you can write an article or a blog entry and cut and paste entire files. Imagine cutting and pasting an entire Spring XML file or the code just to render a simple web page. In some ways, I'm appreciating that JavaFX may be lighter than Flex, but I'm not installing Adobe Flex builder any time soon.
HI Tim,
Do you feel JavaFx will realy compete with silverlight or Flex. I am seeing many blogs comparing these three technologies. Also I wanted to know how this can replace AJAX. javafx is about creating UI based on swing applications.where ajax is purely javascript. its hype?
@Krishna, good questions all of them. I think that you can't avoid comparing JavaFX to Flex. Flex is the current champion, I use Flex every single day, and I really think that Macromedia got it right with Flex.
I do think that once a web application scales past a certain point of interactivity that it no longer makes sense to rely only on AJAX. AJAX can do *almost* anything, but you can't beat Flash whenit comes to interactivity at the moment. Plus, if you've ever tried to code an application with very fine detailed interactivity based on AJAX you'll find that it becomes impossible to keep track of all of the detail (even with Rails or GWT). But I think that there is a spectrum of opinion, I think that the next few years will see the emergence of fluid interfaces, a slight deemphasis of the browser. If I were to bet, I put my money on Flex because they have the developer mind-share and the creative mind-share. But, don't rule out JavaFX, here's why...
...in just a few days, a really interesting community has taken root over at openjfx.org. Sun didn't announce a finished product, they announced a product that is still in the initial stages and they've made it an open source project. I think it will take them at least six months to catch up with Flex features.
So, yes, it is very early, and, no, it isn't hype. I think you'll see a few interesting applications released on the current JavaFX release over the next few months.
Tim,
sounds good. i havn't worked on flex or javafx. after seeing the new trend in RIA's, want to start learning those technologies. i just updated java-fx plug-ins into my Netbeans 6.0 M9. lets me write few programs on javafx. which tool you are using for Adobe flex?
credit goes to netbeans..i have writen simple program using NetBeans. it works fine.
import javafx.ui.*;
Frame {
title: "Test Application"
width: 300
height: 100
visible: true
menubar: MenuBar {
menus: Menu {
text:"File"
items: MenuItem {
text:"Open"
}
}
}
}
Hi,
Is there a specific reason that you wrote a main file? I'm also trying to create a simple functional application, but I'd like to use the standard FXShell to do it, although I will refer to existing java libraries (which is, I think, the biggest advantage javaFX has over Flex). I don't like dependencies from java code to javafx scripts.
Why wrap JavaFX code (which uses Java) in another java program?
@Krishna, I'm using NB 6.0M9, the JavaFX plugin is very buggy. For example, the editor tells me that the Ticker.fx I have has a few errors, it can't import the FeedReader class. But, the program compiles anyway. On the user list yesterday coliver mentioned that the NB5.5 plugin is better.
I'm also having issues because I'm an Eclipse user, and I'm still trying to figure out NetBeans.
@Frank, I'm exploring this method of JavaFX integration because I think that there are going to be a number of people who are interested inusing JavaFX but not rewriting an entire application in JavaFX script. I'm also interested in exploring JavaFX integration with other technologies - I want to see how the JavaFX works with the bindings - could we develop a good JavaFX front-end that sits atop a bunch of Spring managed beans, etc.
I'm definitely not saying this is the right way to do JavaFX, this is just an option. I think that people are going to be interested in integrating JavaFX with an existing program first not necessarily adapting an existing program to JavaFX. I think this provides an avenue for people interested in that route to JavaFX
Yet another language to learn? Crap
@Martin, then don't use it. If you want to code this application in direct Java2D, go straight ahead. Or, if you want to continue writing Swing code, no one is stopping you.
Tim,
you are correct. i have installed Netbeans 5.5. I have tried with 6.0 M9. its not working properly. throws exception about scriptengine is missing. i couldn't solve the error, i moved to 5.5
also its interesting to see how html code is used in the Java FX. it will be more useful for developing the complex screens. i realy liked it.
I have it working fine in M9. All I did was follow the directions which are posted on openfx.org as it says above. Once you've done that, you must download the dependencies as described above. You can then create a new JavaFX application and use the files above. Works without issues...
Nothing really matters without a good deployment strategy and rich multimedia support. If Sun had done a good job 12 years ago with application deployment, we would have seen Java applets and Java desktop applications everywhere already. They can talk all about JavaFX, but at the end, it is the Java run time that will determine the success or failure of JavaFX
@Anonymous, sure. Nice opinion, but in a strange way it has little to do with the good discussion Krishna, Frank, Josh and I were having with one another. Sure, Java on the client side has problem, again, if you don't like it, don't use it. Happy enough if you want to submit an example of the same application in Silverlight.
@Josh, thanks for the note, I'm sure I'm doing *something* wrong in NetBeans. Glad to hear it works for you.
If you just want to use javaFX to create a GUI using existing java classes, you don't need to create a custom main file. You can replace the Ticker.fx by the following code. In that case you only need the FeedReader class. I think it shows the power of JavaFX better for simple applications. For complex embedding it might still be necessary to create a custom main file, but seeing its complexity I'd avoid it (also, I would not have a clue on how to write that
package com.oreilly.onjava.feedticker;
import javafx.ui.*;
import javafx.ui.canvas.*;
import javax.swing.JComponent;
import com.oreilly.onjava.feedticker.FeedReader;
import javafx.ui.filter.*;
import java.net.URL;
//var reader:FeedReader = READER;
// Added these lines:
var reader:FeedReader = new FeedReader(new URL("http://www.oreillynet.com/onjava/blog/atom.xml"));
reader.read();
// --
var canvas = Canvas {
height: 500
width: 445
content:
VBox {
content:
foreach (i in reader.entries)
Group {
content:
[Rect {
x: 5
y: 5
height: 40
width: 435
arcHeight: 20
arcWidth: 20
fill: lightgrey
stroke: black
strokeWidth: 1
filter: [ShadowFilter]
},
Text {
content: bind i.title
font: Font {face: VERDANA, style: [ITALIC, BOLD], size: 14}
transform: translate(10, 10)
},
Text {
content: bind i.author,
font: Font {face: VERDANA, size: 12}
transform: translate(310, 30)
}]
}
}
};
// -- Create a frame in JavaFX, instead of the java code:
Frame {
width: 500
height: 800
content: canvas
visible: true
}
//--
//MY_CONTAINER:JComponent.add(canvas.getComponent());
@Frank, awesome, thanks for the comment.
I created a main because I'm taking the application in a different direction. Stay tuned. Next steps include integrating this with an existing backend (using Spring Framework)
hi,
i want to deploy my helloworld.fx in a webserver i.e tomcat.i created the app in neatbeans 5.5.
in the deployment steps they had given steps reg. sign the jar.
the step is to copy the helloworld.fx,helloworld.jar,f3start.jar into my webserver folder.
they had given f3start.jar found in lib folder.
but i can't find that jar any where in the system.
can anyoen pls help out regarding thsi issue
thanks in advance
Goodjob
very useful article for someone starting on JavaFX. I agree this technology has potential.
Hi Tim,
Nice post - I whole heartedly agrre with you w.r.t. Flex (posting: May 15, 2007 06:28 PM). I think that JavaFX Script could be a strong competitor and offer some valuable competition to Flash/Flex - esp. with the announcements regarding the Java kernal and better install experience.
The thing that really attracts me to this approach is the nice syntax and the backing by the J2SE library which (IMHO) is far better organised and more comprehensive than the current Flex/Flash offering
Anyways, nice post
Alex
@Alex, I've been meaning to finish the follow up to this article for about a week now. I've brought the application to the next step (and at the same time developed a Flex analog). Flex is more mature, clearly, but what draws me to JavaFX is that, in JavaFX I can use any existing class in Java. So, if I need to do something manipulate a collection or parse some XML there are hundreds of components out there for me to choose from. Flex is capable, but I'm constantly trying to rewrite something that is already available in Java.
That being said, I like both Flex and JavaFX, I can see places where I'm going to prefer JavaFX over the other. And I think JavaFX isn't really competing directly with Flex, if anything I think it expands the market to people currently using Swing and it opens the door for developers currently avoiding Swing. But, I'm happy about the fact that there are some brilliant people working for Adobe on Flex and some brilliant people working for Sun on JavaFX.
Oh, and isn't Microsoft working on something similar. :-) I'm ignoring Silverlight for the moment, I don't have any plans on buying internet enabled coffee-tables.
Firstly, as a javaFX learner, i must say this article helped me very much.Thank you.
But i have a question about Ticker.fx code.
I'm using eclipse and writing
"var reader:FeedReader = READER;"
gave me "undefined variable READER in reader:FeedReader=READER" error. I couldn't find why.
can you use classes from an external JAR in JavaFX ??
I am hard-trying to achieve this, but it seems impossible :)
** Not JavaAPI and Swing classes, I mean real third party APIs
HI this is ur Prob