<?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; Tips n&#8217; Tricks</title>
	<atom:link href="http://fxexperience.com/category/tips-n-tricks/feed/" rel="self" type="application/rss+xml" />
	<link>http://fxexperience.com</link>
	<description>Sharing the Experience of JavaFX</description>
	<lastBuildDate>Fri, 03 Feb 2012 22:47:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Restricting Input on a TextField</title>
		<link>http://fxexperience.com/2012/02/restricting-input-on-a-textfield/</link>
		<comments>http://fxexperience.com/2012/02/restricting-input-on-a-textfield/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 16:56:48 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1672</guid>
		<description><![CDATA[I had some little sample I wanted to write where I had a TextField that restricted input. Maybe somebody else out there has already figured out how to do this elegantly, but I hadn&#8217;t and thought it would be worth a small post to demonstrate the technique. Within the TextInputControl is a Content, which actually [...]]]></description>
			<content:encoded><![CDATA[<p>I had some little sample I wanted to write where I had a TextField that restricted input. Maybe somebody else out there has already figured out how to do this elegantly, but I hadn&#8217;t and thought it would be worth a small post to demonstrate the technique.</p>
<p>Within the TextInputControl is a Content, which actually models the TextInputControl&#8217;s content. So for example, this is where we strip out newlines and such if you paste a String into a TextField that contains such characters, but in TextArea we allow those sorts of modifications. There is a protected getContent() method, so in theory a subclass of TextInputControl can manipulate the content directly, although in the case of TextField, it does not.</p>
<p>In fact, the only places in all the code that actually modify the TextField&#8217;s text is in the replaceText and replaceSelection methods defined on TextInputControl. So all you have to do is subclass TextField and override these two methods.</p>
<pre class="brush: java; title: ; notranslate">
field = new TextField() {
    @Override public void replaceText(int start, int end, String text) {
        // If the replaced text would end up being invalid, then simply
        // ignore this call!
        if (!text.matches(&quot;[a-z]&quot;)) {
            super.replaceText(start, end, text);
        }
    }

    @Override public void replaceSelection(String text) {
        if (!text.matches(&quot;[a-z]&quot;)) {
            super.replaceSelection(text);
        }
    }
};
</pre>
<p>In the future we may want to add a more specific method (maybe called &#8220;accept&#8221; which takes the proposed new string after the modification) so that in the off chance that TextField or TextInputControl ends up modifying the content from some additional methods beyond these two, you could still have a reliable way to reject invalid input. However for the time being, this should work just fine!</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/02/restricting-input-on-a-textfield/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>LCD Text support in JavaFX 2.1 Developer Preview</title>
		<link>http://fxexperience.com/2012/01/lcd-text-support-in-javafx-2-1-developer-preview/</link>
		<comments>http://fxexperience.com/2012/01/lcd-text-support-in-javafx-2-1-developer-preview/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 02:43:16 +0000</pubDate>
		<dc:creator>Jonathan Giles</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1644</guid>
		<description><![CDATA[Phil Race has posted a blog post over at the JavaFX Blog on the addition of LCD text support in the latest JavaFX 2.1 developer preview. LCD sub-pixel text has become a must-have for many Windows desktop users, who have become accustomed to its superior legibility and less blocky appearance at smaller point sizes over hinted black [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://fxexperience.com/wp-content/uploads/2012/01/ensemble-lcd1.png"><img class="aligncenter size-full wp-image-1647" title="ensemble-lcd" src="http://fxexperience.com/wp-content/uploads/2012/01/ensemble-lcd1.png" alt="" width="804" height="322" /></a></p>
<p><strong>Phil Race</strong> has posted a blog post over at the JavaFX Blog on the addition of <a href="http://blogs.oracle.com/javafx/entry/lcd_text_support_in_javafx">LCD text support in the latest JavaFX 2.1 developer preview</a>.</p>
<div>
<p style="padding-left: 30px;">LCD sub-pixel text has become a must-have for many Windows desktop users, who have become accustomed to its superior legibility and less blocky appearance at smaller point sizes over hinted black and white text, and being sharper than grey scale anti-aliased text at the same size.</p>
<p style="padding-left: 30px;">Java SE has supported LCD subpixel text on AWT heavyweights and also on Swing components using Java 2D for many years. However up until now, JavaFX has supported only more Mac OS X-like grey scale smoothed text.</p>
<p style="padding-left: 30px;">For the JavaFX 2.1 release we&#8217;ve added the ability to use Windows-style LCD sub-pixel rendering. All the JavaFX UI controls will be LCD-text enabled by default on Windows, as will &#8220;WebView&#8221;, the Webkit-based node for rendering Web content.</p>
<p style="padding-left: 30px;">Applications can also opt-in to use LCD text on the low-level scenegraph &#8220;Text&#8221; node by a new API : Text.setFontSmoothingType(FontSmoothingType.LCD));</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/01/lcd-text-support-in-javafx-2-1-developer-preview/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Curve fitting and styling AreaChart</title>
		<link>http://fxexperience.com/2012/01/curve-fitting-and-styling-areachart/</link>
		<comments>http://fxexperience.com/2012/01/curve-fitting-and-styling-areachart/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 05:50:04 +0000</pubDate>
		<dc:creator>Jasper Potts</dc:creator>
				<category><![CDATA[Charts]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1623</guid>
		<description><![CDATA[I was experimenting today with extending AreaChart to do curve fitting for some example code I was hacking on. It is also a example of what can be done with styling JavaFX charts with CSS. Here is the result: Curve Fitting I have to admit I did not work out all the Math myself for [...]]]></description>
			<content:encoded><![CDATA[<p>I was experimenting today with extending AreaChart to do curve fitting for some example code I was hacking on. It is also a example of what can be done with styling JavaFX charts with CSS. Here is the result:</p>
<div id="applet-container" style="background-image: url('/applications/CurveFittedChartApplet/screenshot.png'); width: 540px; height: 440px;"></div>
<p><span id="more-1623"></span><br />
<script type="text/javascript" src="/applications/CurveFittedChartApplet/web-files/dtjava.js"></script><br />
<script type="text/javascript">// <![CDATA[
        dtjava.embed(
            {
             	url : '/applications/CurveFittedChartApplet/CurveFittedChartApplet.jnlp',
                placeholder : 'applet-container',
                width : 540,
                height : 440 
            },
            {
             	javafx : '2.0+'
            },
            {}
	);
// ]]&gt;</script></p>
<h3>Curve Fitting</h3>
<p>I have to admit I did not work out all the Math myself for the curve fitting I found a great article on CodeProject <a href="http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit">&#8220;Draw a Smooth Curve through a Set of 2D Points with Bezier Primitives&#8221;</a>. Then ported the code to Java from C# and wired it up to our AreaChart. My version is not the most efficient as we do not yet have the correct API hooks to make it easy but we are thinking about how to add them. The current implementation extends AreaChart and overrides the layoutPlotChildren() method. That method creates all the nodes need for the chart and populates the node properties of the Series and Data items. So I can call super to let the standard code do its job then look at the Path elements for the stroked Path and filled Path that make up the AreaChart. I can then replace the LineTo elements with CubicCurveTo with the new control points calculated with the maths from the article. This way everything like auto ranging and animation still works as expected. The only waste is we are creating all the LineTo object and then throwing them away to replace them with CubicCurveTo objects. So here is the code that does this:</p>
<pre class="brush: java; title: ; notranslate">
    /** @inheritDoc */
    @Override protected void layoutPlotChildren() {
        super.layoutPlotChildren();
        for (int seriesIndex=0; seriesIndex &lt; getDataSize(); seriesIndex++) {
            final XYChart.Series&lt;Number, Number&gt; series = getData().get(seriesIndex);
            final Path seriesLine = (Path)((Group)series.getNode()).getChildren().get(1);
            final Path fillPath = (Path)((Group)series.getNode()).getChildren().get(0);
            smooth(seriesLine.getElements(), fillPath.getElements());
        }
    }

    private int getDataSize() {
        final ObservableList&lt;XYChart.Series&lt;Number, Number&gt;&gt; data = getData();
        return (data!=null) ? data.size() : 0;
    }

    private static void smooth(ObservableList&lt;PathElement&gt; strokeElements, ObservableList&lt;PathElement&gt; fillElements) {
        // as we do not have direct access to the data, first recreate the list of all the data points we have
        final Point2D[] dataPoints = new Point2D[strokeElements.size()];
        for (int i = 0; i &lt; strokeElements.size(); i++) {
            final PathElement element = strokeElements.get(i);
            if (element instanceof MoveTo) {
                final MoveTo move = (MoveTo)element;
                dataPoints[i] = new Point2D(move.getX(), move.getY());
            } else if (element instanceof LineTo) {
                final LineTo line = (LineTo)element;
                final double x = line.getX(), y = line.getY();
                dataPoints[i] = new Point2D(x, y);
            }
        }
        // next we need to know the zero Y value
        final double zeroY = ((MoveTo) fillElements.get(0)).getY();

        // now clear and rebuild elements
        strokeElements.clear();
        fillElements.clear();
        Pair&lt;Point2D[], Point2D[]&gt; result = calcCurveControlPoints(dataPoints);
        Point2D[] firstControlPoints = result.getKey();
        Point2D[] secondControlPoints = result.getValue();
        // start both paths
        strokeElements.add(new MoveTo(dataPoints[0].getX(),dataPoints[0].getY()));
        fillElements.add(new MoveTo(dataPoints[0].getX(),zeroY));
        fillElements.add(new LineTo(dataPoints[0].getX(),dataPoints[0].getY()));
        // add curves
        for (int i = 1; i &lt; dataPoints.length; i++) {
            final int ci = i-1;
            strokeElements.add(new CubicCurveTo(
                    firstControlPoints[ci].getX(),firstControlPoints[ci].getY(),
                    secondControlPoints[ci].getX(),secondControlPoints[ci].getY(),
                    dataPoints[i].getX(),dataPoints[i].getY()));
            fillElements.add(new CubicCurveTo(
                    firstControlPoints[ci].getX(),firstControlPoints[ci].getY(),
                    secondControlPoints[ci].getX(),secondControlPoints[ci].getY(),
                    dataPoints[i].getX(),dataPoints[i].getY()));
        }
        // end the paths
        fillElements.add(new LineTo(dataPoints[dataPoints.length-1].getX(),zeroY));
        fillElements.add(new ClosePath());
    }
</pre>
<h3>CSS Styling</h3>
<p>This is just the standard AreaChart in terms of the nodes its drawing with. The first part of the CSS is styling the main chart node and its background. We are using a dark gray texture as the background, adding a 1px black border and a drop shadow. Also adjusting the padding a little.</p>
<pre class="brush: css; title: ; notranslate">
.chart {
    -fx-background-image: url(&quot;background.png&quot;);
    -fx-padding: 15 25 15 15;
    -fx-border-color: black;
    -fx-effect: dropshadow( gaussian , rgba(0,0,0,0.8) , 10, 0.0 , 0 , 2 );
}
</pre>
<p>Next we are looking at the background of the plot area, this is the rectangular area bordered by the two axis. We are using two background images here one a colored glow and the second is transparent white gridlines. The first image is sized to &#8220;cover&#8221; the whole area of the plot background and the second is tiled to fill. We also add black borders to the top and right to complete a box around the plot area including the two axis lines.</p>
<pre class="brush: css; title: ; notranslate">
.chart-plot-background {
    -fx-background-image: url(&quot;chart-background.png&quot;), url(&quot;graph-gridlines.png&quot;);
    -fx-background-size: cover, auto;
    -fx-background-repeat: no-repeat, repeat;
    -fx-background-position: 0% 0%, 0% 100%;
    -fx-border-color: black black transparent transparent;
}
</pre>
<p>The line that connects the data points we are styling to be 2px wide and white.</p>
<pre class="brush: css; title: ; notranslate">
.chart-series-area-line {
    -fx-stroke: white;
    -fx-stroke-width: 2px;
}
</pre>
<p>The filled area under the line we are styling with a linear gradient from white on the left to 100% transparent white on the right. We also use a blend mode to get the desired effect when blending with the colored background of the plot area.</p>
<pre class="brush: css; title: ; notranslate">
.chart-series-area-fill {
    -fx-fill: linear-gradient(to right, white, rgba(255,255,255,0));
    -fx-blend-mode: OVERLAY;
}
</pre>
<p>Making the plot symbols for each data point white.</p>
<pre class="brush: css; title: ; notranslate">
.chart-area-symbol {
    -fx-background-color: white;
}
</pre>
<p>Hiding the tick marks and changing the color of the axis lines to black</p>
<pre class="brush: css; title: ; notranslate">
.axis {
    -fx-tick-mark-visible: false;
    -fx-minor-tick-visible: false;
    -fx-tick-length: 3;
    -fx-minor-tick-length: 0;
    -fx-border-color: transparent;
}
.axis:bottom {
    -fx-border-color: black transparent transparent transparent;
}
.axis:left {
    -fx-border-color: transparent black transparent transparent;
}
</pre>
<p>Styling the text labels on the axis so they are white with black shadow and a little larger than default.</p>
<pre class="brush: css; title: ; notranslate">
.axis Text{
    -fx-fill: white;
}
.tick-mark {
    -fx-font-size: 10px;
    -fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.8) , 0, 0.0 , 0 , 1 );
}
</pre>
<p>There you go that is all you need to take one of our standard charts and make it look completely different. Hopefully this will inspire some of you to try some exciting designs with JavaFX charts.</p>
<h3>Source Code</h3>
<p>The full Netbeans project and code including the maths is available here (<a href="http://fxexperience.com/applications/CurveFittedChartApplet/CurveFittedChart.zip">CurveFittedChart.zip</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/01/curve-fitting-and-styling-areachart/feed/</wfw:commentRss>
		<slash:comments>8</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>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>2</slash:comments>
		</item>
		<item>
		<title>Styling FX Buttons with CSS</title>
		<link>http://fxexperience.com/2011/12/styling-fx-buttons-with-css/</link>
		<comments>http://fxexperience.com/2011/12/styling-fx-buttons-with-css/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 23:36:03 +0000</pubDate>
		<dc:creator>Jasper Potts</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>
		<category><![CDATA[UI Design]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1523</guid>
		<description><![CDATA[A number of people have asked me recently can I create this look or that look using CSS in JavaFX. Or they have said that you could never do that! So I thought I would do a little experiment and try recreating a bunch of common button styles purely using CSS. So without further ado, [...]]]></description>
			<content:encoded><![CDATA[<p>A number of people have asked me recently can I create this look or that look using CSS in JavaFX. Or they have said that you could never do that! So I thought I would do a little experiment and try recreating a bunch of common button styles purely using CSS. So without further ado, here is the result:</p>
<p><img class="aligncenter size-full wp-image-1524" title="CSS Styled Buttons" src="http://fxexperience.com/wp-content/uploads/2011/12/Screen-Shot-2011-12-20-at-2.51.18-PM.png" alt="" width="706" height="873" /><br />
<span id="more-1523"></span><br />
All of these are mostly created with multiple background fill layers each with a gradient. Then there is a little font tweaking and some subtle effects. So for example all you need to make a JavaFX button look like a Windows 7 button is:</p>
<pre class="brush: css; title: ; notranslate">
#windows7-default {
    -fx-background-color:
        #3c7fb1,
        linear-gradient(#fafdfe, #e8f5fc),
        linear-gradient(#eaf6fd 0%, #d9f0fc 49%, #bee6fd 50%, #a7d9f5 100%);
    -fx-background-insets: 0,1,2;
    -fx-background-radius: 3,2,1;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: black;
    -fx-font-size: 14px;
}
</pre>
<p>The first line defines the 3 background fills, first is solid color and the other two are linear gradients. The background-insets offsets the backgrounds so they do not 100% paint over each other and the second background is 1px in from the outside and the 3rd background is 2px in from the outside of the button. The background-radius us setting the corner radius&#8217;s of the 3 backgrounds getting smaller as the backgrounds move in, this makes the gap between the borders a consistent 1 pixel all the way around. Padding adds extra space around the text to make the button bigger by default. Then the last two lines set the text color and size. That is all there is too it.</p>
<p>I have not included styles for the pressed, over and focused states of all the buttons but they can all be easily added in a similar way. I have included a over and pressed state for the &#8220;Record Sales&#8221; button as a example. </p>
<p>You can download the complete Netbeans project with all the code here.<br />
<b><a href="/applications/ButtonStyles.zip">ButtonStyles.zip</a></b></p>
<p>Here is the CSS code of all the button styles you see above:</p>
<pre class="brush: css; title: ; notranslate">
#green {
    -fx-background-color:
        linear-gradient(#f0ff35, #a9ff00),
        radial-gradient(center 50% -40%, radius 200%, #b8ee36 45%, #80c800 50%);
    -fx-background-radius: 6, 5;
    -fx-background-insets: 0, 1;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
    -fx-text-fill: #395306;
}
#round-red {
    -fx-background-color: linear-gradient(#ff5400, #be1d00);
    -fx-background-radius: 30;
    -fx-background-insets: 0;
    -fx-text-fill: white;
}
#bevel-grey {
    -fx-background-color:
        linear-gradient(#f2f2f2, #d6d6d6),
        linear-gradient(#fcfcfc 0%, #d9d9d9 20%, #d6d6d6 100%),
        linear-gradient(#dddddd 0%, #f6f6f6 50%);
    -fx-background-radius: 8,7,6;
    -fx-background-insets: 0,1,2;
    -fx-text-fill: black;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
}
#glass-grey {
    -fx-background-color:
        #c3c4c4,
        linear-gradient(#d6d6d6 50%, white 100%),
        radial-gradient(center 50% -40%, radius 200%, #e6e6e6 45%, rgba(230,230,230,0) 50%);
    -fx-background-radius: 30;
    -fx-background-insets: 0,1,1;
    -fx-text-fill: black;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 3, 0.0 , 0 , 1 );
}
#shiny-orange {
    -fx-background-color:
        linear-gradient(#ffd65b, #e68400),
        linear-gradient(#ffef84, #f2ba44),
        linear-gradient(#ffea6a, #efaa22),
        linear-gradient(#ffe657 0%, #f8c202 50%, #eea10b 100%),
        linear-gradient(from 0% 0% to 15% 50%, rgba(255,255,255,0.9), rgba(255,255,255,0));
    -fx-background-radius: 30;
    -fx-background-insets: 0,1,2,3,0;
    -fx-text-fill: #654b00;
    -fx-font-weight: bold;
    -fx-font-size: 14px;
    -fx-padding: 10 20 10 20;
}
#dark-blue {
    -fx-background-color:
        #090a0c,
        linear-gradient(#38424b 0%, #1f2429 20%, #191d22 100%),
        linear-gradient(#20262b, #191d22),
        radial-gradient(center 50% 0%, radius 100%, rgba(114,131,148,0.9), rgba(255,255,255,0));
    -fx-background-radius: 5,4,3,5;
    -fx-background-insets: 0,1,2,0;
    -fx-text-fill: white;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
    -fx-font-family: &quot;Arial&quot;;
    -fx-text-fill: linear-gradient(white, #d0d0d0);
    -fx-font-size: 12px;
    -fx-padding: 10 20 10 20;
}
#dark-blue Text {
    -fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.9) , 1, 0.0 , 0 , 1 );
}
#record-sales {
    -fx-padding: 8 15 15 15;
    -fx-background-insets: 0,0 0 5 0, 0 0 6 0, 0 0 7 0;
    -fx-background-radius: 8;
    -fx-background-color:
        linear-gradient(from 0% 93% to 0% 100%, #a34313 0%, #903b12 100%),
        #9d4024,
        #d86e3a,
        radial-gradient(center 50% 50%, radius 100%, #d86e3a, #c54e2c);
    -fx-effect: dropshadow( gaussian , rgba(0,0,0,0.75) , 4,0,0,1 );
    -fx-font-weight: bold;
    -fx-font-size: 1.1em;
}
#record-sales:hover {
    -fx-background-color:
        linear-gradient(from 0% 93% to 0% 100%, #a34313 0%, #903b12 100%),
        #9d4024,
        #d86e3a,
        radial-gradient(center 50% 50%, radius 100%, #ea7f4b, #c54e2c);
}
#record-sales:pressed {
    -fx-padding: 10 15 13 15;
    -fx-background-insets: 2 0 0 0,2 0 3 0, 2 0 4 0, 2 0 5 0;
}
#record-sales Text {
    -fx-fill: white;
    -fx-effect: dropshadow( gaussian , #a30000 , 0,0,0,2 );
}
#rich-blue {
    -fx-background-color:
        #000000,
        linear-gradient(#7ebcea, #2f4b8f),
        linear-gradient(#426ab7, #263e75),
        linear-gradient(#395cab, #223768);
    -fx-background-insets: 0,1,2,3;
    -fx-background-radius: 3,2,2,2;
    -fx-padding: 12 30 12 30;
    -fx-text-fill: white;
    -fx-font-size: 12px;
}
#rich-blue Text {
    -fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.8) , 0, 0.0 , 0 , 1);
}
#big-yellow {
    -fx-background-color:
        #ecebe9,
        rgba(0,0,0,0.05),
        linear-gradient(#dcca8a, #c7a740),
        linear-gradient(#f9f2d6 0%, #f4e5bc 20%, #e6c75d 80%, #e2c045 100%),
        linear-gradient(#f6ebbe, #e6c34d);
    -fx-background-insets: 0,9 9 8 9,9,10,11;
    -fx-background-radius: 50;
    -fx-padding: 15 30 15 30;
    -fx-font-family: &quot;Helvetica&quot;;
    -fx-font-size: 18px;
    -fx-text-fill: #311c09;
    -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.1) , 2, 0.0 , 0 , 1);
}
#big-yellow Text {
    -fx-effect: dropshadow( one-pass-box , rgba(255,255,255,0.5) , 0, 0.0 , 0 , 1);
}
#iphone-toolbar {
    -fx-background-color: linear-gradient(#98a8bd 0%, #8195af 25%, #6d86a4 100%);
}
#iphone {
    -fx-background-color:
        #a6b5c9,
        linear-gradient(#303842 0%, #3e5577 20%, #375074 100%),
        linear-gradient(#768aa5 0%, #849cbb 5%, #5877a2 50%, #486a9a 51%, #4a6c9b 100%);
    -fx-background-insets: 0 0 -1 0,0,1;
    -fx-background-radius: 5,5,4;
    -fx-padding: 7 30 7 30;
    -fx-text-fill: #242d35;
    -fx-font-family: &quot;Helvetica&quot;;
    -fx-font-size: 12px;
    -fx-text-fill: white;
}
#iphone Text {
    -fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.8) , 0, 0.0 , 0 , -1 );
}
#ipad-dark-grey {
    -fx-background-color:
        linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
        linear-gradient(#020b02, #3a3a3a),
        linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%),
        linear-gradient(#8a8a8a 0%, #6b6a6b 20%, #343534 80%, #262626 100%),
        linear-gradient(#777777 0%, #606060 50%, #505250 51%, #2a2b2a 100%);
    -fx-background-insets: 0,1,4,5,6;
    -fx-background-radius: 9,8,5,4,3;
    -fx-padding: 15 30 15 30;
    -fx-font-family: &quot;Helvetica&quot;;
    -fx-font-size: 18px;
    -fx-font-weight: bold;
    -fx-text-fill: white;
    -fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.2) , 1, 0.0 , 0 , 1);
}
#ipad-dark-grey Text {
    -fx-effect: dropshadow( one-pass-box , black , 0, 0.0 , 0 , -1 );
}
#ipad-grey {
    -fx-background-color:
        linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
        linear-gradient(#020b02, #3a3a3a),
        linear-gradient(#b9b9b9 0%, #c2c2c2 20%, #afafaf 80%, #c8c8c8 100%),
        linear-gradient(#f5f5f5 0%, #dbdbdb 50%, #cacaca 51%, #d7d7d7 100%);
    -fx-background-insets: 0,1,4,5;
    -fx-background-radius: 9,8,5,4;
    -fx-padding: 15 30 15 30;
    -fx-font-family: &quot;Helvetica&quot;;
    -fx-font-size: 18px;
    -fx-font-weight: bold;
    -fx-text-fill: #333333;
    -fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.2) , 1, 0.0 , 0 , 1);
}
#ipad-grey Text {
    -fx-effect: dropshadow( one-pass-box , white , 0, 0.0 , 0 , 1 );
}
#lion-default {
    -fx-background-color:
        rgba(0,0,0,0.08),
        linear-gradient(#5a61af, #51536d),
        linear-gradient(#e4fbff 0%,#cee6fb 10%, #a5d3fb 50%, #88c6fb 51%, #d5faff 100%);
    -fx-background-insets: 0 0 -1 0,0,1;
    -fx-background-radius: 5,5,4;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: #242d35;
    -fx-font-size: 14px;
}
#lion {
    -fx-background-color:
        rgba(0,0,0,0.08),
        linear-gradient(#9a9a9a, #909090),
        linear-gradient(white 0%, #f3f3f3 50%, #ececec 51%, #f2f2f2 100%);
    -fx-background-insets: 0 0 -1 0,0,1;
    -fx-background-radius: 5,5,4;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: #242d35;
    -fx-font-size: 14px;
}
#windows7-default {
    -fx-background-color:
        #3c7fb1,
        linear-gradient(#fafdfe, #e8f5fc),
        linear-gradient(#eaf6fd 0%, #d9f0fc 49%, #bee6fd 50%, #a7d9f5 100%);
    -fx-background-insets: 0,1,2;
    -fx-background-radius: 3,2,1;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: black;
    -fx-font-size: 14px;
}
#windows7 {
    -fx-background-color:
        #707070,
        linear-gradient(#fcfcfc, #f3f3f3),
        linear-gradient(#f2f2f2 0%, #ebebeb 49%, #dddddd 50%, #cfcfcf 100%);
    -fx-background-insets: 0,1,2;
    -fx-background-radius: 3,2,1;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: black;
    -fx-font-size: 14px;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/12/styling-fx-buttons-with-css/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Alternate row highlighting in empty TableView (and ListView) rows</title>
		<link>http://fxexperience.com/2011/11/alternate-row-highlighting-in-empty-tableview-and-listview-rows/</link>
		<comments>http://fxexperience.com/2011/11/alternate-row-highlighting-in-empty-tableview-and-listview-rows/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 04:53:05 +0000</pubDate>
		<dc:creator>Jonathan Giles</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>
		<category><![CDATA[UI Design]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1499</guid>
		<description><![CDATA[One thing I see asked a lot (either directly via email, or in the rather excellent JavaFX Forums) is why does TableView (and ListView) look like this in JavaFX 2.0: Or, more specifically, why it doesn&#8217;t look like this: I can see where this question comes from, given this is how Swing&#8217;s JTable looks: It [...]]]></description>
			<content:encoded><![CDATA[<p>One thing I see asked a lot (either directly via email, or in the rather excellent <a href="https://forums.oracle.com/forums/forum.jspa?forumID=1385&amp;start=0">JavaFX Forums</a>) is why does TableView (and ListView) look like this in JavaFX 2.0:</p>
<div id="attachment_1500" class="wp-caption aligncenter" style="width: 509px"><img class="size-full wp-image-1500" title="blog-table-1" src="http://fxexperience.com/wp-content/uploads/2011/11/blog-table-1.png" alt="" width="499" height="310" /><p class="wp-caption-text">A TableView control using default styling and API as provided in JavaFX 2.0.</p></div>
<p><span id="more-1499"></span>Or, more specifically, why it doesn&#8217;t look like this:</p>
<div id="attachment_1502" class="wp-caption aligncenter" style="width: 508px"><img class="size-full wp-image-1502" title="blog-table-2" src="http://fxexperience.com/wp-content/uploads/2011/11/blog-table-2.png" alt="" width="498" height="307" /><p class="wp-caption-text">A TableView without alternate row highlighting in empty rows</p></div>
<p>I can see where this question comes from, given this is how Swing&#8217;s JTable looks:</p>
<div id="attachment_1501" class="wp-caption aligncenter" style="width: 535px"><img class="size-full wp-image-1501" title="blog-table-3" src="http://fxexperience.com/wp-content/uploads/2011/11/blog-table-3.png" alt="" width="525" height="188" /><p class="wp-caption-text">Swing JTable</p></div>
<p>It comes down to taste I guess, but given that there is a subset of developers who expect this look, I thought I&#8217;d put a blog post up here to clarify how it is done (and to save me having to explain it to people individually by email!) <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  All you need is the following CSS for TableView:</p>
<pre class="brush: css; title: ; notranslate">
.table-row-cell:empty {
    -fx-background-color: white;
}

.table-row-cell:empty .table-cell {
    -fx-border-width: 0px;
}
</pre>
<p>Similarly, for ListView, you can get away with just the first statement above (slightly modified for ListView):</p>
<pre class="brush: css; title: ; notranslate">
.list-cell:empty {
    -fx-background-color: white;
}
</pre>
<p>The end result is precisely what you see in the second image above (there ain&#8217;t no photoshop trickery here!) <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Hopefully this helps people customising their user interfaces, and hopefully also encourages you to further explore what is possible. The best starting point is the excellent <a href="http://docs.oracle.com/javafx/">JavaFX documentation website</a>, the <a href="http://docs.oracle.com/javafx/2.0/api/javafx/scene/doc-files/cssref.html">CSS Reference</a> (which is about to be updated for 2.0.2 I believe), and as always, the caspian.css file that ships with every JavaFX release (embedded within jfxrt.jar).</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/11/alternate-row-highlighting-in-empty-tableview-and-listview-rows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Correctly Checking KeyEvents</title>
		<link>http://fxexperience.com/2011/10/correctly-checking-keyevents/</link>
		<comments>http://fxexperience.com/2011/10/correctly-checking-keyevents/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 22:59:47 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1431</guid>
		<description><![CDATA[I was just writing a quick little application and I wanted to do something special whenever the user released the enter key inside a TextArea. You might be tempted to do it like this: Can anybody spot the problem in this code? It correctly gets the key event, and it only prints out the text [...]]]></description>
			<content:encoded><![CDATA[<p>I was just writing a quick little application and I wanted to do something special whenever the user released the enter key inside a TextArea. You might be tempted to do it like this:</p>
<pre class="brush: java; title: ; notranslate">
final TextArea editor = new TextArea();
editor.setOnKeyReleased(new EventHandler&lt;KeyEvent&gt;() {
    public void handle(KeyEvent t) {
        if (t.getCode() == KeyCode.ENTER) {
            System.out.println(editor.getText());
        }
    }
});
</pre>
<p>Can anybody spot the problem in this code? It correctly gets the key event, and it only prints out the text if the code of the key event is ENTER. The problem is that it also executes this code if you typed ALT+ENTER, or CTRL+ENTER, or any other combination of modifiers with the key code! JavaFX 2.0 contains a handy little class called KeyCombination which will handle all the annoying checking of key modifiers + key code to see if a specific key event matches. Here is the more correct version:</p>
<pre class="brush: java; title: ; notranslate">
final TextArea editor = new TextArea();
editor.setOnKeyReleased(new EventHandler&lt;KeyEvent&gt;() {
    final KeyCombination combo = new KeyCodeCombination(KeyCode.ENTER);
    public void handle(KeyEvent t) {
        if (combo.match(t)) {
            System.out.println(editor.getText());
        }
    }
});
</pre>
<p>One extra line of code, and you get correct matching of the key events. Sweet!</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/10/correctly-checking-keyevents/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>FXML: Why It Rocks, And The Next Phase</title>
		<link>http://fxexperience.com/2011/10/fxml-why-it-rocks-and-the-next-phase/</link>
		<comments>http://fxexperience.com/2011/10/fxml-why-it-rocks-and-the-next-phase/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 21:03:54 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[FXML]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1426</guid>
		<description><![CDATA[JavaFX 2.0 shipped with a declarative XML-based language for defining user interfaces, called FXML. FXML is a key part of our strategy around making it easier to create user interfaces in Java. Certainly having a markup language has been attractive to web developers since it is a familiar and comfortable way to approach describing a [...]]]></description>
			<content:encoded><![CDATA[<p>JavaFX 2.0 shipped with a declarative XML-based language for defining user interfaces, called <a href="http://download.oracle.com/javafx/2.0/fxml_get_started/jfxpub-fxml_get_started.htm">FXML</a>. FXML is a key part of our strategy around making it easier to create user interfaces in Java. Certainly having a markup language has been attractive to web developers since it is a familiar and comfortable way to approach describing a user interface. But there are other key strategic reasons why FXML is important, how it fits into the broader JavaFX ecosystem, and how it helps you write testable user interfaces with minimal fuss. In essence, FXML helps you follow best practices while also making your life easier.</p>
<p><span id="more-1426"></span></p>
<h3>Quick Introduction</h3>
<p>FXML is an XML-based language for describing UIs. This has become quite commonplace in the industry. Swing had several variants which did just this (including <a href="http://javadesktop.org/articles/JDNC2/index.html#jdncmarkup">JDNC</a>). Flex came with MXML and .NET and Silverlight came with XAML. And then of course the web has always had a non-XML based HTML markup and XML-based XHTML markup, as well as SVG and many other variants. So we&#8217;re not exactly treading new ground here, which is one of the great advantages to FXML. Whereas JavaFX 1.X forced everybody to learn a new language and new tools, with JavaFX 2.0 we explicitly decided to return to familiar languages and familiar tools.</p>
<p>FXML doesn&#8217;t have a schema. It does have some basic predefined structure, but what you can express in FXML and how it applies to constructing object graphs depends on the API of the objects you are trying to construct. It isn&#8217;t <em>only</em> for constructing UI graphs, you can also construct Services or Tasks or domain objects or whatnot. Heck, you can even use JavaScript or other scripting languages in FXML. However, from a Model-View-Controller perspective, FXML works best when simply representing the view in some declarative manner and you let your Java code (or other JVM language) handle the model and controller parts of the pattern.</p>
<h3>Tools</h3>
<p>FXML is a key part of our tooling strategy. One of the major drawbacks to Java RAD tools has been that they create (and sometimes) parse arbitrary Java code and then try to represent this in the GUI editor view. This proved to be so difficult, that nearly every Java RAD tool instead opted for a tool-specific XML file to describe the UI, and then do one-way code generation. The problem with this approach is that the only tool-independent representation of the UI is in Java code, so when you use one GUI builder you are essentially locked into using it, or having to write custom converters to convert from one tool to another. Needless to say, in a large team where people want to use different IDEs this puts up significant barriers to RAD tool adoption.</p>
<p>With JavaFX 2.0 and the introduction of FXML, we&#8217;re defining a standard interchange format which can be used by every RAD tool. Even better, it isn&#8217;t just a tooling format, but is also easy to read / write by hand. We&#8217;re working hard with our Scene Builder tool to make sure it produces clean FXML &#8212; the kind you would have done by hand had you decided to do so. This strategy is of course not new, both MXML and XAML are used in the same manner.</p>
<p>Because FXML doesn&#8217;t have a schema of its own, we anticipate IDEs will add specific FXML editor support such that you will get code completion and so forth when editing FXML by hand. As for myself, I hope to always use a RAD tool <img src='http://fxexperience.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h3>Design Patterns</h3>
<p>The terminology used with FXML is that of MVC. The idea being that the View is the FXML file itself, and should only really have a description of the user interface. The Controller is some Java class (optionally implementing Initializable) which is then declared in the FXML file as the controller for that FXML file. The Model is just some domain objects you have, probably defined on the Java side, that you then need to wire up to the view via the controller. It would look something like this:</p>
<p><i>Sample.FXML</i></p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;?import javafx.scene.control.*?&gt;
&lt;?import javafx.scene.layout.*?&gt;

&lt;VBox xmlns:fx=&quot;http://javafx.com/fxml&quot; fx:controller=&quot;fxmlapp.Sample&quot;&gt;
    &lt;children&gt;
        &lt;TextField fx:id=&quot;firstNameField&quot; onAction=&quot;#submit&quot; /&gt;
        &lt;Label fx:id=&quot;messageLabel&quot; /&gt;
    &lt;/children&gt;
&lt;/VBox&gt;
</pre>
<p><i>Person.java</i></p>
<pre class="brush: java; title: ; notranslate">
package fxmlapp;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Person {
    private StringProperty firstName = new SimpleStringProperty(this, &quot;firstName&quot;, &quot;&quot;);
    public final String getFirstName() { return firstName.get(); }
    public final void setFirstName(String value) { firstName.set(value); }
    public final StringProperty firstNameProperty() { return firstName; }
}
</pre>
<p><i>Sample.java</i></p>
<pre class="brush: java; title: ; notranslate">
package fxmlapp;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;

public class Sample implements Initializable {

    private Person person = new Person();

    @FXML
    private TextField firstNameField;

    @FXML
    private Label messageLabel;

    @FXML
    private void submit(ActionEvent event) {
        messageLabel.setText(person.getFirstName());
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        firstNameField.textProperty().bindBidirectional(person.firstNameProperty());
    }
}
</pre>
<p>In this example, the FXML document contains a TextField and Label. When the &#8220;enter&#8221; key is pressed while the TextField has focus, it will invoke the &#8220;submit&#8221; method on the controller. The controller, meanwhile, is going to update the label whenever the text is submitted.</p>
<p>One thing that is kind of awkward though is that all my binding is being done in Java code. The Controller facilities interaction between the View and Model, and therefore in the initialize method of the controller, you specify how to wire things up. The problem with this is that the RAD tools shouldn&#8217;t be generating Java code (or we&#8217;re back to the same troubles as with previous Java RAD tools), but should only use the FXML document. So that means your RAD tool won&#8217;t be able to do any binding for you.</p>
<p>I could turn things around a little bit and move the binding into the FXML document. This would allow tools to handle data binding in addition to layout. Note that <strong>the following code does not work today</strong> because bidirectional bindings are not supported in FXML, but we are working on fixing that.</p>
<p><i>Sample.fxml</i></p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;?import javafx.scene.control.*?&gt;
&lt;?import javafx.scene.layout.*?&gt;
&lt;?import fxmlapp.Model ?&gt;

&lt;VBox fx:id=&quot;root&quot; xmlns:fx=&quot;http://javafx.com/fxml&quot; fx:controller=&quot;fxmlapp.Sample&quot;&gt;
    &lt;fx:define&gt;
        &lt;Model fx:id=&quot;model&quot; /&gt;
    &lt;/fx:define&gt;
    &lt;children&gt;
        &lt;TextField fx:id=&quot;firstNameField&quot; text=&quot;${model.person.firstName}&quot; /&gt;
        &lt;Label fx:id=&quot;messageLabel&quot; text=&quot;${model.person.firstName}&quot; /&gt;
    &lt;/children&gt;
&lt;/VBox&gt;
</pre>
<p><i>Model.java</i></p>
<pre class="brush: java; title: ; notranslate">
package fxmlapp;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;

public class Model {
    private ObjectProperty&lt;Person&gt; person = new SimpleObjectProperty&lt;Person&gt;(this, &quot;person&quot;);
    public final Person getPerson() { return person.get(); }
    public final void setPerson(Person value) { person.set(value); }
    public final ObjectProperty&lt;Person&gt; personProperty() { return person; }
}
</pre>
<p><i>Sample.java</i></p>
<pre class="brush: java; title: ; notranslate">
package fxmlapp;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;

public class Sample implements Initializable {

    @FXML private Model model;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        model.setPerson(new Person());
    }
}
</pre>
<p>Here the FXML document defines a local &#8220;Model&#8221; variable, to which it binds. The Model is nothing more than a class which then has a &#8220;Person&#8221; object on it, though it could have other state. In the Controller I then get the Model defined in the FXML document and give it the Person object it should operate on. The benefit here is that the controller no longer has any references to the GUI elements defined in the FXML document. This means it would be much easier for tooling support (no modification of the Java code). There is also an elegance to the fact that the State exists independently of the View, and the View just binds to the State.</p>
<p>As I mentioned above, this code does not work today because we don&#8217;t have bidirectional binding support in the FXML language, although that is high on the priority list since it would enable patterns like this to exist.</p>
<p>Unfortunately this fully MVC pattern is more verbose than necessary, because there are actually two different models. We have the &#8220;Person&#8221; object which is actually the domain data model, and then we have the &#8220;Model&#8221; class which is acting as a carrier &#8212; it is the way we declare in the FXML that some domain data will be declared in this &#8220;Model&#8221; so we can bind to it, but it isn&#8217;t actually adding value in and of itself. That is, it is an accidental creation in order to make the system happy, not some essential element in your application. Lets get rid of this boilerplate. Beside MVC there is another great pattern known as the <a href="http://martinfowler.com/eaaDev/PresentationModel.html">Presentation Model</a>.</p>
<p>The Presentation Model is another Smalltalk pattern for describing how to build a UI. From effective engineers I know who have used it in practice, the Presentation Model has significant advantages such as making testing easier. You really ought to go read a bit about it. The essence is very simple: there is a presentation (view), and a presentation model (view model). There is also a data model, it is true, but that becomes exposed to the view via the presentation model. In our terminology, the presentation is the FXML document, and the presentation model is an associated controller.</p>
<p>With this pattern, all the binding logic lives in the FXML document, while all the model data lives in the presentation model. One of the wonderful side effects of this pattern is that I no longer need to have @FXML annotated fields representing the different UI elements, or even have any @FXML annotated fields at all. This simplifies the Controller code, but also makes it easier to maintain because if I add new elements or remove elements or change the ids of the elements or whatnot, I don&#8217;t have to change the code. And remember that the RAD tool want&#8217;s to touch as little code as possible, so removing this tight coupling between sources and FXML is a big plus. In addition, everything is just easier to understand. And the Controller now takes on a significantly simpler and more powerful role. </p>
<p><i>Sample.fxml</i></p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;?import javafx.scene.control.*?&gt;
&lt;?import javafx.scene.layout.*?&gt;

&lt;VBox fx:id=&quot;root&quot; xmlns:fx=&quot;http://javafx.com/fxml&quot; fx:controller=&quot;fxmlapp.Sample&quot;&gt;
    &lt;children&gt;
        &lt;TextField fx:id=&quot;firstNameField&quot; text=&quot;${controller.person.firstName}&quot; /&gt;
        &lt;Label fx:id=&quot;messageLabel&quot; text=&quot;${controller.person.firstName}&quot;/&gt;
    &lt;/children&gt;
&lt;/VBox&gt;
</pre>
<p><i>Sample.java</i></p>
<pre class="brush: java; title: ; notranslate">
package fxmlapp;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;

public class Sample {
    private ObjectProperty&lt;Person&gt; person = new SimpleObjectProperty&lt;Person&gt;(this, &quot;person&quot;);
    public final Person getPerson() { return person.get(); }
    public final void setPerson(Person value) { person.set(value); }
    public final ObjectProperty&lt;Person&gt; personProperty() { return person; }
}
</pre>
<p>As you can see, this is almost exactly like the previous version except now the model state is in the Sample PresentationModel/Controller rather than in the Model class or FXML document, and the FXML document no longer defines its own model variables, but just binds straight through the controller. This example is a <strong>proposal</strong>, it won&#8217;t work today. We are thinking about adding support for this in an upcoming update release. In particular, in addition to needing to add FXML language support for bidirectional binding, we also need to add support for an implicit &#8220;controller&#8221; variable.</p>
<p>The real power of the PresentationModel is that it gives you, the Java developer, the ability to do all the custom things you typically need to do in real world applications. Perhaps the data model comes to use as a single phone number and you need to split it into area code, high numbers, low numbers (555-223-2333 for example) for your UI. In this case, you write some code in the PresentationModel which does this, presenting three simple and straightforward properties that your UI will bidirectionally bind to. Or perhaps you are presenting a form, and you want people to enter items in the form and auto-validate the entire form together, but you don&#8217;t want to update the domain objects until the user &#8220;submits&#8221; the form. In such a case, you can take the domain object and have properties in the PresentationModel represent each individual field, essentially buffering changes from being put back into the domain object until the submit method is called. For example:</p>
<p><i>Sample.fxml</i></p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;?import javafx.scene.control.*?&gt;
&lt;?import javafx.scene.layout.*?&gt;

&lt;FlowPane fx:id=&quot;root&quot; xmlns:fx=&quot;http://javafx.com/fxml&quot; fx:controller=&quot;fxmlapp.Sample&quot;&gt;
    &lt;children&gt;
        &lt;TextField fx:id=&quot;firstNameField&quot; text=&quot;${controller.areaCode}&quot; /&gt;
        &lt;TextField fx:id=&quot;firstNameField&quot; text=&quot;${controller.highDigits}&quot; /&gt;
        &lt;TextField fx:id=&quot;firstNameField&quot; text=&quot;${controller.lowDigits}&quot; /&gt;
    &lt;/children&gt;
&lt;/FlowPane&gt;
</pre>
<p><i>Sample.java</i></p>
<pre class="brush: java; title: ; notranslate">
package fxmlapp;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;

public class Sample {
    public final StringProperty areaCode = new SimpleStringProperty(&quot;this&quot;, &quot;areaCode&quot;, &quot;&quot;);
    public final StringProperty highDigits = new SimpleStringProperty(&quot;this&quot;, &quot;highDigits&quot;, &quot;&quot;);
    public final StringProperty lowDigits = new SimpleStringProperty(&quot;this&quot;, &quot;lowDigits&quot;, &quot;&quot;);

    public void setPhoneNumber(String number) {
        // Of form xxx-xxx-xxxx
        final parts = number.split(&quot;-&quot;);
        areaCode.set(parts[0]);
        highDigits.set(parts[1]);
        lowDigits.set(parts[2]);
    }
}
</pre>
<p>(I used a public final property instead of getters and setters because, I&#8217;m lazy <img src='http://fxexperience.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> . Since this part of the post is about futures, I figured, what the heck).</p>
<p>There are other ways this could be further simplified, if there were binding containers and auto-buffering properties and the like. But the key point here is that the Presentation Model pattern lets you do all this application specific manipulation of state in Java code, by the developer, while the designer is free to modify what the UI looks like or what fields are exposed via the FXML.</p>
<p>This much more interesting because the Presentation Model is also fully testable. You can easily write unit tests for the Presentation Model, to test that buffering is working as expected, validation is working as expected, loading of domain objects works as expected, and so forth. And all this done irrespective of what the actual UI looks like!</p>
<p>Now of course, we want to make all this tool-able. So in a RAD tool you can load up the controller (presentation model) for an FXML document and then bind things directly in the tool. It will introspect and find all the properties exposed on the PM and offer these as bind targets and make this all nice and easy. Those are my thoughts on it. What are yours?</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/10/fxml-why-it-rocks-and-the-next-phase/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>SplitPane in JavaFX 2.0</title>
		<link>http://fxexperience.com/2011/06/splitpane-in-javafx-2-0/</link>
		<comments>http://fxexperience.com/2011/06/splitpane-in-javafx-2-0/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 06:24:15 +0000</pubDate>
		<dc:creator>Jonathan Giles</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1242</guid>
		<description><![CDATA[We&#8217;ve introduced a SplitPane control in JavaFX 2.0, and today I thought I&#8217;d point out an interesting subtlety in the API. For the longest time our SplitPane API primarily consisted of the normal &#8216;left&#8217; and &#8216;right&#8217; (or &#8216;top&#8217; and &#8216;bottom&#8217;) properties (indeed, the JavaDoc as of today still refers to this API). These were synonomous [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve introduced a SplitPane control in JavaFX 2.0, and today I thought I&#8217;d point out an interesting subtlety in the API. For the longest time our SplitPane API primarily consisted of the normal &#8216;left&#8217; and &#8216;right&#8217; (or &#8216;top&#8217; and &#8216;bottom&#8217;) properties (indeed, the JavaDoc as of today <a href="http://download.oracle.com/javafx/2.0/api/javafx/scene/control/SplitPane.html">still refers to this API</a>). These were synonomous &#8211; if you set &#8216;top&#8217; and &#8216;bottom&#8217;, they were literally copied to the &#8216;left&#8217; and &#8216;right&#8217; code, and our SplitPaneSkin just knew to draw with the items stacked vertically, rather than to lay them out horizontally.</p>
<p><img class="aligncenter size-full wp-image-1243" title="splitPane1" src="http://fxexperience.com/wp-content/uploads/2011/06/splitPane1.png" alt="" width="610" height="315" /></p>
<p><span id="more-1242"></span>In the very, very late stages of the JavaFX 2.0 EA program, we decided we didn&#8217;t really like this API all that much. The concept of having both left/right and top/bottom just didn&#8217;t really gel with us. After some discussion, we thought we&#8217;d use the same API style as we do elsewhere in JavaFX 2.0: expose a collection and allow for developers to place their content into it. This mean that to use a SplitPane, you&#8217;d use code such as the following:</p>
<pre class="brush: java; title: ; notranslate">
import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class SplitPaneSample extends Application {

    @Override public void start(Stage stage) {
        HBox hbox = new HBox(20);
        hbox.setTranslateX(20);
        hbox.setTranslateY(20);

        SplitPane splitPane1 = new SplitPane();
        splitPane1.setPrefSize(200, 200);
        final Button l = new Button(&quot;Left Button&quot;);
        final Button r = new Button(&quot;Right Button&quot;);
        splitPane1.getItems().addAll(l, r);
        hbox.getChildren().add(splitPane1);

        Scene scene = new Scene(new Group(hbox), 560, 240);
        scene.setFill(Color.GHOSTWHITE);
        stage.setScene(scene);
        stage.setTitle(&quot;SplitPane&quot;);
        stage.setVisible(true);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
</pre>
<p>The main segment of code is the middle block, where we create a SplitPane, set a preferred size, and add in the two buttons we want to display. I hope you see where I&#8217;m going with this: now that we aren&#8217;t constrained to just having &#8216;left&#8217; and &#8216;right&#8217; nodes, we can actually put in any number of nodes into the items collection &#8211; and the SplitPane will automatically create N &#8211; 1 dividers. For example:</p>
<pre class="brush: java; title: ; notranslate">
        SplitPane splitPane2 = new SplitPane();
        splitPane2.setPrefSize(300, 200);
        final Button l2 = new Button(&quot;Left Button&quot;);
        final Button c2 = new Button(&quot;Center Button&quot;);
        final Button r2 = new Button(&quot;Right Button&quot;);
        splitPane2.getItems().addAll(l2, c2, r2);
        hbox.getChildren().add(splitPane2);
</pre>
<p>The result of this code is shown in the second SplitPane you see in the picture above. Now, a SplitPane wouldn&#8217;t be all that great if it only allows for the SplitPane content to run in a horizontal flow, so we also support setting an orientation on the SplitPane. As mentioned, the default value is HORIZONTAL, which is what you see in the screenshot above. You can also set it to VERTICAL, which you can see in the screenshot below.</p>
<pre class="brush: java; title: ; notranslate">
        SplitPane splitPane1 = new SplitPane();
        splitPane1.setOrientation(Orientation.VERTICAL);
        splitPane1.setPrefSize(200, 200);
        final Button l1 = new Button(&quot;Left Button&quot;);
        final Button r1 = new Button(&quot;Right Button&quot;);
        splitPane1.getItems().addAll(l1, r1);
        hbox.getChildren().add(splitPane1);

        SplitPane splitPane2 = new SplitPane();
        splitPane2.setOrientation(Orientation.VERTICAL);
        splitPane2.setPrefSize(300, 200);
        final Button l2 = new Button(&quot;Left Button&quot;);
        final Button c2 = new Button(&quot;Center Button&quot;);
        final Button r2 = new Button(&quot;Right Button&quot;);
        splitPane2.getItems().addAll(l2, c2, r2);
        hbox.getChildren().add(splitPane2);
</pre>
<p><img class="aligncenter size-full wp-image-1244" title="splitPane2" src="http://fxexperience.com/wp-content/uploads/2011/06/splitPane2.png" alt="" width="604" height="320" /></p>
<p>Now, you can&#8217;t have a single SplitPane with multiple orientations. However, you can quite easily embed one SplitPane inside another to get this effect:</p>
<pre class="brush: java; title: ; notranslate">
        SplitPane splitPane1 = new SplitPane();
        splitPane1.setOrientation(Orientation.VERTICAL);
        splitPane1.setPrefSize(200, 200);
        final Button l1 = new Button(&quot;Top Button&quot;);
        final Button r1 = new Button(&quot;Bottom Button&quot;);
        splitPane1.getItems().addAll(l1, r1);

        SplitPane splitPane2 = new SplitPane();
        splitPane2.setOrientation(Orientation.HORIZONTAL);
        splitPane2.setPrefSize(300, 200);
        final Button c2 = new Button(&quot;Center Button&quot;);
        final Button r2 = new Button(&quot;Right Button&quot;);
        splitPane2.getItems().addAll(splitPane1, c2, r2);
        hbox.getChildren().add(splitPane2);
</pre>
<p>With the code above, you&#8217;ll end up with something a little like this:<br />
<img class="aligncenter size-full wp-image-1245" title="splitPane3" src="http://fxexperience.com/wp-content/uploads/2011/06/splitPane3.png" alt="" width="393" height="313" /></p>
<p>I hope this helps to introduce you to our brand new SplitPane control, and I look forward to see you using it in your applications soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/06/splitpane-in-javafx-2-0/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
	</channel>
</rss>

