Skip to main content

Effects in JavaFX: The Basics

Posted by campbell on January 5, 2009 at 12:12 AM PST

Still Alive

In early 2008, I wrote my only blog entry of the year, on the subject of the filter effects framework that serves as part of the foundation of JavaFX. It has been a fun project to work on, and I'm fairly proud of the result. There was so much more I wanted to write about on the subject, but I wanted to wait until we first had a stable API and delivered an actual product.

It was a long road to JavaFX 1.0, but now that it has shipped, I can finally talk more about using filter effects in JavaFX and what's going on behind the scenes. Since it's a big subject, I'll try to break things up into smaller, more focused blog entries instead of my usual monolithic tomes. (At minimum, it will provide the illusion that I'm more prolific in 2009 than I was in 2008.)

Like any good graphics API, the filter effects framework in JavaFX is easy to use, provides high-quality visual results, and offers top-notch performance. In this entry, I'll just focus on the ease-of-use angle.



Bunny Jump, Bunny Jump

The best place to start is to look at the javafx.scene.effect package API. All of the core filter effect classes extend the abstract javafx.scene.effect.Effect base class. Any Effect instance can be applied to a scene graph Node by setting the Node.effect variable. Each Effect subclass exposes a small number of variables that control the visual appearance of the Node. In addition, most Effect subclasses provide one or more input variables that can be used to "chain" effects (more on that in a future blog entry).

To take a specific example, the DropShadow class provides 5 variables, analogous to knobs on a control panel: color, offsetX, offsetY, radius, and spread. Each "knob" is generally documented with default, minimum, maximum, and identity values, which makes it easy to see the acceptable range of values. Here's a really simple example that shows how to apply a DropShadow effect to a rounded Rectangle and control its appearance through the magic of the bind operator.

And here's the relevant code (or download the complete sources here):


            Rectangle {
                effect: DropShadow {
                    radius: bind radius
                }
                x: 50 y: 30 width: 150 height: 100
                arcWidth: 40 arcHeight: 40
                fill: Color.RED
            }

That's it! Pretty easy, isn't it? You, the developer, only need to concern yourself with turning these simple knobs. The effects framework does all the heavy lifting for you, such as painting the Node into an offscreen image at the appropriate resolution, manipulating the pixels in one of the CPU and/or GPU accelerated backends, and automatically repainting the affected portion of the scene.

For more interactive examples of the built-in Effect subclasses, check out the EffectsPlayground applet featured in the JavaFX Samples Gallery. Stay tuned for entries on quality, performance, and more...


In my ears: No Age, Nouns


In my eyes: Woody Allen, Mere Anarchy

Related Topics >>

Comments

Surprised to see how well JavaFX works in Ubuntu and that JavaFX can run under Sun JRE 6 (update 7). When the applet started up the JavaFX runtime was installed very easily with no fuss and Firefox did not freeze at all!

Having some trouble on my mac. Any thoughts on how to fix it? JNLPAppletLauncher: static initializer java.io.IOException: Cannot access /tmp/jnlp-applet/jln39035 at org.jdesktop.applet.util.JNLPAppletLauncher.initTmpRoot(Unknown Source) at org.jdesktop.applet.util.JNLPAppletLauncher.(Unknown Source) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at java.lang.Class.newInstance0(Class.java:350) at java.lang.Class.newInstance(Class.java:303) at sun.applet.AppletPanel.createApplet(AppletPanel.java:723) at sun.plugin.AppletViewer.createApplet(AppletViewer.java:1864) at sun.applet.AppletPanel.runLoader(AppletPanel.java:652) at sun.applet.AppletPanel.run(AppletPanel.java:326) at java.lang.Thread.run(Thread.java:613)

Looks good on my mac osx 10.5.6 Nice job!

Very small and effective example. Hope to see more filter supports soon. Applet is running in my case.

Ps something really odd happens every time I've commented (from Firefox) after hitting POST the page gets replaced by just the applet..?

Works for me in Firefox with 6u10 now thanks, ie7 is still reporting no Java installed and trying to download 6u11 constantly. Well it did that until I cancelled the download now the ie7 browser crashes every time I try to visit this page or any of the JavaFX demos. No Java installed error prompts seem to be coming from the dtfx.js script. Not sure why a reboot would be necessary as I've not reinstalled anything recently and Firefox seems happy now (after restarting that browser - was doing the no java, install u11 trick before your fix). Nuking the ie7 cache and restarting ie7 didnt help.

Sorry, forgot to re-upload the jnlp file (which is needed on 6u10 and above). Hopefully things are working again...

Oh the EffectBasics_browser.jnlp is missing for me too? (didnt see the error until switching to ie) what initiated the runtime download then? that looks like the usual JWS ext (which'd need the jnlp). Error dialogs dont look much like JWS though.. Hmm unless the u11 culprit was the decora, jmc extensions which get loaded first.. UX needs work on error trapping and how many times do I have to hit cancel to really mean it?

Had a horrible experience with the Applet too. First it demanded 6.0u10 wasn't up-tp-date enough to show JavaFX, then tried to download a web start ext of 6.0.u11 the cancelling of which isn't handled at all well. Almost couldn't see the post for all the popup dialogs & errors. Wouldn't 1.6+ work just as well in the JNLP? the UX ruins the JavaFX experience for me. May have to install noscript if this keeps up (would that work or do I need to greasemonkey java.net to knock out any applets?).

Rats! Can't see the applet either: exception: null. java.io.FileNotFoundException: JNLP not available: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas... at sun.plugin2.applet.JNLP2Manager.loadJarFiles(Unknown Source) at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Exception: java.io.FileNotFoundException: JNLP not available: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas...

Applet works fine. I think I need to look into JavaFX now that demos are starting to appear. It looks great.

Interesting article, thanks.I don't see your example applet though, and I have the following error in my Java console: java.io.FileNotFoundException: http://download.java.net/javadesktop/blogs/campbell/2009.01.05/EffectBas...

jdk7, windows, firefox, errors: netscape.javascript.JSException at netscape.javascript.JSObject.getWindow(Unknown Source) at com.sun.javafx.runtime.adapter.Applet.hideOverlay(Unknown Source) at com.sun.javafx.runtime.adapter.AppletStartupRoutine.run(Unknown Source) at com.sun.javafx.tk.swing.SwingToolkit$StartupRoutine.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) java.lang.ClassCastException: com.sun.scenario.effect.impl.j2d.J2DMergePeer cannot be cast to com.sun.scenario.effect.impl.j2d.rsl.RSLEffectPeer at com.sun.scenario.effect.impl.j2d.rsl.RSLRenderer.dispose(Unknown Source) at com.sun.scenario.effect.impl.j2d.rsl.RSLRenderer$1.onDeviceReset(Unknown Source) at sun.java2d.pipe.hw.AccelDeviceEventNotifier.notifyListeners(Unknown Source) at sun.java2d.pipe.hw.AccelDeviceEventNotifier.eventOccured(Unknown Source) at sun.awt.windows.WToolkit.eventLoop(Native Method) at sun.awt.windows.WToolkit.run(Unknown Source) at java.lang.Thread.run(Unknown Source) BTW, I think it's not very wise to install JavaFX runtime separately. Java applets and webstart applications should be able to include a JavaFX runtime jar from the JavaFX site and cache it without any user interference.