A friend forwarded a email to me a couple days ago from a researcher who wanted to record children sketching on a computer using a graphics tablet. So they could play it back later and watch how they did it etc. It sounded like a cool little app and as I was bored while waiting for a plane back from the IJTC conferance I thought I would have a quick go, how hard can it be 🙂
So here is what I had after a couple hours:
The biggest challenge I had was to stop adding more and more features as it was so easy. If I do some more then I would like to make it save to my website so I can have a gallery of what people have created that other people can replay, maybe next time I have a flight I will do that.
To start with I just wanted to create a simple canvas that I could scribble on and see how it worked, I was suprised how simple it was. Here is the code:
Stage{
title: "Sketch"
scene:
scene = Scene{
width: 400
height: 400
content: [
lines
Rectangle {
width: bind scene.width
height: bind scene.height
fill: Color.TRANSPARENT
onMousePressed: function (e:MouseEvent) {
insert currentPath = Path{
elements: MoveTo{ x: e.x y: e.y }
} into lines.content;
}
onMouseDragged: function (e:MouseEvent) {
insert LineTo{ x: e.x y: e.y } into currentPath.elements;
}
onMouseReleased: function (e:MouseEvent) {
insert LineTo{ x: e.x y: e.y } into currentPath.elements;
currentPath = null;
}
}
]
}
}
It works pretty well for such a basic way of doing it but is limited by the frequency at which it receives mouse events. Interestingly it works way better with a graphics tablet than a mouse as you seem to get many more events. There are also some Java libraries out there for interfacing with graphics tablets to get pressure and tilt information so we could link that in to vary the stroke width for example. I also thought about algorithms that could convert the series of points into smooth curves. There are loads of cool things that could be done with this but it is amazing how useable the dumb/simple version is.
If you would like the Netbeans project with the source so you can play with it Dowload Here. If you have any extra features you add please send them to me and I will post a new version. If there is much interest then we could create a opensource project for a JavaFX Painting application.
10x for shareing all these very nice JavaFX demos ….
Just wondering if there is any chance that you-ll start blogging some JavaFX examples/counterparts for the well known Shine Draw
(http://www.shinedraw.com/) Flash vs. Silverlight examples.
Keep the good work …
Great app! I am just getting started with JavaFX development and I was wondering what you would have to do to add the ability to export the created drawing as an image? If you knew the answer or could point me towards somewhere where I may find the answer I would appreciate it!
I don’t know of a simple way of rendering the javafx scene to a image but as its all very simple paths you can use Java2D to do it very simply. Create a new java.awt.image.BufferedImage of type INT-ARGB then call createGraphics() on it which will give you a Java2D Graphics context. You can then loop though all the Path objects much like I do in the replay and draw them to the graphics context, setting the color, stroke and then drawing. Once done close the graphics and use javax.imageio.ImageIO.write(,”PNG”,new File(“path”)) that will save the image out as a png at the path you specify. Hope that helps, should be about 10 lines of code.
Is there an issue with saving an image through ImageIO in the “JPG” format after it has been manipulated through an ImageView effect? I’ve noticed several examples use PNG, but our website has standardized on JPG. I’ve been working on a variation of the “Effects Playground” demo. When I modify an image through an ImageView effect and then save in JPG format the resulting image changes drastically. The effect is most noticeable when you view the resulting images in different viewers (e.i. “Windows Picture and Fax Viewer” versus “QuickTime PictureViewer”).
Curtis: I am not quite sure how you are saving out the image with effects applied, I assume you are getting the underlaying swing component and rendering to BufferedImage with Java2D then saving. If that is the case I can not see why there should be a issue with JPEG vs PNG. What format is the BufferedImage? The only thing I can think of is you are saving the JPEG with a odd color space or something like that, you may need to play with the ImageIO settings or the type of buffered image you create to render into. JPEG uses a very odd color space by standard “YCbCr” not RGB as it compresses better with less loss of quality. I think JPEG format can store RGB which might be what ImageIO is doing as that is probably what you are passing to it to save. As RGB format JPEGs are not as common there might be issues in some viewers. I may not be 100% right on this little rusty but think its something like this.
I just found the problem and I think it is along the same lines as your response. I copied part of the demo that was working with a PNG and a BufferedImage that was created with the TYPE_INT_ARGB parameter. When I changed it to TYPE_INT_RGB the saved JPGs started matching the ImageView, as well as several external viewers. Thank You.
Very cool example. I really liked it.
Hi!
I altered the Sketch program!
I put a button to save the drawed image.
Check out in my blog:
http://williamantonio.wordpress.com/2009/07/21/salvando-imagens-com-javafx/
I used Rakesh’s example to save the image:
http://blogs.sun.com/rakeshmenonp/en_US/entry/javafx_save_as_image
It’s works well for me.
Thanks a Lot!
Do you mind if I share this information to my students? I will properly cite you.
Thats fine 🙂
The applet on this page just shows a spinning logo.
Ausnahme: Ressource konnte nicht geladen werden: (http://dl.javafx.com/Decora.jnlp, 1.0.1)
com.sun.deploy.net.FailedDownloadException: Ressource konnte nicht geladen werden: (http://dl.javafx.com/Decora.jnlp, 1.0.1)
at com.sun.deploy.net.DownloadEngine.actionDownload(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getCachedFile(Unknown Source)
at com.sun.javaws.LaunchDownload.downloadExtensionsHelper(Unknown Source)
at com.sun.javaws.LaunchDownload.downloadExtensionsHelper(Unknown Source)
at com.sun.javaws.LaunchDownload.downloadExtensions(Unknown Source)
at sun.plugin2.applet.JNLP2Manager.prepareLaunchFile(Unknown Source)
at sun.plugin2.applet.JNLP2Manager.loadJarFiles(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by:
java.io.IOException: bad version response from server:1.1.1
at com.sun.deploy.net.DownloadEngine.actionDownload(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getCachedFile(Unknown Source)
at com.sun.javaws.LaunchDownload.downloadExtensionsHelper(Unknown Source)
at com.sun.javaws.LaunchDownload.downloadExtensionsHelper(Unknown Source)
at com.sun.javaws.LaunchDownload.downloadExtensions(Unknown Source)
at sun.plugin2.applet.JNLP2Manager.prepareLaunchFile(Unknown Source)
at sun.plugin2.applet.JNLP2Manager.loadJarFiles(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Ausnahme: com.sun.deploy.net.FailedDownloadException: Ressource konnte nicht geladen werden: (http://dl.javafx.com/Decora.jnlp, 1.0.1)