<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7706192646925495484</id><updated>2012-01-27T09:28:35.155-08:00</updated><category term='javafx'/><category term='griffon'/><category term='scalafx'/><category term='css'/><category term='groovyfx'/><category term='groovy'/><category term='swing'/><category term='controls'/><category term='flex'/><category term='fll'/><category term='miglayout'/><title type='text'>Pleasing Software</title><subtitle type='html'>please: (verb) cause to feel happy; to satisfy aesthetically.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-4732631361533936769</id><published>2011-09-27T10:08:00.000-07:00</published><updated>2011-10-05T12:59:20.668-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovyfx'/><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='scalafx'/><title type='text'>GroovyFX vs ScalaFX</title><content type='html'>Oh, it's on now.&lt;br /&gt;
&lt;br /&gt;
My good friend and new alternative language nemesis, &lt;a href="http://twitter.com/#!/steveonjava"&gt;Stephen Chin&lt;/a&gt;, published &lt;a href="http://javafx.steveonjava.com/javafx-2-0-and-scala-like-milk-and-cookies/"&gt;a blog post&lt;/a&gt; last night introducing a project he's been working on called &lt;a href="https://code.google.com/p/scalafx/"&gt;ScalaFX&lt;/a&gt;.  A nice, easy way to write JavaFX 2.0 code in Scala.
&lt;br /&gt;
&lt;br /&gt;
I, of course, have been working with Jim Clarke on his &lt;a href="http://groovy.codehaus.org/GroovyFX"&gt;GroovyFX&lt;/a&gt; project. &amp;nbsp;Stephen points out&amp;nbsp;that his ScalaFX library creates code that is more concise and more readable than the Java equivalent. &amp;nbsp;That is undeniably true, but picking on poor Java because it is succinctness-challenged is too easy. &amp;nbsp;How about picking on a language that can defend itself with respect to conciseness, programmer productivity, and modern language features?&lt;br /&gt;
&lt;br /&gt;
I give you the GroovyFX version of the Colorful Circles demo:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;GroovyFX.start { primaryStage -&amp;gt;
  def circles
  def sg = new SceneGraphBuilder(primaryStage)

  sg.stage(title: 'GroovyFX ColorfulCircles', resizable: false, visible: true) {
    scene(width: 800, height: 600, fill: black) {
      group {
        circles = group {
          30.times {
            circle(radius: 200, fill: rgb(255, 255, 255, 0.05),&amp;nbsp;
                   stroke: rgb(255, 255, 255, 0.16),
                   strokeWidth: 4, strokeType: 'outside')
          }
          effect boxBlur(width: 10, height: 10, iterations: 3)
        }
      }
      rectangle(width: 800, height: 600, blendMode: 'overlay') {
        def stops = ['#f8bd55', '#c0fe56', '#5dfbc1', '#64c2f8',&amp;nbsp;
                     '#be4af7', '#ed5fc2', '#ef504c', '#f2660f']
        fill linearGradient(start: [0f, 1f], end: [1f, 0f], stops: stops)
      }
    }

    parallelTransition(cycleCount: indefinite, autoReverse: true) {
      def random = new Random()
      circles.children.each { circle -&amp;gt;
        translateTransition(40.s, node: circle,&amp;nbsp;
                            fromX: random.nextInt(800), fromY: random.nextInt(600),
                            toX: random.nextInt(800), toY: random.nextInt(600))
      }
    }.play()
  }
}
&lt;/pre&gt;
&lt;blockquote&gt;
&lt;b&gt;Update:&lt;/b&gt; Stephen updated his version to make it shorter! &amp;nbsp;He even stole GroovyFX's new gradient stop syntax to do it. &amp;nbsp;That was low. &amp;nbsp;:-) &amp;nbsp;I have no choice but to respond by shortening the GroovyFX version even further. &amp;nbsp;(Thanks to Jim Clarke for the idea of using the parallelTransition in place of the timeline).&lt;/blockquote&gt;
&lt;br /&gt;
Not only is the GroovyFX version even shorter than the ScalaFX version, it is, in my humble opinion, much more readable. &amp;nbsp;By my reckoning that's GroovyFX 1, ScalaFX 0.&lt;br /&gt;
&lt;br /&gt;
What will the final score be? &amp;nbsp;To find out, join Stephen and I for our JavaOne session "JavaFX 2.0 with Alternative Languages" on Wednesday, October 5 at 4:30 PM in the Hotel Nikko. &amp;nbsp;It should be a great time as Stephen and I battle it out to convince you that our language and library is the best choice for JavaFX development.&lt;br /&gt;
&lt;br /&gt;
Who will be the winner? &amp;nbsp;Why, developers of course. &amp;nbsp;No matter which of the two languages you choose, you will have a great JavaFX 2.0 library to go with it!&lt;br /&gt;
&lt;br /&gt;
And here is the psychedelic output of the program, which of course matches Stephen's ScalaFX version and the &lt;a href="http://download.oracle.com/javafx/2.0/get_started/ColorfulCircles.java.html"&gt;original Java version&lt;/a&gt;.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-GsZLUrHnC-U/ToH9gxsYkJI/AAAAAAAAAUc/uwIXEBl_gac/s1600/circles.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="513" src="http://2.bp.blogspot.com/-GsZLUrHnC-U/ToH9gxsYkJI/AAAAAAAAAUc/uwIXEBl_gac/s640/circles.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Happy JavaFX-ing and stay Groovy!&lt;/div&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-4732631361533936769?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/4732631361533936769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/09/groovyfx-vs-scalafx.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/4732631361533936769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/4732631361533936769'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/09/groovyfx-vs-scalafx.html' title='GroovyFX vs ScalaFX'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-GsZLUrHnC-U/ToH9gxsYkJI/AAAAAAAAAUc/uwIXEBl_gac/s72-c/circles.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-4883039310994656696</id><published>2011-08-21T10:12:00.000-07:00</published><updated>2011-08-21T12:12:36.357-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovyfx'/><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='griffon'/><title type='text'>JavaFX on Griffon: Events and Binding</title><content type='html'>&lt;p&gt;I have just uploaded a second screencast (embedded below) in the "JavaFX on Griffon" series. If you missed the first screencast, you can find it &lt;a href="http://pleasingsoftware.blogspot.com/2011/08/writing-javafx-applications-with.html"&gt;here&lt;/a&gt;. This screencast concludes the basic introduction I wanted to provide to writing JavaFX applications with Griffon.&lt;/p&gt;&lt;p style="text-align: center;"&gt;&lt;iframe width="640" height="390" src="http://www.youtube.com/embed/7Ss92PeCUrc" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;In my previous article, I was remiss in forgetting to thank &lt;a href="http://twitter.com/#!/aalmiray"&gt;Andres Almiray&lt;/a&gt;, the leader of the &lt;a href="http://griffon.codehaus.org/"&gt;Giffon&lt;/a&gt; project, for all his help in creating these plugins.  I am thoroughly convinced that Andres spent about twice as much time answering all of my silly questions as it would have taken him to just write the plugins himself.&lt;/p&gt;&lt;p&gt;So Mr. Almiray, thank you for all the time you spent teaching me about Griffon plugins and the Griffon build system.  You, sir, are a scholar and a gentleman!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-4883039310994656696?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/4883039310994656696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/08/javafx-on-griffon-events-and-binding.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/4883039310994656696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/4883039310994656696'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/08/javafx-on-griffon-events-and-binding.html' title='JavaFX on Griffon: Events and Binding'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/7Ss92PeCUrc/default.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-8239916009695886719</id><published>2011-08-20T15:20:00.001-07:00</published><updated>2011-08-24T08:38:50.225-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovyfx'/><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='griffon'/><title type='text'>Writing JavaFX Applications with Griffon</title><content type='html'>&lt;p&gt;I'm really happy to share one of the side projects I've been working on for a while now.  Those of you who follow me on Twitter will have seen images of this in the past, but now I'm finally able to open up the sandbox and let others play.&lt;/p&gt;&lt;p&gt;I have posted a screencast on YouTube that shows how to get started with Griffon, GroovyFX, and JavaFX.  I hope you will agree that it is a really fun and easy combination for writing Java desktop clients.  If you are ready to try it out for yourself, the archetype I used in the video can be downloaded from my &lt;a href="http://deanriverson.github.com/griffon-javafx-archetype/"&gt;GitHub&lt;/a&gt; page.  The screencast is embedded below, broken into two parts since it is a little on the lengthy side.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;iframe width="640" height="510" src="http://www.youtube.com/embed/z6HEHVCpHzo" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt; &lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;iframe width="640" height="510" src="http://www.youtube.com/embed/tnT2rK1KrnI" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;In other GroovyFX news, Jim Clarke and I will be doing an in-depth technical session on GroovyFX at JavaOne.  The session will be the last session of the day on Thursday.  It's titled "GroovyFX: JavaFX is my bag, baby, yeah!" This session will also touch on using GroovyFX with Griffon so I hope you can squeeze it into your busy JavaOne schedule!&lt;/p&gt;&lt;p&gt;Jim and I have also been busy adding more features to GroovyFX.  I hope to post a new article soon describing new features like IDEA code completion and improved event declarations. There is so much Groovy JavaFX stuff to talk about!&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; The next screencast in this series is now &lt;a href="http://pleasingsoftware.blogspot.com/2011/08/javafx-on-griffon-events-and-binding.html"&gt;available&lt;/a&gt;.  This screencast goes into more binding functionality and discusses event handling in JavaFX Griffon applications.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-8239916009695886719?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/8239916009695886719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/08/writing-javafx-applications-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8239916009695886719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8239916009695886719'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/08/writing-javafx-applications-with.html' title='Writing JavaFX Applications with Griffon'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/z6HEHVCpHzo/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-1001010912687592219</id><published>2011-08-08T00:14:00.001-07:00</published><updated>2011-09-29T21:13:43.033-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovyfx'/><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Introducing GroovyFX: It's About Time</title><content type='html'>&lt;img alt="It's About Time!" border="0" height="190" src="http://lh3.ggpht.com/-5Dcb5wTV3Gg/Tj80-LHbOmI/AAAAAAAAATU/wWeqOyEGu_Q/Screen%252520Shot%2525202011-08-07%252520at%2525206.48.59%252520PM.png?imgmax=800" style="float: left;" title="Screen Shot 2011-08-07 at 6.48.59 PM.png" width="180" /&gt;&lt;br /&gt;
GroovyFX is an open source project whose goal is to combine the conciseness of Groovy with the power of JavaFX 2.0. &amp;nbsp;Jim Clarke, the originator of the project, and I have been working hard to make GroovyFX the most advanced library for writing JavaFX code with alternative JVM languages. &amp;nbsp;As you are about to see, it is more than a mere DSL that provides some syntactic sugar for JavaFX code. We have decided that it is past time to share our progress with the wider JavaFX community; this article is long overdue (right, Jonathan?).&lt;br /&gt;
This is the first of many articles I'll be writing about GroovyFX. &amp;nbsp;If you want to stay up to date with the GroovyFX project you can follow this blog or follow me on &lt;a href="http://twitter.com/#!/deanriverson"&gt;Twitter&lt;/a&gt;.&lt;br /&gt;
&lt;h2 style="clear: both;"&gt;


How to Play&lt;/h2&gt;
The &lt;a href="http://groovy.codehaus.org/GroovyFX"&gt;GroovyFX website&lt;/a&gt; has all the information you need to get started but I will summarize it here:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Download and install the latest version of &lt;a href="http://javafx.com/downloads/all.jsp"&gt;JavaFX&lt;/a&gt; and set a JAVAFX_HOME environment variable that points to the root directory of your JavaFX installation. &lt;/li&gt;
&lt;li&gt;Download the latest version of &lt;a href="http://www.gradle.org/downloads.html"&gt;Gradle&lt;/a&gt; (1.0 milestone-4 or better), unzip it, and add it to your path. &amp;nbsp;Gradle provides the easiest and quickest way to build and run the demos.&lt;/li&gt;
&lt;li&gt;Check out the GroovyFX source from&amp;nbsp;&lt;a href="http://svn.codehaus.org/gmod/groovyfx/trunk/"&gt;http://svn.codehaus.org/gmod/groovyfx/trunk/&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
Now you are ready to build and run the demos. &amp;nbsp;You can build the project by changing to the GroovyFX root directory and typing&lt;br /&gt;
&lt;pre&gt;gradle build&lt;/pre&gt;
Once the project builds successfully, you can start running one of the many demos included with the project by typing a command like&lt;br /&gt;
&lt;pre&gt;gradle AnalogClockDemo&lt;/pre&gt;
That will start the application pictured at the top of this article. &amp;nbsp;You can see a complete list of available demos by typing&lt;br /&gt;
&lt;pre&gt;gradle tasks&lt;/pre&gt;
and examining the "Demo" task group.&lt;br /&gt;
&lt;h2&gt;


Setting the Table&lt;/h2&gt;
Setting up and populating a TableView is something that is not only common but can take a surprising amount of code in Java. &amp;nbsp;So we will start with the GroovyFX &lt;a href="http://svn.codehaus.org/gmod/groovyfx/trunk/src/demo/TableViewDemo.groovy"&gt;TableViewDemo&lt;/a&gt; shown in the image below.&lt;br /&gt;
&lt;img alt="Any of these guys would be happy to answer your JavaFX questions." border="0" height="460" src="http://lh4.ggpht.com/-DS3-nJNhu6U/Tj85VFFcyWI/AAAAAAAAATc/0oS_9Hf9E4E/groovyfx-tableview.png?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="Any of these guys would be happy to answer your JavaFX questions" width="600" /&gt;&lt;br /&gt;
The code for this example, in its entirety, is as follows.&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Canonical
class Person {
    @FXBindable String firstName
    @FXBindable String lastName
    @FXBindable String city
    @FXBindable String state
}

def data = [
    new Person('Jim', 'Clarke', 'Orlando', 'FL'),
    new Person('Jim', 'Connors', 'Long Island', 'NY'),
    new Person('Eric', 'Bruno', 'Long Island', 'NY'),
    new Person('Dean', 'Iverson', 'Fort Collins', 'CO'),
    new Person('Jim', 'Weaver', 'Marion', 'IN'),
    new Person('Stephen', 'Chin', 'Belmont', 'CA'),
    new Person('Weiqi', 'Gao', 'Ballwin', 'MO'),
]

GroovyFX.start {
    def sg = new SceneGraphBuilder()

    sg.stage(title: "GroovyFX TableView Demo", visible: true) {
         scene(fill: groovyblue, width: 650, height:450) {
             stackPane(padding: 20) {
                 tableView(items: data) {
                     tableColumn(text: "First Name", property: 'firstName')
                     tableColumn(text: "Last Name", property: 'lastName')
                     tableColumn(text: "City", property: 'city')
                     tableColumn(text: "State", property: 'state')
                 }
             }
         }
    }
}
&lt;/pre&gt;
Compare that with other "simple" &lt;a href="http://www.adam-bien.com/roller/abien/entry/hello_javafx_2_a_tableview"&gt;JavaFX TableView examples&lt;/a&gt;, and it's easy to see that GroovyFX can save you both time and code. &amp;nbsp;There are three main sections to this code: our Person class, the declaration of the data List, and the scene graph itself. &amp;nbsp;The Person class contains the four properties that will be displayed in the TableView. &amp;nbsp;It is annotated with the standard Groovy &lt;code&gt;@Canonical&lt;/code&gt; AST transformation that adds a tuple constructor. &amp;nbsp;This allows us to construct a Person instance using &lt;code&gt;new Person('Jim', 'Clarke', 'Orlando', 'FL')&lt;/code&gt; in our data List. &amp;nbsp;&lt;code&gt;@Canonical&lt;/code&gt; also adds appropriate overrides for the &lt;code&gt;hashCode&lt;/code&gt;, &lt;code&gt;equals&lt;/code&gt;, and &lt;code&gt;toString&lt;/code&gt; methods. &amp;nbsp;These are all generated for us at compile time; this is the power of Groovy's AST transformations.&lt;br /&gt;
The &lt;code&gt;@FXBindable&lt;/code&gt; annotation is a custom AST transform that Jim and I have added to GroovyFX. &amp;nbsp;When you use it to annotate a standard Groovy property, the property will be transformed into a JavaFX property. Its job is to generate all of the boilerplate associated with declaring JavaFX properties. &amp;nbsp;For each annotated property it will generate three methods:&lt;br /&gt;
&lt;pre class="brush:java"&gt;public void setFirstName(String value)
public String getFirstName()
public final StringProperty getFirstNameProperty()
&lt;/pre&gt;
This setup allows you to access your JavaFX properties just as you would any standard Groovy property.&lt;br /&gt;
&lt;pre class="brush:java"&gt;def name = person.firstName
person.firstName = 'James'
person.firstNameProperty.bind( /* some binding expression - more on that below */ )
&lt;/pre&gt;
Considering all of the boilerplate involved when creating JavaFX properties in Java, this will be a real productivity win for GroovyFX users. &amp;nbsp;One last thing to note is that you can also use &lt;code&gt;@FXBindable&lt;/code&gt; to annotate a class. &amp;nbsp;The following code is equivalent to the class declaration above. &amp;nbsp;The FXBindable transform will iterate all of the class properties and transform each one into a JavaFX property.&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Canonical
@FXBindable
class Person {
    String firstName
    String lastName
    String city
    String state
}
&lt;/pre&gt;
We'll now turn our attention to the GroovyFX scene graph declaration. &amp;nbsp;All scene graphs in GroovyFX begin with the &lt;code&gt;GroovyFX.start&lt;/code&gt; method, which takes a closure as its argument. &amp;nbsp;The first few lines of the closure are almost always the same: instantiate a SceneGraphBuilder and use it to declare your stage and scene. &amp;nbsp;The root of our scene graph is a StackPane layout container. &amp;nbsp;This is a nice container to use as a root node since it will be resized as the scene size changes and will also grow and shrink its child nodes if they are resizable (like TableView is). &amp;nbsp;After the stackPane we add a tableView with its data items and its four tableColumn declarations. &amp;nbsp;It is a very concise way to declare your scene graph.&lt;br /&gt;
You have probably noticed that the naming convention for GroovyFX scene graph nodes matches the JavaFX class names with the first letter converted to lower case. &amp;nbsp;This is a convention we follow for all of our nodes. &amp;nbsp;Another convention is that you specify properties for a node using Groovy's &lt;code&gt;propertyName: value&lt;/code&gt; Map syntax. &amp;nbsp;There are a couple of other fun things to note about the scene graph code.&lt;br /&gt;
There is a new color "groovyblue" that is added to JavaFX's Color class at runtime. &amp;nbsp;We use it as the background of all of our demos, but you are free to use it in your code as well (it's the color of the star in the Groovy logo). &amp;nbsp;Any JavaFX color constant can be declared using just its lowercase name such as &lt;code&gt;red&lt;/code&gt;, &lt;code&gt;blue&lt;/code&gt;, or &lt;code&gt;burlywood&lt;/code&gt;. &amp;nbsp;There are also shortcuts for specifying the padding of a node. &amp;nbsp;Above we have just used a single integer value which will be used as the padding on all sides. &amp;nbsp;You can also specify a list with 1, 2, 3, or 4 integers that will be assigned just as they are in CSS. &amp;nbsp;See the GroovyFX &lt;a href="http://svn.codehaus.org/gmod/groovyfx/trunk/src/demo/PaddingDemo.groovy"&gt;PaddingDemo&lt;/a&gt; for the options. &amp;nbsp;These are just a few of the many short cuts and productivity boosters we've incorporated into GroovyFX.&lt;br /&gt;
&lt;h2&gt;


