<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Die, AJAX!</title>
	<link>http://www.dieajax.com</link>
	<description>Helping developers put a new face on the web.</description>
	<pubDate>Mon, 29 Oct 2007 09:39:11 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2</generator>
	<language>en</language>
			<item>
		<title>10 Minute Tutorial - JavaFX: Basic 2D Graphics and Animation</title>
		<link>http://www.dieajax.com/2007/10/15/10-minute-tutorial-javafx-basic-2d-graphics-and-animation/</link>
		<comments>http://www.dieajax.com/2007/10/15/10-minute-tutorial-javafx-basic-2d-graphics-and-animation/#comments</comments>
		<pubDate>Mon, 15 Oct 2007 06:21:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[JavaFX]]></category>
<category>Animation</category><category>JavaFX</category><category>Tutorial</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/10/15/10-minute-tutorial-javafx-basic-2d-graphics-and-animation/</guid>
		<description><![CDATA[My last JavaFX tutorial beared one part fruit and one part pain. Clearly, more bugs need squishing and more language features need exercising before JavaFX can even hope to call itself &#8220;beta&#8221; quality. But, each code drop does get better and better, and even now, I can tell that the end product will turn out [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://www.dieajax.com/2007/09/14/10-minute-tutorial-javafx-event-handling-using-trigger-and-bind/">last JavaFX</a> tutorial beared one part fruit and one part pain. Clearly, more bugs need squishing and more language features need exercising before JavaFX can even hope to call itself &#8220;beta&#8221; quality. But, each code drop does get better and better, and even now, I can tell that the end product will turn out nice. So&#8230;</p>
<p><a href="http://www.amazon.com/gp/product/B000BNX3B4?ie=UTF8&amp;tag=dvmcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B000BNX3B4"><em>&#8230;we will press on.</em></a><img src="http://www.assoc-amazon.com/e/ir?t=dvmcom-20&amp;l=as2&amp;o=1&amp;a=B000BNX3B4" style="border: medium none  ! important; margin: 0px ! important" border="0" height="1" width="1" />(not the greatest movie, but that scene gets me everytime!)</p>
<p>JavaFX, due to its declarative syntax, promises to empower developers with the ability to quickly build engaging user-interfaces by leverage eye-popping effects and animations to deliver a deeper, more visceral experience. But, you&#8217;ve got to walk before you run so this tutorial will explore JavaFX&#8217;s basic animation concepts by creating a simple slideshow containing various shapes. For added fun, each slide will have the ability to rotate. While eye-popping it is not, I think this tutorial will give you a good starting point to begin working on more complex animations.</p>
<h4>Prerequisites</h4>
<ul>
<li>All the prerequisites defined in the <a href="http://www.dieajax.com/2007/08/23/10-minute-tutorial-javafx-hello-world/">first tutorial</a></li>
</ul>
<h4>QuickStart</h4>
<p>If you want to see the result of this tutorial and you have installed all the prerequisites, then please download the ZIP file below, unzip it, open and edit the ShapeSlideShow.bat to match your directory structure and then run the ShapeSlideShow.bat file.<br />
<span class="post-info">If you don&#8217;t know how you should change the .bat file, please read my <a href="http://www.dieajax.com/2007/08/23/10-minute-tutorial-javafx-hello-world/">first JavaFX tutorial</a>.</span></p>
<ul>
<li><a href="/downloads/tutorial/javafx/slideshow/ShapeSlideShow.zip">Shape Slide Show Sample</a> (you may read this software’s license <a href="/software-license">here</a>)</li>
</ul>
<p>You can find a screen shot of the running application, <a href="/samples/tutorial/javafx/slideshow/ShapeSlideShow.png">here</a>.</p>
<h4>Step 1: Create the Slide model</h4>
<p>Every good MVC application has a model, so we&#8217;ll start by modeling a &#8220;slide&#8221; in the slide show. Create a file named &#8220;ShapeSlideshow.fx&#8221; and declare a class named <em>Slide</em> like so:</p>
<pre class="code">
import javafx.ui.*;
import javafx.ui.canvas.*;

class Slide extends Group {
    attribute x: Number;
    attribute y: Number;
    attribute rotation: Number;
}</pre>
<p>The <em>Group</em> class which <em>Slide</em> inherits from gives all nodes contained within the group their own shared coordinate space. So, you can manipulate several UI elements at once by doing simple 2D transforms on the <em>Group</em> itself. You&#8217;ll see this in action later.</p>
<p>As you&#8217;d expect, changing the Slide class&#8217; x and y attributes affect its screen position and the rotation attribute sets its degree of rotation. Nothing fancy here.</p>
<ul id="annotation">
<li><a href="https://openjfx.dev.java.net/nonav/api/javafx/ui/canvas/Group.html">Learn more the Group class</a></li>
</ul>
<h4><a title="step2" name="step2"></a>Step 2: Create the Slideshow model</h4>
<p>Now, we&#8217;ll model an actual slideshow. This will look ugly initially, but it&#8217;ll all make sense later (I hope <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ):</p>
<pre class="code">
class SlideShow {
    attribute width: Number;
    attribute height: Number;
    attribute slideIndex: Number;
    attribute currentSlide: Slide;
    attribute prevSlide: Slide;
    attribute nextSlide: Slide;
    attribute slideWidth: Number;
    attribute slideHeight: Number;
    attribute startX: Number;
    attribute startY: Number;
    attribute nextX: Number;
    attribute nextY: Number;
    attribute slides: Slide*;
<span class="new">
    attribute isAnimating: Boolean;

    attribute currentStopX: Number;
    attribute nextStopX: Number;
    attribute currentSlideX: Number;
    attribute nextSlideX: Number;
    attribute prevSlideX: Number;
    attribute currentSlideRotation: Number;
    attribute animatingNext: Boolean;
</span>
    operation doNextAnimationStopped();
    operation doPrevAnimationStopped();
    operation getSlide( newSlideIndex: Number);
    operation slideNext();
    operation slidePrevious();
    operation rotate();
}</pre>
<p>Yeah, it ain&#8217;t small. I won&#8217;t explain each of these attributes and operations right now. You&#8217;ll see how they get used as we go on. However, I do want to explain the highlighted attributes. Unfortunately, JavaFX currently lacks a way to signal the application when an animation has stopped. So, each of the highlighted attributes helps in determining when JavaFX&#8217;s animation loops have completed running. Hopefully, as JavaFX&#8217;s evolves, I can get rid of this housekeeping cruft.</p>
<h4><a title="step3" name="step3"></a>Step 3: Instantiate and initialize the Slideshow</h4>
<p>We&#8217;ll do this in pieces. First, to set some basic positions and dimensions:</p>
<pre class="code">
attribute SlideShow.slideWidth = 40;
attribute SlideShow.slideHeight = 40;

var slideShow = SlideShow {
    var: self

    slideIndex: 0
    width: 300
    height: 200

    startX: self.width / 2 - self.slideWidth / 2
    startY: self.height / 2 - self.slideHeight / 2
    nextX: self.width
    nextY: self.height / 2 - self.slideHeight / 2</pre>
<p>So, the first two lines say that the slideshow expects all slides to have a width and height of 40 pixels. Next, the width and height of the slideshow gets set to 300 and 200 pixels, respectively and the index of starting slide gets set to 0. The calculation for the startX and startY variables places the first slide smack in the middle of the 300&#215;200 pixel dimensions specified earlier. NextX and nextY place the next slide(s) off screen, so they can &#8220;slide&#8221; into view when needed.</p>
<p>Now, to give the slideshow some slides:</p>
<pre class="code">
    slides:
    [Slide {
        var: slideSelf
<span class="new">
        x: self.startX
        y: self.startY
</span>
        content: Rect {
            width: 40
            height: 40
            fill: green
            stroke: black
        }
        transform: bind [translate(slideSelf.x,slideSelf.y), rotate(slideSelf.rotation,self.slideWidth/2,self.slideHeight/2)]
    },
      Slide {
        var: slideSelf
<span class="new">
        x: self.nextX
        y: self.nextY
</span>
        content: Ellipse {
        	transform: [translate(self.slideWidth/2,self.slideHeight/2)]
            radiusX: 20
	radiusY: 13
            fill: blue
            stroke: black
	}
<span class="new">
	transform: bind [translate(slideSelf.x,slideSelf.y), rotate(slideSelf.rotation,self.slideWidth/2,self.slideHeight/2)]
</span>
    },
    Slide {
        var: slideSelf

        x: self.nextX
        y: self.nextY
        content: Rect {
            width: 40
            height: 40
	arcHeight: 10
	arcWidth: 10
            fill: orange
            stroke: black
        }
        transform: bind [translate(slideSelf.x,slideSelf.y), rotate(slideSelf.rotation,self.slideWidth/2,self.slideHeight/2)]
    }]</pre>
<p>This repetitive, self-explanatory code should read like a book to you by now. I did want to draw your attention to the highlighted sections, however. The first highlighted section  points out that the first slide  (slide index 0) gets positioned at startX and startY. The second highlighted section shows that all the following slides get set to the nextX and nextY positions (essentially waiting off-screen). Finally, I highlighted the last set of lines because we have yet to address the transform attribute shared by most UI elements.</p>
<p>In JavaFX, typically, you can apply a number of &#8220;transforms&#8221; to a UI element by assigning an array of <a href="https://openjfx.dev.java.net/nonav/api/javafx/ui/canvas/Transform.html">Transform</a>-derived objects to its transform attribute. I&#8217;ve included a few of them in the links below.</p>
<ul id="annotation">
<li><a href="https://openjfx.dev.java.net/nonav/api/javafx/ui/canvas/Translate.html">Learn more about the Translate class</a></li>
</ul>
<ul id="annotation">
<li><a href="https://openjfx.dev.java.net/nonav/api/javafx/ui/canvas/Rotate.html">Learn more about the Rotate class</a></li>
</ul>
<ul id="annotation">
<li><a href="https://openjfx.dev.java.net/nonav/api/index.html">Learn more about the Scale class</a></li>
</ul>
<p>Note the <em>bind</em> statement in highlighted transform code I referenced earlier. This bind statement means that as the values for x, y and rotation change in our <em>Slide</em> objects, the objects within the <em>Slide</em> will also get transformed.</p>
<p>Speaking of <em>bind</em>, the Slideshow needs a few <em>bind</em> statements of its own:</p>
<pre class="code">
    prevSlide: bind self.getSlide(self.slideIndex - 1)
    currentSlide: bind self.getSlide(self.slideIndex)
    nextSlide: bind self.getSlide(self.slideIndex + 1)

    currentSlideX: bind self.currentSlide.x
    nextSlideX: bind self.nextSlide.x
    prevSlideX: bind self.prevSlide.x
    currentSlideRotation: bind self.currentSlide.rotation</pre>
<p>So, at all times we track the current, previous and next slides, which get calculated based on the current slideIndex (we&#8217;ll define the getSlide operation in a moment, although you can probably guess what it does). As I stated in <a href="#step2">Step 2</a>, the next four attributes I use merely to detect when animations have stopped, an ability that JavaFX will hopefully gain at a later date. In any case, you&#8217;ll see how they work in a moment.</p>
<h4><a title="step4" name="step4"></a>Step 4: Start animating slides</h4>
<p>Now, the fun part! (Yaaayyyy! <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) But first, (Awwww! <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> ) I&#8217;ll define the getSlide function, as promised:</p>
<pre class="code">
operation SlideShow.getSlide( newSlideIndex:Number ) {
    if( (newSlideIndex &gt;= sizeof (slides)) or (newSlideIndex &lt; 0) ) {
        return null;
    } else {
        return slides[newSlideIndex];
    }
}</pre>
<p>Like I said, self-explanatory.</p>
<p><span class="post-info"><br />
I learned about the differences between JavaFX <em>operation</em>s and <em>function</em>s the hard way. Make sure you know the difference by reading about it <a href="http://java.sun.com/developer/technicalArticles/scripting/javafx/lc/part3/">here</a>.<br />
</span></p>
<p>Moving on to something more interesting, below I pasted the functions which do the real work:</p>
<pre class="code">
operation SlideShow.slideNext() {
    if( ((slideIndex + 1 ) == sizeof( slides )) or isAnimating) {
        return;
    }

   isAnimating = true;
    animatingNext = true;
    <span class="new">currentSlide.x = [currentSlide.x..-1-slideWidth] dur 1000 easein;</span>
    nextSlide.x = [nextSlide.x..startX] dur 1000 easeout;
}

operation SlideShow.slidePrevious() {
    if( ((slideIndex - 1) &lt; 0) or isAnimating ) {
        return;
    }

    isAnimating = true;
    animatingNext = false;
    currentSlide.x = [currentSlide.x..width + 1] dur 1000 easein;
    prevSlide.x = [prevSlide.x..startX] dur 1000 easeout;
}  

operation SlideShow.rotate() {
    if( isAnimating ) {
	return;
    }

    isAnimating = true;
    currentSlide.rotation = [0..720] dur 3000;
}</pre>
<p>I&#8217;ll let you read through the code on your own, but I will say that each function follows a common pattern: determine if the current state of the application allows the animation to occur. If so, start the animation and set flags to ignore all input until it completes.</p>
<p><span class="post-info"><br />
I had some issues overlapping animations on the same UI element, so I decided to prevent that from happening by using the <em>isAnimating</em> variable to determine whether or not to ignore user input. I just keep telling myself, &#8220;pre-alpha code&#8221;, &#8220;pre-alpha code&#8221;&#8230;<br />
</span></p>
<p>We did all this setup for one little operator within the line I highlighted: the dur operator. The <em>dur</em> operator (<em>dur</em> stands for duration) allows you set a variable to an entire range of values over the span of time. So, in the highlighted statement, currentSlide.x gets set to all the values between its current value and  -1 – slideWidth over the span of 1000 milliseconds. The <em>easein</em> qualifier tells the JavaFX animation engine to start the animation slowly and then speed up over time. This makes the slides look like they accelerate as the fly off screen. All in one statement. Pretty neat,  huh?</p>
<ul id="annotation">
<li><a href="http://blogs.sun.com/chrisoliver/entry/programming_animations_in_fx">Learn more about the dur operator</a></li>
</ul>
<ul id="annotation">
<li><a href="http://blogs.sun.com/praveenm/entry/animation_through_fx_and_java">Learn even more about the dur operator</a></li>
</ul>
<ul id="annotation">
<li><a href="http://chaoticjava.com/posts/hooking-up-to-animations-in-javafx/">Learn even more about the dur operator</a></li>
</ul>
<h4>Step 5: Stop animating slides</h4>
<p>Well, JavaFX doesn&#8217;t give us the ability to stop an animation directly just yet, but I hacked together something that will let me know when an animation has completed, at least:</p>
<pre class="code">
operation SlideShow.doNextAnimationStopped() {
    if( (currentSlide.x == -1-slideWidth) and (nextSlide.x == startX)) {
        slideIndex++;
        isAnimating = false;
    }
}

operation SlideShow.doPrevAnimationStopped() {
    if( (currentSlide.x == width + 1) and (prevSlide.x == startX)) {
        slideIndex--;
        isAnimating = false;
    }
}

<span class="new">trigger on SlideShow.currentSlideX = newValue {
    if( animatingNext == true ) {
        doNextAnimationStopped();
    } else {
        doPrevAnimationStopped();
    }
}
</span>

trigger on SlideShow.nextSlideX = newValue {
    doNextAnimationStopped();
}

trigger on SlideShow.prevSlideX = newValue {
    doPrevAnimationStopped();
}

trigger on SlideShow.currentSlideRotation = newValue {
    if( currentSlide.rotation == 720 ) {
	isAnimating = false;
    }
}</pre>
<p>The real key lies in the triggers. Remember, in <a href="#step4">Step 4</a>,  currentSlide.x got animated to push the slide off-screen. Well, in <a href="#step3">Step3</a>, I bound currentSlideX to currentSlide.x so every time currentSlide.x changes (even while it animates), currentSlideX changes. So, in the highlighted code, I set a trigger on currentSlideX to call either  doNextAnimationStopped or  doPrevAnimationStopped (depending on if the user clicked the next or previous button). Both these functions check to see if both animating slides have reached their finish destinations and if so, updates the slide index and sets isAnimating to false thereby creating a poor man&#8217;s event callback system.</p>
<p>Trust me, I enjoyed programming that even less than you enjoyed reading the explanation.</p>
<h4>Step 6: Create the UI (what little there is <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> )</h4>
<p>Let&#8217;s start with the code:</p>
<pre class="code">
Frame {
    title: "Die, Ajax! - Slide Show Sample"
    width: 300
    height: 300
    visible: true
    content:
    Panel {
        content: [
        Canvas {
            var: self
            x: 0
            y: 0
            width: 300
            height: 300
            content:
            [<span class="new">slideShow.slides</span>,
            View {
                transform: [translate(63,180)]
                content: GroupPanel {
                    cursor: DEFAULT
                    var row = Row {alignment: BASELINE}
                    var column1 = Column { }
                    var column2 = Column { }
                    var column3 = Column { }
                    rows: [row]
                    columns: [column1, column2, column3]
                    content:
                    [Button {
                        row: row
                        column: column1
                        text: &#8220;&lt;-&#8221;
                        action: operation() {
                            slideShow.slideNext();
                        }
                    },Button {
                        row: row
                        column: column2
                        text: &#8220;Spin&#8221;
                        action: operation() {
                            slideShow.rotate();
                        }
                    }, Button {
                        row: row
                        column: column3
                        text: &#8220;-&gt;&#8221;
                        action: operation() {
                            slideShow.slidePrevious();
                        }
                    }]
                }
            }]
        }]
    }
}</pre>
<p>Most of this should read pretty easily by now. The statement I highlighted adds the slides to the Frame&#8217;s content list. It adds ALL the slides, even the non-visible ones. Those simply wait off-screen waiting to come into view. Let&#8217;s hope JavaFX&#8217;s clipper doesn&#8217;t take too much of a performance hit for my laziness ;).</p>
<h4>Step 7: Run it!</h4>
<p>All the code in its entirety:</p>
<pre class="code">
import javafx.ui.*;
import javafx.ui.canvas.*;

class Slide extends Group {
    attribute x: Number;
    attribute y: Number;
    attribute rotation: Number;
}

class SlideShow {
	attribute width: Number;
	attribute height: Number;
    attribute slideIndex: Number;
    attribute currentSlide: Slide;
    attribute prevSlide: Slide;
    attribute nextSlide: Slide;
    attribute slideWidth: Number;
    attribute slideHeight: Number;
    attribute startX: Number;
    attribute startY: Number;
    attribute nextX: Number;
    attribute nextY: Number;
    attribute slides: Slide*;
    attribute isAnimating: Boolean;

    //Cruft to determine whether or not animation has stopped
    attribute currentStopX: Number;
    attribute nextStopX: Number;
    attribute currentSlideX: Number;
    attribute nextSlideX: Number;
    attribute prevSlideX: Number;
    attribute currentSlideRotation: Number;
    attribute animatingNext: Boolean;

    operation doNextAnimationStopped();
    operation doPrevAnimationStopped();
    operation getSlide( newSlideIndex: Number);
    operation slideNext();
    operation slidePrevious();
    operation rotate();
}

attribute SlideShow.slideWidth = 40;
attribute SlideShow.slideHeight = 40;

var slideShow = SlideShow {
    var: self

    slideIndex: 0
	width: 300
	height: 200

    startX: self.width / 2 - self.slideWidth / 2
    startY: self.height / 2 - self.slideHeight / 2
    nextX: self.width
    nextY: self.height / 2 - self.slideHeight / 2

    slides:
    [Slide {
		var: slideSelf

        x: self.startX
        y: self.startY
        content: Rect {
            width: 40
            height: 40
            fill: green
            stroke: black
        }
		transform: bind [translate(slideSelf.x,slideSelf.y), rotate(slideSelf.rotation,self.slideWidth/2,self.slideHeight/2)]
    },
		Slide {
		var: slideSelf

        x: self.nextX
        y: self.nextY
        content: Ellipse {
			transform: [translate(self.slideWidth/2,self.slideHeight/2)]
            radiusX: 20
            radiusY: 13
            fill: blue
            stroke: black
		}
		transform: bind [translate(slideSelf.x,slideSelf.y), rotate(slideSelf.rotation,self.slideWidth/2,self.slideHeight/2)]
    },
    Slide {
		var: slideSelf

        x: self.nextX
        y: self.nextY
        content: Rect {
            width: 40
            height: 40
			arcHeight: 10
			arcWidth: 10
            fill: orange
            stroke: black
        }
		transform: bind [translate(slideSelf.x,slideSelf.y), rotate(slideSelf.rotation,self.slideWidth/2,self.slideHeight/2)]
    }]

    prevSlide: bind self.getSlide(self.slideIndex - 1)
    currentSlide: bind self.getSlide(self.slideIndex)
    nextSlide: bind self.getSlide(self.slideIndex + 1)

    currentSlideX: bind self.currentSlide.x
    nextSlideX: bind self.nextSlide.x
    prevSlideX: bind self.prevSlide.x
    currentSlideRotation: bind self.currentSlide.rotation
};

operation SlideShow.getSlide( newSlideIndex:Number ) {
    if( (newSlideIndex &gt;= sizeof (slides)) or (newSlideIndex &lt; 0) ) {
        return null;
    } else {
        return slides[newSlideIndex];
    }
}

operation SlideShow.slideNext() {
    if( ((slideIndex + 1 ) == sizeof( slides )) or isAnimating) {
        return;
    }

    isAnimating = true;
    animatingNext = true;
    currentSlide.x = [currentSlide.x..-1-slideWidth] dur 1000 easein;
    nextSlide.x = [nextSlide.x..startX] dur 1000 easeout;
}

operation SlideShow.slidePrevious() {
    if( ((slideIndex - 1) &lt; 0) or isAnimating ) {
        return;
    }

    isAnimating = true;
    animatingNext = false;
    currentSlide.x = [currentSlide.x..width + 1] dur 1000 easein;
    prevSlide.x = [prevSlide.x..startX] dur 1000 easeout;
}  

operation SlideShow.rotate() {
    if( isAnimating ) {
	return;
    }

    isAnimating = true;
    currentSlide.rotation = [0..720] dur 3000;
}

operation SlideShow.doNextAnimationStopped() {
    if( (currentSlide.x == -1-slideWidth) and (nextSlide.x == startX)) {
        slideIndex++;
        isAnimating = false;
    }
}

operation SlideShow.doPrevAnimationStopped() {
    if( (currentSlide.x == width + 1) and (prevSlide.x == startX)) {
        slideIndex--;
        isAnimating = false;
    }
}

trigger on SlideShow.currentSlideX = newValue {
    if( animatingNext == true ) {
        doNextAnimationStopped();
    } else {
        doPrevAnimationStopped();
    }
}

trigger on SlideShow.nextSlideX = newValue {
    doNextAnimationStopped();
}

trigger on SlideShow.prevSlideX = newValue {
    doPrevAnimationStopped();
}

trigger on SlideShow.currentSlideRotation = newValue {
    if( currentSlide.rotation == 720 ) {
	isAnimating = false;
    }
}

Frame {
    title: "Die, Ajax! - Slide Show Sample"
    width: 300
    height: 300
    visible: true
    content:
    Panel {
        content: [
        Canvas {
            var: self
            x: 0
            y: 0
            width: 300
            height: 300
            content:
            [slideShow.slides,
            View {
                transform: [translate(63,180)]
                content: GroupPanel {
                    cursor: DEFAULT
                    var row = Row {alignment: BASELINE}
                    var column1 = Column { }
                    var column2 = Column { }
                    var column3 = Column { }
                    rows: [row]
                    columns: [column1, column2, column3]
                    content:
                    [Button {
                        row: row
                        column: column1
                        text: "&lt;-"
                        action: operation() {
                            slideShow.slideNext();
                        }
                    },Button {
                        row: row
                        column: column2
                        text: "Spin"
                        action: operation() {
                            slideShow.rotate();
                        }
                    }, Button {
                        row: row
                        column: column3
                        text: "-&gt;"
                        action: operation() {
                            slideShow.slidePrevious();
                        }
                    }]
                }
            }]
        }]
    }
}</pre>
<p>And surely, you know how to do this part by now <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> :</p>
<pre class="code">
"C:\Program Files\Java\jre1.6.0_03\bin\java.exe" -classpath .;"C:\Documents and Settings\David Miles\My Documents\dev\OpenJFX\trunk\lib\javafxrt.jar";"C:\Documents and Settings\David Miles\My Documents\dev\OpenJFX\trunk\lib\swing-layout.jar";"C:\Documents and Settings\David Miles\My Documents\dev\OpenJFX\trunk\lib\Filters.jar" net.java.javafx.FXShell ShapeSlideShow.fx</pre>
<p>Your paths may vary. Actually, I can just about guarantee they will. <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4>Conclusions</h4>
<p>Believe it or not, I actually condensed this code from what I&#8217;d initially written. I originally had a custom-coded triangle and a circle in the slideshow, but couldn&#8217;t get my triangle to rotate correctly and a rotating circle&#8230;not very exciting. Anyway, I hope this tutorial gave you a decent example of creating animations in JavaFX to plagiarize from. <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> As the spec for JavaFX animation evolves, I will do more tutorials on this topic, but for now, get in there and start animating! And remember, you can always look to the <a href="http://download.java.net/general/openjfx/demos/tutorial.jnlp">JavaFX 2D Tutorial</a> for more ideas and explanations.</p>
<p style="display: none; visibility: hidden"><script src="http://www.assoc-amazon.com/s/link-enhancer?tag=dvmcom-20&amp;o=1" type="text/javascript">                                   </script></p>
<p><noscript></noscript></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/10/15/10-minute-tutorial-javafx-basic-2d-graphics-and-animation/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Channel 9 video review: Mike Sampson - Building a Silverlight player for Channel 9</title>
		<link>http://www.dieajax.com/2007/10/09/channel-9-video-review-mike-sampson-building-a-silverlight-player-for-channel-9/</link>
		<comments>http://www.dieajax.com/2007/10/09/channel-9-video-review-mike-sampson-building-a-silverlight-player-for-channel-9/#comments</comments>
		<pubDate>Tue, 09 Oct 2007 05:46:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight]]></category>
<category>Channel 8</category><category>Channel 9</category><category>Expression Studio</category><category>SIlverlight</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/10/09/channel-9-video-review-mike-sampson-building-a-silverlight-player-for-channel-9/</guid>
		<description><![CDATA[WARNING! You may need to watch this video twice. That awesome Star Destroyer model distracted the hell out of me the first time.  Looks like it had the same affect on a few other people, too.
Apparently, Adam Kinney didn&#8217;t have to walk far for this interview. Currently, his office neighbor, Mike Sampson (a.k.a Sampy), [...]]]></description>
			<content:encoded><![CDATA[<p>WARNING! You may need to watch <a href="http://channel9.msdn.com/Showpost.aspx?postid=344297">this video</a> twice. That awesome Star Destroyer model distracted the hell out of me the first time. <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> Looks like it had the same affect on a <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=344332#344332">few</a> <a href="http://channel9.msdn.com/ShowPost.aspx?PostID=344489#344489">other</a> people, too.</p>
<p>Apparently, <a href="http://adamkinney.com/">Adam Kinney</a> didn&#8217;t have to walk far for this interview. Currently, his office neighbor, Mike Sampson (a.k.a Sampy), works on the Silverlight-based media player for Microsoft&#8217;s <a href="http://channel8.msdn.com">Channel 8</a> and <a href="http://channel9.msdn.com">Channel 9</a> websites. So for about fifteen minutes, Mr. Sampy animatedly discusses his extremely positive experience using the Expression suite and Silverlight to bring this media player to life. <a href="http://www.dieajax.com/2007/10/09/channel-9-video-review-mike-sampson-building-a-silverlight-player-for-channel-9/#more-22" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/10/09/channel-9-video-review-mike-sampson-building-a-silverlight-player-for-channel-9/feed/</wfw:commentRss>
		</item>
		<item>
		<title>10 Minute Tutorial - Silverlight: Building a Silverlight application with MSBuild (C#)</title>
		<link>http://www.dieajax.com/2007/10/03/10-minute-tutorial-silverlight-building-a-silverlight-application-with-msbuild-c/</link>
		<comments>http://www.dieajax.com/2007/10/03/10-minute-tutorial-silverlight-building-a-silverlight-application-with-msbuild-c/#comments</comments>
		<pubDate>Thu, 04 Oct 2007 01:10:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Silverlight]]></category>
<category>C#</category><category>Managed Code</category><category>MSBuild</category><category>SIlverlight</category><category>Tutorial</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/10/03/10-minute-tutorial-silverlight-building-a-silverlight-application-with-msbuild-c/</guid>
		<description><![CDATA[&#8220;If you build it they will come&#8221;
Don&#8217;t know about that, but if you use MSBuild, it&#8217;ll sure make everyone&#8217;s life a hell of alot easier.  
Until now, I used batch files to build the C# managed code used in my Silverlight tutorials. Now granted, a build and batch file share many traits: both execute [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/gp/product/078322611X?ie=UTF8&amp;tag=dvmcom-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=078322611X"><em>&#8220;If you build it they will come&#8221;</em></a><img src="http://www.assoc-amazon.com/e/ir?t=dvmcom-20&amp;l=as2&amp;o=1&amp;a=078322611X" style="border: medium none ; margin: 0px" border="0" height="1" width="1" /></p>
<p>Don&#8217;t know about that, but if you use MSBuild, it&#8217;ll sure make everyone&#8217;s life a hell of alot easier. <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Until now, I used batch files to build the C# managed code used in my Silverlight tutorials. Now granted, a build and batch file share many traits: both execute instructions in a (mostly) seequential order on a set of inputs. However, build systems really shine in their ability to provide more domain specific constructs for working with files, directories, source assets and external utilities. This relieves the developer from the typical file shuffling burden that plagues an even midly complex build. As of .NET 2.0, Microsoft provides developers with a build engine, called MSBuild, as part of the runtime distribution. In this tutorial, I will walk through hand-coding a MSBuild build file for the sample code of <a href="http://www.dieajax.com/2007/09/06/10-minute-tutorial-silverlight-using-javascript-to-call-scriptable-managed-code-c/">my last Silverlight tutorial application</a>. <a href="http://www.dieajax.com/2007/10/03/10-minute-tutorial-silverlight-building-a-silverlight-application-with-msbuild-c/#more-21" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/10/03/10-minute-tutorial-silverlight-building-a-silverlight-application-with-msbuild-c/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Channel 9 video review: Tyler Ballance - live from the SilverlightDevCamp in San Francisco</title>
		<link>http://www.dieajax.com/2007/09/19/channel-9-video-review-tyler-ballance-live-from-the-silverlightdevcamp-in-san-francisco/</link>
		<comments>http://www.dieajax.com/2007/09/19/channel-9-video-review-tyler-ballance-live-from-the-silverlightdevcamp-in-san-francisco/#comments</comments>
		<pubDate>Thu, 20 Sep 2007 03:20:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight]]></category>
<category>Channel 9</category><category>Flash</category><category>SIlverlight</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/09/19/channel-9-video-review-tyler-ballance-live-from-the-silverlightdevcamp-in-san-francisco/</guid>
		<description><![CDATA[It looks like Microsoft has found a new victim in their continuing onslaught of consistently excellent, impromptu developer interviews. This time Adam Kinney puts the spotlight on Tyler Ballance, an employee of the picture slide show company, Slide (if you&#8217;ve read any number of MySpace profiles and bulletins, then you&#8217;ve definitely seen their logo). This [...]]]></description>
			<content:encoded><![CDATA[<p>It looks like Microsoft has found a new victim in their continuing onslaught of consistently excellent, impromptu developer interviews. This time <a href="http://adamkinney.com/blog/256/default.aspx">Adam Kinney</a> puts the spotlight on <a href="http://channel9.msdn.com/showpost.aspx?postid=342743">Tyler Ballance</a>, an employee of the picture slide show company, <a href="http://www.slide.com">Slide</a> (if you&#8217;ve read any number of MySpace profiles and bulletins, then you&#8217;ve definitely seen their logo). This young man, seemingly reluctant at first, but opening up once the technical questions started flowing, discusses the San Fransico SilverlightDevCamp and gives his opinion on how programming in Flash compares to Silverlight. <a href="http://www.dieajax.com/2007/09/19/channel-9-video-review-tyler-ballance-live-from-the-silverlightdevcamp-in-san-francisco/#more-20" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/09/19/channel-9-video-review-tyler-ballance-live-from-the-silverlightdevcamp-in-san-francisco/feed/</wfw:commentRss>
		</item>
		<item>
		<title>10 Things I Learned From the September MSDN Event in Atlanta</title>
		<link>http://www.dieajax.com/2007/09/19/10-things-i-learned-from-the-september-msdn-event-in-atlanta/</link>
		<comments>http://www.dieajax.com/2007/09/19/10-things-i-learned-from-the-september-msdn-event-in-atlanta/#comments</comments>
		<pubDate>Wed, 19 Sep 2007 05:39:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight]]></category>
<category>Glen Gordon</category><category>LINQ</category><category>MSDN Event</category><category>SIlverlight</category><category>WCF</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/09/19/10-things-i-learned-from-the-september-msdn-event-in-atlanta/</guid>
		<description><![CDATA[A week ago, I went to the September MSDN event in Atlanta, held at the AMC Parkway Pointe theater. The itinerary included presentations on LINQ (Language Integrated Query), WCF (Windows Communication Foundation) and Silverlight. Having seen live presentations on LINQ and WCF before, I hoped to justify the experience by seeing a dazzling Silverlight presentation, [...]]]></description>
			<content:encoded><![CDATA[<p>A week ago, I went to the <a href="http://blogs.msdn.com/glengordon/archive/2007/09/12/thanks-for-the-teamwork-on-the-atlanta-msdn-event-yesterday.aspx">September MSDN event in Atlanta</a>, held at the AMC Parkway Pointe theater. The itinerary included presentations on <a href="http://msdn2.microsoft.com/netframework/aa904594.aspx">LINQ (Language Integrated Query)</a>, <a href="http://wcf.netfx3.com/">WCF (Windows Communication Foundation)</a> and <a href="http://silverlight.net/">Silverlight.</a> Having seen live presentations on LINQ and WCF before, I hoped to justify the experience by seeing a dazzling Silverlight presentation, in the flesh.</p>
<p>Unfortunately, &#8220;dazzled&#8221; I was not. <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> However overall, the experience did satisfy. <a href="http://www.dieajax.com/2007/09/19/10-things-i-learned-from-the-september-msdn-event-in-atlanta/#more-19" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/09/19/10-things-i-learned-from-the-september-msdn-event-in-atlanta/feed/</wfw:commentRss>
		</item>
		<item>
		<title>10 Minute Tutorial - JavaFX: Event handling using trigger and bind</title>
		<link>http://www.dieajax.com/2007/09/14/10-minute-tutorial-javafx-event-handling-using-trigger-and-bind/</link>
		<comments>http://www.dieajax.com/2007/09/14/10-minute-tutorial-javafx-event-handling-using-trigger-and-bind/#comments</comments>
		<pubDate>Fri, 14 Sep 2007 04:50:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[JavaFX]]></category>
<category>JavaFX</category><category>Tutorial</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/09/14/10-minute-tutorial-javafx-event-handling-using-trigger-and-bind/</guid>
		<description><![CDATA[Clearly, the creators of JavaFX Script want to make it a great MVC programming language. Nothing says this more than baking triggers and binding into the language as first class concepts. According to the documentation, JavaFX triggers operate in the same manner as SQL triggers, allowing you to handle data modification events in an aspect-like [...]]]></description>
			<content:encoded><![CDATA[<p>Clearly, the creators of JavaFX Script want to make it a great MVC programming language. Nothing says this more than baking <em>trigger</em>s and <em>bind</em>ing into the language as first class concepts. According to the documentation, JavaFX triggers operate in the same manner as SQL triggers, allowing you to handle data modification events in an <a href="http://www.eclipse.org/aspectj">aspect-like</a> fashion. And, the bind keyword allows bidirectional binding between two variables so that when one receives an update the other also gets updated. Using these concepts, its easy to remove some of the tedium in handling modification events of UI elements and variables that other languages and frameworks require developers to slog through. <a href="http://www.dieajax.com/2007/09/14/10-minute-tutorial-javafx-event-handling-using-trigger-and-bind/#more-18" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/09/14/10-minute-tutorial-javafx-event-handling-using-trigger-and-bind/feed/</wfw:commentRss>
		</item>
		<item>
		<title>10 Most Important Points From Dr. Tim Sneath&#8217;s and Scott Guthrie&#8217;s Silverlight videos on Channel 9</title>
		<link>http://www.dieajax.com/2007/09/09/10-most-important-points-from-dr-tim-sneaths-and-scott-guthries-silverlight-videos-on-channel-9/</link>
		<comments>http://www.dieajax.com/2007/09/09/10-most-important-points-from-dr-tim-sneaths-and-scott-guthries-silverlight-videos-on-channel-9/#comments</comments>
		<pubDate>Sun, 09 Sep 2007 07:23:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight]]></category>
<category>Channel 9</category><category>Moonlight</category><category>Scott Guthrie</category><category>SIlverlight</category><category>Tim Sneath</category><category>XBAP</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/09/09/10-most-important-points-from-dr-tim-sneaths-and-scott-guthries-silverlight-videos-on-channel-9/</guid>
		<description><![CDATA[I started writing this post as two separate summaries, however these videos contain so much overlapping information, I decided to just combine them. If you want to watch the videos yourself you can find Dr. Sneath&#8217;s video here and Scott Guthire&#8217;s video here.
]]></description>
			<content:encoded><![CDATA[<p>I started writing this post as two separate summaries, however these videos contain so much overlapping information, I decided to just combine them. If you want to watch the videos yourself you can find Dr. Sneath&#8217;s video <a href="http://channel9.msdn.com/Showpost.aspx?postid=340360">here</a> and Scott Guthire&#8217;s video <a href="http://channel9.msdn.com/Showpost.aspx?postid=339594">here</a>.  <a href="http://www.dieajax.com/2007/09/09/10-most-important-points-from-dr-tim-sneaths-and-scott-guthries-silverlight-videos-on-channel-9/#more-16" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/09/09/10-most-important-points-from-dr-tim-sneaths-and-scott-guthries-silverlight-videos-on-channel-9/feed/</wfw:commentRss>
		</item>
		<item>
		<title>10 Minute Tutorial - Silverlight: Using JavaScript to Call Scriptable Managed Code (C#)</title>
		<link>http://www.dieajax.com/2007/09/06/10-minute-tutorial-silverlight-using-javascript-to-call-scriptable-managed-code-c/</link>
		<comments>http://www.dieajax.com/2007/09/06/10-minute-tutorial-silverlight-using-javascript-to-call-scriptable-managed-code-c/#comments</comments>
		<pubDate>Fri, 07 Sep 2007 03:53:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Silverlight]]></category>
<category>C#</category><category>JavaScript</category><category>Managed Code</category><category>SIlverlight</category><category>Tutorial</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/09/06/10-minute-tutorial-silverlight-using-javascript-to-call-scriptable-managed-code-c/</guid>
		<description><![CDATA[My last Silverlight tutorial walked through manipulating a Silverlight control using managed code. So today, we will learn how to access that managed code from JavaScript in an HTML page. The blandness of my last tutorial (a blue rectangle, whoopie) inspired me to spice things up for this tutorial and give you: animated, multi-color rectangles! [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://www.dieajax.com/2007/08/10/10-minute-tutorial-%e2%80%93-silverlight-event-handling-using-managed-code-c/">last Silverlight tutorial</a> walked through manipulating a Silverlight control using managed code. So today, we will learn how to access that managed code from JavaScript in an HTML page. The blandness of my last tutorial (a blue rectangle, whoopie) inspired me to spice things up for this tutorial and give you: animated, multi-color rectangles! Blows your mind, doesn&#8217;t? Lacking the desire or the time to create the necessary XAML myself, I &#8220;borrowed&#8221; it from one of the samples embedded in the absolutely awesome <a href="http://www.simplegeek.com/mharsh/wpfepad/">SilverlightPad</a> application.</p>
<p>Man, I hope that code is open source. <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>In addition to snazzy animations, the application for this tutorial will also contain a couple of form controls that will manipulate the Silverlight content at runtime. The first control, a simple drop down, will allow the user to select the number of rectangles displayed on the screen. The second form control will act as a pause/resume button for the animation.</p>
<p>Okay, let&#8217;s get started! <a href="http://www.dieajax.com/2007/09/06/10-minute-tutorial-silverlight-using-javascript-to-call-scriptable-managed-code-c/#more-15" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/09/06/10-minute-tutorial-silverlight-using-javascript-to-call-scriptable-managed-code-c/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Silverlight 1.0 Released</title>
		<link>http://www.dieajax.com/2007/09/06/silverlight-10-released/</link>
		<comments>http://www.dieajax.com/2007/09/06/silverlight-10-released/#comments</comments>
		<pubDate>Thu, 06 Sep 2007 06:01:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight]]></category>
<category>SIlverlight</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/09/06/silverlight-10-released/</guid>
		<description><![CDATA[Well, it&#8217;s about time!
Just kidding.  Congrats to the Silverlight team. I know they worked their proverbial butts off to get this release out. And at a cursory glance, it looks very solid. I posted some links below that talk about the release in greater detail:
]]></description>
			<content:encoded><![CDATA[<p>Well, it&#8217;s about time!</p>
<p>Just kidding. <img src='http://www.dieajax.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Congrats to the Silverlight team. I know they worked their proverbial butts off to get this release out. And at a cursory glance, it looks very solid. I posted some links below that talk about the release in greater detail:  <a href="http://www.dieajax.com/2007/09/06/silverlight-10-released/#more-14" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/09/06/silverlight-10-released/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Microsoft Showcases Tafiti Silverlight Tech Demo</title>
		<link>http://www.dieajax.com/2007/08/24/microsoft-showcases-tafiti-silverlight-tech-demo/</link>
		<comments>http://www.dieajax.com/2007/08/24/microsoft-showcases-tafiti-silverlight-tech-demo/#comments</comments>
		<pubDate>Fri, 24 Aug 2007 16:51:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Silverlight]]></category>
<category>Demo</category><category>SIlverlight</category>
		<guid isPermaLink="false">http://www.dieajax.com/2007/08/24/microsoft-showcases-tafiti-silverlight-tech-demo/</guid>
		<description><![CDATA[Recently, Microsoft released a technology demo, named Tafiti, as a showcase for thier new Silverlight web browser extension. This demo allows the user to execute web searches and then browse the results in different data visualization structures and also save searches for later. While not meant to be a finished product, Tafiti supposedly represents the [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, Microsoft released a technology demo, named <a href="http://www.tafiti.com/">Tafiti</a>, as a showcase for thier new Silverlight web browser extension. This demo allows the user to execute web searches and then browse the results in different data visualization structures and also save searches for later. While not meant to be a finished product, <a href="http://www.tafiti.com/">Tafiti</a> supposedly represents the new possibilities in data visualization and user interaction that Silverlight unlocks.  <a href="http://www.dieajax.com/2007/08/24/microsoft-showcases-tafiti-silverlight-tech-demo/#more-13" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dieajax.com/2007/08/24/microsoft-showcases-tafiti-silverlight-tech-demo/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
