<?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; Controls</title>
	<atom:link href="http://fxexperience.com/category/controls/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>ListView, custom cell factories, and context menus</title>
		<link>http://fxexperience.com/2012/05/listview-custom-cell-factories-and-context-menus/</link>
		<comments>http://fxexperience.com/2012/05/listview-custom-cell-factories-and-context-menus/#comments</comments>
		<pubDate>Mon, 21 May 2012 03:20:50 +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=1974</guid>
		<description><![CDATA[One question I see occasionally is people asking how to go about using prebuilt cell factories (such as those provided in the DataFX project run by Johan Vos and I, those sitting in the OpenJFX 2.2 repo in the javafx.scene.control.cell package, or just those that they have created internally), and also show a context menu [...]]]></description>
			<content:encoded><![CDATA[<p>One question I see occasionally is people asking how to go about using prebuilt cell factories (such as those provided in the <a href="http://www.javafxdata.org">DataFX project</a> run by <strong>Johan Vos</strong> and I, those sitting in the <a href="http://openjdk.java.net/projects/openjfx/">OpenJFX</a> 2.2 repo in the javafx.scene.control.cell package, or just those that they have created internally), and also show a context menu when the user right clicks. More generally, the problem is that cell factories are blackboxes, and there is no support for chaining cell factories together (or even getting hold of the cells as they are being used).</p>
<p>The answer is quite simple: wrap the cell factory inside another cell factory, and set the ContextMenu on the wrapping cell. In other words, you would write code such as this (for ListView):</p>
<pre class="brush: java; title: ; notranslate">
// The cell factory you actually want to use to render the cell
Callback&lt;ListView&lt;T&gt;, ListCell&lt;T&gt; wrappedCellFactory = ...; 

// The wrapping cell factory that will set the context menu onto the wrapped cell
Callback&lt;ListView&lt;T&gt;, ListCell&lt;T&gt; cellFactory = new Callback&lt;ListView&lt;T&gt;, ListCell&lt;T&gt;&gt;() {
    @Override public ListCell&lt;T&gt; call(ListView&lt;T&gt; listView) {
        ListCell&lt;T&gt; cell = cellFactory == null ? new DefaultListCell&lt;T&gt;() : wrappedCellFactory.call(listView);
        cell.setContextMenu(contextMenu);
        return cell;
    }
};

// Creating a ListView and setting the cell factory on it
ListView&lt;T&gt; listView = new ListView&lt;T&gt;();
listView.setCellFactory(cellFactory);
</pre>
<p><span id="more-1974"></span></p>
<p>Before I get any further, I should note quickly that this blog post is about ListView / ListCell, but the exact same approach (and even code &#8211; barring a little bit of renaming) is still totally applicable to TreeView and TableView. </p>
<p>One thing to note in the code above is the use of DefaultListCell, which is defined below. I made a new class as I was working on this problem, but I just copy/pasted the code out of ListViewSkin for creating default ListCell instances when the end-developer has not installed a custom cell factory. DefaultListCell therefore just handles the most common case of showing text and/or a &#8216;graphic&#8217; (which can be an arbitrarily complex scenegraph node):</p>
<pre class="brush: java; title: ; notranslate">
import javafx.scene.Node;
import javafx.scene.control.ListCell;

public class DefaultListCell&lt;T&gt; extends ListCell&lt;T&gt; {
    @Override public void updateItem(T item, boolean empty) {
        super.updateItem(item, empty);

        if (empty) {
            setText(null);
            setGraphic(null);
        } else if (item instanceof Node) {
            setText(null);
            Node currentNode = getGraphic();
            Node newNode = (Node) item;
            if (currentNode == null || ! currentNode.equals(newNode)) {
                setGraphic(newNode);
            }
        } else {
            setText(item == null ? &quot;null&quot; : item.toString());
            setGraphic(null);
        }
    }
}
</pre>
<p>Of course, I&#8217;m not going to leave you with just the code above! We have to make a more useful API out of this (this is my day job after all)! Therefore, borrowing from the style of the cell factories that are shipping with JavaFX 2.2, I present to you the following sample:</p>
<pre class="brush: java; title: ; notranslate">
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;

/**
 * A fully fleshed out class that allows for context menus to be shown on right click.
 */
public class ContextMenuListCell&lt;T&gt; extends ListCell&lt;T&gt; {

    public static &lt;T&gt; Callback&lt;ListView&lt;T&gt;,ListCell&lt;T&gt;&gt; forListView(ContextMenu contextMenu) {
        return forListView(contextMenu, null);
    }

    public static &lt;T&gt; Callback&lt;ListView&lt;T&gt;,ListCell&lt;T&gt;&gt; forListView(final ContextMenu contextMenu, final Callback&lt;ListView&lt;T&gt;,ListCell&lt;T&gt;&gt; cellFactory) {
        return new Callback&lt;ListView&lt;T&gt;,ListCell&lt;T&gt;&gt;() {
            @Override public ListCell&lt;T&gt; call(ListView&lt;T&gt; listView) {
                ListCell&lt;T&gt; cell = cellFactory == null ? new DefaultListCell&lt;T&gt;() : cellFactory.call(listView);
                cell.setContextMenu(contextMenu);
                return cell;
            }
        };
    }

    public ContextMenuListCell(ContextMenu contextMenu) {
        setContextMenu(contextMenu);
    }
}
</pre>
<p>Now that we have a simple API, we can proceed to use this API along the following lines:</p>
<pre class="brush: java; title: ; notranslate">
// Create a MenuItem and place it in a ContextMenu
MenuItem helloWorld = new MenuItem(&quot;Hello World!&quot;);
ContextMenu contextMenu = new ContextMenu(helloWorld);

// sets a cell factory on the ListView telling it to use the previously-created ContextMenu (uses default cell factory)
listView.setCellFactory(ContextMenuListCell.&lt;Person&gt;forListView(contextMenu));

// Same as above, but uses a custom cell factory that is defined elsewhere
listView.setCellFactory(ContextMenuListCell.&lt;Person&gt;forListView(contextMenu, customCellFactory));
</pre>
<p>This results in the following when a user right-clicks on a cell in the ListView: </p>
<p><img src="http://fxexperience.com/wp-content/uploads/2012/05/contextMenuListView1.png" alt="" title="contextMenuListView" width="205" height="308" class="aligncenter size-full wp-image-1988" /></p>
<p>However, we&#8217;re left with one final issue: we need a way to determine which cell was selected when a MenuItem action is fired. Fortunately, this proves to be trivial: simply refer to the ListView selection model, as selection also changes on right-click (which in some ways is a bug, but for now it suits our needs). Here&#8217;s some sample code:</p>
<pre class="brush: java; title: ; notranslate">
helloWorld.setOnAction(new EventHandler&lt;ActionEvent&gt;() {
    @Override public void handle(ActionEvent e) {
        System.out.println(&quot;Selected item: &quot; + listView.getSelectionModel().getSelectedItem());
    }
});
</pre>
<p>And that&#8217;s that! <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Hopefully this is helpful to people out there. I&#8217;m sure you&#8217;ll have questions and comments &#8211; feel free to leave them on this post so that others may also learn. </p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/05/listview-custom-cell-factories-and-context-menus/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New in JavaFX 2.1: ComboBox</title>
		<link>http://fxexperience.com/2012/03/new-in-javafx-2-1-combobox/</link>
		<comments>http://fxexperience.com/2012/03/new-in-javafx-2-1-combobox/#comments</comments>
		<pubDate>Thu, 15 Mar 2012 20:22:58 +0000</pubDate>
		<dc:creator>Jonathan Giles</dc:creator>
				<category><![CDATA[Controls]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1563</guid>
		<description><![CDATA[One of the missing features of JavaFX in the 2.0 release was a ComboBox control, and I&#8217;m very pleased to say that we&#8217;ll be filling this gap in JavaFX 2.1. Indeed, it is already in the developer preview builds we&#8217;re putting out, and has been sitting in the OpenJFX mercurial repo for some weeks now. [...]]]></description>
			<content:encoded><![CDATA[<p>One of the missing features of JavaFX in the 2.0 release was a ComboBox control, and I&#8217;m very pleased to say that we&#8217;ll be filling this gap in JavaFX 2.1. Indeed, it is already in the <a href="http://www.oracle.com/technetwork/java/javafx/downloads/devpreview-1429449.html">developer preview builds we&#8217;re putting out</a>, and has been sitting in the <a href="http://openjdk.java.net/projects/openjfx/">OpenJFX</a> <a href="http://hg.openjdk.java.net/openjfx/2.1/master/rt">mercurial repo</a> for some weeks now. I&#8217;m fortunate enough to even be getting bug reports filed in our <a href="http://javafx-jira.kenai.com">Jira issue tracker</a>, which is justification enough to be getting early developer preview releases out into your hands as early as we have!</p>
<div id="attachment_1734" class="wp-caption aligncenter" style="width: 668px"><img class="size-full wp-image-1734  " title="ComboBox" src="http://fxexperience.com/wp-content/uploads/2012/02/comboBox2.png" alt="" width="658" height="212" /><p class="wp-caption-text">Non-editable and editable ComboBox controls of all shapes and sizes!</p></div>
<p><span id="more-1563"></span></p>
<p>In the screenshot above you can see what the default ComboBox looks like. On the left you can see three non-editable ComboBox controls, and on the right you see three editable ComboBox controls. The default width of a ComboBox is based on the width of the content of the ComboBox, so that the menu appears as roughly the same width. You&#8217;ll note that the bottom-left ComboBox has a different font &#8211; this is because this ComboBox has a cell factory set on it, which is something I&#8217;ll cover shortly.</p>
<p><strong>A quick detour: What is ComboBoxBase?</strong></p>
<p>The ComboBox control is an extension of the ComboBoxBase class. For most developers this distinction is unnecessary, but for those of you wanting to write your own ComboBox-like control (which I hope is many <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ), the following is worth reading. The ComboBoxBase class is an abstract class, whose goal is to represent the core concept of what a combo box is. ComboBoxBase brings the basic API expected across all combo box implementations. Firstly, it has a value property, which represents either the latest selection the user has made, or the latest input they have provided in the case of editable combo boxes. It also has the show() and hide() methods you would expect. The third key piece of API is the editable property, which specifies whether the ComboBox should allow user input. There is other API also, but what I&#8217;ve mentioned here is the core of it.</p>
<p>As mentioned above, ComboBoxBase is intended to represent the nature of all combo boxes &#8211; that is, a combo box is generically a button that, when clicked or otherwise prompted, shows to the user a number of choices. Examples of other, ComboBox-like controls include <a href="http://openjdk.java.net/projects/openjfx/ux/datePicker/index.html">calendar pickers</a> and <a href="http://www.codeproject.com/Articles/229/Color-Picker-Combo-Box">colour choosers</a>, but even extends to use cases where entire dialogs are popped-up on clicking. The ComboBoxBase does not pretend to know what happens when show() and hide() are called, and that is left up to subclasses whose skin extends the abstract ComboBoxBaseSkin class. For more information, refer to the ComboBox class and its ComboBoxListViewSkin skin class in OpenJFX. If all else fails,  leave a comment on this post or <a href="mailto:jonathan@jonathangiles.net">email me with your questions</a>.</p>
<p>To cement what I mean in the above two paragraphs, the ComboBox class extends ComboBoxBase to provide the most commonly used ComboBox form, which is the kind that displays a popup list from which a user may choose one option. You can see what the popup list looks like in ComboBox in the screenshot below.</p>
<div id="attachment_1739" class="wp-caption aligncenter" style="width: 681px"><img class="size-full wp-image-1739" title="comboBox3" src="http://fxexperience.com/wp-content/uploads/2012/02/comboBox3.png" alt="" width="671" height="385" /><p class="wp-caption-text">A non-editable ComboBox with a popup list showing</p></div>
<p><strong>ComboBox API</strong></p>
<p>The ComboBox control in JavaFX 2.1 has a very familiar API to anyone who has built user interfaces in JavaFX 2.0. It brings with it API from <a href="http://docs.oracle.com/javafx/2.0/api/javafx/scene/control/ListView.html">ListView</a>, <a href="http://docs.oracle.com/javafx/2.0/api/javafx/scene/control/Button.html">Button</a>, <a href="http://docs.oracle.com/javafx/2.0/api/javafx/scene/control/ChoiceBox.html">ChoiceBox</a>, and even a little bit of <a href="http://docs.oracle.com/javafx/2.0/api/javafx/scene/control/TextField.html">TextField</a>. For example, ComboBox borrows from ListView (as well as <a href="http://docs.oracle.com/javafx/2.0/api/javafx/scene/control/TableView.html">TableView </a>and ChoiceBox) the concept of having an items list that contains all elements to show to the user. The generic type of the ComboBox represents the type of the items list. In addition to this, ComboBox has a <a href="http://docs.oracle.com/javafx/2.0/api/javafx/scene/control/Cell.html">cell factory</a> using exactly the same API (including <a href="http://docs.oracle.com/javafx/2.0/api/javafx/scene/control/ListCell.html">ListCell</a>) as the ListView control. This is why in the first screenshot above you see the bottom-left button has a different font &#8211; it is actually Cooper Black, as the bottom-left ComboBox has been populated with the fonts found on my computer. What this means is that the cell factory is used not just for the popup list, but it is also used in the ComboBox &#8216;button&#8217; itself. Check out the screenshot below to understand better.</p>
<div id="attachment_1746" class="wp-caption aligncenter" style="width: 671px"><img class="size-full wp-image-1746" title="comboBox4" src="http://fxexperience.com/wp-content/uploads/2012/02/comboBox4.png" alt="" width="661" height="418" /><p class="wp-caption-text">A ComboBox with a custom cell factory</p></div>
<p>Another very useful addition to the ComboBox API (and one which has been retrofitted into the ChoiceBox API as well) is the support for<a href="http://docs.oracle.com/javafx/2.0/api/javafx/util/StringConverter.html"> StringConverter</a> implementations (which in reality deserves its own blog post to detail the availability of the javafx.util.converter package and the ability to use these converters in the binding API as of JavaFX 2.1. Maybe <a href="http://blog.netopyr.com/">Michael Heinrichs</a> might cover this, *hint* <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ). A StringConverter does exactly what the name suggests: it has two methods, one that takes an Object and returns a String, and the other that takes a String and attempts to return an Object. StringConverter implementations are therefore used within ComboBox for two purposes. Firstly, the ComboBox items list (and the text on the ComboBox button), when displayed to the user, is run through the StringConverter before being displayed. Secondly, it takes the commited text input and attempts to convert it to a object that can then be set in the value property.</p>
<p>The ComboBox makes use of the familiar SelectionModel API that is present in a number of other controls such as ListView, TreeView, TableView, ChoiceBox, TabPane, etc, and it works in the same way. One important point to note is that the ComboBox selection model is a SingleSelectionModel, so the ComboBox control will only ever support single selection. A future, separate control (e.g. ListBox or similar) might support multiple selection.</p>
<p><strong>Conclusion</strong></p>
<p><strong></strong>Hopefully with this post you&#8217;ll have a better understanding of what the ComboBox in JavaFX 2.1 can do. If you have any questions, please leave a comment on this post. If you find a bug, please file it in Jira.</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/03/new-in-javafx-2-1-combobox/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Customized Segmented ToolBar Buttons</title>
		<link>http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/</link>
		<comments>http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 19:17:09 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[FXML]]></category>
		<category><![CDATA[Layout]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>
		<category><![CDATA[UI Design]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1681</guid>
		<description><![CDATA[One of Jasper&#8217;s favorite websites is called Dribbble, which is a place for designers to post whatever work they&#8217;re currently working on for others to view and be inspired from. I got hooked on Dribbble last Thursday and have been looking at a bunch of the mockups and itching to try implementing some of them [...]]]></description>
			<content:encoded><![CDATA[<p>One of Jasper&#8217;s favorite websites is called <a href="http://dribbble.com">Dribbble</a>, which is a place for designers to post whatever work they&#8217;re currently working on for others to view and be inspired from. I got hooked on Dribbble last Thursday and have been looking at a bunch of the mockups and itching to try implementing some of them in JavaFX. Here is my first attempt.</p>
<p><a href="http://dribbble.com/shots/412425-Class-Attendance?list=popular&#038;offset=3"><img src="http://fxexperience.com/wp-content/uploads/2012/02/SegmentedButtonBar-Designer.png" alt="" title="SegmentedButtonBar Designer" width="800" class="aligncenter size-full wp-image-1691" /></a></p>
<p>One of the use cases we used for our CSS support and our ToolBar API was that we wanted to support a style of toolbar button which (at least for me) was popularized on the Mac, which is referred to by Cocoa as a &#8220;segmented&#8221; button. This is essentially nothing more than an HBox of buttons that has been styled such that the first button has rounded left edges, the center buttons are squared up, and the last button has rounded right edges. In the image above by <a href="http://dribbble.com/bady"/>Bady</a>, you can see the segmented button bar in the toolbar area of the application.<br />
<span id="more-1681"></span><br />
So to begin with, here is the Java code that goes into producing this app. This one is going to only have a toolbar, segmented button bar, and then the body area will just be the blue color you see in the above design. I actually will list two different examples here which both produce the same view and which both use the same CSS file. The first is just plain Java, while the second uses FXML to define the UI and a Java file simply loads the UI and configures the stage.</p>
<p><b>SegmentedButtonBarApp &#8211; Just Java</b></p>
<pre class="brush: java; title: ; notranslate">
public class SegmentedButtonBarApp extends Application {
    @Override public void start(Stage stage) throws Exception {
        BorderPane root = new BorderPane();
        root.setId(&quot;background&quot;);

        ToolBar toolBar = new ToolBar();
        root.setTop(toolBar);

        Region spacer = new Region();
        spacer.getStyleClass().setAll(&quot;spacer&quot;);

        HBox buttonBar = new HBox();
        buttonBar.getStyleClass().setAll(&quot;segmented-button-bar&quot;);
        Button sampleButton = new Button(&quot;Tasks&quot;);
        sampleButton.getStyleClass().addAll(&quot;first&quot;);
        Button sampleButton2 = new Button(&quot;Administrator&quot;);
        Button sampleButton3 = new Button(&quot;Search&quot;);
        Button sampleButton4 = new Button(&quot;Line&quot;);
        Button sampleButton5 = new Button(&quot;Process&quot;);
        sampleButton5.getStyleClass().addAll(&quot;last&quot;, &quot;capsule&quot;);
        buttonBar.getChildren().addAll(sampleButton, sampleButton2, sampleButton3, sampleButton4, sampleButton5);
        toolBar.getItems().addAll(spacer, buttonBar);

        Scene scene = new Scene(root, 800, 600);
        scene.getStylesheets().add(getClass().getResource(&quot;segmented.css&quot;).toExternalForm());
        stage.setScene(scene);
        stage.setTitle(&quot;Segmented Button Bar&quot;);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
</pre>
<p><b>SegmentedButtonBarFXMLApp.java and SegmentedButtonBar.fxml &#8211; Java and FXML</b></p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

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

&lt;BorderPane id=&quot;background&quot; prefWidth=&quot;800.0&quot; prefHeight=&quot;600.0&quot; xmlns:fx=&quot;http://javafx.com/fxml&quot;&gt;
    &lt;top&gt;
        &lt;ToolBar&gt;
            &lt;items&gt;
                &lt;Region styleClass=&quot;spacer&quot; /&gt;
                &lt;HBox styleClass=&quot;segmented-button-bar&quot;&gt;
                    &lt;Button text=&quot;Tasks&quot; styleClass=&quot;first&quot; /&gt;
                    &lt;Button text=&quot;Administrator&quot; /&gt;
                    &lt;Button text=&quot;Search&quot; /&gt;
                    &lt;Button text=&quot;Line&quot; /&gt;
                    &lt;Button text=&quot;Process&quot; styleClass=&quot;last&quot; /&gt;
                &lt;/HBox&gt;
            &lt;/items&gt;
        &lt;/ToolBar&gt;
    &lt;/top&gt;
&lt;/BorderPane&gt;
</pre>
<pre class="brush: java; title: ; notranslate">
public class SegmentedButtonBarFXMLApp extends Application{
    @Override public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource(&quot;SegmentedButtonBar.fxml&quot;));
        Scene scene = new Scene(root);
        scene.getStylesheets().add(getClass().getResource(&quot;segmented.css&quot;).toExternalForm());
        stage.setScene(scene);
        stage.setTitle(&quot;Segmented Button Bar From FXML&quot;);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
</pre>
<p>Both of these approach yield the same approach. I think the FXML file in this case is easier to visualize than reading the raw Java code, but either approach is valid. In both approaches you will notice that I have not done any visual styling whatsoever in the code or FXML, it has all been abstracted away to the css file. Here is what the application looks like without any CSS being applied.</p>
<p><a href="http://fxexperience.com/wp-content/uploads/2012/02/Unstyled-SegmentedButtonBar.png"><img src="http://fxexperience.com/wp-content/uploads/2012/02/Unstyled-SegmentedButtonBar.png" alt="" title="Unstyled SegmentedButtonBar" width="754" height="616" class="aligncenter size-full wp-image-1682" /></a></p>
<p>So now lets apply one section of the CSS file at a time, and see how it modifies the look of the application.</p>
<h3>The CSS</h3>
<p>I started off by defining the following rule in CSS:</p>
<pre class="brush: css; title: ; notranslate">
#background {
    -light-black: rgb(74, 75, 78);
    -dark-highlight: rgb(87, 89, 92);
    -dark-black: rgb(39, 40, 40);
    -darkest-black: rgb(5, 5, 5);
    -mid-gray: rgb(216, 222, 227);
    -fx-background-color: -mid-gray;
}
</pre>
<p>There are two things going on in this code. First, you will note that it selects only the node(s) with the id of &#8220;background&#8221;. The node in our scene graph with this id is the BorderPane which forms the root of the scene graph. The first chunk of the CSS file defines the color palette. In JavaFX CSS you can create arbitrary &#8220;variables&#8221; in your CSS by simply defining a declaration, such as <code>-dark-black: rub(39, 40, 40);</code>. Thereafter, you can refer to these named colors.</p>
<div id="attachment_1684" class="wp-caption aligncenter" style="width: 210px"><a href="http://fxexperience.com/wp-content/uploads/2012/02/SegmentedButtonBar-Palette.png"><img src="http://fxexperience.com/wp-content/uploads/2012/02/SegmentedButtonBar-Palette.png" alt="" title="SegmentedButtonBar Palette" width="200" height="40" class="size-full wp-image-1684" /></a><p class="wp-caption-text">SegmentedButtonBar Palette</p></div>
<p>After doing nothing other than defining the color palette and the background, our app now looks like this:</p>
<p><a href="http://fxexperience.com/wp-content/uploads/2012/02/Styled-Background.png"><img src="http://fxexperience.com/wp-content/uploads/2012/02/Styled-Background.png" alt="" title="Styled Background" width="754" height="616" class="aligncenter size-full wp-image-1686" /></a></p>
<p>The background now has this mid-gray color, while the rest of the app looks unchanged. Now, lets style the ToolBar.</p>
<pre class="brush: css; title: ; notranslate">
.tool-bar {
    -fx-base: -dark-black;
    -fx-font-size: 12pt;
    -fx-background-color:
        linear-gradient(to bottom, derive(-fx-base,-30%), derive(-fx-base,-60%)),
        linear-gradient(to bottom, -light-black 2%, -dark-black 98%);
    -fx-background-insets: 0, 0 0 1 0;
    -fx-padding: .9em 0.416667em .9em 0.416667em;
    -fx-effect: dropshadow(two-pass-box,black,5,.2,0,0);
}
</pre>
<p>Here, I am selecting all toolbars in my app to be styled like this. I could have given my tool bar a special style class or ID so that I only targeted it, but in this case this is OK, since I am not using any other tool bars in my app, and if I were, I could style them explicitly by style class or ID if I wanted to. I am telling the toolbar to use the base color of -dark-black. I think the only reason for doing so is so that those automatically derived colors that I&#8217;m not about to override (of which I think only the text fill is ultimately going to be affected) will be styled correctly by default for being on a dark background. I&#8217;ve tweaked the font size to be a bit smaller (on mac it defaults to 13pt).</p>
<p>I&#8217;ve given the toolbar a new background gradient. It simply goes from top-to-bottom. I actually copied this out of caspian.css and then modified the main gradient (the second one in the list) to go from our -light-black palette color to our -dark-black gradient color. I tweaked the insets so that the border (the first gradient in the list) isn&#8217;t drawn on the bottom of the toolbar. I also tweaked the padding so that it would come out pretty close to the designer&#8217;s intent. Finally, I added a drop shadow.</p>
<p><a href="http://fxexperience.com/wp-content/uploads/2012/02/Styled-ToolBar.png"><img src="http://fxexperience.com/wp-content/uploads/2012/02/Styled-ToolBar.png" alt="" title="Styled ToolBar" width="640" height="145" class="aligncenter size-full wp-image-1687" /></a></p>
<p>Now that we&#8217;ve styled the tool bar, it is time to style the segmented buttons (that is, after all, what this post is supposed to be about!). Actually styling the segmented buttons is really pretty easy.</p>
<pre class="brush: css; title: ; notranslate">
.segmented-button-bar .button {
    -fx-background-color:
        -darkest-black,
        -dark-highlight,
        linear-gradient(to bottom, -light-black 2%, -dark-black 98%);
    -fx-background-insets: 0, 1 1 1 0, 2 1 1 1;
    -fx-background-radius: 0;
    -fx-padding: 0.4em 1.833333em 0.4em 1.833333em;
}

.segmented-button-bar .button.first {
    -fx-background-insets: 0, 1, 2 1 1 1;
    -fx-background-radius: 3 0 0 3, 2 0 0 2, 2 0 0 2;
}

.segmented-button-bar .button.last {
    -fx-background-insets: 0, 1 1 1 0, 2 1 1 1;
    -fx-background-radius: 0 3 3 0, 0 2 2 0, 0 2 2 0;
}

.segmented-button-bar .button:pressed {
    -fx-background-color:
        -darkest-black,
        rgb(55, 57, 58),
        linear-gradient(to top, -light-black 2%, -dark-black 98%);
}
</pre>
<p>The segmented buttons are styled such that the first and last are half-rounded, and the middle buttons are squared up. With web CSS you have the &#8220;first-child&#8221; and &#8220;last-child&#8221; pseudo-classes. However these are not implemented in JavaFX, so instead I added the &#8220;first&#8221; and &#8220;last&#8221; style classes to the first and last buttons, respectively. This allows me to use a nice CSS rule to target them separately from any other random button added to the segmented button bar.</p>
<p>Oh, and my &#8220;segmented button bar&#8221; isn&#8217;t a control &#8212; it is just an HBox with some special CSS style. I gave the hbox the style class &#8220;segmented-button-bar&#8221;, and then here from CSS I will target all buttons that are within a segmented-button-bar, and style them specially.</p>
<p>The button is drawn using 3 overlapping background fills. The first is the dark outline, the second is the &#8220;highlight&#8221; &#8212; a lighter line draw to give the bezel look, and then the gradient that fills the rest of the body. The only trick with these is to correctly specify the insets and the corner radius&#8217; so everything ends up looking right. Look closely at the following zoomed-in screenshot of the design:</p>
<p><a href="http://fxexperience.com/wp-content/uploads/2012/02/Search-Button-Zoomed-In.png"><img src="http://fxexperience.com/wp-content/uploads/2012/02/Search-Button-Zoomed-In.png" alt="" title="Search Button Zoomed In" width="810" height="264" class="aligncenter size-full wp-image-1688" /></a></p>
<p>You will notice that there is, on the left of this button, a black line and a highlight line. So does the black line belong to the button to the left of the &#8220;Search&#8221; button? Who draws it? In my case, I decided that the highlight line on the left would be drawn by this button, and the dark line on the right would also be drawn by this button. Thus you can butt multiple buttons against each other and they appear to &#8220;share&#8221; a border. Notice that the middle button draws the black lines on the top and bottom. So basically what I did was draw the black background, then draw a highlight background overtop of it adjusted such that it drew over most of the black background, just leaving 1 px on the top and bottom showing through. Then I drew the main fill adjusted so that the highlight was obscured except for 1 px on the top and left.</p>
<p>The first and last buttons were likewise tweaked to get the right look. The only additional thing done there was to make sure that the corner radius for the top-left and bottom-left edges (for the first button) were rounded and the top-right and bottom-right were squared. The same idea for the last button.</p>
<p>And that&#8217;s it. A SegmentedButtonBar where you can drop in buttons and they will be styled to match the colors, gradients, and so forth that the designer intended. And done by me: somebody who, unlike Jasper, isn&#8217;t very good at making a pretty UI <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Oh, you may be wondering about that &#8220;spacer&#8221; region. I just gave it a simple style to push over the button bar a little ways.</p>
<pre class="brush: css; title: ; notranslate">
.tool-bar .spacer {
    -fx-padding: 0 5.417em 0 0;
}
</pre>
<p>And finally, our app looks pretty good!</p>
<p><a href="http://fxexperience.com/wp-content/uploads/2012/02/SegmentedButtonBar-App-Final2.png"><img src="http://fxexperience.com/wp-content/uploads/2012/02/SegmentedButtonBar-App-Final2.png" alt="" title="SegmentedButtonBar-App-Final2" width="754" height="616" class="aligncenter size-full wp-image-1701" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/02/customized-segmented-toolbar-buttons/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>MoneyField</title>
		<link>http://fxexperience.com/2012/02/moneyfield/</link>
		<comments>http://fxexperience.com/2012/02/moneyfield/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 22:47:40 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1675</guid>
		<description><![CDATA[I started writing an article about how to write new UI controls for OpenJFX using all the internal APIs and architecture and so forth. But then I discovered that the control I was writing as a proof of concept was not using any private API at all, and actually was implementing the Skin differently than [...]]]></description>
			<content:encoded><![CDATA[<p>I started writing an article about how to write new UI controls for OpenJFX using all the internal APIs and architecture and so forth. But then I discovered that the control I was writing as a proof of concept was not using any private API at all, and actually was implementing the Skin differently than I had imagined previously, and I thought I ought to blog about it. Behold, the MoneyField!</p>
<p><a href="http://fxexperience.com/wp-content/uploads/2012/02/MoneyField-Screenshot.png"><img src="http://fxexperience.com/wp-content/uploads/2012/02/MoneyField-Screenshot.png" alt="" title="MoneyField Screenshot" width="556" height="469" class="aligncenter size-full wp-image-1676" /></a></p>
<p><span id="more-1675"></span></p>
<p>The design space for a MoneyField is quite interesting. I did a bunch of research and tried out various different representations of &#8220;money&#8221; in Java, including <a href="http://joda-money.sourceforge.net/">Joda-Money</a>, but in the end the parsing was not satisfactory and I concluded to just use a good old fashioned BigDecimal to represent a monetary value. The best blog I found talking about the issues with BigDecimal for representing Money is this one titled <a href="http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/">BigDecimal and Your Money</a>. I think this same technique that I&#8217;m going to show works equally well whatever the data type is.</p>
<p>The most complex part of implementing this control was using the DecimalFormat for parsing the result back. In fact, I had a lot of trouble parsing the text in the MoneyField and producing a reliable BigDecimal out of it. I&#8217;m sure the implementation is lousy compared to what an expert in parsing such things could do, and I would welcome any feedback on my present implementation.</p>
<p>Writing the Control itself was trivial. I extended MoneyField from Control, and added a <code>value</code> property for holding the BigDecimal that would represent the monetary value of this control. I added a few other properties such as <code>editable</code>, <code>promptText</code>, and <code>prefColumnCount</code>. I also added an onAction event to MoneyField.</p>
<p>Now, there are some interesting things to talk about for you aspiring UI controls authors. Lets take a brief walk through the code.</p>
<pre class="brush: java; title: ; notranslate">
public class MoneyField extends Control {
    /**
     * Creates a new MoneyField. The style class is set to &quot;money-field&quot;.
     */
    public MoneyField() {
        getStyleClass().setAll(&quot;money-field&quot;);
    }

    @Override protected String getUserAgentStylesheet() {
        return getClass().getResource(&quot;MoneyField.css&quot;).toExternalForm();
    }
}
</pre>
<p>Every third party UI control must define the essential skeletal structure that you see in the above code snippet. You should provide a no-arg constructor (or it may not work in FXML). In your constructor, you should set the style class of the control to be the &#8220;css-ized&#8221; name of your control. Just toLowerCase and separate words by dashes. Then, because I want my skin to be entirely defined by CSS, I will override the getUserAgentStylesheet method and have it return a reference to a css file that I am going to define which acts as the &#8220;user agent stylesheet&#8221; for this control. That is, it provides the default CSS style for this control. Here is what my CSS file looks like:</p>
<pre class="brush: css; title: ; notranslate">
#money-text-field {
    -fx-skin: &quot;com.sun.javafx.scene.control.skin.TextFieldSkin&quot;;
}

.money-field {
    -fx-skin: &quot;com.fxexperience.javafx.scene.control.skin.MoneyFieldSkin&quot;;
    -fx-background-color: -fx-shadow-highlight-color, -fx-text-box-border, -fx-control-inner-background;
    -fx-background-insets: 0, 1, 2;
    -fx-background-radius: 3, 2, 2;
    -fx-padding: 3 5 3 5;
    -fx-prompt-text-fill: derive(-fx-control-inner-background,-30%);
    -fx-cursor: text;
}

.money-field:focused {
    -fx-background-color: -fx-focus-color, -fx-text-box-border, -fx-control-inner-background;
    -fx-background-insets: -0.4, 1, 2;
    -fx-background-radius: 3.4, 2, 2;
}

.money-field:disabled {
    -fx-opacity: -fx-disabled-opacity;
}
</pre>
<p>There really isn&#8217;t a lot to say here, other than you can see I have a little trickery around the #money-text-field. Basically, I want the developer to be able to style the money field from CSS using .money-field, but I need to make sure the Skin used with the inner TextField is still a normal TextField. You&#8217;ll see how this fits together in a minute when I describe how the MoneyFieldSkin works.</p>
<p>Back in the MoneyField.java file, I also defined the above mentioned properties and events. First, here is what a &#8220;normal&#8221; property looks like. It is fully observable, readable, and writable.</p>
<pre class="brush: java; title: ; notranslate">
    /**
     * The value of the MoneyField. If null, the value will be treated as &quot;0&quot;, but
     * will still actually be null.
     */
    private ObjectProperty&lt;BigDecimal&gt; value = new SimpleObjectProperty&lt;BigDecimal&gt;(this, &quot;value&quot;);
    public final BigDecimal getValue() { return value.get(); }
    public final void setValue(BigDecimal value) { this.value.set(value); }
    public final ObjectProperty&lt;BigDecimal&gt; valueProperty() { return value; }
</pre>
<p>I am using the SimpleObjectProperty, which takes as parameters a reference to the bean that defined it, and the name of the property. The value of the <code>value</code> property defaults to null. Our doclet produces javadoc on the getter and setter without having to actually write it manually, so that&#8217;s why docs are missing for those. The editable property is likewise defined as a SimpleBooleanProperty.</p>
<p>The onAction is a very straightforward implementation. If you write your own controls and want to include your own action events, it is very easy to do:</p>
<pre class="brush: java; title: ; notranslate">
    /**
     * The action handler associated with this MoneyField, or
     * &lt;tt&gt;null&lt;/tt&gt; if no action handler is assigned.
     *
     * The action handler is normally called when the user types the ENTER key.
     */
    private ObjectProperty&lt;EventHandler&lt;ActionEvent&gt;&gt; onAction = new ObjectPropertyBase&lt;EventHandler&lt;ActionEvent&gt;&gt;() {
        @Override protected void invalidated() {
            setEventHandler(ActionEvent.ACTION, get());
        }

        @Override public Object getBean() { return MoneyField.this; }
        @Override public String getName() { return &quot;onAction&quot;; }
    };
    public final ObjectProperty&lt;EventHandler&lt;ActionEvent&gt;&gt; onActionProperty() { return onAction; }
    public final EventHandler&lt;ActionEvent&gt; getOnAction() { return onActionProperty().get(); }
    public final void setOnAction(EventHandler&lt;ActionEvent&gt; value) { onActionProperty().set(value); }
}
</pre>
<p>You&#8217;ll notice that in the invalidated method of the property I call setEventHandler. This method exists for the registration of such event handlers with the system. Another interesting thing here is that I&#8217;m not extending SimpleObjectProperty, but rather I&#8217;m extending ObjectPropertyBase.</p>
<p>Every property must implement the getBean() and getName() method. SimpleXXX properties have fields which hold the bean &#038; name, and you supply them in the constructor. But XXXPropertyBase properties have no such fields, and you must implement these methods. Why chose one over the other? Well, SimpleXXX properties will have smaller static footprint because they are using a class instead of defining a class, but will have larger dynamic footprint because they have two additional fields which must be saved for each instance. XXXPropertyBase uses larger static footprint because it defines a class, but smaller dynamic footprint because it doesn&#8217;t have to save these two fields. Since I had to subclass an object property anyway for the sake of implementing the invalidated method, I might as well extend ObjectPropertyBase and save a couple fields at runtime.</p>
<p>The Skin for MoneyField was quite interesting. At first I thought I would extend from TextFieldSkin (an internal implementation in JavaFX) but then discovered this wasn&#8217;t necessary. Instead, I could just implement the Skin interface and return a TextField as the &#8220;node&#8221; of the Skin. So the MoneyField defines my UI, and the TextField is actually what I end up using to represent the MoneyField. And then there is a pile of glue code which ties the TextField to the MoneyField. The other nice thing about this approach was that I could implement the entirety of MoneyField and MoneyFieldSkin without using any private API (which, when I started writing this, I didn&#8217;t think was possible).</p>
<pre class="brush: java; title: ; notranslate">
public class MoneyFieldSkin implements Skin&lt;MoneyField&gt; {
    /**
     * The {@code Control} that is referencing this Skin. There is a
     * one-to-one relationship between a {@code Skin} and a {@code Control}.
     * When a {@code Skin} is set on a {@code Control}, this variable is
     * automatically updated.
     */
    private MoneyField control;

    /**
     * This textField is used to represent the MoneyField.
     */
    private TextField textField;

    /**
     * Create a new MoneyFieldSkin.
     * @param control The MoneyField
     */
    public MoneyFieldSkin(final MoneyField control) {
        this.control = control;

        // Create the TextField that we are going to use to represent this MoneyFieldSkin.
        // The textField restricts input so that only valid digits that contribute to the
        // Money can be input.
        textField = new TextField() { // ...
        };

        // ... and a lot more stuff!
    }

    @Override public MoneyField getSkinnable() {
        return control;
    }

    @Override public Node getNode() {
        return textField;
    }

    /**
     * Called by a Skinnable when the Skin is replaced on the Skinnable. This method
     * allows a Skin to implement any logic necessary to clean up itself after
     * the Skin is no longer needed. It may be used to release native resources.
     * The methods {@link #getSkinnable()} and {@link #getNode()}
     * should return null following a call to dispose. Calling dispose twice
     * has no effect.
     */
    @Override public void dispose() {
        textField = null;
    }

    // ... and a lot more stuff!
}
</pre>
<p>The above code lays out the very basic skeletal structure of a Skin. This skin implements the Skin interface directly. The constructor takes the MoneyField it will be working with, and creates the TextField which will represent the skin (or &#8220;draw&#8221; the skin). In the dispose method, we throw away the TextField.</p>
<p>If you ran the code above, you would find a MoneyField that looked and felt like a TextField. None of the properties on the MoneyField would work, but from a visual perspective and a text entry perspective you&#8217;d have, essentially, a TextField. The rest of MoneyFieldSkin is devoted to wiring up the MoneyField API to the TextField and implementing all the parsing and formatting necessary to make it look like a money field.</p>
<p>The remainder of the MoneyFieldSkin isn&#8217;t worth going through in this blog post, though you can <a href='http://fxexperience.com/wp-content/uploads/2012/02/MoneyField.zip'>download the Intellij project</a> and check it out for yourself.</p>
<p>When Jonathan tried this out last night he was getting exceptions with the New Zealand currency. I suspect there may be problems in Australia too. I&#8217;m hoping one of our readers from down under will give it a look and see where my bug is <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>Using the MoneyField is really very straightforward. I hope it is actually useful to boot. I&#8217;m wondering if anybody industrious out there might take this design strategy and write an EmailField and UrlField control, maybe a NumberField control too! It seems eminently doable using only the public API and would make a great addition to the ecosystem (as well as a great addition to the toolkit!).</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/02/moneyfield/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fun JavaFX 2.0 Audio Player</title>
		<link>http://fxexperience.com/2012/01/fun-javafx-2-0-audio-player/</link>
		<comments>http://fxexperience.com/2012/01/fun-javafx-2-0-audio-player/#comments</comments>
		<pubDate>Sat, 07 Jan 2012 08:10:11 +0000</pubDate>
		<dc:creator>Jasper Potts</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[UI Design]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1586</guid>
		<description><![CDATA[I was inspired by Dean Iverson&#8217;s tweet with a audio equalizer in JavaFX: #JavaFX rocks. Literally. An example from our upcoming Pro JavaFX 2 book: pic.twitter.com/tSI4Vry4 and the equalizer view from that Pro JavaFX 2 example app: pic.twitter.com/T6jxvrf9 . updated pic.twitter.com/FqzgVimG So wanted to have a go at doing one my self, so little while later [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://fxexperience.com/wp-content/uploads/2012/01/FXExperiencePlayer-BG.png"><img class="aligncenter size-medium wp-image-1587" title="FXExperiencePlayer" src="http://fxexperience.com/wp-content/uploads/2012/01/FXExperiencePlayer-BG-300x190.png" alt="" width="300" height="190" /></a></p>
<p>I was inspired by <a href="http://twitter.com/deanriverson">Dean Iverson&#8217;s</a> tweet with a audio equalizer in JavaFX:</p>
<blockquote><p>#JavaFX rocks. Literally. An example from our upcoming Pro JavaFX 2 book: <a href="http://pic.twitter.com/tSI4Vry4">pic.twitter.com/tSI4Vry4</a><br />
and the equalizer view from that Pro JavaFX 2 example app: <a href="http://pic.twitter.com/T6jxvrf9">pic.twitter.com/T6jxvrf9</a><br />
. updated <a href="http://pic.twitter.com/FqzgVimG">pic.twitter.com/FqzgVimG</a></p></blockquote>
<p>So wanted to have a go at doing one my self, so little while later I have a design and built a working application. Demo video after the break.</p>
<p><span id="more-1586"></span></p>
<p><iframe src="http://www.youtube.com/embed/QhFXd3Ost3w?rel=0&amp;hd=1" frameborder="0" width="960" height="720"></iframe></p>
<h3>The Design</h3>
<p>I started the design with a free Photoshop file from Diego Monzon:</p>
<p><a href="http://dribbble.com/shots/146460-UI-Rack-Pro-7-Freebie"><img class="alignnone" title="Starting Free PSD" src="http://dribbble.com/system/users/11040/screenshots/146460/ui7.jpg?1309482012" alt="" width="400" height="300" /></a></p>
<p>You will see that some of it like the cool VU meters made it direct though to my design but then I played around with the other parts. I have added a link to the Photoshop file I created so you can see what I have done if you are intrested. From the photoshop file I produced a few PNG files which are used in the application, you can see them in the src images directory. I found a free LCD dot matrix font from dafont which is what I am using for the text on the screen. You can see in the code how this is loaded in JavaFX.</p>
<p><a title="Photoshop design" href="http://fxexperience.com/applications/FXExperiencePlayer-BG.psd.zip">Download the Photoshop File</a> 18Mb</p>
<h4>The Code</h4>
<p>The application did not take that long to build, guess about a day in total and about 800 lines of code. I think it is fully working other than the balance is a little fiddly with the mouse. All the control customizations should have full keyboard navigation <img src='http://fxexperience.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . It is mostly standard UI Controls just styled with Images and CSS. The round knobs like balance and volume I had to do something special for and created a knob skin for the Slider control. There was a bunch of the standard logic to load and parse M3U and XML playlists, a very simple data model object PlayList which just contains a url which it was loaded from and a observable list of Pairs, each Pair being a name for the song and a url to the song. We did not have all the low level media API I needed for the VU meters but as they are only really for show I made of some data from what we can get from AudioSpectrumListener.</p>
<p><a title="Source and NB Project" href="http://fxexperience.com/applications/FxExperiencePlayer.zip">Download the source and Netbeans Project</a> 1.5Mb</p>
<p>Hope you enjoy playing with this fun little app as much as I did creating it. Hope it goes to show that you can create pretty much any UI that you can imagine in JavaFX 2.0 and even use standard controls so you maintain keyboard navigation, accessibility etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2012/01/fun-javafx-2-0-audio-player/feed/</wfw:commentRss>
		<slash:comments>14</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>25</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>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>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>24</slash:comments>
		</item>
		<item>
		<title>Indeterminate CheckBox</title>
		<link>http://fxexperience.com/2011/06/indeterminate-checkbox/</link>
		<comments>http://fxexperience.com/2011/06/indeterminate-checkbox/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 22:54:29 +0000</pubDate>
		<dc:creator>Richard Bair</dc:creator>
				<category><![CDATA[Controls]]></category>
		<category><![CDATA[Tips n' Tricks]]></category>

		<guid isPermaLink="false">http://fxexperience.com/?p=1224</guid>
		<description><![CDATA[The CheckBox in JavaFX can be configured for two states (selected, or not) or three states (selected, unselected, or indeterminate). This indeterminate state is often useful when a checkbox is being used in a TreeView, for example. You might be implementing a tree view showing which features are installed, and need to toggle to an [...]]]></description>
			<content:encoded><![CDATA[<p>The CheckBox in JavaFX can be configured for two states (selected, or not) or three states (selected, unselected, or indeterminate). This indeterminate state is often useful when a checkbox is being used in a TreeView, for example. You might be implementing a tree view showing which features are installed, and need to toggle to an indeterminate state for the branch of some of the children are selected, and some are not.</p>
<p><img class="aligncenter size-full wp-image-1226" title="IndeterminateCheckBox" src="http://fxexperience.com/wp-content/uploads/2011/06/IndeterminateCheckBox.png" alt="" width="400" height="422" /><br />
<span id="more-1224"></span><br />
In JavaFX, putting the CheckBox into a mode where it can be indeterminate is quite simple, simply set the allowIndeterminate property to true:</p>
<pre class="brush: java; title: ; notranslate">
        CheckBox cb = new CheckBox(&quot;Indeterminate CheckBox&quot;);
        cb.setAllowIndeterminate(true);
</pre>
<p>You manipulate the state of the check box through the use of two properties: selected and indeterminate. If allowIndeterminate is true, then as the user clicks on the check box, it will cycle through three state combinations:</p>
<ul>
<li>selected = true, indeterminate = false</li>
<li>selected = false, indeterminate = true</li>
<li>selected = false, indeterminate = false</li>
</ul>
<p>Here is a full example:</p>
<pre class="brush: java; title: ; notranslate">
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class IndeterminateCheckBox extends Application {
    Label label;
    CheckBox cbox;

    @Override public void start(Stage stage) {
        label = new Label();

        cbox = new CheckBox(&quot;Indeterminate CheckBox&quot;);
        cbox.setIndeterminate(true);
        cbox.setAllowIndeterminate(true);

        ChangeListener&lt;Boolean&gt; listener = new ChangeListener&lt;Boolean&gt;() {
            @Override
            public void changed(ObservableValue&lt;? extends Boolean&gt; prop, Boolean old, Boolean val) {
                updateLabel();
            }
        };

        cbox.selectedProperty().addListener(listener);
        cbox.indeterminateProperty().addListener(listener);
        updateLabel();

        VBox vbox = new VBox(7);
        vbox.setAlignment(Pos.CENTER);
        vbox.getChildren().addAll(label, cbox);
        Scene scene = new Scene(vbox, 400, 400);
        stage.setTitle(&quot;Hello CheckBox&quot;);
        stage.setScene(scene);
        stage.setVisible(true);
    }

    private void updateLabel() {
        final String txt = cbox.isIndeterminate() ? &quot;The check box is indeterminate&quot; :
                cbox.isSelected() ? &quot;The check box is selected&quot; :
                &quot;The check box is not selected&quot;;

        label.setText(txt);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
</pre>
<p>So, whenever either the indeterminate or selected property changes, we update the label&#8217;s text to match. This is kind of gross though (now that I&#8217;ve typed it out), because I have to attach a listener to two different properties. It would be nicer if there were a proper event handler that I could attach to the CheckBox which would be notified whenever indeterminate or selected changed.</p>
<p>I&#8217;ve filed a JIRA <a href="http://javafx-jira.kenai.com/browse/RT-13992">RT-13992</a> to track this.</p>
<p>Meanwhile, I can also use the high level binding APIs to do this. Here is an alternative implementation.</p>
<pre class="brush: java; title: ; notranslate">
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class IndeterminateCheckBox2 extends Application {
    @Override public void start(Stage stage) {
        CheckBox cbox = new CheckBox(&quot;Indeterminate CheckBox&quot;);
        cbox.setIndeterminate(true);
        cbox.setAllowIndeterminate(true);

        Label label = new Label();
        label.textProperty().bind(
            Bindings.when(cbox.indeterminateProperty()).
                then(&quot;The check box is indeterminate&quot;).
                otherwise(
                    Bindings.when(cbox.selectedProperty()).
                        then(&quot;The check box is selected&quot;).
                        otherwise(&quot;The check box is not selected&quot;))
        );

        VBox vbox = new VBox(7);
        vbox.setAlignment(Pos.CENTER);
        vbox.getChildren().addAll(label, cbox);
        Scene scene = new Scene(vbox, 400, 400);
        stage.setTitle(&quot;Hello CheckBox&quot;);
        stage.setScene(scene);
        stage.setVisible(true);
    }

    public static void main(String[] args) {
        launch(args);
    }
}
</pre>
<p>And that&#8217;s pretty darn slick, IMHO.</p>
]]></content:encoded>
			<wfw:commentRss>http://fxexperience.com/2011/06/indeterminate-checkbox/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