A Time for Binding&lt;/h2&gt;
GroovyFX also has a nice surprise for those of you that miss the simple but powerful binding syntax in JavaFX Script. &amp;nbsp;When JavaFX was ported to Java, the team at Oracle came up with a nice fluent API for specifying binding. &amp;nbsp;Here is an example of this API:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;        hourAngleProperty().bind(Bindings.add(hoursProperty().multiply(30.0),
                                              minutesProperty().multiply(0.5)));
        minuteAngleProperty().bind(minutesProperty().multiply(6.0));
        secondAngleProperty().bind(secondsProperty().multiply(6.0));
&lt;/pre&gt;
Not bad, but all of the method calls do tend to obfuscate the rather simple binding expression.  Wouldn't it be great if you could write these kinds of binding expressions in a more natural way?  Say, something like this?&lt;br /&gt;
&lt;pre class="java" name="code"&gt;        hourAngleProperty.bind((hoursProperty * 30.0) + (minutesProperty * 0.5))
        minuteAngleProperty.bind(minutesProperty * 6.0)
        secondAngleProperty.bind(secondsProperty * 6.0)
&lt;/pre&gt;
This is exactly what Jim has just added to GroovyFX.  This functionality uses Groovy's operator overriding ability combined with its ability to add methods to existing classes.  The result is all-natural binding goodness with only the essence of the binding and little ceremony.  In fact the above expressions are part of the AnalogClockDemo pictured at the start of this article.  The code for the demo's Time class is below.&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@FXBindable
class Time {
    Integer hours
    Integer minutes
    Integer seconds

    Double hourAngle
    Double minuteAngle
    Double secondAngle

    public Time() {
        // bind the angle properties to the clock time
        hourAngleProperty.bind((hoursProperty * 30.0) + (minutesProperty * 0.5))
        minuteAngleProperty.bind(minutesProperty * 6.0)
        secondAngleProperty.bind(secondsProperty * 6.0)

        // Set the initial clock time
        def calendar = Calendar.instance
        hours = calendar.get(Calendar.HOUR)
        minutes = calendar.get(Calendar.MINUTE)
        seconds = calendar.get(Calendar.SECOND)
    }

    /**
     * Add a second to the time
     */
    public void addOneSecond() {
        seconds = (seconds + 1) % 60
        if (seconds == 0) {
            minutes = (minutes + 1)  % 60
            if (minutes == 0) {
                hours = (hours + 1) % 12
            }
        }
    }
}
&lt;/pre&gt;
Note the use of &lt;code&gt;@FXBindable&lt;/code&gt; for easy property declarations, the simple expressive binding, and the natural way of accessing the properties.  You use the property name by itself for getting and setting values.  You use the property name followed by "Property" to access the underlying JavaFX property class when you need to add listeners or bindings. For completeness, the scene graph code used to draw the clock face is shown below.&lt;br /&gt;
&lt;pre class="java" name="code"&gt;time = new Time()

GroovyFX.start {
    def width = 240.0
    def height = 240.0
    def radius = width / 3.0
    def centerX = width / 2.0
    def centerY = height / 2.0

    def sg = new SceneGraphBuilder()

    sg.stage(title: "GroovyFX Clock Demo", width: 245, height: 265, visible: true, resizable: false) {
       def hourDots = []
        for (i in 0..11) {
            def y = -Math.cos(Math.PI / 6.0 * i) * radius
            def x = ((i &amp;gt; 5) ? -1 : 1) * Math.sqrt(radius * radius - y * y)
            def r = i % 3 ? 2.0 : 4.0

            hourDots &amp;lt;&amp;lt; circle(fill: black, layoutX: x, layoutY: y, radius: r)
        }

        scene(fill: groovyblue) {
            group(layoutX: centerX, layoutY: centerY) {
                // outer rim
                circle(radius: radius + 20) {
                    fill(radialGradient(radius: 1.0, center: [0.0, 0.0], focusDistance: 0.5, focusAngle: 0,
                                        stops: [[0.9, silver], [1.0, black]]))
                }
                // clock face
                circle(radius: radius + 10, stroke: black) {
                    fill(radialGradient(radius: 1.0, center: [0.0, 0.0], focusDistance: 4.0, focusAngle: 90,
                                        stops: [[0.0, white], [1.0, cadetblue]]))
                }
                // dots around the clock for the hours
                nodes(hourDots)
                // center
                circle(radius: 5, fill: black)
                // hour hand
                path(fill: black) {
                    rotate(angle: bind(time.hourAngleProperty))
                    moveTo(x: 4, y: -4)
                    arcTo(radiusX: -1, radiusY: -1, x: -4, y: -4)
                    lineTo(x: 0, y: -radius / 4 * 3)
                }
                // minute hand
                path(fill: black) {
                    rotate(angle: bind(time.minuteAngleProperty))
                    moveTo(x: 4, y: -4)
                    arcTo(radiusX: -1, radiusY: -1, x: -4, y: -4)
                    lineTo(x: 0, y: -radius)
                }
                // second hand
                line(endY: -radius - 3, strokeWidth: 2, stroke: red) {
                    rotate(angle: bind(time.secondAngleProperty))
                }
            }
        }
    }

    sequentialTransition(cycleCount: "indefinite") {
        pauseTransition(1.s, onFinished: {time.addOneSecond()})
    }.playFromStart()
}
&lt;/pre&gt;
Once again, this is the &lt;a href="http://svn.codehaus.org/gmod/groovyfx/trunk/src/demo/AnalogClockDemo.groovy"&gt;AnalogClockDemo&lt;/a&gt; located in src/demo in the GroovyFX project. These binding expressions should still be considered experimental, but you can see them in action If you run the demo with Gradle. &amp;nbsp;It should appear as shown here.&lt;br /&gt;
&lt;img alt="A Groovy Clock" border="0" height="379" src="http://lh5.ggpht.com/-XPeWfGXHwCw/Tj-MyXcgKYI/AAAAAAAAATk/0BrRJgMldaI/groovyfx-clock-full.png?imgmax=800" style="display: block; margin-left: auto; margin-right: auto;" title="A Groovy Clock" width="359" /&gt;&lt;br /&gt;
The GroovyFX AnalogClockDemo was inspired by one of the &lt;a href="http://download.oracle.com/javafx/2.0/jruby/jfxpub-jruby.htm"&gt;JRuby examples&lt;/a&gt; on &lt;a href="http://www.javafx.com/"&gt;javafx.com&lt;/a&gt;&lt;br /&gt;
&lt;h2&gt;


