<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JavaFX News, Demos and Insight // FX Experience &#187; General</title>
	<atom:link href="http://fxexperience.com/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://fxexperience.com</link>
	<description>Sharing the Experience of JavaFX</description>
	<lastBuildDate>Mon, 21 May 2012 03:34:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Introducing Scenic View</title>
		<link>http://fxexperience.com/2012/05/introducing-scenic-view/</link>
		<comments>http://fxexperience.com/2012/05/introducing-scenic-view/#comments</comments>
		<pubDate>Mon, 07 May 2012 00:11:50 +0000</pubDate>
		<dc:creator>Jonathan Giles</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Layout]]></category>
		<category><![CDATA[UI Design]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1956</guid>
		<description><![CDATA[Developing user interfaces is tricky, regardless of whether you&#8217;re just trying to understand the high level scenegraph layout, or whether you&#8217;re pushing pixels for a finely tuned user interface. I understand and feel for people in this situation. UI developers come up with all kinds of tricks, for example, temporarily introducing a bold one pixel [...]]]></description>
			<content:encoded><![CDATA[<p>Developing user interfaces is tricky, regardless of whether you&#8217;re just trying to understand the high level scenegraph layout, or whether you&#8217;re pushing pixels for a finely tuned user interface. I understand and feel for people in this situation. UI developers come up with all kinds of tricks, for example, temporarily introducing a bold one pixel border of varying colours around components to better understand the user interface. I certainly know I have done that countless times in the past when building user interfaces, and frankly, it is painful and massively time consuming.</p>
<p>Inside the JavaFX team, since times of yore (that is, since at least JavaFX 1.3, but perhaps earlier &#8211; my memory fails me here), we&#8217;ve had this remarkable little tool that was called Scenic View. It somehow just burst into existence, through the brilliance of <a href="http://amyfowlersblog.wordpress.com/">Amy Fowler</a>, whom many should know as the layout guru for both Swing and JavaFX. Scenic View is a tool that can be called to browse a live view of the application scenegraph. Here&#8217;s a screenshot:</p>
<p><img class="aligncenter size-full wp-image-1958" title="sv1" src="http://fxexperience.com/wp-content/uploads/2012/05/sv11.png" alt="" width="668" height="593" /><span id="more-1956"></span></p>
<p>The nice thing about Scenic View is that it can also display overlays in your user interface to indicate three things: the baselineOffset, the boundsInParent, and the layoutBounds. These let you very easily see why your user interface is the way it is. I&#8217;ve attached another screenshot below, which shows this. The third rectangle in has been selected in ScenicView, and as such has a yellow filled rectangle to indicate its boundsInParent, and a green dashed (and unfilled) rectangle to indicate the layoutBounds. The interesting thing to note is that despite the rectangle having been rotated, the layoutBounds still reflect the unrotated rectangle, and that this is what the layout containers use to lay out nodes. In other words, the rectangles on either side of the rotated rectangle make no allowance for the rotation (although there are ways to force this to happen if that is what you want &#8211; listen to Amy&#8217;s talk (linked below) to learn more).</p>
<p><img class="aligncenter size-full wp-image-1960" title="sv2" src="http://fxexperience.com/wp-content/uploads/2012/05/sv2.png" alt="" width="545" height="451" /></p>
<p>Amy presented her <a href="http://www.parleys.com/#st=5&amp;id=2734&amp;sl=0">Introduction to JavaFX layout</a> talk at JavaOne San Francisco in October 2011, and I&#8217;ve gone on to re-present it at JavaOne conferences in Japan and India. What we covered in these talks was a whole bunch of layout fundamentals, and then we worked through how to use these fundamentals to build a JavaFX user interface. The worked example was on building aspects of the Scenic View application, and then we used the Scenic View application to demonstrate some of the layout concepts we had spoken about previously.</p>
<p>The Scenic View application shown above only differs visually from what Amy presented at JavaOne (which you can see in the link above). This is all I&#8217;ve done &#8211; the rest is all from Amy. What you can see in the image above is standard JavaFX, styled with a bit of custom CSS (borrowed heavily from Scene Builder). There are still a few visual quirks I&#8217;d like to improve, but I&#8217;ve been wanting to get this released for a very, very long time, so I&#8217;ll do that first, and then we can talk about improvements.</p>
<p>So, today, I am finally able to put up a <a href="http://dl.dropbox.com/u/6320469/ScenicView.jar">jar file of the ScenicView application</a>. Drop this into your project, and simply fire up Scenic View by calling ScenicView.show(scene) with the scene of your application. There is actually a secret shortcut that will automatically start up Scenic View from your running application, but that won&#8217;t stay around forever so I won&#8217;t publicise it (although it is in our open source code, so maybe you can find it)&#8230;.</p>
<p>Please, leave comments, requests for functionality, and offers to add said functionality in the comments section below. I look forward to your feedback.</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/05/introducing-scenic-view/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Extending PathBuilder</title>
		<link>http://fxexperience.com/2012/01/extending-pathbuilder/</link>
		<comments>http://fxexperience.com/2012/01/extending-pathbuilder/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 21:51:56 +0000</pubDate>
		<dc:creator>Jasper Potts</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1613</guid>
		<description><![CDATA[I came across the interesting blog &#8220;JavaFx and HTML5 differences&#8221; by Chika Okereke. Looking at the example code and comparing to the HTML Canvas version I thought the Java code could be made less verbose and easier to read. Original Code So I hacked together a Extended version of the PathBuilder that ships with JavaFX [...]]]></description>
			<content:encoded><![CDATA[<p>I came across the interesting blog <a href="http://www.jpedal.org/PDFblog/2012/01/javafx-and-html5-differences-shapes-work-differently/" target="_blank">&#8220;JavaFx and HTML5 differences&#8221;</a> by Chika Okereke. Looking at the example code and comparing to the HTML Canvas version I thought the Java code could be made less verbose and easier to read.</p>
<p><b>Original Code</b>
<pre class="brush: java; title: ; notranslate">Path path_4 = new Path();
ObservableList shape_4 = path_4.getElements();
shape_4.add(new MoveTo(50,50));
shape_4.add(new LineTo(150,50));
shape_4.add(new LineTo(150,150));
shape_4.add(new LineTo(50,150));
shape_4.add(new LineTo(50,50));
path_4.setStrokeWidth(2);
path_4.setStroke(Color.rgb(255,0,0));</pre>
<p>So I hacked together a Extended version of the PathBuilder that ships with JavaFX 2.0 adding methods for all of the path elements like moveTo() etc. The end result seems much cleaner code to me, what do you think?</p>
<p><b>Code with new Builder</b>
<pre class="brush: java; title: ; notranslate">Path path4 = PathBuilderExtended.create()
        .moveTo(50, 50)
        .lineTo(150, 50)
        .lineTo(150, 150)
        .lineTo(50, 150)
        .closePath()
        .strokeWidth(2)
        .stroke(Color.RED)
        .build();
</pre>
<p>This seemed a lot cleaner and simpler to read. I have filed a feature request <a href="http://javafx-jira.kenai.com/browse/RT-19266">RT-19266</a> in JIRA to add this to the platform. Feel free to comment on the bug if you any feedback or better suggestions. Also I have attached a implementation of this builder to the bug so you can see how it would be implemented or use it with your code today. </p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/01/extending-pathbuilder/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>An FX Experience Retrospective</title>
		<link>http://fxexperience.com/2011/12/an-fx-experience-retrospective/</link>
		<comments>http://fxexperience.com/2011/12/an-fx-experience-retrospective/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 05:41:31 +0000</pubDate>
		<dc:creator>Jonathan Giles</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1569</guid>
		<description><![CDATA[With the end of 2011 nearing, I thought it would be a good time look back on what has happened in the world of JavaFX this year&#8230; As you may recall, it was October 2010, at JavaOne, where Oracle announced publicly that JavaFX was going to see a reboot. It was announced that JavaFX was [...]]]></description>
			<content:encoded><![CDATA[<p>With the end of 2011 nearing, I thought it would be a good time look back on what has happened in the world of JavaFX this year&#8230;</p>
<p><span id="more-1569"></span></p>
<p>As you may recall, it was October 2010, at JavaOne, where Oracle announced publicly that JavaFX was going to see a reboot. It was announced that JavaFX was to transition from the &#8216;JavaFX Script&#8217; language to being built in Java. This decision was made inside Oracle only a month or two prior to the announcement, which led to a number of JavaOne sessions and BOFs being quickly cancelled and replaced to cover the new direction. At JavaOne 2010 the sessions were therefore discussing what was coming, rather than what was available in JavaFX 1.3.1 (which was the last release in the JavaFX 1.x line). I remember showing demonstrations of not much more than rectangles being drawn on screen, using what was then our Java APIs (but which permutated considerably during the course of development). This was the JavaFX 2.0 state of the art at the time, and we have come a long way since then!</p>
<p>Another vivid recollection I have from JavaOne 2010 is the various reactions that people had of this news. It varied from those in shock at losing their favourite language, to those who said it was long overdue and was the right way to proceed with JavaFX. I tried to ease people into this new approach by clarifying that, of course, now that JavaFX is in Java, many other JVM languages can come in to make developing JavaFX more enjoyable again, especially if developers were to write improved DSL extensions to these languages. Fortunately, exactly this has happened, with projects such as <a href="http://groovy.codehaus.org/GroovyFX">GroovyFX</a>, <a href="http://code.google.com/p/scalafx/">ScalaFX</a>, and of course, the JavaFX Script fork, <a href="http://code.google.com/p/visage/">Visage</a>, coming in to simplify the development of rich JavaFX user interfaces.</p>
<p>Work continued apace in redeveloping JavaFX in Java through late 2010, and in early 2011 we begun to offer early access builds of JavaFX 2.0 to close partners. Despite the builds being made available to actual end-developers, API changes were happening at an incredibly rapid pace. I&#8217;m sure this led to great frustration (which is also why the builds were not more widely distributed). Internally, these major API changes were massively helped by our use of <a href="http://projectlombok.org/">Lombok</a> during the early prototype stages, as it allowed for us to create custom annotations to represent our properties, and simply update our Lombok code to recompile with a massively different API. As our API became more stable, we started to remove our dependency on Lombok, and today it is not used at all in our source code.</p>
<p>As development continued with JavaFX 2.0, we started to do something I was, and continue to be, very proud of &#8211; we started making pre-release builds available to the community. This let you, the consumers of the API, provide invaluable feedback to the developers. No one wins when &#8216;big bang&#8217; releases are made without discussion, and frankly, the JavaFX community rock &#8211; whether it is in comments on blog posts, in the <a href="https://forums.oracle.com/forums/forum.jspa?forumID=1385">JavaFX forum</a>, in the <a href="http://mail.openjdk.java.net/mailman/listinfo/openjfx-dev">openjfx-dev mailing list</a>, or in one-on-one emails sent to developers in the JavaFX team (it&#8217;s normally not hard to guess our @oracle.com email addresses!).</p>
<p>As JavaOne 2011 drew closer, JavaFX 2.0 was continuing to see refinement, with APIs being finalised, performance being improved, and bugs squashed. Unsurprisingly for most people, JavaFX 2.0 was released at JavaOne 2011. In addition to porting the JavaFX 1.3.1 source code to Java, JavaFX 2.0 also ships with a huge number of new features that were developed at the same time. I&#8217;m loathe to include a list, as I&#8217;m certain I&#8217;ll miss out plenty of cool stuff, but from my point of view as a controls team member, JavaFX 2.0 includes new API for properties, binding, collections, animation, new controls such as TreeView, TableView, ChoiceBox, Menus, SplitPane, TitledPane, HTMLEditor, and Accordion, improved layout APIs (including GridPane), the WebView component, and much more. In addition to the new API, JavaFX 2.0 ships as the first release to enable the brand new Prism graphics engine, as well as the new Glass framework for windowing and other native operating system integration. Of course, feel free to comment on your favourite new feature (especially if I missed it out)! <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Perhaps the most controversial topic related to JavaFX was its lack of cross-platform support from the get-go &#8211; JavaFX 2.0 shipped as a Windows-only release. The uncertainty around what this meant led Richard (the newly crowned Java Client Architect) to blog about this in his &#8216;<a href="http://fxexperience.com/2011/05/is-javafx-2-0-cross-platform/">Is JavaFX 2.0 Cross Platform?</a>&#8216; post. The general reasoning for this approach was that we could either make a tiered release plan (as we did), and get the Windows build out sooner, or hold back the release for a much longer time so that development of Windows, Mac OS, Linux, etc builds could all get up to the same level prior to release. We ended up doing the tiered release approach, as it meant we could get a solid Windows release out sooner, and focus on getting other platforms solid subsequently. I&#8217;m sure this upset people that wanted support for their preferred operating system from the start, but I&#8217;m also comfortable with the approach taken for the reason above.</p>
<p>Almost as soon as JavaFX 2.0 shipped, JavaFX 2.0.1 was released, as the JavaFX team jumped on the Java release train of alternating security and bug-fix releases. Because of this, JavaFX 2.0.1 shipped only a few weeks after JavaFX 2.0 did, with just a few security-related fixes. Very few engineers inside Oracle were involved in this release, with most focused on the forthcoming JavaFX 2.0.2 release instead.</p>
<p><a href="../2011/12/javafx-2-0-2-released/">JavaFX 2.0.2 was released</a> to coincide with Java 7u2 (which JavaFX is co-bundled with) in early December. JavaFX 2.0.2 includes a huge number of bug fixes, optimisations, some new API, and an improved redistribution license. As mentioned, it was the first release following JavaFX 2.0 that features considerable development effort by all teams. For me it was an exciting release due to the huge number of bugs we were able to squash between JavaFX 2.0 going into code freeze (since about a month before JavaOne) and JavaFX 2.0.2 going into code freeze around early November.</p>
<p>Not content with this pace, <a href="http://fxexperience.com/2011/12/javafx-2-1-early-access-for-windows-build-06-now-available/">JavaFX 2.1 early access builds</a> were also announced in December. JavaFX 2.1 builds are available for Windows and Mac OS, allowing for the same JavaFX code to run on both operating systems without any changes necessary. The JavaFX 2.1 builds are intended to be weekly releases, and of course are not as production-ready as the JavaFX 2.0.2 release (but also not as exciting <img src='http://fxexperience.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ). Already, people are exploring <a href="http://marxsoftware.blogspot.com/2011/12/sneaking-peek-at-javafx-21-beta.html">what is new in these builds</a>, which as of JavaFX 2.1 build 06 includes a bunch of new collections API, a ComboBox control, new charts, and native DirectoryChooser support. There is also plenty more coming in JavaFX 2.1, but which has not hit a public release yet.</p>
<p>Aside from the amazing pace of releases containing bug fixes and new features, I can&#8217;t conclude this look back without mentioning the news that was announced at JavaOne 2011 that all of JavaFX will be open sourced. Already, the <a href="http://openjdk.java.net/projects/openjfx/">OpenJFX</a> project exists, with the UI controls being available (and developed) in the open. Amazingly, the <a href="http://mail.openjdk.java.net/mailman/listinfo/openjfx-dev">openjfx-dev mailing list</a>, which opened up on December 1, has already had <a href="http://mail.openjdk.java.net/pipermail/openjfx-dev/2011-December/thread.html">442 posts</a> in December, and there are 107 people already signed up to the list. The discussion is lively, and brings together community members and Oracle employees to discuss the future of the JavaFX API. Already there have been discussions on a range of topics, and your feedback is appreciated no end.</p>
<p>On a side note, FX Experience, the blog run by Richard, Jasper and I (Jonathan), also continues to grow at a nice pace. In 2009, FX Experience received 54,444 views, at an average of 259 views per day (for the seven months the site was running from June). In 2010, the average daily visitors was 326 people, which led us to have 118,926 visits in 2010. This year, with two days remaining, we grew the visitor numbers to average 530 views per day, resulting in 192,928 visits in the year. I&#8217;m very pleased at the growth this blog continues to see, and hope that it continues for the foreseeable future.</p>
<p>The top 12 posts this year were the following (ignoring the fact that this favours posts from earlier in the year):</p>
<ol>
<li><a href="../2010/09/javafx-2-0/" target="_blank">JavaFX 2.0</a></li>
<li><a href="../2011/07/introducing-fxml" target="_blank">Introducing FXML</a></li>
<li><a href="../2011/05/is-javafx-2-0-cross-platform/" target="_blank">Is JavaFX 2.0 Cross Platform?</a></li>
<li><a href="../2011/05/maps-in-javafx-2-0/" target="_blank">Maps in JavaFX 2.0</a></li>
<li><a href="../2011/05/javafx-2-0-charts/" target="_blank">JavaFX 2.0 Charts</a></li>
<li><a href="../2011/07/worker-threading-in-javafx-2-0/" target="_blank">Worker Threading in JavaFX 2.0</a></li>
<li><a href="../2011/05/javafx-2-0-beta-is-available/" target="_blank">JavaFX 2.0 Beta is Available!</a></li>
<li><a href="../2011/10/fxml-why-it-rocks-and-the-next-phase/" target="_blank">FXML: Why It Rocks, And The Next Phase</a></li>
<li><a href="../2011/02/javafx-links-of-the-week-february-13/" target="_blank">JavaFX links of the week, February 13</a></li>
<li><a href="../2011/05/simple-3d-cubes-in-javafx-2-0/" target="_blank">Simple 3D Cubes in JavaFX 2.0</a></li>
<li><a href="../2011/06/splitpane-in-javafx-2-0/" target="_blank">SplitPane in JavaFX 2.0</a></li>
<li><a href="../2011/10/fxml-guice/" target="_blank">FXML + Guice</a></li>
</ol>
<p>Looking forward, the <a href="http://javafx.com/roadmap/">JavaFX roadmap</a> was updated recently to detail our plans for JavaFX 2.1, 2.2 and 3.0. If you want to be more involved in these discussions, joining the <a href="http://mail.openjdk.java.net/mailman/listinfo/openjfx-dev">openjfx-dev mailing list</a> is the place to start. There are a number of exciting plans for next year, including full support for Mac OS and Linux, the JavaFX Scene Builder tool (for easily building user interfaces), as well as plenty of new features/API, and of course a huge number of bug fixes.</p>
<p>That&#8217;s all I can really recall for JavaFX this year. I&#8217;m sure I&#8217;ve forgotten more than I remember, but I hope that the insight into the year that has been has been interesting, and I hope you&#8217;re all enjoying using JavaFX. Next year stands to be another exciting year, so strap yourself in tight and hold on &#8211; it&#8217;s gonna be a fun ride! <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/12/an-fx-experience-retrospective/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>SWT Interop</title>
		<link>http://fxexperience.com/2011/12/swt-interop/</link>
		<comments>http://fxexperience.com/2011/12/swt-interop/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 02:40:51 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1549</guid>
		<description><![CDATA[With JavaFX 2.0.2, we&#8217;ve included support for interop with SWT in the same way that we support interop with Swing. That is, you can embed JavaFX within your SWT applications! Although e(fx)clipse has been doing this for a little while by embedding FX -> Swing -> SWT, you can now skip the intermediate embedding into [...]]]></description>
			<content:encoded><![CDATA[<p>With JavaFX 2.0.2, we&#8217;ve included support for interop with SWT in the same way that we support interop with Swing. That is, you can embed JavaFX within your SWT applications! Although e(fx)clipse has been doing this for a little while by embedding FX -> Swing -> SWT, you can now skip the intermediate embedding into Swing and just go straight to SWT. Because FX and SWT share the same basic threading model, this is really easy to do.</p>
<p><a href="http://fxexperience.com/wp-content/uploads/2011/12/SWT-interop.png"><img src="http://fxexperience.com/wp-content/uploads/2011/12/SWT-interop-1024x844.png" alt="" title="SWT-interop" width="655" height="506" class="aligncenter size-large wp-image-1551" /></a><br />
<span id="more-1549"></span></p>
<p>In this code sample, the Table is an SWT table, but the chart is a JavaFX Chart. I create the data model and place it in an ObservableList, and supply this to both the table and the chart. As you edit the table, it ends up also directly manipulating the chart data model, which causes it to animate to the new value.</p>
<pre class="brush: java; title: ; notranslate">
package swt.demo;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swt.FXCanvas;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.util.Pair;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import com.sun.javafx.runtime.VersionInfo;

/**
*
* @author Richard
*/
public class SWTDemo {
   public static void main(String[] args) {
       Display display = new Display();
       Shell shell = new Shell(display);

       // Print version info
       System.out.println(&quot;SWT &quot; +  SWT.getPlatform() + &quot; &quot; +  SWT.getVersion());
       String runtimeVersion = VersionInfo.getRuntimeVersion();
       System.out.println(&quot;FX &quot; + runtimeVersion);

       shell.setLayout(new FillLayout());

       // Create the fake TabPane guy
       final TabFolder tabFolder = new TabFolder(shell, SWT.NONE);
       TabItem chartTab = new TabItem(tabFolder, SWT.NULL);
       chartTab.setText(&quot;JavaFX Chart and SWT Table&quot;);
       TabItem browserTab = new TabItem(tabFolder, SWT.NULL);
       browserTab.setText(&quot;Web Browser&quot;);

       Canvas canvas = new Canvas(tabFolder, SWT.NULL);
       GridLayout layout = new GridLayout(1, true);
       canvas.setLayout(layout);
       chartTab.setControl(canvas);

       // Create the data (I'll use the Chart's data model for
       // both the chart and the table)
       ObservableList&lt;BarChart.Series&gt; bcData = FXCollections.observableArrayList();
       bcData.add(createSeries(new Pair(&quot;2007&quot;, new Double(567)), new Pair(&quot;2008&quot;, new Double(956)), new Pair(&quot;2009&quot;, new Double(1154))));
       bcData.add(createSeries(new Pair(&quot;2007&quot;, new Double(1292)), new Pair(&quot;2008&quot;, new Double(1665)), new Pair(&quot;2009&quot;, new Double(1927))));
       bcData.add(createSeries(new Pair(&quot;2007&quot;, new Double(1292)), new Pair(&quot;2008&quot;, new Double(2559)), new Pair(&quot;2009&quot;, new Double(2774))));

       Canvas chart = createChart(canvas, bcData);
       chart.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
       Table table = createTable(canvas, bcData);
       table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
       createTableEditor(table);

       shell.pack();
       shell.open();
       while (!shell.isDisposed()) {
           if (!display.readAndDispatch()) {
               display.sleep();
           }
       }
   }

   private static BarChart.Series&lt;String,Number&gt; createSeries(Pair&lt;String,Double&gt;... values) {
       ObservableList&lt;BarChart.Data&gt; series = FXCollections.&lt;BarChart.Data&gt;observableArrayList();
       for (int i=0; i&lt;values.length; i++) {
           series.add(new BarChart.Data(values[i].getKey(), values[i].getValue()));
       }
       return new BarChart.Series(series);
   }

   private static Canvas createChart(Composite shell, ObservableList&lt;BarChart.Series&gt; bcData) {
       final FXCanvas fxPanel = new FXCanvas(shell, SWT.NONE);
       CategoryAxis xAxis = new CategoryAxis();
       xAxis.setCategories(FXCollections.&lt;String&gt;observableArrayList(&quot;2007&quot;, &quot;2008&quot;, &quot;2009&quot;));
       xAxis.setLabel(&quot;Year&quot;);
       double tickUnit = 1000.0;
       NumberAxis yAxis = new NumberAxis();
       yAxis.setTickUnit(tickUnit);
       yAxis.setLabel(&quot;Units Sold&quot;);
       final BarChart chart = new BarChart(xAxis, yAxis, bcData);
       fxPanel.setScene(new Scene(chart));
       return fxPanel;
   }

   private static Table createTable(Composite parent, ObservableList&lt;BarChart.Series&gt; bcData) {
       Table table = new Table (parent, SWT.BORDER | SWT.HIDE_SELECTION);
       table.setLinesVisible(true);
       table.setHeaderVisible(true);
       String[] titles = {&quot;2007&quot;, &quot;2008&quot;, &quot;2009&quot;};
       for (int i=0; i&lt;titles.length; i++) {
           TableColumn column = new TableColumn (table, SWT.NONE);
           column.setText(titles [i]);
       }
       for (int i=0; i&lt;bcData.size(); i++) {
           createRow(table, bcData.get(i));
       }
       for (int i=0; i&lt;titles.length; i++) {
           table.getColumn (i).setWidth(400/3);
       }
       return table;
   }

   private static TableItem createRow(Table table, BarChart.Series&lt;String,Number&gt; series) {
       TableItem item = new TableItem (table, SWT.NONE);
       item.setData(series);
       int count = 0;
       for (BarChart.Data&lt;String,Number&gt; data : series.getData()) {
           item.setText(count++, data.getYValue().toString());
       }
       return item;
   }

   private static void createTableEditor (final Table table) {
       final TableEditor editor = new TableEditor (table);
       editor.horizontalAlignment = SWT.LEFT;
       editor.grabHorizontal = true;
       table.addListener (SWT.MouseDown, new Listener () {
           public void handleEvent (Event event) {
               Rectangle clientArea = table.getClientArea ();
               Point pt = new Point (event.x, event.y);
               int index = table.getTopIndex ();
               while (index &lt; table.getItemCount ()) {
                   boolean visible = false;
                   final TableItem item = table.getItem (index);
                   for (int i=0; i&lt;table.getColumnCount (); i++) {
                       Rectangle rect = item.getBounds (i);
                       if (rect.contains (pt)) {
                           final int column = i;
                           final Text text = new Text (table, SWT.NONE);
                           final String oldText = item.getText (i);
                           Listener textListener = new Listener () {
                               public void handleEvent (final Event e) {
                                   switch (e.type) {
                                       case SWT.FocusOut:
                                           item.setText (column, text.getText ());
                                           text.dispose ();
                                           break;
                                       case SWT.Traverse:
                                           switch (e.detail) {
                                               case SWT.TRAVERSE_ESCAPE:
                                                   text.setText(oldText);
                                                   //FALL THROUGH
                                               case SWT.TRAVERSE_RETURN:
                                                   item.setText (column, text.getText ());
                                                   text.dispose ();
                                                   e.doit = false;
                                           }
                                           break;
                                       case SWT.Dispose:
                                           if (item.isDisposed() || (text.getText().equals(oldText))) break;
                                           BarChart.Data&lt;String,Number&gt; oldData = ((BarChart.Series&lt;String,Number&gt;)item.getData()).getData().get(column);
                                           try {
                                               double result = Double.parseDouble(text.getText().trim());
                                               oldData.setYValue(result);
                                           } catch (NumberFormatException ex) {
                                               item.setText(column, oldText);
                                           }
                                           break;
                                   }
                               }
                           };
                           text.addListener (SWT.FocusOut, textListener);
                           text.addListener (SWT.Traverse, textListener);
                           text.addListener (SWT.Dispose, textListener);
                           editor.setEditor (text, item, i);
                           text.setText (item.getText (i));
                           text.selectAll ();
                           text.setFocus ();
                           return;
                       }
                       if (!visible &amp;&amp; rect.intersects (clientArea)) {
                           visible = true;
                       }
                   }
                   if (!visible) return;
                   index++;
               }
           }
       });
   }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/12/swt-interop/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Introduction to DataFX</title>
		<link>http://fxexperience.com/2011/10/introduction-to-datafx/</link>
		<comments>http://fxexperience.com/2011/10/introduction-to-datafx/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 02:31:34 +0000</pubDate>
		<dc:creator>Jonathan Giles</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Links]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1452</guid>
		<description><![CDATA[One of the projects I worked on leading up to JavaOne 2011 was the DataFX project, which, as I wrote on the website, &#8220;is an open source project that intends to make retrieving, massaging, populating, viewing, and editing data in JavaFX UI controls easier. It’s all that boring kludge work you have to do between [...]]]></description>
			<content:encoded><![CDATA[<p>One of the projects I worked on leading up to JavaOne 2011 was the <a href="http://www.javafxdata.org">DataFX project</a>, which, as I wrote on the website, &#8220;is an open source project that intends to make retrieving, massaging, populating, viewing, and editing data in JavaFX UI controls easier. It’s all that boring kludge work you have to do between getting user requirements and delivering a rich user experience.&#8221;</p>
<p>DataFX is a project Johan Vos and I have been working on for many months now, and it has gone through a number of iterations in that time. At JavaOne 2011 we put out a first release (let&#8217;s call it version 0.0.1 for lack of an official version number), and today I want to briefly introduce it for those of you who didn&#8217;t attend JavaOne. However, even if you didn&#8217;t attend JavaOne, we&#8217;ve put the <a href="http://www.javafxdata.org/downloads/javaone-2011-slides.pdf">slides online</a>.</p>
<p>To be very clear, DataFX is not an Oracle project! Johan and I both developed this in our own time, and it does not necessarily represent the future plans of the official JavaFX project. This project was built to make many of the UI controls I develop easier to work with by filling in the gaps as of the current JavaFX 2.0 release. Oracle may or may not have future plans in the same area as DataFX, but for now DataFX exists to fill the gap. For more details, check out the <a href="http://www.javafxdata.org/faq/">DataFX FAQ</a>.</p>
<p>To make things easier to understand let&#8217;s conceptually split DataFX into two sub-projects which attack a common problem from two different angles.</p>
<p><span id="more-1452"></span><strong>Data Sources</strong></p>
<p>The first sub-project deals with the logistics of getting data into the user interface controls by providing various <a title="Data Sources" href="http://www.javafxdata.org/content/data-sources/">data source adapters</a>. These adapters are intended to provide convenience around populating JavaFX controls such as ListView and TableView (at this stage, although we&#8217;d love to eventually also support populating TreeView and charts). This is achieved by abstracting away the implementation details surrounding data source retrieval and massaging, such that data can be rapidly loaded and seen on screen. This is done by essentially creating data sources that are ObservableList instances, allowing for them to be directly loaded into the ListView and TableView &#8216;items&#8217; property. In the case of TableView, DataFX can also auto-generate TableColumn instances with pre-built cell value factories defined.</p>
<pre class="brush: java; title: ; notranslate">
DataSourceReader dsr1 = new FileReader(&quot;foo.xml&quot;);
DataSourceReader dsr2 = new NetworkReader (&quot;http://foo.bar/foo.xml&quot;);

XmlDataSource ds1 = new XmlDataSource(dsr1);

TableView tableView = new TableView();
tableView.setItems(ds1);
tableView.getColumns().addAll(ds1.getColumns());
</pre>
<p>An example of how to use this API is shown above. We define two DataSourceReader instances: one is a FileReader, the other a NetworkReader (although in this example the NetworkReader isn&#8217;t used any further). In both cases it is important to note that the DataSourceReader is datatype-agnostic &#8211; that is, it only cares about where the data is coming from, not the format of the data. At present DataFX only ships with these two DataSourceReader implementations, but it is probable that over time we will add more classes. You can see the JavaDoc for these classes in the <a href="http://www.javafxdata.org/javadoc/index.html?org/javafxdata/datasources/io/package-summary.html">org.javafxdata.datasources.io</a> package.</p>
<p>Once the DataSourceReader instance is created, we must then create a DataSource using one of the implementations provided in the <a href="http://www.javafxdata.org/javadoc/index.html?org/javafxdata/datasources/protocol/package-summary.html">org.javafxdata.datasources.protocol</a> package. In the example below, we create an XmlDataSource, which knows how to parse an XML data stream and create an ObservableList that can be set directly into a ListView or TableView. Also, because it extends <a href="http://www.javafxdata.org/javadoc/index.html?org/javafxdata/datasources/protocol/TableWrapper.html">TableWrapper</a>, it has a getColumns() method that can be used to set the columns in a TableView instance. At present, we have DataSource implementations for CSV files, Java Objects, <a href="http://www.redfx.org">RedFX</a> and XML files. Again, we intend to add further data source implementations in the future as time permits.</p>
<p>Now that the DataSource exists, we create a TableView instance, and set the items property to be the data source itself. We also add all the columns the data source generates into the TableView columns property. This not only creates a column header with default text, it also creates a default cell value factory to populate the cells in that column. This is often the most complex part of using a TableView, and is completely unnecessary in data sources by default (of course, you are free to just create your own TableColumn instances also).</p>
<p>With a (by default) version number of 0.0.1, we recognise that DataFX is not a finished product. For one, it never will be &#8211; it&#8217;s a free project that we are making available here &#8211; but also we recognise the gaping holes in the data sources sub-project. In particular, along with what I&#8217;ve listed above, we also want to provide much more convenience around features such as sorting, filtering, and on-demand loading. If there is anything else that you think is missing, you can find the contact details over at the <a href="http://www.javafxdata.org">DataFX website</a>.</p>
<p><strong>Cell Factories</strong></p>
<div class="wp-caption alignright" style="width: 401px"><img title="CheckBox TreeView" src="http://www.javafxdata.org/screenshots/CheckBoxCell-TreeView.PNG" alt="" width="391" height="519" /><p class="wp-caption-text">A TreeView with support for CheckBoxes</p></div>
<p>The other sub-project of the DataFX project is dealing with the need to more easily visualise data once it is already appearing inside the ListView, TreeView and TableView controls. This customisation is done almost entirely using the cell factories API that is available in all three controls (I&#8217;ll try to blog more about cell factories in a future post). In other words, the default cell factory implementation provided by ListView/TreeView/TableView is sometimes not sufficient &#8211; it simply calls toString() on the data objects and shows it onscreen. In these circumstances, it is necessary to provide your own cell factory, and this is where DataFX comes in &#8211; it provides a number of useful cell factories that you can drop in and use, often with only one line of code.</p>
<p>There are a number of pre-built custom cells. You can see the full list on the <a href="http://www.javafxdata.org/content/cell-factories/">cell factories page</a> on the DataFX website, but briefly, it includes the following:</p>
<ul>
<li>TextField (for text editing)</li>
<li>ChoiceBox (for selecting between a small number of choices)</li>
<li>CheckBox (for toggling a boolean property)</li>
<li>ProgressBar (for graphically representing a number as it progresses from 0.0 to 1.0)</li>
<li>Money formatting (formats a Number instance using a default Locale, and applies CSS to make negative values red, and positive values green)</li>
<li>Dynamically variable row heights (e.g. on mouse hover, a row will grow to show more information)</li>
</ul>
<p>For each cell type mentioned above, there is a separate static factory class that contains a number of convenience methods. These methods should be your first port of call. You can find both the cells, and the more convenient cell factories API in the <a href="http://www.javafxdata.org/javadoc/index.html?org/javafxdata/control/cell/package-summary.html">org.javafxdata.control.cell</a> package. You should explore these javadocs as I have spent considerable effort ensuring that they contain all necessary information. For screenshots of all the cell factories currently available, you can go to the <a href="http://www.javafxdata.org/content/cell-factories/">cell factories page</a> on the DataFX website (clicking on the ticks will take you to a screenshot for that feature &#8211; I&#8217;ll try to make this more intuitive when I have time). I&#8217;ve attached one screenshot to this blog post, for the CheckBox TreeView.</p>
<p>In the code snippet below, I demonstrate how simple it is to make a ListView support text editing of cells when the user double-clicks on a row. In particular, note that the last line is the only line that uses the DataFX API (i.e. the reference to TextFieldCellFactory is from DataFX) &#8211; the other three lines are normal ListView API that should already be familiar to many developers.</p>
<pre class="brush: java; title: ; notranslate">
ListView&lt;String&gt; listView = new ListView&lt;String&gt;();
listView.setItems(namesList);
listView.setEditable(true);
listView.setCellFactory(TextFieldCellFactory.forListView());
</pre>
<p>Again, the cell factories implementation certainly lacks features, but we think it provides a good starting point for the most common use cases. If there is a cell factory you think is missing, get in touch and let us know &#8211; we may just build it for you! <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>Conclusion</strong></p>
<p>Johan and I both hope that DataFX is useful to you. We welcome feedback and requests for features &#8211; our goal is to make development of rich user interfaces in JavaFX 2.0 as simple as possible. Any use cases you can share with us will be much appreciated as we continue to refine our APIs, as well as provide additional data sources and cell factory implementations.</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/10/introduction-to-datafx/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Introducing FXML</title>
		<link>http://fxexperience.com/2011/07/introducing-fxml/</link>
		<comments>http://fxexperience.com/2011/07/introducing-fxml/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 04:15:21 +0000</pubDate>
		<dc:creator>Jonathan Giles</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1348</guid>
		<description><![CDATA[I was just given notice that we were allowed to share an internal FXML document originally written by Greg Brown, a member of the JavaFX controls team. What follows is a painfully slow (and very labour intensive!) PDF to HTML conversion We&#8217;ve updated the document, and instead of re-translating it every time, I will now [...]]]></description>
			<content:encoded><![CDATA[<p>I was just given notice that we were allowed to share an internal FXML document originally written by <strong>Greg Brown</strong>, a member of the JavaFX controls team. <del>What follows is a painfully slow (and very labour intensive!) PDF to HTML conversion</del> We&#8217;ve updated the document, and instead of re-translating it every time, I will now just be posting the PDF file directly. If you find any mistakes, please leave a comment (or <a href="mailto:jonathan@jonathangiles.net">email me</a>), and I&#8217;ll update the document. I also have to add the normal disclaimers: this is a draft document, and it is likely that it may change leading up to the GA release of JavaFX 2.0. With that out of the way, read on and enjoy! <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div id="attachment_1386" class="wp-caption aligncenter" style="width: 138px"><a href="http://fxexperience.com/wp-content/uploads/2011/08/Introducing-FXML.pdf"><img class="size-full wp-image-1386" title="Introducing FXML" src="http://fxexperience.com/wp-content/uploads/2011/07/pdf_file.png" alt="" width="128" height="128" /></a><p class="wp-caption-text">Download the latest &#39;Introducing FXML&#39; document</p></div>
<p>In case you&#8217;re wondering what FXML is, FXML is a scriptable, XML-based markup language for constructing Java object graphs. It provides a convenient alternative to constructing such graphs in procedural code, and is ideally suited to defining the user interface of a JavaFX application, since the hierarchical structure of an XML document closely parallels the structure of the JavaFX scene graph.</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/07/introducing-fxml/feed/</wfw:commentRss>
		<slash:comments>69</slash:comments>
		</item>
		<item>
		<title>Worker Threading in JavaFX 2.0</title>
		<link>http://fxexperience.com/2011/07/worker-threading-in-javafx-2-0/</link>
		<comments>http://fxexperience.com/2011/07/worker-threading-in-javafx-2-0/#comments</comments>
		<pubDate>Sat, 02 Jul 2011 23:49:15 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[API Design]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1281</guid>
		<description><![CDATA[For the past couple of years the industry has continued to follow Moore&#8217;s Law by shifting from CPU clock speed to increasing the number of cores and threads per core. Even cell phones are getting multiple cores these days! Taking advantage of all these cores and threads is one of the hallmarks of modern GUI [...]]]></description>
			<content:encoded><![CDATA[<p>For the past couple of years the industry has continued to follow <a href="http://en.wikipedia.org/wiki/Moore's_law">Moore&#8217;s Law</a> by shifting from CPU clock speed to increasing the number of cores and threads per core. Even <a href="http://www.engadget.com/2010/12/15/lg-optimus-2x-first-dual-core-smartphone-launches-with-android/">cell phones</a> are getting multiple cores these days! Taking advantage of all these cores and threads is one of the hallmarks of modern GUI platforms. But all this concurrency brings a multitude of problems to the application developer, not least of which is that writing multithreaded applications is <em>hard!</em></p>
<p>In designing JavaFX 2.0, we of course needed to address both how the scene graph would behave in the presence of multiple threads, and how developers could effectively do work in background threads and keep the UI responsive. In short, the JavaFX scene graph, like all other mainstream GUI toolkits, is not thread-safe and must be accessed and manipulated from the UI thread (call the FX Application thread). Swing and AWT had the same basic policy (only work with Swing or AWT from the Event Dispatching Thread), as did SWT (only interact with SWT resources and components from the thread that owns them), as do all other major toolkits (JavaScript / HTML included).</p>
<p>The most common problem with this design is that developers who do not do work on background threads invariably create unresponsive applications, since this long lived (potentially blocking) code happens on the same thread that processes user events. That is, while your long lived operation is running, no mouse or key events are being processed, which leads to an application that appears to &#8220;hang&#8221;.</p>
<p>Further, actually writing well behaved background workers is difficult and error prone. Even if you create a Runnable and create a Thread and do your long-lived work in that background thread, at some point you need to communicate back to the UI, either with the result of the long-lived computation, or by communicating to a ProgressIndicator of some kind what the progress of this long-lived operation is. This is error prone, because you must be sure to communicate with the UI by putting events back onto the event queue (using Platform.runLater, the equivalent of Swing&#8217;s invokeLater).</p>
<p><em>Note: This article is a sneak peek at a new API which is coming in the next couple of weeks, but is not currently available in the Beta builds! There is a deprecated Task class in the beta builds which will be removed and replaced with the one detailed here.</em></p>
<p>Suppose we have a simple background thread which just counts from 0 to 1 million. Suppose I have a single ProgressBar, and that I need to update the progress of this ProgressBar as the counter runs. A naive implementation might look like this:</p>
<pre class="brush: java; title: ; notranslate">
final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
    @Override public void run() {
        for (int i=1; i&lt;=1000000; i++) {
            final int counter = i;
            Platform.runLater(new Runnable() {
                @Override public void run() {
                    bar.setProgress(counter/1000000.0);
                }
            });
        }
    }
}).start();
</pre>
<p>This is a hideous hunk of code, a crime against nature (and programming in general). First, you&#8217;ll lose brain cells just looking at this double nesting of Runnables. Second, it is going to swamp the event queue with little Runnables &#8212; a million of them in fact. Clearly, we needed some API to make it easier to write background workers which then communicate back with the UI.</p>
<p>Java comes with a very complete set of concurrency libraries in the java.util.concurrent package. We wanted to leverage what was already defined in Java, but we needed to extend these APIs to take into account the FX Application thread and the constraints that GUI programmers are under. The javafx.concurrent package contains three core files: Worker, Task, and Service.</p>
<p>Before diving into the rather verbose description (taken from the proposed javadocs) for Worker, Task, and Service I wanted to cut to the chase and show some examples. The first key thing to mention, is that Worker is an interface that is implemented by both Task and Service, and which adds the sort of convenience API necessary for a background worker that is useful for communicating back with a UI. Second, Task extends from java.util.concurrent.FutureTask. This means that a Task can very cleanly fit into the concurrent libraries. As you may know, FutureTask implements Runnable, and can be passed to an Executor&#8217;s execute() method.</p>
<p>So real quick, here is the same example as above, but it suffers from none of the flaws exhibited in the naive implementation.</p>
<pre class="brush: java; title: ; notranslate">
Task task = new Task&lt;Void&gt;() {
    @Override public Void run() {
        static final int max = 1000000;
        for (int i=1; i&lt;=max; i++) {
            updateProgress(i, max);
        }
        return null;
    }
};
ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();
</pre>
<p>In this example, I first create my Task. The task implementation just does its work, invoking the protected <code>updateProgress</code> method defined on Task, which ends up updating progress, totalWork, and workDone properties on the Task. I then create my ProgressBar and bind its progress property with the progress property of the Task. Then, since Task is a Runnable, I can just create a new Thread passing it the Task and then start the Thread.</p>
<p>Alternatively, I could create an Executor or ExecutorService (such as a ThreadPoolExecutorService) and <code>execute</code> the task using the ExecutorService.</p>
<p><span id="more-1281"></span></p>
<p><b><i>Edit July 11, 2011: I have updated the API slightly since this post was originally written, and I&#8217;ve updated the post to reflect the current names. In particular, the &#8220;progress&#8221; property is now a value between 0 and 1 (or -1), matching the &#8220;progress&#8221; property on ProgressIndicator and other parts of the platform. &#8220;workDone&#8221; and &#8220;totalWork&#8221; are used to indicate the total units of work to do (such as bytes to be downloaded) and the total units of work that have been done (such as the bytes that have been downloaded). I&#8217;m not totally jazzed by the names, but felt it was important for &#8220;progress&#8221; to mean the same thing on Worker and ProgressIndicator.</i></b></p>
<p>Below are some further descriptions taken from the javadocs.</p>
<h2>Worker</h2>
<p>A Worker is an object which performs some work in one or more background threads, and who&#8217;s state is observable and available to JavaFX applications and is usable from the main JavaFX Application thread. This interface is primarily implemented by both Task and Service, providing a common API among both classes which makes it easier for libraries and frameworks to write user interfaces with observable workers.</p>
<p>A Worker may, or may not be reusable, depending on the implementation. A Task, for example, is not reusable while a @link Service is.</p>
<p>A Worker has a well defined life cycle. Every Worker begins in the READY state. When the Worker has been scheduled for work (for example, when a Service&#8217;s start() method is called), it is transitioned to SCHEDULED. Even Workers which are not technically scheduled, but started immediately (such as with Task#run()) will transition through SCHEDULED on its way to the  RUNNING state.</p>
<p>When the Worker is actually performing its work, the state will have been transitioned to RUNNING. If the Worker completes normally, it will end in the SUCCEEDED state, and the result of the Worker will be set as the <code>value</code> property. If however an Exception occurs during the execution of the Worker, then the state will be set to FAILED and the <code>exception</code> property will be set to the Exception which occurred.</p>
<p>At any time prior to the conclusion of the Worker (that is, if the state is not already SUCCEEDED or FAILED) the developer may invoke the Worker#cancel() method. If called, the Worker will cease execution (if possible, including use of Thread.interrupt) and the state changed to CANCELLED.</p>
<p>The only valid beginning state for a Worker is READY, and the valid ending states are CANCELLED, SUCCEEDED, and FAILED. The <code>running</code> property is set to true when the state is either SCHEDULED or RUNNING.</p>
<p>The Worker&#8217;s progress can be monitored via three different properties, <code>workDone</code>, <code>totalWork</code>, and <code>progress</code>. These properties are set by the actual implementation of the Worker interface, but can be observed by anybody. The <code>workDone</code> is a number between -1 (meaning indeterminate progress) and <code>totalWork</code>, inclusive. When <code>workDone == totalWork</code> the <code>progress</code> will be 100% (or 1). <code>totalWork</code> will be a number between -1 and Long.MAX_VALUE, inclusive. The progress will be either -1 (meaning indeterminate), or a value between 0 and 1, inclusive, representing 0% through 100%.</p>
<p>A Worker which is in the READY or SCHEDULED states will always have <code>workDone</code> and <code>progress</code> set to -1. A Worker which is in the SUCCEEDED state will always have <code>workDone == totalWork</code> and <code>progress == 1 or -1</code>. In any other state, the values for these properties may be any value in their respective valid ranges.</p>
<h2>Task</h2>
<p>A fully observable implementation of a FutureTask. Tasks exposes additional state and observable properties useful for programming asynchronous tasks in JavaFX, as defined in the Worker interface. An implementation of Task must override the Task#call() method. This method is invoked on the background thread. Any state which is used in this method must be safe to read and write from a background thread. For example, manipulating a live scene graph from this method is unsafe and will result in runtime exceptions.</p>
<p>Tasks are flexibly and extremely useful for the encapsulation of work. Because Service is designed to execute a Task, any Tasks defined by the application or library code can easily be used with a Service. Likewise, since Task extends from FutureTask, it is very easy and natural to use a Task with the java concurrency java.util.concurrent.Executor API. Finally, since a Task is Runnable, you can also call it directly (by invoking the Task#run() method) from another background thread. This allows for composition of work.</p>
<p>Although java.util.concurrent.ExecutorService defines several methods which take a Runnable, you should generally limit yourself to using the <code>execute</code> method inherited from java.util.concurrent.Executor.</p>
<p>As with FutureTask, a Task is a one-shot class and cannot be reused. See Service for a reusable Worker.</p>
<p>Because the Task is designed for use with JavaFX GUI applications, it ensures that every change to the public properites, as well as change notifications for state, errors, and for event handlers, all occur on the main JavaFX application thread. Accessing these properties from a background thread will result in runtime exceptions being raised.</p>
<h2>Service</h2>
<p>A Service is a non-visual component encapsulating the information required to perform some work on one or more background threads. As part of the JavaFX UI library, the Service knows about the JavaFX Application thread and is designed to alieviate the application developer from the burden of manging multithreaded code that interacts with the user interface. As such, all of the methods and state on the Service are intended to be invoked exclusively from the JavaFX Application thread.</p>
<p>Service implements {@link Worker}. As such, you can observe the state of the background operation and optionally cancel it. Service is a reusable Worker, meaning that it can be reset and restarted. Due to this, a Service can be constructed declarativley and restarted on demand.</p>
<p>If an java.util.concurrent.Executor is specified on the Service, then it will be used to actually execute the background worker. Otherwise, a daemon thread will be created and executed. If you wish to create non-daemon threads, then specify a custom Executor (for example, you could use a ThreadPoolExecutor).</p>
<p>Because a Service is intended to simplify declarative use cases, subclasses should expose as properties the input parameters to the work to be done. For example, suppose I wanted to write a Service which read the first line from any URL and returned it as a String. Such a Service might be defined, such that it had a single property, <code>url</code>. It might be implemented as:</p>
<pre class="brush: java; title: ; notranslate">
public class FirstLineService extends Service {
    private StringProperty url = new StringProperty();
    public final void setUrl(String value) { url.set(value); }
    public final String getUrl() { return url.get(); }
    public final StringProperty urlProperty() { return url; }

    protected Task createTask() {
        final String _url = getUrl();
        return new Task&lt;InputStream&gt;() {
            protected String call() {
                URL u = new URL(_url);
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(u.openStream()));
                String result = in.readLine();
                in.close();
                return result;
            }
        }
    }
 }
</pre>
<h2>Conclusion</h2>
<p>We anticipate that libraries of Tasks, both specialized for your specific application and also general libraries of Tasks will be developed over time that perform common operations such as downloading files, performing HTTP form submits, copying files, uploading files, sorting, doing statistical analysis, and so forth. These reusable bodies of code can then be combined together, used with thread pools or other rich executor services, and used with Services.</p>
<p>Let us know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/07/worker-threading-in-javafx-2-0/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>JavaFX Code Names</title>
		<link>http://fxexperience.com/2011/06/javafx-code-names/</link>
		<comments>http://fxexperience.com/2011/06/javafx-code-names/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 15:58:40 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1262</guid>
		<description><![CDATA[I was just going through the bug database and realized that, to my knowledge, we&#8217;ve never actually told people what the code names are for our releases, and that that is pretty useful to know when filing bugs. Ever since JavaFX 1.0 we&#8217;ve used street or area names from San Francisco as our code names. [...]]]></description>
			<content:encoded><![CDATA[<p>I was just going through the bug database and realized that, to my knowledge, we&#8217;ve never actually told people what the code names are for our releases, and that that is pretty useful to know when filing bugs. Ever since JavaFX 1.0 we&#8217;ve used street or area names from San Francisco as our code names. Honestly I can&#8217;t remember the 1.0 code name anymore. 1.2 was called &#8220;Marina&#8221;, 1.3 was &#8220;SoMa&#8221; (South of Market).</p>
<p>This release, 2.0, is called &#8220;Presidio&#8221;, and the next major release is called &#8220;Lombard&#8221;. So when you see that your issue is targeted at one of these, you know what we&#8217;re taking about! If it remains &#8220;untargeted&#8221;, then it has gone into the pool from which we draw features for future releases, but may not be targeted to a specific release until later in the planning cycle.</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/06/javafx-code-names/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Maps in JavaFX 2.0</title>
		<link>http://fxexperience.com/2011/05/maps-in-javafx-2-0/</link>
		<comments>http://fxexperience.com/2011/05/maps-in-javafx-2-0/#comments</comments>
		<pubDate>Wed, 01 Jun 2011 02:11:10 +0000</pubDate>
		<dc:creator>Jasper Potts</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1170</guid>
		<description><![CDATA[Something that you see more and more with client applications at the moment is embedded map components. This blog will show you how to embed Google, Yahoo or Bing maps in your JavaFX application. Download a copy of the application and try it out. The jar file is linked below, just download it and double [...]]]></description>
			<content:encoded><![CDATA[<p>Something that you see more and more with client applications at the moment is embedded map components. This blog will show you how to embed Google, Yahoo or Bing maps in your JavaFX application.</p>
<div id="attachment_1171" class="wp-caption aligncenter" style="width: 610px"><a href="http://fxexperience.com/wp-content/uploads/2011/05/Screen-shot-2011-05-27-at-6.54.48-PM.png"><img class="size-full wp-image-1171 " title="Screen shot 2011-05-27 at 6.54.48 PM" src="http://fxexperience.com/wp-content/uploads/2011/05/Screen-shot-2011-05-27-at-6.54.48-PM.png" alt="" width="600" height="497" /></a><p class="wp-caption-text">Google Maps in JavaFX 2.0</p></div>
<p>Download a copy of the application and try it out. The jar file is linked below, just download it and double click. This requires you to have the JavaFX 2.0 beta runtime installed.</p>
<p style="color: #ff5400; text-align: center;"><strong><br />
<a href="http://fxexperience.com/applications/WebMap.jar"><img style="text-align: center; padding: 0; margin: 0;" src="http://fxexperience.com/applications/jar-icon.png" alt="" /><br />
Download double clickable jar</a></strong></p>
<p><span id="more-1170"></span></p>
<h3>Using the Application</h3>
<p>The toolbar at the top of the application is all JavaFX controls, it communicates with the web map by calling JavaScript functions. Clicking on the Road,Satellite, Hybrid or Terrain sends commands to the JavaScript map library to change the map style. The Google, Yahoo and Bing buttons change the HTML page to use different map providers. As you type in the location field it navigates to the location, try &#8220;London&#8221; or &#8220;New York&#8221; for example. The zoom in/out buttons call JavaScript functions to change the map zoom level.</p>
<div id="attachment_1185" class="wp-caption aligncenter" style="width: 610px"><a href="http://fxexperience.com/wp-content/uploads/2011/05/Screen-shot-2011-05-27-at-6.55.11-PM.png"><img class="size-full wp-image-1185" title="Yahoo Maps" src="http://fxexperience.com/wp-content/uploads/2011/05/Screen-shot-2011-05-27-at-6.55.11-PM.png" alt="" width="600" height="497" /></a><p class="wp-caption-text">Yahoo Maps in JavaFX 2.0</p></div>
<div id="attachment_1186" class="wp-caption aligncenter" style="width: 610px"><a href="http://fxexperience.com/wp-content/uploads/2011/05/Screen-shot-2011-05-27-at-6.55.19-PM.png"><img class="size-full wp-image-1186" title="Bing Maps" src="http://fxexperience.com/wp-content/uploads/2011/05/Screen-shot-2011-05-27-at-6.55.19-PM.png" alt="" width="600" height="497" /></a><p class="wp-caption-text">Bing Maps in JavaFX 2.0</p></div>
<h3>How it&#8217;s Built</h3>
<p>There are three parts to the application: the HTML and JavaScript code, the JavaFX application and the css styling.</p>
<h4>The HTML Code</h4>
<pre class="brush: xml; title: ; notranslate">
&lt;html&gt;
&lt;head&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;initial-scale=1.0, user-scalable=no&quot; /&gt;
&lt;style type=&quot;text/css&quot;&gt;
  html { height: 100% }
  body { height: 100%; margin: 0px; padding: 0px }
  #map_canvas { height: 100%; background-color: #666970; }
&lt;/style&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://maps.google.com/maps/api/js?sensor=false&quot;&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  function initialize() {
    var latlng = new google.maps.LatLng(37.39822, -121.9643936);
    var myOptions = {
      zoom: 14,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      mapTypeControl: false,
      navigationControl: false,
      streetViewControl: false,
      backgroundColor: &quot;#666970&quot;
    };

    document.geocoder = new google.maps.Geocoder();
    document.map = new google.maps.Map(document.getElementById(&quot;map_canvas&quot;),myOptions);

    document.zoomIn = function zoomIn() {
    	var zoomLevel = document.map.getZoom();
    	if (zoomLevel &lt;= 20) document.map.setZoom(zoomLevel + 1);
    }

    document.zoomOut = function zoomOut() {
    	var zoomLevel = document.map.getZoom();
    	if (zoomLevel &gt; 0) document.map.setZoom(zoomLevel - 1);
    }

    document.setMapTypeRoad = function setMapTypeRoad() {
    	document.map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
    }
    document.setMapTypeSatellite = function setMapTypeSatellite() {
    	document.map.setMapTypeId(google.maps.MapTypeId.SATELLITE);
    }
    document.setMapTypeHybrid = function setMapTypeHybrid() {
    	document.map.setMapTypeId(google.maps.MapTypeId.HYBRID);
    }
    document.setMapTypeTerrain = function setMapTypeTerrain() {
    	document.map.setMapTypeId(google.maps.MapTypeId.TERRAIN);
    }

    document.goToLocation = function goToLocation(searchString) {
        document.geocoder.geocode( {'address': searchString}, function(results, status) {
      	  if (status == google.maps.GeocoderStatus.OK) {
            document.map.setCenter(results[0].geometry.location);
          } else {
            alert(&quot;Geocode was not successful for the following reason: &quot; + status);
          }
        });
    }
  }
&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=&quot;initialize()&quot;&gt;
  &lt;div id=&quot;map_canvas&quot; style=&quot;width:100%; height:100%&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>This is the code for using Google Maps API, there is similar code for Yahoo and Bing in the attached Netbeans project below. This is very basic use of the Google Maps API to create a full page map and provide some constant JavaScript functions that the JavaFX application can call. You could have called the Google API directly from JavaFX but it seemed simpler to provide a basic abstraction layer in JavaScript so the only difference the JavaFX app sees is the URL. The other two APIs Yahoo and Bing require that you register to get a API key to be able to use them. The code is provided you just need to insert you API keys into the HTML files.</p>
<h4>The JavaFX Code</h4>
<p>The most basic application without the toolbar to just show the map would be:</p>
<pre class="brush: java; title: ; notranslate">
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebMap extends Application {

    @Override public void start(Stage stage) {
        // create web engine and view
        final WebEngine webEngine = new WebEngine(getClass().getResource(&quot;googlemap.html&quot;).toString());
        final WebView webView = new WebView(webEngine);
        // create scene
        stage.setTitle(&quot;Web Map&quot;);
        Scene scene = new Scene(webView,1000,700, Color.web(&quot;#666970&quot;));
        stage.setScene(scene);
        // show stage
        stage.setVisible(true);
    }

    static { // use system proxy settings when standalone application
        System.setProperty(&quot;java.net.useSystemProxies&quot;, &quot;true&quot;);
    }

    public static void main(String[] args){
        Application.launch(args);
    }
}
</pre>
<p>The next step is to create the toolbar, this is just a bunch of JavaFX controls in a Toolbar with actions that call the JavaScript functions in the HTML page.</p>
<pre class="brush: java; title: ; notranslate">
import ....

public class WebMap extends Application {
    private Timeline locationUpdateTimeline;

    @Override public void start(Stage stage) {
        // create web engine and view
        final WebEngine webEngine = new WebEngine(
                getClass().getResource(&quot;googlemap.html&quot;).toString());
        final WebView webView = new WebView(webEngine);
        // create map type buttons
        final ToggleGroup mapTypeGroup = new ToggleGroup();
        final ToggleButton road = new ToggleButton(&quot;Road&quot;);
        road.setSelected(true);
        road.setToggleGroup(mapTypeGroup);
        final ToggleButton satellite = new ToggleButton(&quot;Satellite&quot;);
        satellite.setToggleGroup(mapTypeGroup);
        final ToggleButton hybrid = new ToggleButton(&quot;Hybrid&quot;);
        hybrid.setToggleGroup(mapTypeGroup);
        final ToggleButton terrain = new ToggleButton(&quot;Terrain&quot;);
        terrain.setToggleGroup(mapTypeGroup);
        mapTypeGroup.selectedToggleProperty().addListener(
                            new ChangeListener&lt;Toggle&gt;() {
            public void changed(
                    ObservableValue&lt;? extends Toggle&gt; observableValue,
                    Toggle toggle, Toggle toggle1) {
                if (road.isSelected()) {
                    webEngine.executeScript(&quot;document.setMapTypeRoad()&quot;);
                } else if (satellite.isSelected()) {
                    webEngine.executeScript(&quot;document.setMapTypeSatellite()&quot;);
                } else if (hybrid.isSelected()) {
                    webEngine.executeScript(&quot;document.setMapTypeHybrid()&quot;);
                } else if (terrain.isSelected()) {
                    webEngine.executeScript(&quot;document.setMapTypeTerrain()&quot;);
                }
            }
        });
        // add map source toggles
        ToggleGroup mapSourceGroup = new ToggleGroup();
        final ToggleButton google = new ToggleButton(&quot;Google&quot;);
        google.setSelected(true);
        google.setToggleGroup(mapSourceGroup);
        final ToggleButton yahoo = new ToggleButton(&quot;Yahoo&quot;);
        yahoo.setToggleGroup(mapSourceGroup);
        final ToggleButton bing = new ToggleButton(&quot;Bing&quot;);
        bing.setToggleGroup(mapSourceGroup);
        // listen to selected source
        mapSourceGroup.selectedToggleProperty().addListener(
                            new ChangeListener&lt;Toggle&gt;() {
            public void changed(
                    ObservableValue&lt;? extends Toggle&gt; observableValue,
                    Toggle toggle, Toggle toggle1) {
                terrain.setDisable(true);
                if (google.isSelected()) {
                    terrain.setDisable(false);
                    webEngine.load(
                          getClass().getResource(&quot;googlemap.html&quot;).toString());
                } else if (yahoo.isSelected()) {
                    webEngine.load(
                          getClass().getResource(&quot;bingmap.html&quot;).toString());
                } else if (bing.isSelected()) {
                    webEngine.load(
                          getClass().getResource(&quot;yahoomap.html&quot;).toString());
                }
                mapTypeGroup.selectToggle(road);
            }
        });
        // add search
        final TextBox searchBox = new TextBox(&quot;95054&quot;);
        searchBox.setColumns(12);
        searchBox.setPromptText(&quot;Search&quot;);
        searchBox.rawTextProperty().addListener(new ChangeListener&lt;String&gt;() {
            public void changed(
                    ObservableValue&lt;? extends String&gt; observableValue,
                    String s, String s1) {
                // delay location updates to we don't go too fast file typing
                if (locationUpdateTimeline!=null) locationUpdateTimeline.stop();
                locationUpdateTimeline = new Timeline();
                locationUpdateTimeline.getKeyFrames().add(
                    new KeyFrame(new Duration(400),
                            new EventHandler&lt;ActionEvent&gt;() {
                        public void handle(ActionEvent actionEvent) {
                            webEngine.executeScript(&quot;document.goToLocation(\&quot;&quot;+
                                    searchBox.getRawText()+&quot;\&quot;)&quot;);
                        }
                    })
                );
                locationUpdateTimeline.play();
            }
        });
        Button zoomIn = new Button(&quot;Zoom In&quot;);
        zoomIn.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
            public void handle(ActionEvent actionEvent) {
                webEngine.executeScript(&quot;document.zoomIn()&quot;);
            }
        });
        Button zoomOut = new Button(&quot;Zoom Out&quot;);
        zoomOut.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
            public void handle(ActionEvent actionEvent) {
                webEngine.executeScript(&quot;document.zoomOut()&quot;);
            }
        });
        // create toolbar
        ToolBar toolBar = new ToolBar();
        toolBar.getStyleClass().add(&quot;map-toolbar&quot;);
        toolBar.getItems().addAll(
                road, satellite, hybrid, terrain,
                createSpacer(),
                google, yahoo, bing,
                createSpacer(),
                new Label(&quot;Location:&quot;), searchBox, zoomIn, zoomOut);
        // create root
        BorderPane root = new BorderPane();
        root.getStyleClass().add(&quot;map&quot;);
        root.setCenter(webView);
        root.setTop(toolBar);
        // create scene
        stage.setTitle(&quot;Web Map&quot;);
        Scene scene = new Scene(root,1000,700, Color.web(&quot;#666970&quot;));
        stage.setScene(scene);
        scene.getStylesheets().add(&quot;/webmap/WebMap.css&quot;);
        // show stage
        stage.setVisible(true);
    }

    private Node createSpacer() {
        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);
        return spacer;
    }

    static { // use system proxy settings when standalone application
        System.setProperty(&quot;java.net.useSystemProxies&quot;, &quot;true&quot;);
    }

    public static void main(String[] args){
        Application.launch(args);
    }
}
</pre>
<h4>The CSS Code</h4>
<p>The last part of the application is a little css to style the toolbar and make it look dark to stand out from the maps.</p>
<pre class="brush: css; title: ; notranslate">
.map{
    -fx-background-color: #666970;
}
.map-toolbar .button, .map-toolbar .toggle-button, .map-toolbar .label {
    -fx-text-fill: white;
    -fx-background-radius: 0;
}
.map-toolbar{
    -fx-base: #505359;
    -fx-background: #505359;
    -fx-shadow-highlight-color: transparent;
    -fx-spacing: 5;
    -fx-padding: 4 4 4 4;
    -fx-background-color: linear (0%,0%) to (0%,100%) stops
                (0%,#919398)
                (4%,#919398)
                (4.1%,#666970)
                (66%,#494d53)
                (94%,#3c3f46)
                (94.1%,#515151);
}
</pre>
<h3>Download Source</h3>
<p style="color: #ff5400; text-align: center;"><strong><br />
<a href="http://fxexperience.com/applications/WebMapProject.zip"><img style="text-align: center; padding: 0; margin: 0;" src="http://fxexperience.com/applications/project-zip.png" alt="" /><br />
Download Netbeans Project</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/05/maps-in-javafx-2-0/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>JavaFX 2.0 Charts</title>
		<link>http://fxexperience.com/2011/05/javafx-2-0-charts/</link>
		<comments>http://fxexperience.com/2011/05/javafx-2-0-charts/#comments</comments>
		<pubDate>Sat, 28 May 2011 16:00:11 +0000</pubDate>
		<dc:creator>Jasper Potts</dc:creator>
				<category><![CDATA[Charts]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1128</guid>
		<description><![CDATA[We did a complete rewrite of charts in JavaFX 2.0 to add cool features like: Dynamic Data Support Animation Auto Ranging CSS Styling There is a sample application called &#8220;Chart Sampler&#8221; that ships with JavaFX 2.0 Beta that shows some of what can be done with the new charts. Here are a few screen shots [...]]]></description>
			<content:encoded><![CDATA[<p>We did a complete rewrite of charts in JavaFX 2.0 to add cool features like:</p>
<ul>
<li>Dynamic Data Support</li>
<li>Animation</li>
<li>Auto Ranging</li>
<li>CSS Styling</li>
</ul>
<p>There is a sample application called &#8220;Chart Sampler&#8221; that ships with JavaFX 2.0 Beta that shows some of what can be done with the new charts. Here are a few screen shots to tempt you to go and check it out <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /><br />
<a href="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Bar.png"><img class="aligncenter size-full wp-image-1129" title="Charts - Bar" src="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Bar.png" alt="" width="540" height="401" /></a><br />
<span id="more-1128"></span><br />
<a href="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Pie.png"><img class="aligncenter size-full wp-image-1130" title="Charts - Pie" src="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Pie.png" alt="" width="540" height="401" /></a><br />
<a href="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Scatter.png"><img class="aligncenter size-full wp-image-1131" title="Charts - Scatter" src="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Scatter.png" alt="" width="540" height="401" /></a><br />
<a href="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Audio.png"><img class="aligncenter size-full wp-image-1132" title="Charts Audio" src="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Audio.png" alt="" width="540" height="401" /></a><br />
<a href="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Candle-Stick.png"><img class="aligncenter size-full wp-image-1133" title="Charts - Candle Stick" src="http://fxexperience.com/wp-content/uploads/2011/05/Charts-Candle-Stick.png" alt="" width="540" height="401" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/05/javafx-2-0-charts/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