Conclusion&lt;/h2&gt;
&lt;a href="http://groovy.codehaus.org/GroovyFX"&gt;GroovyFX&lt;/a&gt; is a young project and it is advancing rapidly. &amp;nbsp;We are only just now getting close to releasing our first version, but it already has a lot of very useful functionality. &amp;nbsp;It has support for virtually every JavaFX shape, control, and chart. &amp;nbsp;It even provides great integration with the brand new FXML functionality (see the &lt;a href="http://svn.codehaus.org/gmod/groovyfx/trunk/src/demo/FXMLDemo.groovy"&gt;FXMLDemo&lt;/a&gt;).&lt;br /&gt;
There is quite a lot of documentation and many examples on the project's web site. &amp;nbsp;We invite you to get involved: download and play with the code then let us know what you think. &amp;nbsp;You can file &lt;a href="http://jira.codehaus.org/browse/GMOD"&gt;JIRA issues&lt;/a&gt; for things that don't work or features you would like to see. &amp;nbsp;Our goal with GroovyFX is to make it fun and easy to write client Java applications. &amp;nbsp;So join in!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-1001010912687592219?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/1001010912687592219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/08/introducing-groovyfx-it-about-time.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/1001010912687592219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/1001010912687592219'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/08/introducing-groovyfx-it-about-time.html' title='Introducing GroovyFX: It&amp;#39;s About Time'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/-5Dcb5wTV3Gg/Tj80-LHbOmI/AAAAAAAAATU/wWeqOyEGu_Q/s72-c/Screen%252520Shot%2525202011-08-07%252520at%2525206.48.59%252520PM.png?imgmax=800' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-334177091925400259</id><published>2011-02-24T17:44:00.001-08:00</published><updated>2011-02-24T17:50:52.100-08:00</updated><title type='text'>Xoom, Xoom, Xoom</title><content type='html'>&lt;p&gt;Android really shines on a tablet.  After playing with my new Xoom tablet and Android Honeycomb for a few hours now, I get the sense that Android was really meant for the larger screen.  The notifications, the multitasking, the widgets; they all combine to make an incredibly powerful and rich tablet OS.  Having a home screen with your calendar and email at your finger tips is incredibly more useful than page after page of icon matrixes.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="x1.png" src="http://lh5.ggpht.com/__eCG_vXQUQk/TWcJStiXR0I/AAAAAAAAANk/X0DQv4wQXVI/x1.png?imgmax=800" border="0" alt="X1" width="600" height="375" /&gt;&lt;/p&gt;&lt;p&gt;And switching between applications is much nicer on Honeycomb.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="x3.png" src="http://lh6.ggpht.com/__eCG_vXQUQk/TWcJaRkpUaI/AAAAAAAAANw/NMg8mQ_Xbg4/x3.png?imgmax=800" border="0" alt="X3" width="600" height="375" /&gt;&lt;/p&gt;&lt;p&gt;To think that all this time Android has really been a tablet OS crammed into a smart phone just bursting to get free.  By the same token, I can see now just how lame iOS is as a nice, but limited phone OS when running scaled up to a larger screen on the iPad.&lt;/p&gt;&lt;p&gt;And the Xoom hardware is very impressive. It is slightly taller but significantly narrower than the iPad and has much smaller bevels around the screen as well. Although this does make it harder to carry the Xoom without leaving finger tip smudges. The dual core Tegra2 processor makes everything feel pretty snappy as well. &lt;/p&gt;&lt;p&gt;The Xoom has a higher resolution packed into a slightly smaller screen which makes for higher DPI. Games like Angry Birds and eBooks look incredible on the Xoom's higher density screen.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="x2.png" src="http://lh3.ggpht.com/__eCG_vXQUQk/TWcJWwZkLuI/AAAAAAAAANo/hj0L7baLwYc/x2.png?imgmax=800" border="0" alt="X2" width="600" height="375" /&gt;&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="x4.png" src="http://lh5.ggpht.com/__eCG_vXQUQk/TWcJY-BO2GI/AAAAAAAAANs/Zga_nEYU-nY/x4.png?imgmax=800" border="0" alt="X4" width="600" height="375" /&gt;&lt;/p&gt;&lt;p&gt;Notice how the status bar at the bottom of the screen goes into a minimal mode when reading a book?  The same thing happens when viewing a movie in order to minimize the distraction of that bottom strip.  These are really nice touches that I would usually expect from Apple rather than Google.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Of course, I'm talking here in terms of environment only.  With a few exceptions, as far as applications go, iPad wins hands down.  No question.  No contest.&lt;/p&gt;&lt;p&gt;As we have seen in the past, a superior OS usually doesn't win against an OS with more apps so this should be an interesting fight.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-334177091925400259?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/334177091925400259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/02/xoom-xoom-xoom.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/334177091925400259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/334177091925400259'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/02/xoom-xoom-xoom.html' title='Xoom, Xoom, Xoom'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/__eCG_vXQUQk/TWcJStiXR0I/AAAAAAAAANk/X0DQv4wQXVI/s72-c/x1.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-8339921673723898577</id><published>2011-02-12T17:42:00.001-08:00</published><updated>2011-02-12T17:54:39.726-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='griffon'/><title type='text'>A Sweet Combination: JavaFX 2.0 EA, Griffon, and Groovy</title><content type='html'>&lt;p&gt;Working with the recent early access release of &lt;a href="http://javafx.com/roadmap/"&gt;JavaFX 2.0&lt;/a&gt; has been interesting.  On one hand, the scene graph API you know and love translates surprisingly well to Java.  The team at Oracle has done a nice job of keeping the new API simple to use.  The animation support still makes it easy to do the simple things, and possible to do the sophisticated.  The memory overhead is down while performance is up.  All good.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="Screen shot 2011-02-12 at 6.30.30 PM.png" src="http://lh3.ggpht.com/__eCG_vXQUQk/TVc2_CRbg_I/AAAAAAAAANE/x57qKF0NGhk/Screen%20shot%202011-02-12%20at%206.30.30%20PM.png?imgmax=800" border="0" alt="Screen shot 2011 02 12 at 6 30 30 PM" width="600" height="466" /&gt;&lt;/p&gt;&lt;p&gt;There are definitely places where JavaFX Script (now &lt;a href="http://code.google.com/p/visage/"&gt;Visage&lt;/a&gt;) is missed.  Binding, object literals, functional programming, and easy internationalization were all particularly useful language features.  To make up for this loss, you can now use all of the old, familiar Java tools to write JavaFX including all of the awesome testing libraries and IDEs that Java is known for.  In my opinion, this more than makes up for the loss of the awesomeness that was the JavaFX Script syntactic sugar.&lt;/p&gt;&lt;p&gt;You can always add some of that sweetness back in by using one of the many great JVM languages at our disposal.  My weapon of choice happens to be &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; and I can tell you that Groovy and JavaFX are a potent combination.  Apparently Groovy is a terrific language for expressing application frameworks as it boasts two of the best in the Java world: &lt;a href="http://www.grails.org/"&gt;Grails&lt;/a&gt; for web applications and &lt;a href="http://griffon.codehaus.org/"&gt;Griffon&lt;/a&gt; for desktop applications.&lt;/p&gt;&lt;p&gt;Yesterday I decided to take a quick look at what would be involved in creating a JavaFX application plugin for Griffon.  I was pleasantly surprised at how easy it was.  Griffon's architecture is clean and the documentation was great.  It took me a lot longer than it should have just because I was enjoying looking around under Griffon's hood.&lt;/p&gt;&lt;p&gt;A video showing the results of my little experiment is embedded below.&lt;/p&gt;&lt;p&gt;&lt;object width="640" height="390"&gt;&lt;param name="movie" value="http://www.youtube.com/v/w0RfpZQwYTE?version=3"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed type="application/x-shockwave-flash" width="640" height="390" src="http://www.youtube.com/v/w0RfpZQwYTE?version=3" allowfullscreen="true" allowscriptaccess="always"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;p&gt;I plan to continue developing this plugin with the ultimate goal being first-class Griffon support for JavaFX applications when JavaFX 2.0 ships later this fall.&lt;/p&gt;&lt;p&gt;The JavaFX team at Oracle has a lot of work ahead of them.  There are some missing features and some rough edges, but this Early Access release is a great start.  I can't wait to see the finished product.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-8339921673723898577?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/8339921673723898577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/02/sweet-combination-javafx-20-ea-griffon.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8339921673723898577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8339921673723898577'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2011/02/sweet-combination-javafx-20-ea-griffon.html' title='A Sweet Combination: JavaFX 2.0 EA, Griffon, and Groovy'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/__eCG_vXQUQk/TVc2_CRbg_I/AAAAAAAAANE/x57qKF0NGhk/s72-c/Screen%20shot%202011-02-12%20at%206.30.30%20PM.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-5970761952089285212</id><published>2010-07-17T14:08:00.001-07:00</published><updated>2010-07-17T14:15:13.579-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>My Bads</title><content type='html'>&lt;p&gt;Just a quick update (long overdue - sorry!) to correct a couple of errors in my last two posts.&lt;/p&gt;&lt;p&gt;First, going all the way back to my post &lt;a href="http://pleasingsoftware.blogspot.com/2010/04/so-whats-it-all-good-for.html"&gt;So What's It All Good For?&lt;/a&gt;, I realized while using my 'X' shape on another control that I had flubbed one of the coordinates in the SVG path.  This made the 'X' look a little hinkey.  Although it was really only noticeable at larger sizes, I went back and fixed the SVG path in that post.  Now the 'X' checkbox looks better.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="simpleskinning.png" src="http://lh4.ggpht.com/__eCG_vXQUQk/TEIdAQp49QI/AAAAAAAAAHQ/s0WM8JptbN4/simpleskinning.png?imgmax=800" border="0" alt="simpleskinning.png" width="477" height="282" /&gt;&lt;/p&gt;&lt;p&gt;My second mistake was of a larger variety.  I incorrectly claimed in my &lt;a href="http://pleasingsoftware.blogspot.com/2010/05/into-background.html"&gt;Into the Background&lt;/a&gt; post that you couldn't use a gradient as the background of a ScrollView because once you added other Nodes, the CSS engine would throw an exception.  Turns out it was user error.&lt;/p&gt;&lt;p&gt;You see, I was assigning the gradient to the -fx-background property in the .scene style.  The fact is that this property must evaluate to a color, not a gradient, because it is used later in the default Caspian style sheet as the base color from which other gradients are calculated.  For some reason the CSS engine objected to me trying to force it to using a gradient as a color stop in another gradient.  Go figure!&lt;/p&gt;&lt;p&gt;This is the reason that the error would only manifest once another control was added to the scene as that was when the gradient-based-on-gradient calculation would be triggered.&lt;/p&gt;&lt;p&gt;My mistake was kindly pointed out by David Grieve in response to my initial bug report &lt;a href="http://javafx-jira.kenai.com/browse/RT-8759"&gt;here&lt;/a&gt;.  I have also updated the original article to demonstrate a variation of the technique that David suggested.  Thanks David!&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="ScrollViewGrad.png" src="http://lh6.ggpht.com/__eCG_vXQUQk/TEIdBJuzPJI/AAAAAAAAAHU/9tRJVUEdI9U/ScrollViewGrad.png?imgmax=800" border="0" alt="ScrollViewGrad.png" width="480" height="402" /&gt;&lt;/p&gt;&lt;p&gt;Hopefully these kinds of mistakes will be less likely to happen in the future now that some nice &lt;a href="http://java.sun.com/javafx/1.3/docs/api/javafx.scene/doc-files/cssref.html"&gt;documentation&lt;/a&gt; of the JavaFX CSS engine exists.  There is also a new JIRA case opened to add better error handling and reporting to the CSS engine, which should also be a big help.&lt;/p&gt;&lt;p&gt;p.s. If you haven't signed the &lt;a href="http://steveonjava.com/javafx-petition/"&gt;petition to open source the JavaFX runtime&lt;/a&gt;, please do so now!  Having access to the source code could also help avoid these kinds of "misunderstandings" in the future.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-5970761952089285212?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/5970761952089285212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/07/my-bads.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/5970761952089285212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/5970761952089285212'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/07/my-bads.html' title='My Bads'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/__eCG_vXQUQk/TEIdAQp49QI/AAAAAAAAAHQ/s0WM8JptbN4/s72-c/simpleskinning.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-8260861708920397855</id><published>2010-05-29T12:36:00.001-07:00</published><updated>2010-07-17T18:12:22.419-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Into the Background</title><content type='html'>&lt;p&gt;&lt;em&gt;Update: This post has been edited to show you how to use a gradient as the background of a ScrollView.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The new and improved support for CSS﻿ in JavaFX 1.3 includes a .scene style class which is a convenient place to initialize all sorts of application settings such as fonts and colors.  Therefore, you would also think that the .scene class is the place to specify the background color for the scene, right?  If you do, you're in good company.  And just like the rest of us, you would be wrong.&lt;/p&gt;&lt;p&gt;It turns out that the only place to set the fill property of the Scene is in your JavaFX code.  But there are some tricks you can use if you want the ability to control the background of your scene from a CSS file.&lt;/p&gt;&lt;h2&gt;ScrollViews and Rectangles&lt;/h2&gt;&lt;p&gt;The simplest way to create a background that can be styled is to use a ScrollView as the background node in your scene.  The advantage of using a ScrollView is that if the window is resized to be smaller than the content, scrollbars will automatically appear.  This is a handy feature to have in a main window.﻿  The following code demonstrates the technique.&lt;/p&gt;&lt;pre class="brush:javafx"&gt;Stage {
    var sceneRef: Scene;
    title: "ScrollView Background"
    scene: sceneRef = Scene {
        width: 400
        height: 300
        stylesheets: "{__DIR__}scrollViewBackground.css"
        content: [
            ScrollView {
                width: bind sceneRef.width
                height: bind sceneRef.height
                node: // Rest of your content goes here﻿
            }
        ]
    }
}&lt;/pre&gt;&lt;p&gt;﻿Here I simply placed the ScrollView first in the Scene's content and bound its width and height to the size of the Scene.  Instant background.&lt;/p&gt;&lt;p&gt;If you then create a style sheet that sets the -fx-background property on the .scene selector, the ScrollView will pick it up automatically.&lt;/p&gt;&lt;pre class="brush:css"&gt;.scene {
    -fx-background: skyblue;
}&lt;/pre&gt;&lt;p&gt;The results are pictured below.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="ScrollView.png" src="http://lh6.ggpht.com/__eCG_vXQUQk/TAFswEq4nZI/AAAAAAAAAGw/jtTdgFXssic/ScrollView.png?imgmax=800" border="0" alt="ScrollView.png" width="480" height="402" /&gt;&lt;/p&gt;&lt;p&gt;Using a gradient as a background for the ScrollView is also possible, although it requires a little more work in your style sheet.  You need to add two new styles that redefine the default background of the ScrollView so that it incorporates a gradient rather than a solid color.&lt;/p&gt;&lt;pre class="brush:javafx"&gt;.scene {
    -fx-background: skyblue;
    -my-scene-background: linear (0%, 0%) to (0%, 100%) stops (0%, derive(-fx-background, 25%)) (100%, derive(-fx-background, -35%));
}
#sceneBackground {
    -fx-background-color: -fx-box-border, -my-scene-background;
}
#sceneBackground:focused {
    -fx-background-color: -fx-focus-color, -fx-box-border, -my-scene-background;
}&lt;/p&gt;&lt;/pre&gt;&lt;p&gt;Note that I have used an ID selector for these new styles so that it overrides only the -fx-background-color of the single ScrollView that I have designated as my scene's background.  I was careful to preserve the -fx-box-border and -fx-focus-color settings of the default ScrollView styles (from caspian.css) so that, other than the gradient, the background will look exactly like a standard ScrollView.&lt;/p&gt;&lt;p&gt;I have also defined my background gradient in the .scene section of the style sheet so that it can be reused in both of the #sceneBackground styles.  Declaring CSS "variables" like this is a feature of the JavaFX CSS support.&lt;/p&gt;&lt;p&gt;Once these additions to the application's style sheet have been made, you just need to add the proper ID to the ScrollView being used as the scene's background and you are done.  This is what the JavaFX code and our window look like now.&lt;/p&gt;&lt;pre class="brush:javafx"&gt;Stage {
    var sceneRef: Scene;
    title: "ScrollView Background"
    scene: sceneRef = Scene {
        width: 400
        height: 300
        stylesheets: "{__DIR__}scrollViewBackground.css"
        content: [
            ScrollView {
                id: "sceneBackground"
                width: bind sceneRef.width
                height: bind sceneRef.height
                node: // Your content goes here...
            }
        ]
    }
}&lt;/pre&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="ScrollViewGrad.png" src="http://lh4.ggpht.com/__eCG_vXQUQk/TEIU5P8xvaI/AAAAAAAAAHI/OMnP9DgIsKo/ScrollViewGrad.png?imgmax=800" border="0" alt="ScrollViewGrad.png" width="480" height="402" /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size: 14px; font-weight: bold;"&gt;Rectangle Backgrounds&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Another lightweight option for creating a styled background is to use a simple Rectangle.&lt;/p&gt;&lt;pre class="brush:javafx"&gt;Stage {
    var sceneRef: Scene;
    title: "Rectangle Background"
    scene: sceneRef = Scene {
        width: 400
        height: 300
        stylesheets: "{__DIR__}rectangleBackground.css"
        content: [
            Rectangle {
                styleClass: "background"
                width: bind sceneRef.width
                height: bind sceneRef.height
            }
            // Rest of your content goes here
        ]
    }
}﻿&lt;/pre&gt;&lt;p&gt;This is similar to the ScrollView version except that a Rectangle is inserted as the first node in the Scene and its width and height are bound to the Scene's size.  Note that I assigned a styleClass of "background" to the Rectangle.  The style sheet now looks like this:&lt;/p&gt;&lt;pre class="brush:css"&gt;.scene {
    -my-scene-background: linear (0%, 0%) to (0%, 100%) stops (0%, derive(skyblue, 25%)) (100%, derive(skyblue,-25%));
}
.background {
    -fx-fill: -my-scene-background;
}﻿&lt;/pre&gt;&lt;p&gt;In the style sheet above, I've assigned a gradient to the -my-scene-background property in the .scene section and then used it to set the Rectangle's fill (-fx-fill) in the .background section which was the styleClass for the background Rectangle.  Of course, I could have just assigned the gradient to the -fx-fill property directly, but as was pointed out above, doing it this way makes that gradient available for use by other styles in the style sheet.&lt;/p&gt;&lt;h2&gt;Regions: Imagine the Possibilities&lt;/h2&gt;&lt;p&gt;For the more adventurous, you can also use a Region for your background.  This gives you the ability to have background colors, borders, and even images!&lt;/p&gt;&lt;p&gt;&lt;img style="float: left;" title="warningsignsmall.png" src="http://lh4.ggpht.com/__eCG_vXQUQk/TAFsvODW0fI/AAAAAAAAAGs/EIBWefadAVY/warningsignsmall.png?imgmax=800" border="0" alt="warningsignsmall.png" width="64" height="57" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt; Warning!  Non-public APIs in use beyond this point. &lt;span style="font-weight: normal;"&gt;Proceed at your own risk!  (It's really not &lt;em&gt;that&lt;/em&gt; risky)&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;All of the core controls in JavaFX 1.3 are made of Regions.  Because of this, Regions are heavily tied into the new CSS support and have a lot more styling options than any other type of node.  You can assign background colors and images, style borders, and even change the shape of the Region all from a style sheet.&lt;/p&gt;&lt;p&gt;But you don't have to write a control to make use of a Region.  Regions are a subclass of the public Stack container and therefore can be used anywhere in the scene graph.  Which means that a Region makes a great background for a Scene.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="RegionGray.png" src="http://lh4.ggpht.com/__eCG_vXQUQk/TAFsxIeepWI/AAAAAAAAAG0/v9k14OCd29c/RegionGray.png?imgmax=800" border="0" alt="RegionGray.png" width="680" height="402" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="RegionSpring.png" src="http://lh6.ggpht.com/__eCG_vXQUQk/TAFsyMOkCMI/AAAAAAAAAG4/S0GPlbyX00c/RegionSpring.png?imgmax=800" border="0" alt="RegionSpring.png" width="680" height="402" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="webstartsmall2.gif" src="http://idisk.mac.com/driverson/Public/webstartsmall2.gif" border="0" alt="webstartsmall2.gif" /&gt;&lt;/p&gt;&lt;p&gt;The top image shows a window with a gray gradient background that is typical of a default Caspian color scheme.  The bottom image shows a combination of a background color and a background image that is positioned along the bottom of the window and repeated in the x-direction to fill the window with flowers in a celebration of Spring (with apologies to all of our friends in the Southern Hemisphere).&lt;/p&gt;&lt;p&gt;The code and the stylesheet are shown below in their entirety.&lt;/p&gt;&lt;pre class="brush:javafx"&gt;Stage {
    var sceneRef: Scene;
    var backgroundRef: Node;
    title: "Region Background"
    scene: sceneRef = Scene {
        width: 600
        height: 300
        stylesheets: ["{__DIR__}jfxtras.css", "{__DIR__}sceneStyles.css"]
        content: [
            backgroundRef = Region {
                styleClass: "background1"
                width: bind sceneRef.width
                height: bind sceneRef.height
            }
            VBox {
                var fillWidth = LayoutInfo { hfill: true }
                spacing: 10
                padding: Insets { top: 10, right: 10, bottom: 10, left: 10 }
                content: [
                    XEtchedButton {
                        text: "Business As Usual"
                        layoutInfo: fillWidth
                        action: function () {
                            backgroundRef.styleClass = "background1"
                        }
                    }
                    XEtchedButton {
                        text: "Yay, It's Spring!"
                        layoutInfo: fillWidth
                        action: function () {
                            backgroundRef.styleClass = "background2"
                        }
                    }
                ]
            }
        ]
    }
}&lt;/pre&gt;&lt;pre class="brush:css"&gt;﻿.scene {
    -fx-font: 24pt "Amble Condensed"
}&lt;p&gt; &lt;/p&gt;&lt;p&gt;.background1 {
    -fx-color: lightgray;
    -fx-background-color: -fx-body-color;
    -fx-background-image: null;
}&lt;/p&gt;&lt;p&gt;.background2 {
    -fx-background-color: #81E2F7;
    -fx-background-image: "flowersbluesky.png";
    -fx-background-position: left bottom;
    -fx-background-repeat: repeat-x;
}
&lt;/p&gt;&lt;/pre&gt;&lt;div&gt;﻿Regions definitely provide the most flexibility and power as the background of a Scene.  The only drawback is that Region is not part of the JavaFX runtime's public API.  As such, there is always the possibility that the class may change or disappear in future releases.  In this case, I think the fact that the core controls now rely on Regions means that they will be around in one form or another for a long time.&lt;/div&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-8260861708920397855?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/8260861708920397855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/05/into-background.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8260861708920397855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8260861708920397855'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/05/into-background.html' title='Into the Background'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/__eCG_vXQUQk/TAFswEq4nZI/AAAAAAAAAGw/jtTdgFXssic/s72-c/ScrollView.png?imgmax=800' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-2638543961733207987</id><published>2010-04-29T10:07:00.000-07:00</published><updated>2010-04-29T10:38:27.246-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><title type='text'>Back Off, Steve</title><content type='html'>I cannot express my indignation adequately in &lt;a href="http://twitter.com/deanriverson"&gt;140 characters&lt;/a&gt;.  &lt;div&gt;
&lt;/div&gt;&lt;div&gt;Apple has published a well-written &lt;a href="http://www.apple.com/hotnews/thoughts-on-flash/"&gt;open letter&lt;/a&gt; from Steve Jobs about the iPhone/iPad vs Flash kerfuffle.&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Being used to the &lt;a href="http://www.oracle.com/technology/tech/java/index.html"&gt;JVM&lt;/a&gt;, I will admit that the Flash Player does not seem as fast or robust.  But I do find it to be a fairly pleasant development environment.  And it is very good at what it was designed for.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;The real problem I have with the open letter is the last, most important reason Jobs lists.  It boils down to: we just want to protect our developers from making bad choices (as defined by us).  By force if necessary.  This is just so wrong for so many reasons.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;If Apple wants to ban the Flash Player from their platforms, fine.  But don't try to dictate what languages developers can use under the guise of "supporting open standards."  Apple, if the use of ActionScript leads to inferior applications, they will be killed off by the native applications.  The point is: &lt;i&gt;fair competition should always be allowed to determine the winner.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;If Adobe's tools make it easy for developers to create nice applications that people want to use, you do everyone a disservice by imposing additional artificial restrictions on your already closed-garden app store.  &lt;i&gt;Stop hindering free competition!&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;
&lt;/i&gt;&lt;/div&gt;&lt;div&gt;I really enjoy developing applications on my brand new MacBook Pro.  But my next mobile device is going to be powered by a &lt;a href="http://developer.android.com/index.html"&gt;little green robot&lt;/a&gt;.  Not because I want to make a statement.  Just because I want to be able to decide how to write applications for my own device.  And for me personally, neither Objective-C nor HTML5 are appealing choices.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Just my worthless opinion.  We now return to our regularly scheduled JavaFX addiction.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-2638543961733207987?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/2638543961733207987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/2638543961733207987'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/04/back-off-steve.html' title='Back Off, Steve'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-667373182620441703</id><published>2010-04-27T09:02:00.000-07:00</published><updated>2010-06-06T11:01:39.179-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>So What's It All Good For?</title><content type='html'>&lt;p&gt;Ok, so my &lt;a href="http://pleasingsoftware.blogspot.com/2010/04/advanced-javafx-control-styling.html"&gt;previous post&lt;/a&gt; (which I refer to facetiously as the Encyclopedia of JavaFX Styling) was a tad on the long-ish side.  It contained a lot of not-so-trivial-to-understand information.  It contained information that was biased toward helping control authors understand the new system rather than application developers.&lt;/p&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;So I can certainly understand the reactions of some folks: "Holy cow that looks complicated!" or "Why should I learn all of that?" or "What's this new-fangled system even good for?".  The reason application developers should learn the new styling system is very simple: &lt;em&gt;you can now do things with a few lines of CSS that used to take many lines of JavaFX code&lt;/em&gt;.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size: medium;"&gt;Like all of JavaFX, it's all about developer productivity!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Let's say as an application developer you decided that:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;All of your application buttons should be round, or&lt;/li&gt;&lt;li&gt;Your checkboxes should have red X's rather than black checks and the text associated with them should turn red when the checkbox is selected, or&lt;/li&gt;&lt;li&gt;You want an awesome slider for your "number of gold stars" rating system complete with a star-shaped thumb bar that casts a drop shadow!  (Really?  Ok...).&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Pre-JavaFX 1.3 you would be doing some combination of styling and overriding skin classes and rewriting skin code.  Now with JavaFX 1.3, all of this is just a style sheet away.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class="brush:css"&gt;.scene {
    -fx-font: 16pt "Amble"
}

.button {
    -fx-base: dodgerblue;
    -fx-shape: "M 50,30  m 0,25  a 1,1 0 0,0 0,-50  a 1,1 0 1,0 0,50";
    -fx-scale-shape: false;
}

.check-box:selected *.label {
    -fx-text-fill: red
}

.check-box:selected *.mark {
    -fx-background-color: red;
    -fx-shape: "M 0,0 H1 L 4,3 7,0 H8 V1 L 5,4 8,7 V8 H7 L 4,5 1,8 H0 V7 L 3,4 0,1 Z";
}

.slider *.track {
    -fx-base: derive( goldenrod, 50% );
}

.slider *.thumb {
    -fx-shape: "M 50,5 L 37,40 5,40 30,60 20,95 50,75 80,95 70,60 95,40 63,40 Z";
    -fx-background-color: derive(goldenrod,-50%), goldenrod;
    -fx-background-radius: 0, 0;
    -fx-background-insets: 0, 2;
    -fx-padding: 10;
    -fx-effect: dropshadow( two-pass-box , rgba(0,0,0,0.6) , 4, 0.0 , 0 , 1 );
}
&lt;/pre&gt;&lt;p&gt;Just apply this style sheet and BLAM!  All your buttons are round, all your checkboxes are X'ed, and all of your sliders are golden.  Life is good.  Behold.&lt;/p&gt;&lt;p&gt;&lt;img style="display: block; margin-left: auto; margin-right: auto;" title="simpleskinning.png" src="http://lh3.ggpht.com/__eCG_vXQUQk/TAviASZGLYI/AAAAAAAAAHA/xzU8dnc4viM/simpleskinning.png?imgmax=800" border="0" alt="simpleskinning.png" width="477" height="282" /&gt;&lt;/p&gt;&lt;p&gt;Although... we may want to re-think that red checkbox label.  Ick.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-667373182620441703?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/667373182620441703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/04/so-whats-it-all-good-for.html#comment-form' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/667373182620441703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/667373182620441703'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/04/so-whats-it-all-good-for.html' title='So What&amp;#39;s It All Good For?'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/__eCG_vXQUQk/TAviASZGLYI/AAAAAAAAAHA/xzU8dnc4viM/s72-c/simpleskinning.png?imgmax=800' height='72' width='72'/><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-5929899271004208294</id><published>2010-04-26T11:45:00.001-07:00</published><updated>2010-04-27T05:53:37.883-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Advanced JavaFX Control Styling</title><content type='html'>&lt;p&gt;JavaFX v1.3 includes a brand new and much more powerful CSS-based styling and skinning engine.  This article will take a peak under the covers and show you how to get the most out of JavaFX styling so you can develop a unique look for your applications.  I'll even show you how to do some basic re-skinning of the core controls - changing not just their color scheme but also their shape! - all from the comfort and convenience of your style sheet. That is a lot of ground to cover so we better get started.&lt;/p&gt;&lt;h2&gt;Understanding Regions&lt;/h2&gt;&lt;blockquote&gt; &lt;strong&gt;Warning!!&lt;/strong&gt;
The Region API is not public and is not considered a finished work. It can, and certainly will, change in future versions.  Maybe even in JavaFX v1.3.1.  The code presented here is for demonstration of the concepts underlying the new styling system in JavaFX 1.3.  If you are considering using this information to build your own custom controls, be sure you understand the down side of using private APIs!&lt;/blockquote&gt;&lt;p&gt;In v1.3 the core controls are made up of regions.  Regions are basically a shape with one or more backgrounds and borders. All core control skins inherit from SkinBase which extends Region. Take the LabelSkin as an example.  Its inheritance hierarchy looks like this:&lt;/p&gt;&lt;p&gt;LabelSkin -&gt; SkinBase -&gt; Region -&gt; Stack&lt;/p&gt;&lt;p&gt;So the controls are regions, but they can also have zero or more sub-regions. Think of a scroll bar control.  It is a region, but it also has sub-regions for the thumb button, the track, and the up and down arrow buttons.&lt;/p&gt;&lt;p&gt;Regions are tied into the new CSS system and can be fully specified, right down to their shape, from a style sheet.&lt;/p&gt;&lt;p&gt;Note that SkinBase does not inherit from Skin at any point.  A SkinBase can be assigned to a custom control's skin variable through the use of the SkinAdapter class.  The SkinAdapter will take care of passing along the control and behavior assignments to the SkinBase when SkinAdapter is set as the Control's skin.&lt;/p&gt;&lt;h4&gt;Creating a Demonstration Control&lt;/h4&gt;&lt;p&gt;I simply define a class that extends Control, assign the skin using the SkinAdapter, and override the styleClass variable.&lt;/p&gt;&lt;pre class="brush:javafx"&gt;
public class DemoControl extends Control {
    // This is the class I'll use in style sheets
    override var styleClass = "demo-control";

    // SkinAdapter lets me use a Region as a Skin
    override var skin = SkinAdapter {
        rootRegion: DemoControlRegionSkin{}
    }
}&lt;/pre&gt;
&lt;p&gt;Next I define a Region-based skin by creating a class that extends SkinBase.&lt;/p&gt;&lt;pre class="brush:javafx"&gt;
public class DemoControlRegionSkin extends SkinBase {
    // SkinAdapter will set up SkinBase's control and behavior vars
    var cc = bind control as DemoControl;

    // You should always give your control skins a default preferred size
    override function getPrefWidth( height ) { 100 }
    override function getPrefHeight( width ) { 100 }
}&lt;/pre&gt;
&lt;h2&gt;JavaFX Styling Techniques&lt;/h2&gt;&lt;p&gt;I think it's best to start with a basic example and build up from there.  So I'll begin by creating a simple scene and adding our new demo control.&lt;/p&gt;&lt;pre class="brush:javafx"&gt;
Stage {
    title: "JavaFX CSS Controls"
    scene: Scene {
        var stack:Stack;

        width: 300
        height: 300
        stylesheets: "{__DIR__}controlStyles.css"

        content: [
            stack = Stack {
                width: bind stack.scene.width
                height: bind stack.scene.height
                content: [
                      DemoControl {
                          layoutInfo: LayoutInfo {
                              width: 250
                              height: 250
                          }
                      }
                ]
            }
        ]
    }
}&lt;/pre&gt;&lt;p&gt;I created a simple Scene that is 300 by 300 pixels and has a Stack container that fills it completely.  I then created a new instance of my DemoControl and set it's preferred width and height to be 250 pixels.  Note that this will override the preferred width and height of 100 that I entered into the control skin itself when I added those functions.  By default a Stack will size its children to their preferred size and center them.  Therefore, when this program is run we should see a 250 by 250 rectangle (a.k.a. a square) centered in the scene.  I'll now add some minimal styling in controlStyles.css (which is added to the Scene above) so the Region's rectangle will be visible.&lt;/p&gt;&lt;pre class="brush:css"&gt;
.scene {
    -fx-font: 16pt "Amble";
    -dean-slightlydarkergreen: derive( green, -25% );
}

.demo-control {
    -fx-background-color: skyblue;
    -fx-border-color: -dean-slightlydarkergreen;
    -fx-border-width: 2;
}&lt;/pre&gt;&lt;p&gt;This small style sheet first sets a default font for the Scene.  I haven't added any controls with text yet, but I will later and it's always nice to set these things up in one place.  Below the font attribute, I demonstrate a feature of JavaFX styling: the ability to derive a new color from an existing one and store it for later use.  In this case, I created a darker version of Green and named it -dean-slightlydarkergreen.  Not only am I now immortalized in my own style sheet, but the DemoControl can reference this attribute later as shown above for the control's border color.  Note that I use the same class string "demo-control" that I hard-coded into my DemoControl class.  Let's see how this looks so far.&lt;/p&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/S9ZAdBsAX4I/AAAAAAAAAEU/ePtpFvf6buE/s1600/cssctrl.png" /&gt;
&lt;h4&gt;Gradients&lt;/h4&gt;&lt;p&gt;You can also specify linear gradients in your style sheet.  The image and code below shows a fancier version of the DemoControl.&lt;/p&gt;&lt;table style="background-color:azure; border: solid 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border-bottom: solid 1px"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/S9ZC3fKHNKI/AAAAAAAAAEc/MwfA6jE5xMo/s1600/gradientctrl.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464628718884828322" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre class="brush:css"&gt;
#gradient.demo-control {
    -dean-lightnavy: derive(navy, 100%);
    -dean-navygrad: linear (0%,0%) to (100%,0%) stops (0%, -dean-lightnavy) (100%, navy);
    -fx-background-color: linear (0%,0%) to (0%,50%) stops (0%, derive(deepskyblue, 80%)) (30%, deepskyblue) reflect;
    -fx-border-color: -dean-navygrad null -dean-navygrad null;
    -fx-border-width: 8 0 8 0;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;You can see by the CSS selector "#gradient.demo-control" that this style will be applied to DemoControls with "gradient" for an ID.  I didn't have to change any JavaFX script code to make this work other than adding the id: "gradient" attribute to the DemoControl's object literal declaration in the Scene, thereby picking up this new style.&lt;/p&gt;&lt;p&gt;In this style, I also derive a new light navy color and then reference it again when I define my navy gradient (-dean-navygrad).  This gradient is then used as the border color.  I use it on the top and bottom while setting the left and right border colors to null.  Similarly, I set the top and bottom border widths to 8 pixels while the left and right borders have a 0 width.  Many style attributes of a Region have this ability to specify top, right, bottom, and left properties individually.  On the other hand, if I were to simply say "-fx-border-width: 8" then all borders would be 8 pixels wide.&lt;/p&gt;&lt;p&gt;The Region's background color is a slightly more complicated linear gradient.  It goes half way down the rectangle and is then reflected so the bottom half matches the top.  Note that you can even embed "derive" functions inside of linear gradient definitions.  More power!&lt;/p&gt;&lt;h4&gt;Multiple Backgrounds&lt;/h4&gt;&lt;p&gt;As I said at the beginning, Regions are made up of a shape and one or more backgrounds and borders.  Let's take a look at how you define multiple backgrounds and borders for your region.  Once again, I will make no changes to our source code other than the control's ID in the scene and a new style in the style sheet.&lt;/p&gt;&lt;table style="background-color:azure; border: solid 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border-bottom: solid 1px"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/S9ZFIyfhd6I/AAAAAAAAAEk/z9-ijXk2DFY/s1600/multbgctrl.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464631215155935138" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre class="brush:css"&gt;
#multibg.demo-control {
    -fx-background-color: skyblue, mediumaquamarine;
    -fx-background-radius: 15 0 15 0;
    -fx-background-insets: 0, 20;
    -fx-border-color: navy, darkcyan;
    -fx-border-style: dotted;
    -fx-border-width: 2;
    -fx-border-radius: 15 0 15 0;
    -fx-border-insets: 0, 20;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Most of the style attributes of a Region can take multiple items in their declarations.  You can see examples of this in the declarations of the -fx-background-color, -fx-background-insets, and the -fx-border-color attributes.  In these cases, the first item is applied to the first background, the second item is applied to the second background and so on.  Therefore we end up with a skyblue rectangle with navy border and a medium aquamarine rectangle with a dark cyan border.  The first background has no insets (it is filled right to the border of the control), while the second rectangle is inset by 20 pixels on all sides.&lt;/p&gt;&lt;p&gt;In cases where there are multiple backgrounds but only one item specified, the first item will be applied to all backgrounds.  For example, both rectangles have top-left and bottom-right rounded corners defined by the -fx-background-radius and -fx-border-radius attributes.  Since only one set of radius attributes are defined, it will be applied to both backgrounds.&lt;/p&gt;&lt;p&gt;The thing to remember is that commas separate multiple items in a single attribute (as in the two items specified by -fx-background-color above), whereas spaces are used as the separators in an item that can take multiple values (as in the one item having 4 values specified by -fx-border-radius above).  Crystal clear?  Good.  Let's take it up a notch.&lt;/p&gt;&lt;h4&gt;Getting Fancier&lt;/h4&gt;&lt;p&gt;Here's a twist: many of those attributes that can take multiple values in a single item (like -fx-border-radius) can also take multiple items.  This allows you, for example, to specify a different set of border radius values for each background.&lt;/p&gt;&lt;table style="background-color:azure; border: solid 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border-bottom: solid 1px"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://2.bp.blogspot.com/__eCG_vXQUQk/S9ZacL7hySI/AAAAAAAAAEs/tjv3_kB5POQ/s1600/multibgoppcorners.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464654638145980706" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre class="brush:css"&gt;
#multibgoppcorners.demo-control {
    -fx-background-color: skyblue, mediumaquamarine;
    -fx-background-radius: 15 0 15 0, 0 15 0 15;
    -fx-background-insets: 0, 20 40 20 40;
    -fx-border-color: navy, darkcyan;
    -fx-border-style: dotted, dashed;
    -fx-border-width: 2, 1;
    -fx-border-radius: 15 0 15 0, 0 15 0 15;
    -fx-border-insets: 0, 20 40 20 40;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Here I specify a completely different set of values for the -fx-background-radius, -fx-background-insets, -fx-border-radius, and -fx-border-insets attributes for each background.  Remember, multiple values within a single item are separated by spaces while multiple items are separated by commas.&lt;/p&gt;&lt;h4&gt;Styling Conclusions&lt;/h4&gt;&lt;p&gt;In this section I've experimented with the most common style attributes that are used on Regions.  You can also use the regular Node style attributes that I covered &lt;a href="http://pleasingsoftware.blogspot.com/2010/04/brief-introduction-to-styling-controls.html"&gt;here&lt;/a&gt;.  Of interest will be Node's -fx-opacity, -fx-effect, and -fx-cursor attributes.  It should also be noted that Regions have a corresponding set of attributes for image-based backgrounds and borders (i.e. -fx-background-image and -fx-border-image and so on).  I'm not going to cover them here, but I would expect Oracle to publish full documentation on these attributes very soon.&lt;/p&gt;&lt;h2&gt;Shaping Controls&lt;/h2&gt;&lt;p&gt;So far, I've just used the default rectangular shape but by using the style sheet I can make a region take on just about any shape that can be imagined.  The shape of a Region is specified using SVG path notation.  This notation uses a compact encoding to describe shapes using a series of commands and coordinates.  Commands are represented by a single letter.  For example, M is the move-to command.  If the command letter is upper case then the coordinates that follow are considered absolute coordinates whereas the coordinates are interpreted as relative if the letter is lower case.  So "M 0 1" means move to location 0,1 while "m 0 1" means move 1 unit in the y direction from the current location.  See &lt;a href="http://www.w3.org/TR/SVG/paths.html#PathData"&gt;this&lt;/a&gt; page for details of the SVG path syntax.&lt;/p&gt;&lt;h3&gt;Movement and Lines&lt;/h3&gt;&lt;p&gt;Drawing shapes with one or more lines is extremely easy.  The format of the commands is shown in the following table.&lt;/p&gt;&lt;table rules="cols" style="background-color:azure; border: solid 1px;width=90%"&gt;&lt;tbody&gt;&lt;tr style="border: solid 1px;"&gt;&lt;td&gt;Move to&lt;/td&gt;&lt;td&gt;M x y
m x y&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Line to&lt;/td&gt;&lt;td&gt;L (x y)+
l (x y)+&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border: solid 1px;"&gt;&lt;td&gt;Horizontal line to&lt;/td&gt;&lt;td&gt;H x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Vertical line to&lt;/td&gt;&lt;td&gt;V y&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border: solid 1px;"&gt;&lt;td&gt;Close the current path&lt;/td&gt;&lt;td&gt;Z
z&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Suppose I wanted a triangular region instead of the default rectangle.&lt;/p&gt;&lt;table style="background-color:azure; border: solid 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border-bottom: solid 1px"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/S9Zf11ARdjI/AAAAAAAAAE0/wB6sE6KqMFI/s1600/lineshape.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464660576226604594" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre class="brush:css"&gt;
#line.demo-control {
    -fx-shape: "M 0,1 L 1,1 .5,0 Z";
    -fx-background-color: skyblue, blue;
    -fx-background-insets: 0, 20 20 10 20;
}&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
The coordinate system used in these paths is the same one used in JavaFX: x increases to the right, y increases down.  So our shape is defined as:
&lt;ol&gt;&lt;li&gt;Move down one unit in the y direction&lt;/li&gt;&lt;li&gt;Draw a poly-line to the coordinate 1,1 and then 0.5,0&lt;/li&gt;&lt;li&gt;Close the path&lt;/li&gt;&lt;/ol&gt;By the way, the use of commas to separate the x,y coordinates in a SVG path command are purely optional.  I like to use them because it makes the command more readable to me.  I'm using capital letters so those coordinates are absolute, not relative to each other.  By default, the shape is scaled to fill the area of the control, so the scale of the coordinates doesn't matter.  I could have just as easily used 0, 50, and 100 rather than 0, 0.5 and 1.0.

You can see that even though the shape has changed, our ability to specify multiple backgrounds with offsets hasn't.  One thing to watch our for is that, with non-rectangular shapes, the insets may need to be adjusted to keep the inner shape centered.  Here I had to adjust the bottom inset of the second background to make the triangles look centered.  I don't know if this is a bug or a feature, but for JavaFX 1.3 be aware that you may need to play with the insets to get things to look exactly as you want.  And although the coordinates of the shape are scaled, the insets are still specified in pixels.
&lt;h4&gt;Cubic Curves&lt;/h4&gt;&lt;p&gt;The SVG path commands for drawing cubic Bezier curves are shown in the following table.&lt;/p&gt;
&lt;table rules="cols"  style="background- border: solid 1px; width: 90%color:azure;"&gt;&lt;tbody&gt;&lt;tr style="border: solid 1px;"&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;Cubic Bezier curve to
&lt;i&gt;Draws a curve from the current point to x,y.
x1,y1 is the control point at the beginning of the curve.
x2,y2 is the control point at the end of the curve.&lt;/i&gt;&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;C (x1 y1 x2 y2 x y)+
c (x1 y1 x2 y2 x y)+&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border: solid 1px;"&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;Cubic Bezier curve to (shorthand)
&lt;i&gt;Draws a curve from the current point to x,y.
The control point at the beginning of the curve is the reflection of the second control point from the previous curve.
x2,y2 is the control point at the end of the curve.&lt;/i&gt;&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;S (x2 y2 x y)+
s (x2 y2 x y)+&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;So let's take a look at a region shaped with cubic curves.&lt;/p&gt;
&lt;table style="background-color:azure; border: solid 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border-bottom: solid 1px"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://2.bp.blogspot.com/__eCG_vXQUQk/S9ZinpkDpfI/AAAAAAAAAE8/lU9gPTmoSec/s1600/cubiccurve.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464663631172183538" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre class="brush:css"&gt;
#cubic.demo-control {
    -fx-shape: "M100,200 C100,100 250,100 250,200 S400,300 400,200 Z";
    -fx-background-color: skyblue, blue;
    -fx-background-insets: 0, 10;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
This is admittedly a somewhat fanciful shape for a control.  It is important to note that the control's clickable area still takes up the whole 250 by 250 pixels even though the Region's backgrounds take up a smaller area.

&lt;h4&gt;Quadratic Curves&lt;/h4&gt;

The quadratic Bezier curve commands are shown in the table below.

&lt;table rules="cols"  style="background- border: solid 1px; width: 90%color:azure;"&gt;&lt;tbody&gt;&lt;tr style="border: solid 1px;"&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;Quadratic Bezier curve to
&lt;i&gt;Draws a curve from the current point to x,y.
x1,y1 is the control point of the curve.&lt;/i&gt;&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;Q (x1 y1 x y)+
q (x1 y1 x y)+&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="border: solid 1px;"&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;Quadratic Bezier curve to (shorthand)
&lt;i&gt;Draws a curve from the current point to x,y.
The control point at the beginning of the curve is the reflection of the control point from the previous curve.&lt;/i&gt;&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;T (x y)+
t (x y)+&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

Let's take a look at a quadratic curve example.

&lt;table style="background-color:azure; border: solid 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border-bottom: solid 1px"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://4.bp.blogspot.com/__eCG_vXQUQk/S9Zmb8AAQlI/AAAAAAAAAFE/IBHFn72Eu5Y/s1600/quadratic.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464667828009321042" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre class="brush:css"&gt;
#quadratic.demo-control {
    -fx-shape: "M0,200 Q100,50 200,200 T500,100";
    -fx-background-color: skyblue, blue;
    -fx-background-insets: 0, 10;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

The shape of our region just keeps getting more interesting!

&lt;h4&gt;Elliptical Arcs&lt;/h4&gt;

The arc command is easily the most confusing of the SVG path commands.  Use of SVG graphical editors is highly recommended!

&lt;table rules="cols"  style="background- border: solid 1px; width: 90%color:azure;"&gt;&lt;tbody&gt;&lt;tr style="border: solid 1px;"&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;Elliptical arc to
&lt;i&gt;rx ry - The radius of the resulting arc
x-axis-rotation - Rotation of the x in degrees
large-arc-flag - If 1 then the largest arc between the start and end points will be drawn.  If 0 then the smallest are will be drawn.
sweep-flag - Indicates the direction in which the arc is drawn.  A 1 specifies the positive direction, a 0 specifies the negative direction.
x y - The end point of the resulting arc.  These are absolute coordinates or are relative to the start point (the current location) depending on whether the A or a command is used.&lt;/i&gt;&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span class="Apple-style-span"&gt;A (rx,ry x-axis-rotation large-arc-flag sweep-flag x,y)+
a (rx,ry x-axis-rotation large-arc-flag sweep-flag x,y)+
&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

What are arcs good for?  Lot's of things, of course, but circles are an obvious choice.  However, drawing a circle with arc commands is not as trivial as you would imagine.  Here is an example.

&lt;table style="background-color:azure; border: solid 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="border-bottom: solid 1px"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://2.bp.blogspot.com/__eCG_vXQUQk/S9Znl1MOpwI/AAAAAAAAAFM/-Ld9ziW5BMY/s1600/arc.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464669097491867394" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;pre class="brush:css"&gt;
#arc.demo-control {
    -fx-shape: "M 50,30  m 0,25  a 1,1 0 0,0 0,-50  a 1,1 0 1,0 0,50";
    -fx-background-color: skyblue, blue;
    -fx-background-insets: 0, 10;
}
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;

As you can see, you actually need to define two arcs: one for each 180 degree ellipse.

&lt;h4&gt;Final Thoughts on Shapes&lt;/h4&gt;

The ability to change, not just the colors, but the actual shapes of the regions that make up the core controls gives application developers unprecedented control over the look of their applications.  Need a slider with a gold star for the thumb track?  Easy.  Buttons that look like clouds?  Very do-able.  The only limit is your imagination.  Just remember, as with many of the things that JavaFX makes easy for developers: with great power comes great responsibility!

&lt;h2&gt;Using Caspian Styles&lt;/h2&gt;
&lt;div&gt;&lt;span class="Apple-style-span"   style="  ;font-family:Cambria, Georgia, 'Times New Roman', Times, serif;font-size:medium;"&gt;&lt;p&gt;One last thing I want to address is the subject of using that styles in caspian.css with your own controls.  The Caspian class in JavaFX 1.2 contained several nice utility functions that would generate nice gradients that tied into the Caspian theme.  That class no longer exists in JavaFX 1.3.  To use the Caspian theme with your own controls, you will need to use the values defined in the caspian.css style sheet.&lt;/p&gt;&lt;p&gt;Let's return to the DemoControl and make it look like it fits in with the Caspian controls.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;table class="LightBlue" style="border-collapse: collapse; width: 575px; "&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="color: black; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: black; border-right-color: black; border-bottom-color: black; border-left-color: black; background-color: azure; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; text-align: center; "&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/S9ZoibtfDSI/AAAAAAAAAFU/y7C7I4_RqSw/s1600/caspianregion.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464670138624052514" /&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="color: black; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: black; border-right-color: black; border-bottom-color: black; border-left-color: black; background-color: rgb(214, 230, 246); padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; text-align: left; "&gt;&lt;pre class="brush:css"&gt;
#caspian.demo-control {
    -fx-background-color: -fx-body-color;
    -fx-background-radius: 5;
    -fx-border-color: null;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div&gt;As you can see, all I've done is use the -fx-body-color attribute from caspian.css as my background color, added a corner radius to match Caspian's, and turned off the border I would normally inherit from the default demo-control style.  In order for the -fx-body-color attribute to be defined, the caspian.css has to be loaded into the scene.  Instantiating any core control will take care of this.  In this case, I not only instantiated a button, but I also added it to the scene's Stack container just for comparison.&lt;/div&gt;&lt;h4&gt;Adding Borders&lt;/h4&gt;&lt;div&gt;Now I'll go the whole nine yards and add Caspian-style borders as well.  I can take these right out of the button style in caspian.css.&lt;/div&gt;&lt;div&gt;&lt;pre class="brush:css"&gt;
#caspianborders.demo-control {
    -fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;
    -fx-background-radius: 5, 5, 4, 3;
    -fx-background-insets: 0 0 -1 0, 0, 1, 2;
    -fx-border-width: 0;
}&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;Here I have actually defined four different backgrounds for the DemoControl's region.  The insets are used to make sure they appear properly as a shadow, two borders and the body.  Using the Caspian-defined attributes for body, border and shadow color means that my DemoControl will respond to changes in the application-defined -fx-base attribute.  This is the attribute you would set if you wanted to change the base color of all Caspian controls in the entire application.  I can set -fx-base to a new color in the .scene style and both DemoControl and the button will pick up the change.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;table class="LightBlue" style="border-collapse: collapse; width: 575px; "&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="color: black; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: black; border-right-color: black; border-bottom-color: black; border-left-color: black; background-color: azure; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; text-align: center; "&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://4.bp.blogspot.com/__eCG_vXQUQk/S9ZqBGqzREI/AAAAAAAAAFc/69tCMgrKcjo/s1600/caspianborderregion.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464671765063222338" /&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="color: black; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: black; border-right-color: black; border-bottom-color: black; border-left-color: black; background-color: rgb(214, 230, 246); padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; text-align: left; "&gt;&lt;pre class="brush:css"&gt;
.scene {
     -fx-font: 16pt "Amble";
     -fx-base: dodgerblue;
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;h4&gt;Final Conclusion&lt;/h4&gt;&lt;div&gt;I really like the power and flexibility of the new CSS support in JavaFX 1.3.  Styling and skinning controls is now easier than ever.  If you need to, you can create an entirely unique look for your application without having to change any lines of JavaFX source code.  It brings us a true separation of presentation and program logic.  All in all, I give it a gold star.  A gold star button even!&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;table class="LightBlue" style="border-collapse: collapse; width: 575px; "&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" style="color: black; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: black; border-right-color: black; border-bottom-color: black; border-left-color: black; background-color: azure; padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; text-align: center; "&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://3.bp.blogspot.com/__eCG_vXQUQk/S9ZqpjQgYGI/AAAAAAAAAFk/EVIBsOkv17w/s1600/goldstar.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5464672459932328034" /&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="color: black; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: black; border-right-color: black; border-bottom-color: black; border-left-color: black; background-color: rgb(214, 230, 246); padding-top: 4px; padding-right: 4px; padding-bottom: 4px; padding-left: 4px; text-align: left; "&gt;&lt;pre class="brush:css"&gt;
#star.button {
     -fx-shape: "M 50,5 L 37,40 5,40 30,60 20,95 50,75 80,95 70,60 95,40 63,40 Z";
     -fx-base: goldenrod
}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;

&lt;h2&gt;References&lt;/h2&gt;

I found these things handy while learning about all of this:

&lt;ol&gt;
&lt;li&gt;The caspian.css style sheet located in com/sun/javafx/scene/control/skin/caspian/caspian.css in the javafx-ui-controls.jar packaged with the JavaFX SDK.&lt;/li&gt;
&lt;li&gt;The Style Editor example at: &lt;a href="http://www.javafx.com/samples/StyleEditor/index.html"&gt;http://www.javafx.com/samples/StyleEditor/index.html&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-5929899271004208294?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/5929899271004208294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/04/advanced-javafx-control-styling.html#comment-form' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/5929899271004208294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/5929899271004208294'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/04/advanced-javafx-control-styling.html' title='Advanced JavaFX Control Styling'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__eCG_vXQUQk/S9ZAdBsAX4I/AAAAAAAAAEU/ePtpFvf6buE/s72-c/cssctrl.png' height='72' width='72'/><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-8073420268421049627</id><published>2010-04-22T19:51:00.000-07:00</published><updated>2010-04-27T09:44:26.212-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>A Brief Introduction to Styling Controls in JavaFX 1.3</title><content type='html'>&lt;p&gt; Support for styling the core controls using CSS has been greatly enhanced for JavaFX 1.3.  In fact, the default skin for the core controls, called Caspian, is now written as a style sheet rather than in JavaFX Script code.  Below is an example of a small JavaFX 1.3 style sheet that I wrote for &lt;a href="http://learnjavafx.typepad.com/weblog/2010/04/your-calendar-pwn3d-leveraging-the-javafx-scene3d-conditionalfeature.html"&gt; Jim Weaver's 3D Calendar application: &lt;/a&gt; &lt;/p&gt; &lt;pre class="brush:css"&gt;
.scene {
   /* default font for all content, inherited by all nodes */
   -fx-font: 16pt "Amble Cn";

   /* main color palette */
   -fx-base: #AEBBD2;
   -fx-accent: #385589;
   -fx-mark-color: #3E857C;
}

.text-box {
   -fx-effect: innershadow( two-pass-box, rgba(0,0,0,0.2), 10, 0.0, 0, 2 );
   -fx-text-fill: #385589
}

#title.text-box {
   -fx-font-size: 125%;
}

.button:strong {
   -fx-text-fill: #D3DAE9;
}
&lt;/pre&gt; &lt;p&gt; If you have used JavaFX's CSS support in previous versions, you will notice some changes in how style sheets are now written. &lt;/p&gt; &lt;ul&gt; &lt;li&gt; Where you used to write Scene, TextBox, and Button, you should now write .scene, .text-box, and .button.  These are CSS class selectors, which kind of makes sense since you are selecting JavaFX control classes. &lt;/li&gt; &lt;li&gt; All JavaFX style attributes now start with the -fx extension in order to avoid conflicts with standard CSS attributes.  For example, you should now write -fx-font rather than just font. &lt;/li&gt; &lt;li&gt; This style sheet also contains an example of one of the new features in JavaFX 1.3's style sheet support: the ability to an inner shadow effect.  You can also specify a drop shadow using a similar syntax  &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Here is a table of some more new and fun attributes that can be set from style sheets.&lt;/p&gt; &lt;table style="width: 100%; border: 1px #6699CC solid;" cellspacing=0&gt;&lt;thead style="text-align: left;"&gt;&lt;tr&gt;&lt;th style="border-bottom: 1px #6699CC dotted;"&gt;Attribute&lt;/th&gt; &lt;th style="border-bottom: 1px #6699CC dotted;"&gt;Example Value(s)&lt;/th&gt; &lt;th style="border-bottom: 1px #6699CC dotted;"&gt;Works On&lt;/th&gt; &lt;th style="border-bottom: 1px #6699CC dotted;"&gt;Notes&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody style="text-align: left;"&gt; &lt;tr&gt; &lt;td style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-cursor&lt;/td&gt; &lt;td style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;crosshair | default | hand | move | text | wait&lt;/td&gt; &lt;td style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-opacity&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;0 .. 1.0&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt;&lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-rotate&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;0 .. 360&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Defaults to 0.  Not taken into account in layoutBounds&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-scale-x&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Number&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Defaults to 1.  Not taken into account in layoutBounds&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-scale-y&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Number&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Defaults to 1.  Not taken into account in layoutBounds&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-scale-z&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Number&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Defaults to 1.  Not taken into account in layoutBounds&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-translate-x&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Number&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Defaults to 0.  Not taken into account in layoutBounds&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-translate-y&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Number&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Defaults to 0.  Not taken into account in layoutBounds&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-translate-z&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Number&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Nodes&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Defaults to 0.  Not taken into account in layoutBounds&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-focus-color&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;white | #FFEEDD | #FFF&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Controls&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Color of the focus outline&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-control-inner-background&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;white | #FFEEDD | #FFF&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;TextBox, PasswordBox, ListView&lt;/td&gt;&lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-mark-color&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;blue | #0000FF | #00F&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;CheckBox, RadioButton, ScrollBar&lt;/td&gt;&lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;-fx-echo-char&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;"\u263A";&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;PasswordBox&lt;/td&gt; &lt;td  style="vertical-align: top; border-bottom: 1px #6699CC dotted;"&gt;Make your password boxes friendly!&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; 
&lt;p&gt; This is just a sample of some of the power of the new CSS support.  I haven't even touched on linear and radial gradients, deriving colors using &lt;code&gt;derive( pink, -20% )&lt;/code&gt;, the ladder function, or alternative ways of specifying colors: &lt;code&gt;rgb()&lt;/code&gt;, &lt;code&gt;rgba()&lt;/code&gt;, &lt;code&gt;hsb()&lt;/code&gt;, and &lt;code&gt;hsba()&lt;/code&gt;.  So much left to cover! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-8073420268421049627?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/8073420268421049627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/04/brief-introduction-to-styling-controls.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8073420268421049627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8073420268421049627'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2010/04/brief-introduction-to-styling-controls.html' title='A Brief Introduction to Styling Controls in JavaFX 1.3'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-2224802595081756200</id><published>2009-12-11T10:51:00.000-08:00</published><updated>2010-04-27T09:44:44.623-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='controls'/><title type='text'>Creating Custom Caspian Controls</title><content type='html'>&lt;p&gt; Creating custom controls in JavaFX is not difficult.  Creating custom controls that fit nicely with the  default Caspian theme, with its pervasive use of gradients and animation, is a little trickier.  This is  only because the utility classes and methods that make it simple lie buried within com.sun packages that  are not publicly documented.  A little digging reveals a few gems that can be used to make your controls  fit right in with the core JavaFX controls. &lt;/p&gt; &lt;p&gt; If you are observant, you will not fail to notice that this post also serves to &lt;em&gt;emphasize&lt;/em&gt; some of the many reasons that I love, and love working with, Caspian. &lt;/p&gt; &lt;blockquote&gt; &lt;strong&gt;Warning #1&lt;/strong&gt;
This post is not an introduction to writing controls in JavaFX.  I will not cover the basics of the Control - Skin - Behavior classes.  A quick and simple tutorial on this topic can be found &lt;a href="http://jonathangiles.net/blog/?p=478"&gt;here&lt;/a&gt;. &lt;/blockquote&gt; &lt;blockquote&gt; &lt;strong&gt;Warning #2&lt;/strong&gt;
All of the information in this post applies only to JavaFX 1.2.1.  One of the dangers of using non-public classes is that they can change significantly from version to version (and they certainly will for JavaFX 1.3).  If there is interest, I will update this information after JavaFX 1.3 is released. &lt;/blockquote&gt; &lt;blockquote&gt; &lt;strong&gt;Apology #1&lt;/strong&gt;
I discovered the information I'm about to present here while writing my own controls.  None of this should be considered official Caspian documentation since I do not work for Sun and I do not have access to their source code (but hopefully I will when they release the source someday).  Everything here is accurate as far as I can tell, but I apologize if I have any of the details wrong.  Hopefully someone from Sun will read this and let me know if I've made any mistakes. &lt;/blockquote&gt; &lt;blockquote&gt; &lt;strong&gt;Knock-knock Joke #1 (of 100)&lt;/strong&gt;
Knock, knock.
Who's there?
Yewben.
Yewben who?
Yewben warned, now on with the post!
&lt;/blockquote&gt; &lt;h2&gt;Caspian 101 - Colors and Gradients&lt;/h2&gt; &lt;p&gt; Caspian controls in JavaFX 1.2.1 all make use of a mixin class called &lt;code&gt;Colorable&lt;/code&gt;.  This mixin provides the ubiquitous &lt;code&gt;base&lt;/code&gt; and &lt;code&gt;accent&lt;/code&gt; properties that can be used to style the controls.  The &lt;code&gt;base&lt;/code&gt; property specifies the base color of the control while the &lt;code&gt;accent&lt;/code&gt; property specifies the accent color on those controls that support it.  ListView, for example, uses the &lt;code&gt;accent&lt;/code&gt; property to specify the color with which it draws the selection highlight in the list. &lt;em&gt;Usage of the Colorable mixin makes Caspian controls incredibly easy to style.&lt;/em&gt; &lt;/p&gt; &lt;p&gt; Two other colors are generated from the base color: the &lt;em&gt;over&lt;/em&gt; color, which is used when the mouse pointer is over the control, and the &lt;em&gt;pressed&lt;/em&gt; color, used when a control is (you guessed it) pressed.  Caspian also generates five &lt;code&gt;Paint&lt;/code&gt; objects from the base color: the body paint, the text paint, the border paint, the highlight line paint, and the shadow highlight paint.  The screenshot below shows an application that displays these various colors and paints.  It has been annotated with lines that show where they are used on a Caspian button (click the image to see a larger version). &lt;/p&gt; &lt;p&gt; If you launch the application, you can see that the button is a live control that has been scaled up to four times its normal size.  If you hover the mouse cursor over the button or click on it, you will see the control's use of the over and pressed colors as well.  &lt;em&gt;Caspian is remarkably clever about generating nice looking controls from a single color.&lt;/em&gt; &lt;/p&gt;  &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://idisk.mac.com/driverson/Public/images/CaspianColors.png"&gt;&lt;img style="display:block; text-align:center;cursor:pointer; cursor:hand;width: 640px; height: 456px;" src="http://idisk.mac.com/driverson/Public/images/CaspianColors.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;a href="http://idisk.mac.com/driverson/Public/jnlp/CaspianColors.jnlp"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 88px; height: 34px;" src="http://idisk.mac.com/driverson/Public/webstartsmall2.gif" border="0" alt="" /&gt;&lt;/a&gt; &lt;p&gt; The &lt;code&gt;Caspian&lt;/code&gt; class in the &lt;code&gt;com.sun.javafx.scene.control.caspian&lt;/code&gt; package provides easy access to these color-generating capabilities via module level functions: &lt;/p&gt; &lt;ul style="list-style: none"&gt; &lt;li&gt;&lt;code&gt;Caspian.getOverColor( base: Color )&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Caspian.getPressedColor( base: Color )&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Caspian.getBodyPaint( base: Color )&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Caspian.getTextPaint( base: Color )&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Caspian.getBorderPaint( base: Color )&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Caspian.getHighlightLinePaint( base: Color )&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Caspian.getShadowHighlightPaint( base: Color )&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt; Therefore, the first step in creating a control that fits in with the native Caspian controls is to use the Colorable mixin class and use it's base property to generate the other colors for your control. &lt;/p&gt;  &lt;pre class="brush:javafx"&gt;
public class MyControlSkin extends Skin, Colorable {

def bodyPaint = bind Caspian.getBodyPaint( base );
def overPaint = bind Caspian.getBodyPaint( Caspian.getOverColor( base ) );
def pressedPaint = bind Caspian.getBodyPaint( Caspian.getPressedColor( base ) );

var mousePressed = false;

def background = Rectangle {
   fill: bind {
       if (mousePressed) {
           pressedPaint
       } else if (background.hover) {
           overPaint
       } else {
           bodyPaint
       }
   }
   stroke: bind Caspian.getBorderPaint( base )
   blocksMouse: true
   onMousePressed: function( me: MouseEvent ) {
       mousePressed = true;
       // ... may also need to notify the Behavior ...
   }
   onMouseReleased: function( me: MouseEvent ) {
       mousePressed = false;
       // ... may also need to notify the Behavior ...
   }
}

// ... I'm too modest to show more skin ...
}
   &lt;/pre&gt; &lt;p&gt; With just a few lines of code you get nice Caspian gradients for your control plus your custom control will respond to the same &lt;code&gt;base&lt;/code&gt; style property as any core JavaFX control.  In this simple example I only changed the body paint in response to mouse events.  The core JavaFX controls also tend to update their border and highlight colors in response to hover and pressed events.  You can see this when you run the Caspian Colors application above and interact with the button. &lt;/p&gt; &lt;h2&gt;Caspian 102 - Animated State Transitions&lt;/h2&gt; &lt;p&gt; Getting the colors and gradients right is only half the battle.  Caspian also uses nice animated transitions when the control changes its state.  For instance, when a button is disabled it doesn't just flip to a disabled state, it animates the transition with a smooth fade of the button's opacity. Similar animations occur when a control gets enabled, gains or loses focus, gets hovered over, or gets clicked.  &lt;em&gt;Caspian provides a smooth and fluid user experience.&lt;/em&gt; &lt;/p&gt; &lt;p&gt; This is something I want to support in my own controls since I am a subscriber to the &lt;a href="http://graphics-geek.blogspot.com/"&gt;Chet Haas&lt;/a&gt; school of thought regarding the positive role that good, subtle animation cues can play in a user interface.  Animating all of those state transitions could become a real chore, so it's a good thing that you can cheat and take advantage of the hard work already done by the team at Sun.  Allow me to introduce you to the &lt;code&gt;States&lt;/code&gt;, &lt;code&gt;State&lt;/code&gt;, and &lt;code&gt;StateTransition&lt;/code&gt; classes. All of these little beauties are found in the &lt;code&gt;com.sun.javafx.animation.transition&lt;/code&gt; package. &lt;/p&gt; &lt;p&gt; The &lt;code&gt;State&lt;/code&gt; class allows you to define each state of your control.  The class has four properties of interest: &lt;/p&gt; &lt;table style="border-spacing: 10px"&gt; &lt;tbody&gt;&lt;tr&gt; &lt;td&gt;&lt;code&gt;id&lt;/code&gt;&lt;/td&gt;&lt;td&gt;The name of the state.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;defaultState&lt;/code&gt;&lt;/td&gt; &lt;td&gt;Should be set to &lt;code&gt;true&lt;/code&gt; if this state is the one in which your control starts.&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;active&lt;/code&gt;&lt;/td&gt; &lt;td&gt; Should be set to &lt;code&gt;true&lt;/code&gt; when this state is active.  Normally this will be bound to some property of the control.  For example, when defining the "hover" state, you would bind the state's &lt;code&gt;active&lt;/code&gt; property to the skin node's &lt;code&gt;hover&lt;/code&gt; property. &lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;&lt;code&gt;priority&lt;/code&gt;&lt;/td&gt; &lt;td&gt;An integer value that is used to establish precedence when multiple states are active at the same time.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; The &lt;code&gt;StateTransition&lt;/code&gt; class derives from &lt;code&gt;Transition&lt;/code&gt; and allows you to define the animation that will occur when your control moves from one state to another.  The properties of interest in this class are &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;fromState&lt;/code&gt;, &lt;code&gt;toState&lt;/code&gt;, and &lt;code&gt;animation&lt;/code&gt;. The &lt;code&gt;fromState&lt;/code&gt; property is a string that allows you to specify the &lt;code&gt;id&lt;/code&gt; of the state you are transitioning from.  Likewise for the &lt;code&gt;toState &lt;/code&gt;property. &lt;/p&gt; &lt;p&gt; And finally, the &lt;code&gt;States&lt;/code&gt; class keeps track of your control's states and manages the transitions between them.  The following code shows an example of the states and transitions for a custom control. &lt;/p&gt; &lt;pre class="brush:javafx"&gt;
def FAST_TRANSITION = 250ms;
def SLOW_TRANSITION = 500ms;

public class MyControlSkin extends Skin, Colorable {
override var color = base;  // color is another property defined in Colorable

def over = bind Caspian.getOverColor( base );
def pressed = bind Caspian.getPressedColor( base );

var mousePressed = false;

def states = States {
   states: [
       State { id: "disabled", active: bind control.disabled }
       State { id: "armed",    active: bind mousePressed }
       State { id: "hover",    active: bind control.hover }
       State { id: "enabled",  active: bind not control.disabled, defaultState: true }
   ]
   transitions: [
       StateTransition {
           id: "Enter-Enabled"
           toState: "enabled"
           animation: ParallelTransition {
               content: [
                   ColorTransition {
                       colorable: this
                       toValue: base
                       duration: SLOW_TRANSITION
                   }
                   FadeTransition {
                       node: bind node
                       toValue: 1.0
                       duration: FAST_TRANSITION
                   }
               ]
           }
       }
       StateTransition {
           id: "Enter-Hover"
           toState: "hover"
           animation: ColorTransition {
               colorable: this
               toValue: over
               duration: FAST_TRANSITION
           }
       }
       StateTransition {
           id: "Enter-Armed"
           toState: "armed"
           animation: ColorTransition {
               colorable: this
               toValue: pressed
               duration: FAST_TRANSITION
           }
       }
       StateTransition {
           id: "Enter-Disabled"
           toState: "disabled"
           animation: FadeTransition {
               node: bind node
               toValue: 0.33
               duration: FAST_TRANSITION
           }
       }
   ]
}

// ... Move along, nothing more to see ...
}
   &lt;/pre&gt; &lt;p&gt; True to the spirit of JavaFX's declarative syntax, all you have to do is declare your states and the transitions between them and the rest is handled for you!  You can't ask for easier animations than that. &lt;/p&gt; &lt;p&gt; In addition to those shown above, many controls also have "focused", "focused+hover", and "focused+armed" states defined as well (along with their corresponding transitions).  Note that I did not specify any priorities in the &lt;code&gt;State&lt;/code&gt; declarations above.  That is because the order in which the states are declared establishes a default priority.  You only need to specify an explicit priority if you want to override this default.  Also note that I didn't specify a &lt;code&gt;fromState&lt;/code&gt; in any of my state transitions.  I was telling the &lt;code&gt;States&lt;/code&gt; class that it can use that transition when entering the target state from any other state.  You only need to specify a &lt;code&gt;fromState&lt;/code&gt; if you want the transition to be used only when entering a state from one other particular state. &lt;/p&gt; &lt;p&gt; This code makes use of another Caspian gem, the &lt;code&gt;ColorTransition&lt;/code&gt; class which is found in the &lt;code&gt;com.sun.javafx.scene.control.caspian&lt;/code&gt; package.  It will animate the &lt;code&gt;Colorable&lt;/code&gt; mixin's &lt;code&gt;color&lt;/code&gt; property from one value to another.  This is yet another reason to make use of the &lt;code&gt;Colorable&lt;/code&gt; mixin in your code - easy color animations! &lt;/p&gt;&lt;h2&gt;The Etched Button Control&lt;/h2&gt; &lt;p&gt; This control was created because I wanted a close button for the  &lt;a href="http://jfxtras.org/portal/core/-/wiki/JFXtras/XPane"&gt;XPane&lt;/a&gt; control that looked like it was etched into the background of the title bar.  I wanted the etched button to fit in as closely as possible with the other Caspian controls as well.  The resulting control is shown in the image below. &lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__eCG_vXQUQk/SycUzOQ748I/AAAAAAAAADo/Vwz_R3_01jc/s1600-h/xetchedbuttondemo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 197px; height: 400px;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/SycUzOQ748I/AAAAAAAAADo/Vwz_R3_01jc/s400/xetchedbuttondemo.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5415319947171324866" /&gt;&lt;/a&gt;&lt;a href="http://idisk.mac.com/driverson/Public/jnlp/XEtchedButtonDemo.jnlp"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 88px; height: 34px;" src="http://idisk.mac.com/driverson/Public/webstartsmall2.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; The button features animations for over and pressed states as well as the disabled state.  There are a few other nice features as well.  The button can display text or a graphic, or both.  It can optionally apply an etched effect to its content.  The effect is similar to the one Jasper shows in a recent &lt;a href="http://fxexperience.com/2009/11/text-effects/"&gt;blog post&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;Clicking on the disable check box will disable both the etched button and the normal Caspian button.  You can also compare their over and pressed animations to verify that they are a close match. This control shows that it is possible to match the look and feel of the Caspian controls very closely by simply using some of the classes that are provided with the standard JavaFX runtime. &lt;/p&gt; &lt;h2&gt;P.S.&lt;/h2&gt; &lt;blockquote&gt; Knock, knock.
Who's there?
Yewer.
Yewer who?
Yewer afraid I was going to tell 100 knock-knock jokes weren't you!
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-2224802595081756200?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/2224802595081756200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/12/creating-custom-caspian-controls.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/2224802595081756200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/2224802595081756200'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/12/creating-custom-caspian-controls.html' title='Creating Custom Caspian Controls'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__eCG_vXQUQk/SycUzOQ748I/AAAAAAAAADo/Vwz_R3_01jc/s72-c/xetchedbuttondemo.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-602419085990672799</id><published>2009-12-02T19:42:00.000-08:00</published><updated>2009-12-03T06:04:22.421-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fll'/><title type='text'>Kids + Robots = FUN!</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__eCG_vXQUQk/Sxc8u2bqFWI/AAAAAAAAADA/O5gv6isE4SE/s1600-h/DSC_0144.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 400px; height: 268px;" src="http://3.bp.blogspot.com/__eCG_vXQUQk/Sxc8u2bqFWI/AAAAAAAAADA/O5gv6isE4SE/s400/DSC_0144.JPG" alt="" id="BLOGGER_PHOTO_ID_5410860252892108130" border="0" /&gt;&lt;/a&gt;Every year from August to December, somewhere between 90 and 99.9 percent of my free time is taken up as a volunteer helping to organize the Poudre Qualifier, a regional &lt;a href="http://www.firstlegoleauge.org/"&gt;FIRST LEGO League&lt;/a&gt; robotics tournament.  FIRST LEGO League (or FLL) is a robotics competition for teams of kids from 9 to 15 years old.   At the Poudre Qualifier, we host over 300 kids on 48 teams.  These kids have spent the last 2 months (or more) building a robot using a LEGO MindStorms robotics kit and creating a research project.  Their robot will try to do as many missions as possible on a 8-foot by 4-foot playing field in two and a half minutes.&lt;/div&gt;
Of all of the &lt;a href="http://www.usfirst.org/"&gt;FIRST&lt;/a&gt; (For Inspiration and Recognition of Science and Technology) robotics competitions, FLL is unique in that the robot is completely autonomous.  It must be smart enough to go out and accomplish its missions and return to base all on its own.  If the kids have to rescue the robot out on the table they incur a penalty.  Here is a &lt;a href="http://gallery.mac.com/driverson#100079"&gt;video&lt;/a&gt; of a robot doing its thing during a past competition.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__eCG_vXQUQk/Sxc87RLck3I/AAAAAAAAADI/vAgpSZH6YmM/s1600-h/IMG_4189.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 268px;" src="http://3.bp.blogspot.com/__eCG_vXQUQk/Sxc87RLck3I/AAAAAAAAADI/vAgpSZH6YmM/s400/IMG_4189.JPG" alt="" id="BLOGGER_PHOTO_ID_5410860466230301554" border="0" /&gt;&lt;/a&gt;The kids also do a research project based on the theme of that year's competition.  Recent themes have included nanotechnology, energy, and transportation.  At the tournaments, a team presents their research project to a panel of experts.  Teams are also judged on a technical interview, where they answer questions about their robot's design, construction, and programming; as well as a teamwork exercise to test their ability to solve problems as a team.


&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__eCG_vXQUQk/Sxc9KV4I85I/AAAAAAAAADQ/YooRfYiY9sA/s1600-h/IMG_4220.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: right; cursor: pointer; width: 400px; height: 300px;" src="http://3.bp.blogspot.com/__eCG_vXQUQk/Sxc9KV4I85I/AAAAAAAAADQ/YooRfYiY9sA/s400/IMG_4220.JPG" alt="" id="BLOGGER_PHOTO_ID_5410860725189538706" border="0" /&gt;&lt;/a&gt;With well over 100,000 kids on over 15,000 teams all over the world, FLL is a terrific program for getting young people interested in science and technology in an exciting and fun way.  By talking to and learning from experts, kids find out that they can use science and technology to make a positive difference in their world.  They also learn many valuable life skills for a future engineer or scientist: teamwork, public speaking, being interviewed, working and performing under the pressure of deadlines, and most of all, how to compete while treating teammates and opponents with respect and courtesy.  That is a concept called &lt;span style="font-style: italic;"&gt;Gracious Professionalism&lt;/span&gt; and it is the core value of FIRST.
&lt;/div&gt;
What FIRST really needs is volunteers who want to share their passion for science and technology with a new generation of enthusiasts.  So my request to you, dear reader, is to find a &lt;a href="http://usfirst.org/roboticsprograms/fll/content.aspx?id=762"&gt;FIRST event&lt;/a&gt; near you and volunteer!  Be a referee, a judge, a coach... whatever you want.  Just get involved!  It will only cost you a few hours or a day, and I guarantee that you will have an amazing time.  All of the FIRST events are free and open to the public, so you can also come out and watch these kids having a great time solving difficult problems.

If you live here in Colorado, we have the state championship tournament coming up.  Information can be found &lt;a href="http://fll.coloradofirst.org/"&gt;here&lt;/a&gt;.  And by the way, more photos from our tournament can be found &lt;a href="http://picasaweb.google.com/PoudreFLL"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-602419085990672799?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/602419085990672799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/12/kids-robots-fun.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/602419085990672799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/602419085990672799'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/12/kids-robots-fun.html' title='Kids + Robots = FUN!'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/__eCG_vXQUQk/Sxc8u2bqFWI/AAAAAAAAADA/O5gv6isE4SE/s72-c/DSC_0144.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-6490195207632975927</id><published>2009-10-02T19:51:00.001-07:00</published><updated>2009-10-02T19:53:52.081-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><title type='text'>JavaFX Interview</title><content type='html'>The folks at Sun were kind enough to ask me to visit with them about one of my favorite subjects: &lt;a href="http://www.javafx.com"&gt;JavaFX&lt;/a&gt;.&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;a href="http://blogs.sun.com/chhandomay/entry/interview_with_javafx_developer_dean"&gt;Check it out&lt;/a&gt; if you're so inclined.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-6490195207632975927?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/6490195207632975927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/10/javafx-interview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/6490195207632975927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/6490195207632975927'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/10/javafx-interview.html' title='JavaFX Interview'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-1161392234014961433</id><published>2009-08-23T14:51:00.000-07:00</published><updated>2009-08-23T21:50:09.439-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><title type='text'>Flex 4 vs JavaFX 1.2: Dance Battle</title><content type='html'>&lt;p&gt;I make it a point to follow Chet Hass on his &lt;a href="http://graphics-geek.blogspot.com/"&gt;Codedependent blog&lt;/a&gt;. He always has something interesting to say about features in Flex.  Even though I rarely use Flex, he often demonstrates interesting animations or visual effects.&lt;/p&gt;&lt;p&gt;His latest &lt;a href="http://graphics-geek.blogspot.com/2009/08/video-transform-effects-in-flex-4.html"&gt;post&lt;/a&gt; talks about the new transform effects in the upcoming Flex 4.  Specifically he uses move (translate), rotate, and scale transforms to manipulate a control and make it twirl gracefully across the screen.  Ok, that's a stretch, but I had to work the dance thing in here somewhere.  You may want to watch his demonstration video now.&lt;/p&gt;&lt;p&gt;When I saw the MXML code that Chet was using for his demo, I was struck by how similar it is to the way I would accomplish the same thing in JavaFX.  Below is Chet's Flex 4 demo code:&lt;/p&gt;&lt;pre class="brush:xml"&gt;
&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:d="http://ns.adobe.com/fxg/2008/dt"
    xmlns:s="library://ns.adobe.com/flex/spark"&amp;gt;

    &amp;lt;fx:Declarations&amp;gt;
        &amp;lt;s:Parallel id="transformer" target="{button}"&amp;gt;
            &amp;lt;s:Move xFrom="50" xTo="150" autoCenterTransform="true"/&amp;gt;
            &amp;lt;s:Rotate angleFrom="0" angleTo="360" autoCenterTransform="true"/&amp;gt;
            &amp;lt;s:Scale scaleXFrom="1" scaleXTo="2" autoCenterTransform="true"/&amp;gt;
        &amp;lt;/s:Parallel&amp;gt;
    &amp;lt;/fx:Declarations&amp;gt;

    &amp;lt;s:Button id="button" x="50" y="100" label="Transform Me"
        click="transformer.play()"/&amp;gt;
&amp;lt;/s:Application&amp;gt;
&lt;/pre&gt;&lt;p&gt;And here is the same thing in JavaFX 1.2 formatted to emphasize the similarity:&lt;/p&gt;&lt;pre class="brush:javafx"&gt;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.animation.transition.*;

var transformer:ParallelTransition;

def button = Button { layoutX: 50, layoutY: 100, text: "Transform Me"
    action: function() { transformer.playFromStart() }
}

transformer = ParallelTransition {
    node: button
    content: [
        RotateTransition { fromAngle: 0, toAngle: 360 }
        TranslateTransition { fromX: 0, toX: 100 }
        ScaleTransition { fromX: 1, toX: 2 }
    ]
}

Scene {
    width: 400
    height: 300
    content: button
}
&lt;/pre&gt;&lt;p&gt;And here is the JavaFX application:&lt;/p&gt;&lt;script src="http://dl.javafx.com/1.2/dtfx.js"&gt;&lt;/script&gt;&lt;script&gt;javafx({archive: "http://idisk.mac.com/driverson/Public/jnlp/ControlTransform.jar", width: 400, height: 300, code: "controltransform.Main2", name: "ControlTransform" });&lt;/script&gt;&lt;p&gt;Some points of comparison:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;MXML and XAML always lose me at &lt;code&gt;xmlns&lt;/code&gt;.  I'll take &lt;code&gt;import&lt;/code&gt; statements any day, although most IDEs will manage XML namespaces and import statements for you.  In general I simply prefer writing my declarative code in a programming language rather than a data interchange format - no matter how &lt;em&gt;Flex&lt;/em&gt;-ible it is.&lt;/li&gt;&lt;li&gt;Deployment in a browser: Flex wins.  Period.  The deployment team at Sun has done a lot of work to narrow this particular gap, but Flash is still everywhere and it just works.  I fully expect some significant number of people to have trouble running the applet above.  And applets still flicker when the browser scrolls.  Not serious, just annoying.&lt;/li&gt;&lt;li&gt;Flex has a slight edge in brevity, I think.  But in return for some extra characters, you get all the benefits of static typing.  The JavaFX compiler can catch syntax errors for you and IDEs will flag them immediately without having to run the program first.  IDEs can also support much more robust refactoring and code completion (at least in theory, hopefully the Netbeans JavaFX plugin will finally get some more attention soon).&lt;/li&gt;&lt;li&gt;It seems odd that previous versions of Flex couldn't display text on a rotating control.  And even these new transform effects have some gotchas to watch out for; like having to set autoCenterTransform on all the effects since they manipulate the same data under the covers.  Not that JavaFX doesn't have some gotchas, but for the most part the foundation is solid.  This kind of thing always surprises me when I hear about it.  Flex is supposed to be way more mature, after all.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__eCG_vXQUQk/SpIC3vrqx5I/AAAAAAAAACI/xt4zze2bCcs/s1600-h/mobile_control_transform.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 288px; height: 400px;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/SpIC3vrqx5I/AAAAAAAAACI/xt4zze2bCcs/s400/mobile_control_transform.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5373360462122108818" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The JavaFX code above works on mobile devices (like the HTC Touch Diamond shown to the right) as well as on the desktop and in a browser.  I'm just saying.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Twirling controls aside, you obviously can't make a definitive comparison of two competing technologies based on such a simple piece of sample code.  I found it interesting how similar the code actually was between the two platforms.  Hopefully you did too.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-1161392234014961433?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/1161392234014961433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/08/flex-4-vs-javafx-12-dance-battle.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/1161392234014961433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/1161392234014961433'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/08/flex-4-vs-javafx-12-dance-battle.html' title='Flex 4 vs JavaFX 1.2: Dance Battle'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__eCG_vXQUQk/SpIC3vrqx5I/AAAAAAAAACI/xt4zze2bCcs/s72-c/mobile_control_transform.png' height='72' width='72'/><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-6437137098929514074</id><published>2009-08-05T23:19:00.000-07:00</published><updated>2009-08-06T06:13:30.657-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='miglayout'/><title type='text'>Steve at the SDForum</title><content type='html'>&lt;p&gt;My good friend and co-author Stephen Chin has posted a screencast and slides from a talk he gave recently at the SDForum.  Here is the &lt;a href="http://steveonjava.com/2009/08/05/watch-widgetfx-and-jfxtras-at-the-sdforum/"&gt;link&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;By the way, if you want to reproduce his greeting to the group using MigLayout, the code would look like this:&lt;/p&gt;&lt;pre class="brush:javafx"&gt;
ResizableScene {
    width: 400
    height: 100
    fill: Color.GRAY
    content: MigLayout {
        constraints: "fill"
        content: [
            ResizableRectangle {
                effect: DropShadow{}
                fill: LinearGradient {
                    stops: [
                        Stop { color: Color.PURPLE }
                        Stop { color: Color.BLACK, offset: 1 }
                    ]
                }
                layoutInfo: nodeConstraints( "pos 20 20 container.x2-20 container.y2-20" )
            }
            Text {
                content: "Welcome SDForum Java SIG"
                font: Font.font( null, FontWeight.BOLD, 18 )
                fill: Color.WHITE
                layoutInfo: nodeConstraints( "center" )
            }
        ]
    }
}
&lt;/pre&gt;&lt;p&gt;No need for a Deck or a Border, MigLayout is all you need in this case.  You can just use absolute positioning to create the 20 pixel border around the purple rectangle.  And thanks to the container-relative positioning of MigLayout, the rectangle will resize with the scene just as in Steve's original demo.&lt;/p&gt;&lt;p&gt;Great presentation, Steve!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-6437137098929514074?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/6437137098929514074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/08/my-good-friend-and-co-author-stephen.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/6437137098929514074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/6437137098929514074'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/08/my-good-friend-and-co-author-stephen.html' title='Steve at the SDForum'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-8691876028467645232</id><published>2009-06-22T19:32:00.000-07:00</published><updated>2009-10-02T11:45:26.401-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><category scheme='http://www.blogger.com/atom/ns#' term='miglayout'/><title type='text'>MigLayout for JavaFX Reloaded</title><content type='html'>&lt;p&gt;
JavaFX 1.2 brought many changes to the layout system in the JavaFX runtime.  MigLayout for JavaFX has been fully updated to take advantage of these changes.  The updated version is part of JFXtras v0.5 that was &lt;a href="http://steveonjava.com/2009/06/22/jfxtras-0-5-release-announcement/"&gt;released&lt;/a&gt; a short time ago.
&lt;/p&gt;   &lt;h2&gt;Getting Started with MigLayout&lt;/h2&gt;The first thing you need to do is download&lt;a href="http://code.google.com/p/jfxtras/downloads/list"&gt; JFXtras&lt;/a&gt; version 0.5 and add the JFXtras-0.5.jar file to your project.  You will also need to obtain the MigLayout v3.7 (for Java) jar file.  This jar file is included in the JFXtras source distribution (in the lib directory) or you can get it directly from the&lt;a href="http://www.migcalendar.com/miglayout/versions/3.7/miglayout-3.7.jar"&gt; MigLayout&lt;/a&gt; site. One other thing you should always keep handy is the MigLayout &lt;a href="http://migcalendar.com/miglayout/cheatsheet.html"&gt;cheat sheet&lt;/a&gt;.
&lt;h3&gt;Simple Test&lt;/h3&gt; There are several examples of MigLayout usage included in the source distribution of JFXtras. You will find them in the tests/org/jfxtras/scene/layout directory. Let's start by taking a look at one of them: MigSimpleTest.fx.  The code for this example is listed below.

&lt;pre class="brush:javafx"&gt;
package org.jfxtras.scene.layout;

import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import org.jfxtras.scene.ResizableScene;

Stage {
    title: "Mig Centering Test"
    scene: ResizableScene {
        width: 200
        height: 200
        fill: Color.PINK

        content: MigLayout {
            constraints: "fill"
            width: 100
            height: 100
            layoutInfo: MigNodeLayoutInfo {
                constraints: "center"
            }
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;This example shows the use of the &lt;code&gt;layoutInfo&lt;/code&gt; variable that was added to the &lt;code&gt;Node&lt;/code&gt; base class in JavaFX v1.2.  The &lt;code&gt;LayoutInfo&lt;/code&gt; class was created to provide a generic way of specifying layout constraints for any node in the scene graph.  A subclass of &lt;code&gt;LayoutInfo&lt;/code&gt; called &lt;code&gt;MigNodeLayoutInfo&lt;/code&gt; is used to hold the specialized constraints string for a node in a MigLayout container.  In the example above, the only node constraint specified is &lt;code&gt;center&lt;/code&gt; which will keep the rectangle centered in the container.
&lt;/p&gt;&lt;blockquote&gt;Note: The node constraints string in the JavaFX version of MigLayout has the same syntax as the component constraints in the Java version.  In JavaFX, we deal in nodes instead of components.  See the MigLayout &lt;a href="http://migcalendar.com/miglayout/cheatsheet.html"&gt;cheat sheet&lt;/a&gt; for details.
&lt;/blockquote&gt;In this particular case, the rectangle also stays centered in the scene thanks to the use of a JFXtras&lt;code&gt; ResizableScene&lt;/code&gt; which automatically passes resize information on to the MigLayout container.
&lt;h3&gt;LayoutInfo Convenience Functions&lt;/h3&gt;Setting the layoutInfo variable with a new &lt;code&gt;MigNodeLayoutInfo&lt;/code&gt; class every time can get tedious. There are two convenience functions in the MigLayout class that reduce the amount of typing required.  The first is the &lt;code&gt;nodeConstraints&lt;/code&gt; function.  It has the following signature:
&lt;pre&gt;
public function nodeConstraints( constraints:String ):MigNodeLayoutInfo
&lt;/pre&gt;&lt;p&gt;    This function simply constructs and returns a new &lt;code&gt;MigNodeLayoutInfo&lt;/code&gt; object with the given constraints string.  This is a module-level function in the MigLayout.fx file and therefore needs to be imported like this:
&lt;/p&gt;&lt;pre&gt;import org.jfxtras.scene.layout.MigLayout.*;
&lt;/pre&gt;Using this new function, you might rewrite the &lt;code&gt;Rectangle&lt;/code&gt; literal above as:
&lt;pre class="brush:javafx"&gt;Rectangle {
    width: 100
    height: 100
    layoutInfo: nodeConstraints( "center" )
}
&lt;/pre&gt;The second convenience function is named &lt;code&gt;migNode&lt;/code&gt; and is used to associate a constraints string with a scene graph node that was created at some other point in the program.  The function's signature is:
&lt;pre&gt;public function migNode( node:Node, constraints:String ):Node
&lt;/pre&gt;This function is also a module-level function located in the MigLayout.fx file and therefore can be imported into your program using the same &lt;code&gt;import&lt;/code&gt; statement as the one given above for the nodeConstraints function.  Rewriting our simple test code to use this function might look something like this:
&lt;pre class="brush:javafx"&gt;package org.jfxtras.scene.layout;

import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import org.jfxtras.scene.ResizableScene;
import org.jfxtras.scene.layout.MigLayout.*;

var blackRect = Rectangle {
    width: 100
    height: 100
}

Stage {
    title: "Mig Centering Test"
    scene: ResizableScene {
        width: 200
        height: 200
        fill: Color.PINK

        content: MigLayout {
            constraints: "fill"
            content: [
                migNode( blackRect, "center" )
               // ... other nodes are added here ...
            ]
        }
    }
}
&lt;/pre&gt;This form is recommended when you have a non-trivial scene graph declaration.  It allows you to easily see what nodes are being managed by your container and what their constraints are.
&lt;h2&gt;Migrating from a Previous Version&lt;/h2&gt;&lt;p&gt;   Those who have used MigLayout in JavaFX 1.0 or 1.1 will notice a few changes:
&lt;/p&gt; &lt;ul&gt;&lt;li&gt;The layout constraints are now set using the &lt;code&gt;constraints&lt;/code&gt; variable instead of the &lt;code&gt;layout&lt;/code&gt; variable.  The old name conflicts with the new layout facilities in JavaFX 1.2.
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;fitParent&lt;/code&gt; variable has been removed from the MigLayout class.  If you want your MigLayout container to expand to fill the entire scene, just use JFXtras' ResizeableScene class as above.
&lt;/li&gt;
&lt;li&gt;The MigNode class has been removed since it is no longer needed.  The new &lt;code&gt;layoutInfo&lt;/code&gt; variable in the &lt;code&gt;Node&lt;/code&gt; class gives us a way to associate constraints with a node.
&lt;/li&gt;
&lt;li&gt;Since the MigNode class (and therefore MigNode.fx) no longer exists, the migNode convenience function was moved to the MigLayout.fx file.
&lt;/li&gt; &lt;/ul&gt; &lt;h2&gt;Wrap Up&lt;/h2&gt;&lt;p&gt;     The MigLayout container released in JFXtras 0.5 was much improved for JavaFX 1.2.  It not only incorporates the new layout system, but several bugs were fixed and it is now compatible with the latest release of MigLayout.  There are more details about this updated version of MigLayout for JavaFX in the just-released &lt;a href="http://www.amazon.com/gp/product/1430218754?ie=UTF8&amp;amp;tag=pleassoftw-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1430218754"&gt;Pro JavaFX™ Platform&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=pleassoftw-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1430218754" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt; book of which I was fortunate enough to be a co-author.
&lt;/p&gt;&lt;p&gt;    Lastly, Amy Fowler has also updated her wonderful &lt;a href="http://weblogs.java.net/blog/aim/archive/2009/07/bounds_unleashe.html"&gt;article&lt;/a&gt; on JavaFX layout. I highly recommend it!
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-8691876028467645232?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/8691876028467645232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/06/miglayout-for-javafx-reloaded.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8691876028467645232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8691876028467645232'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/06/miglayout-for-javafx-reloaded.html' title='MigLayout for JavaFX Reloaded'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-7713593010036535321</id><published>2009-06-12T00:47:00.000-07:00</published><updated>2009-06-13T10:33:19.245-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><title type='text'>Creating XYCharts in JavaFX</title><content type='html'>&lt;i&gt;Note: This entry is the second in a series on the new chart components in JavaFX 1.2. Like the &lt;a href="http://pleasingsoftware.blogspot.com/2009/06/this-is-test.html"&gt;first entry&lt;/a&gt;, this one is also an excerpt from the upcoming "Pro JavaFX Platform" book written by Jim Weaver, Stephen Chin, Weiqi Gao, and myself. You can find out more by clicking on the book image to the right of this page. -- Dean&lt;/i&gt;

The remaining five types of charts are all meant to work with XY data. These charts are all subtypes of the XYChart base class. As such they are rendered against a background grid and include a horizontal and vertical axis.

&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Bar Chart&lt;/span&gt;
A bar chart plots data from a sequence of BarChart.Series objects. Each series contains a sequence of BarChart.Data objects that each contains the value (the height of the bar) and the category that the bar belongs to. Therefore a bar chart data object can be declared as shown in the following code snippet.
&lt;pre class="brush:javafx;gutter:false"&gt;
BarChart.Data {
  category: “Category Name”
  value: 42
}
&lt;/pre&gt;
The horizontal axis for the bar chart is of type CategoryAxis. The public categories sequence variable must contain category names that match those given to the BarChart.Data objects. The vertical axis of a bar chart is a ValueAxis. As of JavaFX 1.2, the only concrete implementation of a ValueAxis is the NumberAxis class. A NumberAxis represents a range of numeric values and has variables that allow for control over the appearance and the number of tick marks and label that are shown along the axis. A typical axis declaration for a bar chart is shown in the listing below. The code declares a category axis with three categories and a number axis that ranges from 0 to 100 with a labeled tick mark every 20 units for a total of 6 labels (counting the label at 0).
&lt;pre class="brush:javafx;gutter:false"&gt;
BarChart {
  categoryAxis: CategoryAxis {
    categories: [ "Category 1", "Category 2", "Category 3" ]
  }
  valueAxis: NumberAxis {
    label: "Y Axis"
    upperBound: 100
    tickUnit: 20
  }
}
&lt;/pre&gt;
The next listing shows a complete program that displays a bar chart showing the sales report for Acme, Incorporated from 2007 to 2009. The data to be displayed in the chart is defined at the top. Each year will be it’s own category. The data values are generated from the sales figures for each of the three products over the three different years. The vertical axis is a NumberAxis that shows the number of units sold and is defined such that it can accommodate the largest sales value. It will have a labeled tick mark every 1,000 units starting at 0 and ending at 3,000. This gives a total of four labels along the vertical axis. The public data variable accepts the sequence of BarChart.Series objects to plot. Each BarChart.Series object also has its own public data variable, which accepts a sequence of BarChart.Data objects. A for expression is used to generate the actual sequence of BarChart.Data objects from the sequences defined at the beginning of the listing. Finally, the categoryGap variable (highlighted) is used to increase the spacing between the yearly data to provide more differentiation between the categories. The complete source code is in the BarChartIntro.fx file from the ChartIntro example project.
&lt;pre class="brush:javafx;gutter:false"&gt;
def years = [ "2007", "2008", "2009" ];
def anvilsSold = [  567, 1292, 2423 ];
def skatesSold = [  956, 1665, 2559 ];
def pillsSold = [ 1154, 1927, 2774 ];

Stage {
  title: "Bar Chart Intro"
  scene: Scene {
    content: [
      BarChart {
        title: "Acme, Inc. Sales Report"
        titleFont: Font { size: 24 }
        categoryGap: 25
        categoryAxis: CategoryAxis {
          categories: years
        }
        valueAxis: NumberAxis {
          label: "Units Sold"
          upperBound: 3000
          tickUnit: 1000
        }
        data: [
          BarChart.Series {
            name: "Anvils"
            data: for (j in [0..&amp;lt;sizeof years]) {
              BarChart.Data {
                category: years[j]
                value: anvilsSold[j]
              }
            }
          }
          BarChart.Series {
            name: "Rocket Skates"
            data: for (j in [0..&amp;lt;sizeof years]) {
              BarChart.Data {
                category: years[j]
                value: skatesSold[j]
              }
            }
          }
          BarChart.Series {
            name: "Earthquake Pills"
            data: for (j in [0..&amp;lt;sizeof years]) {
              BarChart.Data {
                category: years[j]
                value: pillsSold[j]
              }
            }
          }
        ]
      }
    ]
  }
}
&lt;/pre&gt;
Caution If you forget to declare the axes for a XYChart then no data will show up on your chart. This is one of the few times you cannot rely on the default values of the chart. In the previous example, if the CategoryAxis or the ValueAxis were left undeclared then no bars would have been drawn on the sales chart.

The resulting chart is shown in below. Much like the pie charts, the default look for bar charts is a clean, modern look with lighting and shading affects built right in. There is also a drop-in replacement for BarChart named BarChart3D, which can be used to give the chart a 3-dimensional appearance.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/__eCG_vXQUQk/SjH-ZGXO05I/AAAAAAAAABw/dYZyxTrr_l4/s1600-h/barchart.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 343px;" src="http://2.bp.blogspot.com/__eCG_vXQUQk/SjH-ZGXO05I/AAAAAAAAABw/dYZyxTrr_l4/s400/barchart.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346333939823727506" /&gt;&lt;/a&gt;

&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Line and Area Charts&lt;/span&gt;
A line chart can be constructed using the LineChart class. It can show one or more LineChart.Series objects each of which contain a sequence of LineChart.Data objects. This pattern should be familiar now. It is the same for an AreaChart, whose data variable accepts a sequence of AreaChart.Series objects each of which contain a sequence of AreaChart.Data objects. We will use these charts to plot the mathematical functions sine and cosine as shown here:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__eCG_vXQUQk/SjH_B3eO9OI/AAAAAAAAAB4/rLkFlIot-ss/s1600-h/lineareachart.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 179px;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/SjH_B3eO9OI/AAAAAAAAAB4/rLkFlIot-ss/s400/lineareachart.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346334640201200866" /&gt;&lt;/a&gt;

The source code for this program can be found in the LineAreaChartIntro.fx file in the ChartIntro example project. To plot the sine and cosine functions, we need to create a horizontal axis that goes from 0 to 2π and a vertical axis that goes from -1.0 to 1.0. The listing below shows two functions that generate these NumberAxis objects. You may be wondering why these axis objects are being generated by functions rather than just declaring them as variables and reusing them for both charts. The answer lies in the fact that the Axis base class is derived from Node. Like any Node, an Axis can only appear in the scene graph once. Since we are not allowed share these axis objects between our two charts, we must write functions that create new axis objects each time they are called.

&lt;pre class="brush:javafx;gutter:false"&gt;
/**
 * An x axis that goes from 0 to 2*PI with labels every PI/2 radians.
 * The labels are formatted to display on 2 significant digits.
 */
function createXAxis() {
  NumberAxis {
    label: "Radians"
    upperBound: 2 * Math.PI
    tickUnit: Math.PI / 2
    formatTickLabel: function(value) {
      "{%.2f value}"
    }
  }
}

/**
 * A y axis that that goes from -1 to 1 with labels every 0.5 units.
 */
function createYAxis() {
  NumberAxis {
    upperBound: 1.0
    lowerBound: -1.0
    tickUnit: 0.5
  }
}
&lt;/pre&gt;
The createXAxis function illustrates the use of the formatTickLabel function variable to format the values that will be used as tick labels on the axis. In this case, we format the numbers to keep only two significant digits after the decimal point. In addition, the code to create the y-axis shows how to set a non-zero lower bound for an axis.

The next code listing shows the code that creates the LineChart object and adds it to the scene. This code follows the same pattern we’ve seen before. LineChart has a public data variable that takes a sequence of LineChart.Series objects. In this case we have one sequence for the sine wave and one for the cosine wave. Within each series, the data sequence is populated by a range expression that generates the LineChart.Data objects, which correspond to the points along the sine or cosine curves. Since we can’t show any data without our axes, we use the createXAxis and createYAxis functions shown earlier. Normally a line chart will plot a symbol at each data point – a circle, triangle, square or some such shape. The lines of the chart then connect these symbols. In this case, we have so many data points that the symbols would obscure the lines. So we tell the chart not to generate the symbols by setting the showSymbols variable to false. Another default setting for line charts is for the data to cast a shadow on the chart’s background. Since this makes the lines of this particular chart more difficult to see we turn off the drop shadow by setting dataEffect to null.
&lt;pre class="brush:javafx;gutter:false"&gt;
function createAreaChart() {
  AreaChart {
    title: "Area Chart"
    translateX: 550
    xAxis: createXAxis()
    yAxis: createYAxis()
    data: [
      AreaChart.Series {
        name: "Sine Wave"
        data: for (rads in [0..2*Math.PI step 0.01]) {
          AreaChart.Data {
            xValue: rads
            yValue: Math.sin( rads )
          }
        }
      }
      AreaChart.Series {
        name: "Cosine Wave"
        data: for (rads in [0..2*Math.PI step 0.01]) {
          AreaChart.Data {
            xValue: rads
            yValue: Math.cos( rads )
          }
        }
      }
    ]
  }
}
&lt;/pre&gt;
&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Scatter and Bubble Charts&lt;/span&gt;
Scatter and bubble charts are just like the other three XY charts we’ve looked at.  The classes, ScatterChart and BubbleChart respectively, have a public data variable that accepts a sequence of series object.  You guessed it: ScatterChart.Series and BubbleChart.Series.  Each of these series has a public data variable that holds a sequence of their respective data objects: ScatterChart.Data and BubbleChart.Data.  However, the BubbleChart.Data class also contains a radius variable that is used to set the size of the bubble for each data point.  The figure below shows an example of a scatter chart and a bubble chart.  In this program, the charts are just plotting the distribution of points generated by the javafx.util.Math.random function.  Using the JavaFX math functions allow our code to remain portable to mobile devices.  We will discuss that more in Chapter 10.    The radius of the bubbles in the bubble chart is determined by the order in which the points are generated.  The bubbles start small and get bigger as points are generated.  You can roughly tell the order in which each point was generated.  This is simply an interesting way to view the randomness of the random number generator.  The code for this program is found in ScatterBubbleChartIntro.fx in the ChartIntro example project.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/__eCG_vXQUQk/SjIC-aqVwZI/AAAAAAAAACA/l6G8xF0EFNY/s1600-h/scatterbubble.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 177px;" src="http://3.bp.blogspot.com/__eCG_vXQUQk/SjIC-aqVwZI/AAAAAAAAACA/l6G8xF0EFNY/s400/scatterbubble.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346338978974253458" /&gt;&lt;/a&gt;

The code to create a scatter chart is pretty straightforward.  First we define a function that creates a number axis that ranges from 0.00 to 1.00 with labels every 0.25 units.  The tick labels are once again formatted to keep only 2 digits after the decimal points.  The createAxis function itself takes a String parameter to use as the label for the number axis.  This allows the reuse of the function to create labels for both the x- and y-axes.  The ScatterChart has only one data series and that series contains a sequence of 100 data objects whose x and y values are generated randomly.  The only extra bit of customization done here is to hide the legend since we do only have the one data series.

&lt;pre class="brush:javafx;gutter:false"&gt;
/**
 * An x axis that goes from 0 to 1.0 and displays labels every 0.25 units.
 * The labels are formatted to display on 2 significant digits.
 */
function createAxis( label:String ) {
  NumberAxis {
    label: label
    upperBound: 1.0
    tickUnit: 0.25
    formatTickLabel: function(value) {
      "{%.2f value}"
    }
  }
}

/**
 * Create a scatter chart that displays random points.
 */
function createScatterChart() {
  ScatterChart {
    title: "Scatter Chart"
    legendVisible: false
    xAxis: createAxis( "X Axis" )
    yAxis: createAxis( "Y Axis" )
    data: [
      ScatterChart.Series {
        data: for (i in [1..100]) {
          ScatterChart.Data {
            xValue: Math.random()
            yValue: Math.random()
          }
        }
      }
    ]
  }
}
&lt;/pre&gt;
The source code that creates the bubble chart, shown below, is very similar.  The big difference here is the radius variable of the BubbleChart.Data class.  This is unique to the bubble chart data and, as previously mentioned, allows us to control the size of the bubble on the plot.  The radius values scale based on the axes of the plot.  In our case the axes both go from 0.0 to 1.0.  Therefore a bubble radius of 0.5 would create a bubble that filled the entire chart (if centered) since its diameter would be 1.0.  If our axes went from 0 to 10 instead, then a bubble with a radius of 0.5 would be smaller, taking up only 1/10 of the chart.  The code in the listing below creates bubbles whose radius varies from 0.001 to 0.1 as the value of i goes from 1 to 100.
&lt;pre class="brush:javafx;gutter:false"&gt;
function createBubbleChart() {
  BubbleChart {
    title: "Bubble Chart"
    legendVisible: false
    translateX: 550
    xAxis: createAxis( "X Axis" )
    yAxis: createAxis( "Y Axis" )
    data: [
      BubbleChart.Series {
        data: for (i in [1..100]) {
          BubbleChart.Data {
            xValue: Math.random()
            yValue: Math.random()
            radius: i / 1000.0
          }
        }
      }
    ]
  }
}
&lt;/pre&gt;
&lt;i&gt;This concludes part two of this series.  In the third and final excerpt, we will take a look at adding interaction to your charts and all of the customization options available in the chart API.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-7713593010036535321?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/7713593010036535321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/06/creating-xycharts-in-javafx.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/7713593010036535321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/7713593010036535321'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/06/creating-xycharts-in-javafx.html' title='Creating XYCharts in JavaFX'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/__eCG_vXQUQk/SjH-ZGXO05I/AAAAAAAAABw/dYZyxTrr_l4/s72-c/barchart.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-3333188251606187972</id><published>2009-06-09T11:30:00.000-07:00</published><updated>2009-06-10T01:41:58.770-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><title type='text'>Creating Charts in JavaFX</title><content type='html'>&lt;span style="font-style: italic;"&gt;Note: This entry is an excerpt from the upcoming "Pro JavaFX Platform" book written by Jim Weaver, Stephen Chin, Weiqi Gao, and myself.  You can find out more by clicking on the book image to the right of this page.  -- Dean

&lt;/span&gt;The chart components included in JavaFX give developers an easy way to let the users of their applications visualize a wide variety of data.  There are six kinds of charts supported in JavaFX 1.2:
&lt;ul&gt;&lt;li&gt;An Area Chart displays quantitative data like a line chart but with the area between the line and the horizontal axis shaded.  Good for comparing the magnitude of two or more series of data.&lt;/li&gt;&lt;li&gt;The Bar Chart is a good way to show data in a way that makes it easy to see how the data changes over time or under a set of different conditions.  The data is represented as rectangular area or, in the case of a 3D chart, a cubic volume whose height corresponds to the value of the data point being displayed.&lt;/li&gt;&lt;li&gt;Bubble Charts plot data points on a 2-dimensional grid and have the extra ability to display the relative magnitudes of the data by controlling the diameter of the point (or bubble) displayed at each XY coordinate.&lt;/li&gt;&lt;li&gt;A Line Chart is a simple way to display 2-dimensional data points where each point is connected to the next point in the data series by a line.&lt;/li&gt;&lt;li&gt;Pie Charts are typically used to display the relative percentages of a series of values on a circle.  The value of each piece of data, as a percentage of the total, dictates how much of the circle’s area it takes up.  In other words, the chart shows how big a slice of the pie each value represents.&lt;/li&gt;&lt;li&gt;The Scatter Chart is used to plot the points of one or more series of data.  These charts are typically used to show the correlation (or not) of the data by comparing how the data points are clustered (or not).
&lt;/li&gt;&lt;/ul&gt;One of these things is not like the others.  Other than the pie chart, all of these charts are meant to handle 2-dimensional data points as pairs of XY coordinates.  The class hierarchy, shown below, of the chart components in the javafx.scene.chart package reflects this fact.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__eCG_vXQUQk/Si9p1GNf0CI/AAAAAAAAABY/s3HClqc8ROA/s1600-h/chartHierarchy.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/Si9p1GNf0CI/AAAAAAAAABY/s3HClqc8ROA/s400/chartHierarchy.png" alt="" id="BLOGGER_PHOTO_ID_5345607643633274914" border="0" /&gt;&lt;/a&gt;
The ChartDemo program, which is included with the Chapter 5 examples and is shown below, displays an example of each of these types of charts.  In the next sections we’ll take a look at how to use each of these different charts and the many different ways that they can be customized.

&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://idisk.mac.com/driverson/Public/jnlp/ChartDemo.jnlp"&gt;&lt;img style="cursor: pointer; width: 400px; height: 337px;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/Si9sAOL7zVI/AAAAAAAAABg/H328tZzrDu8/s400/chartdemo.png" alt="" id="BLOGGER_PHOTO_ID_5345610033776020818" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Click the image to launch the demo&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;a href="http://idisk.mac.com/driverson/Public/jnlp/ChartDemo.jnlp"&gt;&lt;/a&gt;
&lt;span style="font-size:180%;"&gt;Common Chart Properties&lt;/span&gt;
The Chart abstract base class contains several public variables that are common to all charts.  One such property that all charts share is a title.  The following public variables in the Chart class control the style, position, and content of the title displayed on a chart.
&lt;ul&gt;&lt;li&gt;title is a String whose contents will be displayed as the title of the chart.  Setting this variable to null or an empty string (its default value) causes the chart to be rendered without a title.&lt;/li&gt;&lt;li&gt;titleFill controls the fill color of the title text.  Since it is of type Paint, it can be a solid color as well as a linear or radial gradient.&lt;/li&gt;&lt;li&gt;titleFont allows you to set the Font to be used to render the title text.&lt;/li&gt;&lt;li&gt;titleGap is a Number that specifies the number of pixels to leave as a gap between the title and the content of the chart.&lt;/li&gt;&lt;li&gt;titleSide is an enumeration that specifies which side of the chart the title will appear on.  Its type is javafx.scene.chart.part.Side and its possible values are TOP, BOTTOM, LEFT, and RIGHT.
&lt;/li&gt;&lt;/ul&gt;All charts are also capable of displaying a legend.  The legend is very useful when your charts are displaying more than one data series.  It allows the user to easily see which of the plotted data points belongs to each of the data series.  The public variables below affect how the legend is presented on a chart.
&lt;ul&gt;&lt;li&gt;legendGap is a Number that specifies the number of pixels to leave as a gap between the legend and the content of the chart.&lt;/li&gt;&lt;li&gt;legendSide specifies which side of the chart the legend will appear on.  Like titleSide, the possible values are TOP, BOTTOM, LEFT, and RIGHT.
&lt;/li&gt;&lt;li&gt;legendVisible is a Boolean value that controls whether the legend will be shown on the chart or hidden.
&lt;/li&gt;&lt;/ul&gt;The Chart class also has a public-read variable named legend that provides a reference to the actual Legend object used by the chart.  This object can be used to customize many aspects of the legend and will be discussed later in the section on customization.

&lt;span style="font-size:180%;"&gt;Pie Chart&lt;/span&gt;
Getting a basic pie chart on the screen is very straightforward.  All you really need is a sequence of PieChart.Data objects and a title string.  For each value that you want to display in your pie chart you just create a PieChart.Data object and supply the value and a text string to use as the label for the value.  The sequence of data objects is then used in the pie chart’s declaration.  Since every chart is-a Node, you can just insert the chart into your scene graph in order to display it.  The listing below demonstrates how to create and display a PieChart.  Notice that we have used the titleFont variable to make the chart’s title stand out a little more.  The source code is from PieChartIntro.fx, which can be found in the ChartIntro example project.

&lt;pre class="brush:javafx"&gt;
Stage {
  title: "Pie Chart"
  scene: Scene {
    content: [
      PieChart {
        title: "What Is Your Favorite Pie?"
        titleFont: Font { size: 24 }
        data: [
          PieChart.Data {
            value: 21
            label: "Pumpkin"
          }
          PieChart.Data {
            value: 33
            label: "Apple"
          }
          PieChart.Data {
            value: 17
            label: "Cherry"
          }
          PieChart.Data {
            value: 29
            label: "3.14159"
          }
        ]
      }
    ]
  }
}
&lt;/pre&gt;

This chart is rendered as shown in the image below.  Note that right out of the box, the charts have a modern look with lighting and shading effects baked right in.  You can also see that by default the title appears at the top of the chart.  If you prefer a more 3-dimensional look to your pie charts, you can use the PieChart3D class instead of a PieChart.  Everything in the listing above (aside from the class name) can remain the same and the result will have the appearance of a 3-dimensional disk instead of a circle.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__eCG_vXQUQk/Si9v4034i7I/AAAAAAAAABo/-YnW3YvZpFM/s1600-h/piechart.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 274px;" src="http://1.bp.blogspot.com/__eCG_vXQUQk/Si9v4034i7I/AAAAAAAAABo/-YnW3YvZpFM/s400/piechart.png" alt="" id="BLOGGER_PHOTO_ID_5345614304768461746" border="0" /&gt;&lt;/a&gt;

&lt;span style="font-style: italic;"&gt;That concludes this entry.  In the next entry, I'll continue this excerpt by taking a closer look at XYCharts.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-3333188251606187972?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/3333188251606187972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/06/this-is-test.html#comment-form' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/3333188251606187972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/3333188251606187972'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/06/this-is-test.html' title='Creating Charts in JavaFX'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/__eCG_vXQUQk/Si9p1GNf0CI/AAAAAAAAABY/s3HClqc8ROA/s72-c/chartHierarchy.png' height='72' width='72'/><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7706192646925495484.post-8923641447847051463</id><published>2009-06-07T14:17:00.000-07:00</published><updated>2009-06-07T14:47:17.144-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='swing'/><category scheme='http://www.blogger.com/atom/ns#' term='javafx'/><title type='text'>Old Posts</title><content type='html'>For reference, here are some posts from my old blog at java.net and some of my posts from javafxpert.com:

&lt;a href="http://weblogs.java.net/blog/diverson/archive/2007/03/a_guide_to_the.html"&gt;A Guide to the Future (of Swing Applications)&lt;/a&gt;: &lt;span style="font-style: italic;"&gt;March 19, 2007&lt;/span&gt;
&lt;a href="http://weblogs.java.net/blog/diverson/archive/2007/04/swing_applicati_1.html"&gt;Swing Application Framework Hacks Unleashed For Smarty Pantses&lt;/a&gt;: &lt;span style="font-style: italic;"&gt;April 2, &lt;/span&gt;&lt;span style="font-style: italic;"&gt;2007&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;a href="http://weblogs.java.net/blog/diverson/archive/2007/04/beans_binding_f_1.html"&gt;Beans Binding For Me?  You Shouldn't Have&lt;/a&gt;: &lt;span style="font-style: italic;"&gt;April 3, &lt;/span&gt;&lt;span style="font-style: italic;"&gt;2007&lt;/span&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;
&lt;a href="http://learnjavafx.typepad.com/weblog/2009/01/javafx-skins-game.html"&gt;
&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://learnjavafx.typepad.com/weblog/2009/01/javafx-skins-game.html"&gt;JavaFX Skins Game&lt;/a&gt;: &lt;span style="font-style: italic;"&gt;January 1, 2009&lt;/span&gt;
&lt;a href="http://learnjavafx.typepad.com/weblog/2009/01/javafx-calculator.html"&gt;Part 3 of Building a JavaFX Calculator&lt;/a&gt;: &lt;span style="font-style: italic;"&gt;January 15, 2009&lt;/span&gt;
&lt;a href="http://learnjavafx.typepad.com/weblog/2009/01/spotlight-effects-with-javafx.html"&gt;Spotlight Effects for JavaFX&lt;/a&gt;: &lt;span style="font-style: italic;"&gt;January 25, 2009&lt;/span&gt;

&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7706192646925495484-8923641447847051463?l=pleasingsoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pleasingsoftware.blogspot.com/feeds/8923641447847051463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/06/old-posts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8923641447847051463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7706192646925495484/posts/default/8923641447847051463'/><link rel='alternate' type='text/html' href='http://pleasingsoftware.blogspot.com/2009/06/old-posts.html' title='Old Posts'/><author><name>Dean Iverson</name><uri>http://www.blogger.com/profile/10775967623378633903</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://1.bp.blogspot.com/__eCG_vXQUQk/Siwy1asFLDI/AAAAAAAAAAM/vAhEL9QBZ6w/S220/headshot.jpg'/></author><thr:total>0</thr:total></entry></feed>
