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

<channel>
	<title>Macca Blog</title>
	<atom:link href="http://markmacumber.net/feed" rel="self" type="application/rss+xml" />
	<link>http://markmacumber.net</link>
	<description>My life experiences with code and design</description>
	<lastBuildDate>Fri, 23 Jul 2010 12:01:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Sprite animations using WPF/Silverlight and JavaFX</title>
		<link>http://markmacumber.net/2010/07/sprite-animations-using-wpfsilverlight-and-javafx.html</link>
		<comments>http://markmacumber.net/2010/07/sprite-animations-using-wpfsilverlight-and-javafx.html#comments</comments>
		<pubDate>Fri, 23 Jul 2010 11:54:27 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[Developer]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[animation]]></category>

		<guid isPermaLink="false">http://markmacumber.net/?p=35</guid>
		<description><![CDATA[Usually when you begin to write any sort of application that requires visual flare, animations are always on the cards.
Since WPF and JavaFX (and Apple&#8217;s Cocoa Touch) use a similar animation framework of a declarative nature, meaning, that the developer defines elements at time steps and then the framework works out the rest, it becomes [...]]]></description>
			<content:encoded><![CDATA[<p>Usually when you begin to write any sort of application that requires visual flare, animations are always on the cards.</p>
<p>Since WPF and JavaFX (and Apple&#8217;s Cocoa Touch) use a similar animation framework of a declarative nature, meaning, that the developer defines elements at time steps and then the framework works out the rest, it becomes &#8220;<em>less intuitive</em>&#8221; to find out how to render an image sprite (PNG for example) animation.</p>
<p>This blog post will provide some idea of how to implement a sprite based animation using WPF and JavaFX.</p>
<h2>JavaFX</h2>
<p>Here is what a basic sprite based animation class looks like in JavaFX</p>
<p>[JavaFX]<br />
/*<br />
 * SpriteAnimator.fx<br />
 */</p>
<p>package javafxsprites;<br />
import javafx.scene.CustomNode;<br />
import javafx.animation.KeyFrame;<br />
import javafx.animation.Timeline;<br />
import javafx.scene.Node;<br />
import javafx.scene.image.Image;<br />
import javafx.scene.image.ImageView;</p>
<p>/**<br />
 * @author Mark Macumber<br />
 */</p>
<p>public class SpriteAnimator extends CustomNode {<br />
    var _currentFrame:Integer = 1;</p>
<p>    public var xPos:Number = 0.0;<br />
    public var yPos:Number = 0.0;<br />
    public var FPS:Integer = 30;</p>
<p>    var tl = Timeline {<br />
	repeatCount: Timeline.INDEFINITE<br />
	keyFrames : [<br />
		KeyFrame {<br />
			time : bind Duration.valueOf(1000/FPS)<br />
            action: function() {<br />
                _currentFrame++;<br />
                if (_currentFrame > 11)<br />
                _currentFrame = 1;<br />
            }<br />
		}<br />
    ]<br />
    };</p>
<p>    override protected function create () : Node {<br />
        var img = ImageView {<br />
            x: bind xPos,<br />
            y: bind yPos,<br />
            image: bind<br />
                Image { url: &#8220;{__DIR__}sprites/{_currentFrame}.png&#8221;; }<br />
        };<br />
        tl.play();<br />
        return img;<br />
    }<br />
}<br />
[/JavaFX]</p>
<p>Inside your sprites directory, just add 0.png, 1.png, etc&#8230; all the way through to the 11.png (or however many frames you have)</p>
<p>This is a pretty simple implementation, which essentially just updates the image property of the ImageView that is returned as part of the create() method.</p>
<p>Here is how you might use the class: </p>
<p>[JavaFX]<br />
package javafxsprites;<br />
import javafx.stage.Stage;<br />
import javafx.scene.Scene;</p>
<p>/**<br />
 * @author Mark Macumber<br />
 */</p>
<p>Stage {<br />
    title: &#8220;JavaFX and Sprites&#8221;<br />
    scene: Scene {<br />
        width: 400<br />
        height: 250<br />
        content: [<br />
            SpriteAnimator{ xPos: 150, yPos: 40, FPS: 15, NumberOfFrames: 10 }<br />
        ]<br />
    }<br />
}<br />
[/JavaFX]</p>
<p>Pretty Simple huh? <img src='http://markmacumber.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>You might be wondering why I bothered to create a custom class called SpriteAnimator, instead of just using an ImageView which I update. The answer is really simple, &#8220;re-use and encapsulation&#8221;, you can make this class flexible, rich, and re-usable very easily.</p>
<h2>WPF/Silverlight</h2>
<p>The following class has been ripped from a project that I was working on, so it is quite involved and very feature rich, and hence, very large <img src='http://markmacumber.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Basically it allows you to create a custom UserControl which allows for sprite animations based on file-system images, in memory-byte array images or pre-built up Lists of Image classes.</p>
<p>The reason for this was for performance reasons, sometimes for larger animations in certain areas of the application where lots was going on, the byte[] animations performed better that the filesystem images. Also things like file size of the images, etc&#8230; all attributed to the performance improvements/decreases.</p>
<h3>Usage</h3>
<p>The <strong>usage</strong> of this class is simple, you create an Image on your page, then pass the Source property of that Image class into the constructor of this class. Then call start() and your image source will be updated using pretty simple dependency property techniques.</p>
<p>Some of the other features of this class are as follows:</p>
<ul>
<li>Create a BitmapImage from a byte array (if, say, you read in an image from the file system or a stream into a byte[]) via the static CreateImageFromBytes method
</li>
<li>Pause/Unpause the animation</li>
<li>Stop/Start the animation</li>
<li>Revers the animation</li>
<li>Change the framerate</li>
<li>Seek within the animation, this is useful is you have an animation that is time based</li>
</ul>
<h3>Warning:</h3>
<p>This class was ripped and quickly cleaned up for this blog post, if there are any issues with it, they should be just minor issues, please let me know if you come across any issues and I will do my best to fix it up.</p>
<p>I do NOT provide any guarantees with this class, please use it at your own risk (I know, typical disclaimer)</p>
<p>[csharp]<br />
using System;<br />
using System.Collections.Generic;<br />
using System.IO;<br />
using System.Windows;<br />
using System.Windows.Controls;<br />
using System.Windows.Media.Animation;<br />
using System.Windows.Media.Imaging;<br />
using System.Windows.Media;</p>
<p>namespace MarkMacumber.Helpers<br />
{<br />
	//Interface for any clean-ups required<br />
	public interface ICleanupFilmstrip<br />
	{<br />
		void AfterCompleted();<br />
	}</p>
<p>    public class FilmstripAnimator : UserControl<br />
    {<br />
        private enum RunMode<br />
        {<br />
            /// <summary><br />
            /// Run with pre loaded bitmap images<br />
            /// </summary><br />
            Images,</p>
<p>            /// <summary><br />
            /// Run with bitmap images loaded on the fly from the file system<br />
            /// </summary><br />
            FileSystem,</p>
<p>            /// <summary><br />
            /// Using byte arrays for the image source<br />
            /// </summary><br />
            Bytes<br />
        }</p>
<p>        private static readonly DependencyProperty CurrentFrameProperty = DependencyProperty.Register(&#8220;CurrentFrame&#8221;, typeof(int), typeof(FilmstripAnimator), new PropertyMetadata(0, OnCurrentFrameChanged));<br />
        public static readonly DependencyProperty FrameRateProperty = DependencyProperty.Register(&#8220;FrameRate&#8221;, typeof(int), typeof(FilmstripAnimator), new PropertyMetadata(30));</p>
<p>        //different ways of accessing image data, file system, in memory bitmaps, in memory bytes<br />
        private readonly List<BitmapImage> _filmstripImages;<br />
        private readonly List<Byte[]> _filmstripBytes;<br />
        private readonly List<string> _filmstripImagePaths;</p>
<p>        private Storyboard _filmstripStoryboard;</p>
<p>        private readonly RunMode _mode = RunMode.FileSystem;</p>
<p>        //view components<br />
        public Image FilmstripImageHost;<br />
        internal ImageBrush FilmstripImageBrushHost;</p>
<p>        //clean up tasks<br />
        public ICleanUpFilmstrip CleanUp { get; set; }</p>
<p>        private static BitmapImage CreateImageFromBytes(byte[] filmstripBytes)<br />
        {<br />
            var memoryStream = new MemoryStream(filmstripBytes);</p>
<p>            var imageSource = new BitmapImage();<br />
            imageSource.BeginInit();<br />
            imageSource.CacheOption = BitmapCacheOption.None;<br />
            imageSource.CreateOptions = BitmapCreateOptions.PreservePixelFormat;<br />
            imageSource.StreamSource = memoryStream;<br />
            imageSource.EndInit();<br />
            return imageSource;<br />
        }</p>
<p>        public Filmstrip(List<Byte[]> filmstripBytes, ImageBrush imageToUpdate)<br />
        {<br />
            _mode = RunMode.Bytes;<br />
            _filmstripBytes = filmstripBytes;<br />
            FilmstripImageBrushHost = imageToUpdate;</p>
<p>            FilmstripImageBrushHost.ImageSource = CreateImageFromBytes(_filmstripBytes[0]);<br />
            CreateStoryboard();<br />
        }</p>
<p>        public Filmstrip(List<BitmapImage> filmstripImages, ImageBrush imageToUpdate)<br />
        {<br />
            _mode = RunMode.Images;<br />
            _filmstripImages = filmstripImages;<br />
            FilmstripImageHost = new Image { Stretch = Stretch.Fill };<br />
            FilmstripImageBrushHost = imageToUpdate;<br />
            FilmstripImageBrushHost.ImageSource = filmstripImages[0];</p>
<p>            CreateStoryboard();<br />
        }</p>
<p>        public Filmstrip(List<string> filmstripImagePaths)<br />
        {<br />
            FilmstripImageHost = new Image { Stretch = Stretch.Fill };<br />
            _filmstripImagePaths = filmstripImagePaths;<br />
            Content = FilmstripImageHost;<br />
            CreateStoryboard();<br />
        }</p>
<p>        public Filmstrip(List<BitmapImage> filmstripImages)<br />
        {<br />
            _mode = RunMode.Images;</p>
<p>            FilmstripImageHost = new Image { Stretch = Stretch.Fill };<br />
            _filmstripImages = filmstripImages;<br />
            Content = FilmstripImageHost;<br />
            CreateStoryboard();<br />
        }</p>
<p>        private static void OnCurrentFrameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)<br />
        {<br />
            var filmstrip = (Filmstrip)d;<br />
            if (filmstrip.FrameCount <= 0) return;</p>
<p>            //If we are using an ImageBrush then use the in memory bitmaps<br />
            if (filmstrip.FilmstripImageBrushHost != null)<br />
            {<br />
                if (filmstrip._mode == RunMode.Images)<br />
                {<br />
                    filmstrip.FilmstripImageBrushHost.ImageSource = null;<br />
                    BitmapImage newSource = filmstrip._filmstripImages[filmstrip.CurrentFrame];<br />
                    filmstrip.FilmstripImageBrushHost.ImageSource = newSource;<br />
                }<br />
                else<br />
                {<br />
                    filmstrip.FilmstripImageBrushHost.ImageSource = null;<br />
                    BitmapImage newByteImage = CreateImageFromBytes(filmstrip._filmstripBytes[filmstrip.CurrentFrame]);<br />
                    filmstrip.FilmstripImageBrushHost.ImageSource = newByteImage;<br />
                }<br />
            }<br />
            //If we are NOT using the ImageBrush but we still want to use images from memory<br />
            else if (filmstrip._filmstripImages != null)<br />
            {<br />
                filmstrip.FilmstripImageHost.Source = null;<br />
                BitmapImage newImageSource = filmstrip._filmstripImages[filmstrip.CurrentFrame];<br />
                filmstrip.FilmstripImageHost.Source = newImageSource;<br />
            }</p>
<p>            //Otherwise, use the images from the filesystem, which typically are for larger animations<br />
            else<br />
            {<br />
                BitmapImage source = new BitmapImage(new Uri(filmstrip._filmstripImagePaths[filmstrip.CurrentFrame]));<br />
                RenderOptions.SetBitmapScalingMode(source, BitmapScalingMode.LowQuality);<br />
                filmstrip.FilmstripImageHost.Source = null;<br />
                filmstrip.FilmstripImageHost.Source = source;<br />
            }<br />
        }</p>
<p>        private void CreateStoryboard()<br />
        {<br />
            CreateStoryboard(0);<br />
        }</p>
<p>        private void CreateStoryboard(int from)<br />
        {<br />
            int? targetTo;<br />
            Duration dur;<br />
            if (_mode == RunMode.FileSystem)<br />
            {<br />
                targetTo = new int?((this._filmstripImagePaths.Count == 0) ? 0 : (this._filmstripImagePaths.Count - 1));<br />
                dur = TimeSpan.FromSeconds(_filmstripImagePaths.Count);<br />
            }<br />
            else if (_mode == RunMode.Images)<br />
            {<br />
                targetTo = new int?((_filmstripImages.Count == 0) ? 0 : (_filmstripImages.Count - 1));<br />
                dur = TimeSpan.FromSeconds(_filmstripImages.Count);<br />
            }<br />
            else<br />
            {<br />
                targetTo = new int?((_filmstripBytes.Count == 0) ? 0 : (_filmstripBytes.Count - 1));<br />
                dur = TimeSpan.FromSeconds(_filmstripBytes.Count);<br />
            }</p>
<p>            var element = new Int32Animation();<br />
            element.From = from;<br />
            element.To = targetTo;<br />
            element.Duration = dur;<br />
            Storyboard.SetTargetProperty(element, new PropertyPath(CurrentFrameProperty));<br />
            _filmstripStoryboard = new Storyboard {SpeedRatio = this.FrameRate};<br />
            _filmstripStoryboard.Children.Add(element);<br />
            _filmstripStoryboard.Completed += FilmstripStoryboard_Completed;<br />
        }</p>
<p>        private void FilmstripStoryboard_Completed(object sender, EventArgs e)<br />
        {<br />
            if (CleanUp != null)<br />
                CleanUp.AfterCompleted();<br />
            _filmstripStoryboard.Completed -= FilmstripStoryboard_Completed;<br />
        }</p>
<p>        public void Pause()<br />
        {<br />
            _filmstripStoryboard.Pause(this);<br />
        }</p>
<p>        public void Unpause()<br />
        {<br />
            _filmstripStoryboard.Resume(this);<br />
        }</p>
<p>        public void Stop()<br />
        {<br />
            if (_filmstripStoryboard != null)<br />
                _filmstripStoryboard.Stop(this);<br />
        }</p>
<p>        public void Start()<br />
        {<br />
            Start(TimeSpan.Zero, true);<br />
        }</p>
<p>        public void Start(TimeSpan beginTime, bool loop)<br />
        {<br />
            Start(beginTime, loop, false);<br />
        }</p>
<p>        public void Start(TimeSpan beginTime, bool loop, bool reverse)<br />
        {<br />
            if (_filmstripStoryboard == null) return;</p>
<p>            if (beginTime != TimeSpan.Zero) _filmstripStoryboard.Children[0].BeginTime = new TimeSpan?(beginTime);<br />
            if (loop) _filmstripStoryboard.Children[0].RepeatBehavior = RepeatBehavior.Forever;<br />
            _filmstripStoryboard.Children[0].AutoReverse = reverse;<br />
            _filmstripStoryboard.Begin(this, true);<br />
        }</p>
<p>        /// <summary><br />
        /// From the current position, reverse the animation<br />
        /// </summary><br />
        public void Reverse(int durationOfReverse)<br />
        {<br />
            _filmstripStoryboard.Pause(this);</p>
<p>            var element = _filmstripStoryboard.Children[0] as Int32Animation;</p>
<p>            element.From = CurrentFrame;<br />
            element.To = 0;<br />
            element.Duration = new Duration(new TimeSpan(0,0,0,0, durationOfReverse));<br />
            Storyboard.SetTargetProperty(element, new PropertyPath(CurrentFrameProperty));</p>
<p>            //speed up reversal<br />
            _filmstripStoryboard.SpeedRatio = 1;<br />
            _filmstripStoryboard.Begin(this, true);<br />
        }</p>
<p>        public void MoveFilmstripForward(int secondsToMoveForward)<br />
        {<br />
            var hasValue = _filmstripStoryboard.GetCurrentTime(this).HasValue;<br />
            if (!hasValue) return;</p>
<p>            TimeSpan currentTime = (TimeSpan) _filmstripStoryboard.GetCurrentTime(this);<br />
            TimeSpan timeToMoveForward = new TimeSpan(0, 0, secondsToMoveForward * this.FrameRate);<br />
            TimeSpan newFilmstripLocation = currentTime.Add(timeToMoveForward);</p>
<p>            _filmstripStoryboard.Seek(this, newFilmstripLocation, TimeSeekOrigin.BeginTime);<br />
        }</p>
<p>        public void MoveFilmstripBackward(int secondsToMoveBackward)<br />
        {<br />
            var hasValue = _filmstripStoryboard.GetCurrentTime(this).HasValue;<br />
            if (!hasValue) return;<br />
            TimeSpan currentTime = (TimeSpan) _filmstripStoryboard.GetCurrentTime(this);<br />
            TimeSpan timeToMoveBackward = new TimeSpan(0, 0, secondsToMoveBackward * this.FrameRate);<br />
            TimeSpan newFilmstripLocation = currentTime.Subtract(timeToMoveBackward);</p>
<p>            if (newFilmstripLocation.TotalMilliseconds < 1)<br />
                newFilmstripLocation = new TimeSpan(0, 0, 0);</p>
<p>            this._filmstripStoryboard.Seek(this, newFilmstripLocation, TimeSeekOrigin.BeginTime);<br />
        }</p>
<p>        public void AdjustFrameRate(int frameRate)<br />
        {<br />
            _filmstripStoryboard.SpeedRatio = frameRate;<br />
            FrameRate = frameRate;<br />
        }</p>
<p>        private int CurrentFrame<br />
        {<br />
            get<br />
            {<br />
                return (int)base.GetValue(CurrentFrameProperty);<br />
            }<br />
        }</p>
<p>        public int FrameCount<br />
        {<br />
            get<br />
            {<br />
                if (_mode == RunMode.FileSystem)<br />
                    return _filmstripImagePaths.Count;<br />
                if (_mode == RunMode.Bytes)<br />
                    return _filmstripBytes.Count;<br />
               return _filmstripImages.Count;<br />
            }<br />
        }</p>
<p>        public int FrameRate<br />
        {<br />
            get<br />
            {<br />
                return (int)base.GetValue(FrameRateProperty);<br />
            }<br />
            set<br />
            {<br />
                base.SetValue(FrameRateProperty, value);<br />
            }<br />
        }<br />
    }<br />
}<br />
[/csharp]</p>
<p>I have only just been learning about Apples world and the Cocoa-Touch framework, so when I know more about it I will be sure to post about it.</p>
<p>As always, please give feedback if you enjoyed this blog post, found some errors, or if you would like more information in general.</p>
<p>Thanks<br />
&#8211; Macca (Mark)</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2010/07/sprite-animations-using-wpfsilverlight-and-javafx.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Migration to Wordpress</title>
		<link>http://markmacumber.net/2010/04/migration-to-wordpress.html</link>
		<comments>http://markmacumber.net/2010/04/migration-to-wordpress.html#comments</comments>
		<pubDate>Tue, 06 Apr 2010 12:24:09 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[Microsoft Surface]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[blogger]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://markmacumber.net/?p=31</guid>
		<description><![CDATA[Hi everybody!
I know I know&#8230; I&#8217;ve been very slack getting together more posts, but honestly I have been very busy working with various different technologies. All of these learning&#8217;s have given me great insight into many of the different worlds that exist in the UI space of software development.
I hope to share many different ideas, [...]]]></description>
			<content:encoded><![CDATA[<p>Hi everybody!</p>
<p>I know I know&#8230; I&#8217;ve been very slack getting together more posts, but honestly I have been very busy working with various different technologies. All of these learning&#8217;s have given me great insight into many of the different worlds that exist in the UI space of software development.</p>
<p>I hope to share many different ideas, thoughts, techniques and more over the next few months, so please watch this space.</p>
<p>I was lucky enough to work as the lead developer on a Microsoft Surface application that was used at the Australian Open 2010, this project was incredibly challenging and full of surprises, I learned a lot!</p>
<p>Also, you may or may not have noticed, that I moved to Wordpress. I need to give props to this blog that helped me migrate over from Blogger to Wordpress:</p>
<p><a title="http://www.mamablogga.com/the-ultimate-guide-to-migrating-from-blogger-to-wordpress/" href="http://www.mamablogga.com/the-ultimate-guide-to-migrating-from-blogger-to-wordpress/">http://www.mamablogga.com/the-ultimate-guide-to-migrating-from-blogger-to-wordpress/</a></p>
<p>Thanks <strong>mamablogga</strong></p>
<p>Anyways, I hope to get this blog up and running again very soon, so please watch this space.</p>
<p>Cheers,</p>
<p>Mark</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2010/04/migration-to-wordpress.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Switch worlds from JavaFX to WPF and the designer workflow</title>
		<link>http://markmacumber.net/2009/10/switch-worlds-from-javafx-to-wpf-and-the-designer-workflow.html</link>
		<comments>http://markmacumber.net/2009/10/switch-worlds-from-javafx-to-wpf-and-the-designer-workflow.html#comments</comments>
		<pubDate>Wed, 28 Oct 2009 11:11:00 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[Designer]]></category>
		<category><![CDATA[Developer]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://markmacumber.net/2009/10/switch-worlds-from-javafx-to-wpf-and-the-designer-workflow.html</guid>
		<description><![CDATA[As some of you may be aware, for a long time I have been eagerly following JavaFX. Playing with it, getting involved in the entire JavaFX world.
It was easy for me to get into it because at work I was also heavily involved in Java work. I was writing a Gwt application that used a [...]]]></description>
			<content:encoded><![CDATA[<p>As some of you may be aware, for a long time I have been eagerly following JavaFX. Playing with it, getting involved in the entire JavaFX world.</p>
<p>It was easy for me to get into it because at work I was also heavily involved in Java work. I was writing a Gwt application that used a Java back end and was working in an Ubuntu development environment, not to mention surrounded by other Java enthusiasts.</p>
<p>Over the last few years, I had really become more and more aware of front end technologies and the emergence of new UI/UX/Front end frameworks, such as Silverlight, Flex, JavaFX, JQuery, Dojo, etc&#8230; Seeing a pattern, I took it upon myself to ensure that I understood how each and every one worked (at least to some degree) and went from there.</p>
<p>Originally having a .Net background, I expressed my interest &#8220;up the chain&#8221; for some more .Net project work and was given the opportunity to work on an exciting new .Net WPF (Windows Presentation Foundation) project.</p>
<p>Very quickly it was detailed that UI/UX was of high importance and the skill sets that our team had, while very strong, lacked in some of the finer points of UI (at least from a creative point of view).</p>
<p>Over the last few weeks I have been really beginning to understand the value of the Designer/Developer workflow. Microsoft have done a wonderful job with the Expression Suite of tools that tie in Visual Studio and WPF apps together.</p>
<p>The one thing that I now know, is that in order for JavaFX to succeed, (which it has the potential for) Sun MUST create a powerful and complete work flow for designer/developers to with.</p>
<p>I know all about the plugins for JavaFX and Photoshop, but that&#8217;s not enough. What it really needs is the full designer, which must incorporate all attributes of JavaFX such as binding, styling, time lines (at a creative level) as well as the technical side.</p>
<p>I look forward to having a play with the designer that is <a href="http://sellmic.com/blog/2009/06/13/new-screenshots-of-the-javafx-design-tool/">currently under development</a> and seeing where that is (which is looking freaking sweet).</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_k_IbgsLtQiM/SuglyZxblgI/AAAAAAAAAb8/H3AIL_538nU/s1600-h/jfx_design_tool_preview2.jpg"><img style="cursor: pointer; width: 439px; height: 246px;" src="http://3.bp.blogspot.com/_k_IbgsLtQiM/SuglyZxblgI/AAAAAAAAAb8/H3AIL_538nU/s400/jfx_design_tool_preview2.jpg" alt="" id="BLOGGER_PHOTO_ID_5397605701245441538" border="0" /></a><br /><span style="font-style: italic;">(thanks to </span><a style="font-style: italic;" href="http://sellmic.com/blog/2009/06/13/new-screenshots-of-the-javafx-design-tool/">selmic.com</a><span style="font-style: italic;"> for the pics)</span></p>
<p>At the moment however, it really feels like JavaFX has a lot of catching up to do, and with the release of WPF 4 just around the corner (beta 2 just being released), the benchmark is set high.</p>
<p><span style="font-weight: bold;font-size:130%;" >Final thought</span><br />The next year for JavaFX will make it or break it. The adoption rate must pick up and a complete stack, from development to creative must exist. I do, believe that it can be done, and I will be along for the ride pushing JavaFX where I can, especially to my colleagues and fellow onliners&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2009/10/switch-worlds-from-javafx-to-wpf-and-the-designer-workflow.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaFX and RSS cont&#8230;</title>
		<link>http://markmacumber.net/2009/09/javafx-and-rss-cont.html</link>
		<comments>http://markmacumber.net/2009/09/javafx-and-rss-cont.html#comments</comments>
		<pubDate>Wed, 23 Sep 2009 08:49:00 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[Examples]]></category>
		<category><![CDATA[JFXtras]]></category>
		<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[RSS]]></category>

		<guid isPermaLink="false">http://markmacumber.net/2009/09/javafx-and-rss-cont.html</guid>
		<description><![CDATA[Just a quick note to say that my RSS Feed Example as fully documented here, is now posted as a full loaded sample on the very popular JFXtras.org website.
The link can be found here.
(obligatory screen shot)
And to launch it right NOW click here.
Enjoy!
Mark
]]></description>
			<content:encoded><![CDATA[<p>Just a quick note to say that my <a href="http://markmacumber.blogspot.com/2009/09/javafx-and-rss.html">RSS Feed Example</a> as fully documented here, is now posted as a full loaded sample on the very popular <a href="http://jfxtras.org/">JFXtras.org</a> website.</p>
<p>The link can be found <a href="http://jfxtras.org/portal/samples/all?p_p_id=101_INSTANCE_1Bl5&amp;p_p_lifecycle=0&amp;p_p_state=normal&amp;p_p_mode=view&amp;p_p_col_id=column-2&amp;p_p_col_pos=1&amp;p_p_col_count=2&amp;_101_INSTANCE_1Bl5_struts_action=%2Fasset_publisher%2Fview_content&amp;_101_INSTANCE_1Bl5_urlTitle=using-rss-in-javafx&amp;_101_INSTANCE_1Bl5_type=content&amp;redirect=%2Fportal%2Fsamples%2Fall%3Fp_p_id%3D141_INSTANCE_10dB%26p_p_lifecycle%3D0%26p_p_state%3Dnormal%26p_p_mode%3Dview%26p_p_col_id%3Dcolumn-1%26p_p_col_pos%3D3%26p_p_col_count%3D6%26p_r_p_564233524_tag%3Drss%26p_r_p_564233524_folksonomy%3Dtrue">here</a>.</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_k_IbgsLtQiM/SrnjEPrHcTI/AAAAAAAAAXc/QWAAZZeiTuU/s1600-h/rssexample.gif"><img style="cursor: pointer; width: 300px; height: 300px;" src="http://3.bp.blogspot.com/_k_IbgsLtQiM/SrnjEPrHcTI/AAAAAAAAAXc/QWAAZZeiTuU/s400/rssexample.gif" alt="" id="BLOGGER_PHOTO_ID_5384584491564495154" border="0" /></a><br /><span style="font-style: italic;">(obligatory screen shot)</span></p>
<p>And to launch it right NOW click <a href="http://jfxtras.org/portal/c/document_library/get_file?uuid=0bef0942-d660-4392-b675-d2b9eed2810b&amp;groupId=10128&amp;name=Using%20RSS%20in%20JavaFX.jnlp">here</a>.</p>
<p>Enjoy!</p>
<p>Mark</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2009/09/javafx-and-rss-cont.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaFX and RSS</title>
		<link>http://markmacumber.net/2009/09/javafx-and-rss.html</link>
		<comments>http://markmacumber.net/2009/09/javafx-and-rss.html#comments</comments>
		<pubDate>Mon, 14 Sep 2009 08:52:00 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[RSS]]></category>

		<guid isPermaLink="false">http://markmacumber.net/2009/09/javafx-and-rss.html</guid>
		<description><![CDATA[JavaFX is known to be a rich media platform, for use in creating a rich interface for the end user, but when you think of rich media you tend to think of streaming video, animations, graphics etc&#8230; what you tend to quickly forget about is RSS (and Atom for that matter).
It has become such a [...]]]></description>
			<content:encoded><![CDATA[<p><span class="blsp-spelling-error" id="SPELLING_ERROR_0">JavaFX</span> is known to be a rich media platform, for use in creating a rich interface for the end user, but when you think of rich media you tend to think of streaming video, animations, graphics etc&#8230; what you tend to quickly forget about is <span class="blsp-spelling-error" id="SPELLING_ERROR_1">RSS</span> (and Atom for that matter).</p>
<p>It has become such a standard detail of nearly every piece of the web these days, that it has been taken for granted, which is why I thought I would post a quick blog entry about the <span class="blsp-spelling-error" id="SPELLING_ERROR_2">RSS</span> support in <span class="blsp-spelling-error" id="SPELLING_ERROR_3">JavaFX</span>.</p>
<p>Firstly, <span class="blsp-spelling-error" id="SPELLING_ERROR_4">RSS</span> is treated as a first citizen of information for use in any <span class="blsp-spelling-error" id="SPELLING_ERROR_5">RIA</span> (Rich <span class="blsp-spelling-corrected" id="SPELLING_ERROR_6">Internet</span> Application, <span style="font-style: italic;">what ever that means these days</span>!). You get a massive amount of control and help while building any interaction with <span class="blsp-spelling-error" id="SPELLING_ERROR_7">RSS</span>.</p>
<p>The <span style="font-weight: bold;">javafx.data.feed.rss</span> package contains all of the classes that you need, but it ultimately boils down to the <a href="http://java.sun.com/javafx/1.2/docs/api/javafx.data.feed.rss/javafx.data.feed.rss.RssTask.html"><span class="blsp-spelling-error" id="SPELLING_ERROR_8">RssTask</span></a> class. This class has hooks for the parsing of the feed, the time interval of the reloading of the feed, exception handling, etc&#8230;</p>
<p>There are also classes that represent the different items of the feed too, such as the <a href="http://java.sun.com/javafx/1.2/docs/api/javafx.data.feed.rss/javafx.data.feed.rss.Item.html">Item</a> class, which represents each individual <span class="blsp-spelling-error" id="SPELLING_ERROR_9">RSS</span> item (containing the properties such as title, link, comments, description, etc&#8230;).</p>
<p>Here is a quick code snippet that gets the <span class="blsp-spelling-error" id="SPELLING_ERROR_10">RSS</span> feed and fires a function when it parses each <span class="blsp-spelling-error" id="SPELLING_ERROR_11">RSS</span> item:
<pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"><code>var <span class="blsp-spelling-error" id="SPELLING_ERROR_12">rssTask</span> = <span class="blsp-spelling-error" id="SPELLING_ERROR_13">RssTask</span> {interval: 30slocation: "http://feeds.feedburner.com/javaposse"<span class="blsp-spelling-error" id="SPELLING_ERROR_14">onStart</span>: function() {   <span class="blsp-spelling-error" id="SPELLING_ERROR_15">println</span>("loading <span class="blsp-spelling-error" id="SPELLING_ERROR_16">RSS</span> feed...");}<span class="blsp-spelling-error" id="SPELLING_ERROR_17">onItem</span>: function(<span class="blsp-spelling-error" id="SPELLING_ERROR_18">rssItem</span>:Item) {   //process each item}<span class="blsp-spelling-error" id="SPELLING_ERROR_19">onException</span>:function(e:Exception){   <span class="blsp-spelling-error" id="SPELLING_ERROR_20">println</span>("There was an error: {e.<span class="blsp-spelling-error" id="SPELLING_ERROR_21">getMessage</span>()}");}<span class="blsp-spelling-error" id="SPELLING_ERROR_22">onDone</span>: function(){ <span class="blsp-spelling-error" id="SPELLING_ERROR_23">println</span>("done reading <span class="blsp-spelling-error" id="SPELLING_ERROR_24">RSS</span>"); }};<span class="blsp-spelling-error" id="SPELLING_ERROR_25">rssTask</span>.start();</code></pre>
<p>This <span class="blsp-spelling-error" id="SPELLING_ERROR_26">RssTask</span> will fetch the <span class="blsp-spelling-error" id="SPELLING_ERROR_27">RSS</span> feed for the popular <a href="http://javaposse.com/"><span class="blsp-spelling-error" id="SPELLING_ERROR_28">JavaPosse</span></a> podcast (which I highly recommend by the way, easily the best podcast around).</p>
<p>So I decided to whip up a little desktop app that parses the feed and will just display a simple little list of items using the title, etc&#8230;</p>
<pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"><code>package <span class="blsp-spelling-error" id="SPELLING_ERROR_29">rssfeedexample</span>;

import javafx.scene.Scene;import javafx.data.feed.rss.RssTask;import javafx.data.feed.rss.Item;import javafx.stage.Stage;import java.lang.Exception;import javafx.scene.Group;import javafx.scene.image.Image;import javafx.scene.image.ImageView;import javafx.scene.shape.Rectangle;import javafx.scene.paint.Color;import javafx.scene.CustomNode;import javafx.scene.Node;import javafx.scene.text.Font;import javafx.scene.text.Text;import javafx.scene.control.ScrollBar;import javafx.scene.control.Hyperlink;import javafx.stage.Alert;

/*** @author Mark <span class="blsp-spelling-error" id="SPELLING_ERROR_30">Macumber</span>*/

var <span class="blsp-spelling-error" id="SPELLING_ERROR_31">theRssItems</span>:<span class="blsp-spelling-error" id="SPELLING_ERROR_32">RssRectangleItem</span>[] = [];

var <span class="blsp-spelling-error" id="SPELLING_ERROR_33">rssTask</span> = <span class="blsp-spelling-error" id="SPELLING_ERROR_34">RssTask</span> {interval: 30slocation: "http://feeds.feedburner.com/javaposse"<span class="blsp-spelling-error" id="SPELLING_ERROR_35">onStart</span>: function() {    <span class="blsp-spelling-error" id="SPELLING_ERROR_36">println</span>("loading <span class="blsp-spelling-error" id="SPELLING_ERROR_37">RSS</span> feed...");}<span class="blsp-spelling-error" id="SPELLING_ERROR_38">onItem</span>: function(<span class="blsp-spelling-error" id="SPELLING_ERROR_39">rssItem</span>:Item) {    insert <span class="blsp-spelling-error" id="SPELLING_ERROR_40">RssRectangleItem</span>{title: <span class="blsp-spelling-error" id="SPELLING_ERROR_41">rssItem</span>.title; <span class="blsp-spelling-error" id="SPELLING_ERROR_42">linkAddress</span>: <span class="blsp-spelling-error" id="SPELLING_ERROR_43">rssItem</span>.link} into <span class="blsp-spelling-error" id="SPELLING_ERROR_44">theRssItems</span>;}<span class="blsp-spelling-error" id="SPELLING_ERROR_45">onException</span>:function(e:Exception){    <span class="blsp-spelling-error" id="SPELLING_ERROR_46">println</span>("There was an error: {e.<span class="blsp-spelling-error" id="SPELLING_ERROR_47">getMessage</span>()}");}<span class="blsp-spelling-error" id="SPELLING_ERROR_48">onDone</span>: function(){ <span class="blsp-spelling-error" id="SPELLING_ERROR_49">println</span>("done reading <span class="blsp-spelling-error" id="SPELLING_ERROR_50">RSS</span>"); <span class="blsp-spelling-error" id="SPELLING_ERROR_51">scrollBar</span>.disable = false; }};<span class="blsp-spelling-error" id="SPELLING_ERROR_52">rssTask</span>.start();

var <span class="blsp-spelling-error" id="SPELLING_ERROR_53">scrollBar</span> : <span class="blsp-spelling-error" id="SPELLING_ERROR_54">ScrollBar</span> = <span class="blsp-spelling-error" id="SPELLING_ERROR_55">ScrollBar</span> {<span class="blsp-spelling-error" id="SPELLING_ERROR_56">translateX</span>: bind (435 - <span class="blsp-spelling-error" id="SPELLING_ERROR_57">scrollBar</span>.width)<span class="blsp-spelling-error" id="SPELLING_ERROR_58">translateY</span>: 0vertical: trueheight: 415<span class="blsp-spelling-error" id="SPELLING_ERROR_59">blockIncrement</span>: 415<span class="blsp-spelling-error" id="SPELLING_ERROR_60">unitIncrement</span>: 30min: 0max: 415<span class="blsp-spelling-error" id="SPELLING_ERROR_61">focusTraversable</span>: false<span class="blsp-spelling-error" id="SPELLING_ERROR_62">blocksMouse</span>: truedisable: true};

class <span class="blsp-spelling-error" id="SPELLING_ERROR_63">RssRectangleItem</span> extends <span class="blsp-spelling-error" id="SPELLING_ERROR_64">CustomNode</span>{public var title:String;public var <span class="blsp-spelling-error" id="SPELLING_ERROR_65">linkAddress</span>:String;var cont:Rectangle;var i = <span class="blsp-spelling-error" id="SPELLING_ERROR_66">sizeof</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_67">theRssItems</span>;override function create():Node {    cont = Rectangle {        width: 250        height: 60        stroke: Color.BLACK        fill: Color.WHITE        <span class="blsp-spelling-error" id="SPELLING_ERROR_68">arcHeight</span>: 12        <span class="blsp-spelling-error" id="SPELLING_ERROR_69">arcWidth</span>: 12        x: 55        y: bind (i * 65) - (<span class="blsp-spelling-error" id="SPELLING_ERROR_70">scrollBar</span>.value);    };

    var <span class="blsp-spelling-error" id="SPELLING_ERROR_71">img</span> = <span class="blsp-spelling-error" id="SPELLING_ERROR_72">ImageView</span> {        x: bind cont.x + 5        y: bind cont.y + 15        image:            Image {                <span class="blsp-spelling-error" id="SPELLING_ERROR_73">url</span>:"{__DIR__}<span class="blsp-spelling-error" id="SPELLING_ERROR_74">feedIcon</span>.<span class="blsp-spelling-error" id="SPELLING_ERROR_75">png</span>"            }    };

    var <span class="blsp-spelling-error" id="SPELLING_ERROR_76">titleText</span> = Text {        font : Font { size: 10 }        x: bind <span class="blsp-spelling-error" id="SPELLING_ERROR_77">img</span>.x + 45,        y: bind <span class="blsp-spelling-error" id="SPELLING_ERROR_78">img</span>.y        content: bind title        <span class="blsp-spelling-error" id="SPELLING_ERROR_79">wrappingWidth</span>: 200    };

    var link = Hyperlink{        text: "[link...]";        <span class="blsp-spelling-error" id="SPELLING_ERROR_80">layoutX</span>: bind <span class="blsp-spelling-error" id="SPELLING_ERROR_81">titleText</span>.x;        <span class="blsp-spelling-error" id="SPELLING_ERROR_82">layoutY</span>: bind <span class="blsp-spelling-error" id="SPELLING_ERROR_83">titleText</span>.y + 20;        action: function():Void{            Alert.inform("Link Alert", "take me to the link...{<span class="blsp-spelling-error" id="SPELLING_ERROR_84">linkAddress</span>}");        }    };

    Group {        content: [cont, <span class="blsp-spelling-error" id="SPELLING_ERROR_85">img</span>, <span class="blsp-spelling-error" id="SPELLING_ERROR_86">titleText</span>, link]    }}}

Stage {title: "<span class="blsp-spelling-error" id="SPELLING_ERROR_87">JavaFX</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_88">RSS</span> Example"width: 450height: 450scene: Scene {    content: bind [ <span class="blsp-spelling-error" id="SPELLING_ERROR_89">theRssItems</span>,<span class="blsp-spelling-error" id="SPELLING_ERROR_90">scrollBar</span> ]}}</code></pre>
<p><span style="font-style: italic;">The only thing you will need to do to get this code to run, is to get the <span class="blsp-spelling-error" id="SPELLING_ERROR_91">RSS</span> image (posted below)</span></p>
<p>Here is a quick screen shot too:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_k_IbgsLtQiM/Sq4JBjk4c3I/AAAAAAAAAXM/Q3JS9F7zulU/s1600-h/JavaFX_RSS.gif"><img style="cursor: pointer; width: 400px; height: 400px;" src="http://3.bp.blogspot.com/_k_IbgsLtQiM/Sq4JBjk4c3I/AAAAAAAAAXM/Q3JS9F7zulU/s400/JavaFX_RSS.gif" alt="" id="BLOGGER_PHOTO_ID_5381248527088776050" border="0" /></a></p>
<p>And this is the <span class="blsp-spelling-error" id="SPELLING_ERROR_92">RSS</span> image that I have used:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_k_IbgsLtQiM/Sq4JMiXIFsI/AAAAAAAAAXU/iSc9M_1riYc/s1600-h/feedIcon.png"><img style="cursor: pointer; width: 32px; height: 32px;" src="http://3.bp.blogspot.com/_k_IbgsLtQiM/Sq4JMiXIFsI/AAAAAAAAAXU/iSc9M_1riYc/s400/feedIcon.png" alt="" id="BLOGGER_PHOTO_ID_5381248715741206210" border="0" /></a></p>
<p>It is also at this point that I would like to make sure I <span class="blsp-spelling-corrected" id="SPELLING_ERROR_93">don&#8217;t</span> forget about the Atom support in <span class="blsp-spelling-error" id="SPELLING_ERROR_94">JavaFX</span>, there is pretty much the same amount of support for <span style="font-weight: bold;">easily</span> getting Atom working quickly within <span class="blsp-spelling-error" id="SPELLING_ERROR_95">JavaFX</span>.</p>
<p>I will hopefully be uploading this example to the <span class="blsp-spelling-error" id="SPELLING_ERROR_96">JFXtras</span> website so that people can download the code, and run an example through <span class="blsp-spelling-error" id="SPELLING_ERROR_97">JNLP</span>, so watch <span style="font-weight: bold;">this</span> space!</p>
<p>If you have any issues running the code, please let me know.</p>
<p>Until next time,</p>
<p>Good Coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2009/09/javafx-and-rss.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Updated SpaceMissionFX to JavaFX 1.2</title>
		<link>http://markmacumber.net/2009/08/updated-spacemissionfx-to-javafx-1-2.html</link>
		<comments>http://markmacumber.net/2009/08/updated-spacemissionfx-to-javafx-1-2.html#comments</comments>
		<pubDate>Mon, 31 Aug 2009 10:50:00 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[JNLP]]></category>
		<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[SpaceMissionFX]]></category>
		<category><![CDATA[games programming]]></category>

		<guid isPermaLink="false">http://markmacumber.net/2009/08/updated-spacemissionfx-to-javafx-1-2.html</guid>
		<description><![CDATA[&#8220;Some&#8221; of you may know of the SpaceMissionFX game that I wrote a while back to get familiar with JavaFX.
Well that was written in JavaFX 1.1 and I have decided that it is time to update it and make it compatible with 1.2 (also, I have not posted in a while!)&#8230;
In case you were wondering, [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Some&#8221; of you may know of the <a href="http://markmacumber.blogspot.com/2008/11/space-mission-fx.html">SpaceMissionFX</a> game that I wrote a while back to get familiar with JavaFX.</p>
<p>Well that was written in JavaFX 1.1 and I have decided that it is time to update it and make it compatible with 1.2 (also, I have not posted in a while!)&#8230;</p>
<p>In case you were wondering, there weren&#8217;t many API changes required, which was a great relief!</p>
<p>So here is a few more screens and the link to the <a href="http://jfxtras.org">jfxtras.org</a> samples site:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k_IbgsLtQiM/SputpMuayzI/AAAAAAAAAWc/s1bDhPHxP3Q/s1600-h/screen1.gif"><img style="cursor: pointer; width: 400px; height: 400px;" src="http://4.bp.blogspot.com/_k_IbgsLtQiM/SputpMuayzI/AAAAAAAAAWc/s1bDhPHxP3Q/s400/screen1.gif" alt="" id="BLOGGER_PHOTO_ID_5376081503498980146" border="0" /></a><br /><span style="font-style: italic;">(in game action)</span></p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_k_IbgsLtQiM/SputvOaPrWI/AAAAAAAAAWk/8zdiKQ-zVmQ/s1600-h/screen2.gif"><img style="cursor: pointer; width: 400px; height: 400px;" src="http://1.bp.blogspot.com/_k_IbgsLtQiM/SputvOaPrWI/AAAAAAAAAWk/8zdiKQ-zVmQ/s400/screen2.gif" alt="" id="BLOGGER_PHOTO_ID_5376081607030451554" border="0" /></a><br /><span style="font-style: italic;">(destroying an asteroid)</span></p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k_IbgsLtQiM/Sputy5RHr3I/AAAAAAAAAWs/Bbz_WeGcolU/s1600-h/screen3.gif"><img style="cursor: pointer; width: 400px; height: 400px;" src="http://4.bp.blogspot.com/_k_IbgsLtQiM/Sputy5RHr3I/AAAAAAAAAWs/Bbz_WeGcolU/s400/screen3.gif" alt="" id="BLOGGER_PHOTO_ID_5376081670074511218" border="0" /></a><br /><span style="font-style: italic;">(death by asteroid)</span></p>
<p>I have also uploaded the project, including the <a href="http://jfxtras.org/portal/c/document_library/get_file?uuid=c094249f-eb69-42a0-9206-d0d8d7d71927&amp;groupId=10128&amp;name=SpaceMissionFX.jnlp">JNLP</a>, netbeans project and the source code to the jfxtras.org website.</p>
<p>You can find it <a href="http://jfxtras.org/portal/samples/all?p_p_id=101_INSTANCE_1Bl5&amp;p_p_lifecycle=0&amp;p_p_state=normal&amp;p_p_mode=view&amp;p_p_col_id=column-2&amp;p_p_col_pos=1&amp;p_p_col_count=2&amp;_101_INSTANCE_1Bl5_struts_action=%2Fasset_publisher%2Fview_content&amp;_101_INSTANCE_1Bl5_urlTitle=spacemissionfx&amp;_101_INSTANCE_1Bl5_type=content&amp;redirect=%2Fportal%2Fsamples%2Fall%3Fp_p_id%3D141_INSTANCE_10dB%26p_p_lifecycle%3D0%26p_p_state%3Dnormal%26p_p_mode%3Dview%26p_p_col_id%3Dcolumn-1%26p_p_col_pos%3D3%26p_p_col_count%3D6%26p_r_p_564233524_tag%3Dasteroids%26p_r_p_564233524_folksonomy%3Dtrue">here</a></p>
<p>As always, I love feedback, so if you like what you see, or want to know more, please let me know!</p>
<p>Until next time&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2009/08/updated-spacemissionfx-to-javafx-1-2.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JavaFX Graphing and Charting with Hudson pt 2</title>
		<link>http://markmacumber.net/2009/07/javafx-graphing-and-charting-with-hudson-pt-2.html</link>
		<comments>http://markmacumber.net/2009/07/javafx-graphing-and-charting-with-hudson-pt-2.html#comments</comments>
		<pubDate>Mon, 20 Jul 2009 11:07:00 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[Charting]]></category>
		<category><![CDATA[Graphing]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaFX]]></category>

		<guid isPermaLink="false">http://markmacumber.net/2009/07/javafx-graphing-and-charting-with-hudson-pt-2.html</guid>
		<description><![CDATA[In my last post on building some bar charts with the data gathered from the Hudson REST api, http://markmacumber.blogspot.com/2009/07/javafx-graphing-and-charting-with.html.
In this article I would like to extend the basic functionality of that graph and also highlight broken builds with RED bars.
The basic idea behind this small enhancement, is to structure the XML parsing in a more [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post on building some bar charts with the data gathered from the Hudson REST api, http://markmacumber.blogspot.com/2009/07/javafx-graphing-and-charting-with.html.</p>
<p>In this article I would like to extend the basic functionality of that graph and also highlight broken builds with <span style="color: rgb(204, 0, 0);">RED</span> bars.</p>
<p>The basic idea behind this small enhancement, is to structure the XML parsing in a more efficient manor and clean up some of the code.</p>
<p>I also wanted to add a floating dialog over each bar to show details of the build (which you could easily extend to add more details).</p>
<p>I will be using the EXACT same Java code to access the XML from Hudson, as posted in the <a href="http://markmacumber.blogspot.com/2009/07/javafx-graphing-and-charting-with.html">previous blog entry</a>.</p>
<p>Here is the source code:</p>
<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"><code>package hudsongraphs;

import javafx.stage.Stage;import javafx.scene.Scene;import javafx.scene.chart.BarChart;import javafx.scene.chart.part.CategoryAxis;import javafx.scene.chart.part.NumberAxis;import javafx.scene.text.Font;import javafx.scene.paint.Color;

import javafx.scene.input.MouseEvent;import javafx.scene.shape.Rectangle;import javafx.scene.text.Text;

import hudsonremoteaccess.Hudson;

import org.dom4j.Document;import org.dom4j.tree.DefaultElement;

/*** Hudson Graphing:* Sample JavaFX application that will make a remote call to the Hudson* API's, parse the XML and generate a nice bar-graph of build information.* @author Mark Macumber*/var hudson:Hudson = new Hudson();

var xmlDoc:Document = hudson.getXMLHudsonQuery();var builds = xmlDoc.selectNodes("//build");

var numbers:String[] = [];

//the actual bar char datavar barChartData:BarChart.Data[];

var currentMouseX:Number = 0;var currentMouseY:Number = 0;

//Text that will float in the dialogvar buildText:Text = Text {font : Font { size: 12 }x: bind currentMouseX + 12,y: bind currentMouseY + 20};

//floating rectangle that will follow the mouse on each buildvar floatingRect:Rectangle = Rectangle{width: 120height: 50arcHeight: 5arcWidth: 5fill: Color.WHITESMOKEstroke: Color.BLACKx: bind currentMouseXy: bind currentMouseYvisible: false};

for (build in builds) {var idx = indexof build;var bDuration = getElement(build as DefaultElement, "duration");var durationInMilliseconds = Number.valueOf(bDuration);var durationInMinutes = ((durationInMilliseconds/1000)/60);

var bNumber = getElement(build as DefaultElement, "number");var bResult = getElement(build as DefaultElement, "result");var bDisplayName = getElement(build as DefaultElement, "fullDisplayName");

insert bNumber into numbers;

var barChart:BarChart.Data =BarChart.Data {   category: bNumber   value: durationInMinutes};

var chartNode = Rectangle{onMouseMoved: function( e: MouseEvent ):Void {   currentMouseX = e.sceneX + 15;   currentMouseY = e.sceneY + 5;   floatingRect.visible = true;   buildText.content = "{bDisplayName}\nDuration: {durationInMinutes as Integer}mins";}x: 0y: 0width: bind barChart.widthheight: bind barChart.heightfill: if (bResult == "SUCCESS") Color.GREEN else Color.RED;};

barChart.bar = chartNode;insert barChart into barChartData;}

function getElement(element:DefaultElement, xpath:String):String{(element.selectNodes(xpath).get(0) as DefaultElement).getData() as String;}

Stage {title: "Hudson Build Duration Timeline"width: 800height: 450scene: Scene {content: [BarChart {title: "Hudson Build Duration Timeline"width: 750titleFont: Font { size: 24 }categoryGap: 2categoryAxis: CategoryAxis { categories: numbers}valueAxis: NumberAxis { label: "Build Duration (minutes)" upperBound: 500 tickUnit: 100}data: [ BarChart.Series {   name: "Build #'s"   fill: Color.GREEN   data: barChartData }]},floatingRect,buildText]}}</code></pre>
<p>As you can see, the code is actually pretty strait forward, and the enhancements has been mainly around how to parse the XML, and create the floating box, which, I have to admit, was a fair amount of trial an error <img src='http://markmacumber.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Here is a screen shot:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_k_IbgsLtQiM/SmRYFHkCpCI/AAAAAAAAAWM/tnP3w_zIcGc/s1600-h/hudson-graph_2.gif"><img style="cursor: pointer; width: 400px; height: 225px;" src="http://1.bp.blogspot.com/_k_IbgsLtQiM/SmRYFHkCpCI/AAAAAAAAAWM/tnP3w_zIcGc/s400/hudson-graph_2.gif" alt="" id="BLOGGER_PHOTO_ID_5360506301430539298" border="0" /></a></p>
<p>The full source code is available via the <a href="http://code.google.com/p/jfxtras/">JFXtras project,</a> in which this sample has been checked in for all to see and use in the &#8220;samples&#8221; project.</p>
<p>You will find it under the <span style="font-weight: bold;">MarkMacumberFX\HudsonGraphs</span></p>
<p>There is also an article published on the <a href="http://jfxtras.org/portal/samples/all/-/asset_publisher/1Bl5/content/16612?redirect=%2Fportal%2Fsamples%2Fall">JFXtras.org</a> samples page that contains all the links you will need to run the JNLP file, etc&#8230;</p>
<p>I will be hoping to continually update this code and make more and more graphs, to enhance the Hudson reporting, and hopefully getting some kind of real integration with Hudson.</p>
<p>Here is a direct link to the JNLP file:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://jfxtras.org/portal/webdav/liferay.com/guest/document_library/Samples/MarkMacumberFX/JNLP/HudsonGraphs_v0.1.jnlp"><img style="cursor: pointer; width: 88px; height: 34px;" src="http://3.bp.blogspot.com/_k_IbgsLtQiM/SmRaJU_b7tI/AAAAAAAAAWU/I2O0REnBRYQ/s400/webstart.gif" alt="" id="BLOGGER_PHOTO_ID_5360508572777836242" border="0" /></a></p>
<p>Enjoy<br />Mark!</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2009/07/javafx-graphing-and-charting-with-hudson-pt-2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaFX Graphing and Charting with Hudson</title>
		<link>http://markmacumber.net/2009/07/javafx-graphing-and-charting-with-hudson.html</link>
		<comments>http://markmacumber.net/2009/07/javafx-graphing-and-charting-with-hudson.html#comments</comments>
		<pubDate>Mon, 13 Jul 2009 10:26:00 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[Charting]]></category>
		<category><![CDATA[Graphing]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaFX]]></category>

		<guid isPermaLink="false">http://markmacumber.net/2009/07/javafx-graphing-and-charting-with-hudson.html</guid>
		<description><![CDATA[With the release of JavaFX 1.2, came a whole heap of API changes and new features.
Some of these new features include the charting API, this impressive API includes charts for Bar Graphs, Pie Charts, Bubble Charts, Lines Charts, and more. My own graphing API that I was building was solid, but did not cover as [...]]]></description>
			<content:encoded><![CDATA[<p>With the release of <a href="http://javafx.com/">JavaFX 1.2</a>, came a whole heap of API changes and new features.</p>
<p>Some of these new features include the <a href="http://javafx.com/docs/articles/javafx1-2.jsp#chartcontrols">charting API</a>, this impressive API includes charts for Bar Graphs, Pie Charts, Bubble Charts, Lines Charts, and more. My <a href="http://markmacumber.blogspot.com/2009/01/jfxgraph-code-sample.html">own graphing API </a>that I was building was solid, but did not cover as many areas as the official API.</p>
<p>I thought I would go through a great demo of what you can achieve with this API, in particular I want to build a small JavaFX applet, that sends a request to a <a href="https://hudson.dev.java.net/">Hudson server</a>, get some data and build some graphs.</p>
<p><a href="https://hudson.dev.java.net/">Hudson</a> (one of the most popular Continuous Integration applications on the market), has an <a href="http://wiki.hudson-ci.org/display/HUDSON/Remote+access+API">API</a> built into it that allows a user to send a http request to get previous build information, as well as other remote information.</p>
<p><span style="font-weight: bold;font-size:130%;" >Goal</span></p>
<p>My intention here is to expose a nice way to use JavaFX, Java and the Charting API to create a practical applet that can give developers a visual overview of their build history.</p>
<p><span style="font-size:130%;"><span style="font-weight: bold;">Overview</span></span></p>
<p>This implementation actually has a very small number of steps involved:
<ol>
<li>Build a small Java library that queries Hudson for XML</li>
<li>Build a JavaFX app that uses that library to parse and build a simple Bar Graph</li>
</ol>
<p><span style="font-size:130%;"><span style="font-weight: bold;">#1, The Java Library</span></span></p>
<p>This java library will make use of the popular XML library <a href="http://www.dom4j.org/">dom4J</a> to parse the Hudson data from a simple http request.</p>
<p><span style="font-weight: bold;font-size:100%;" ><span style="font-style: italic;">The hudson server:</span></span></p>
<p>I want to make this demonstration accessible to anyone that wants to run it, so I needed to find a public Hudson server, I did a quick Google search and came across (via the <a href="http://wiki.hudson-ci.org/display/HUDSON/Remote+access+API">Huson wiki page</a>) the publicly accessible <a href="http://deadlock.netbeans.org/hudson/">deadlock netbeans</a> Hudson server.</p>
<p><span style="font-style: italic;">FYI, to quickly summarize, you send a http request to the hudson server like http://deadlock.netbeans.org/hudson/api/xml and you get XML back&#8230; (you can also get JSON on a per build basic or for the whole project!).</p>
<p></span>The java code for the request is as follows:
<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"><code>package hudsonremoteaccess;

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL;import java.net.URLConnection;import java.util.logging.Level;import java.util.logging.Logger;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerException;import javax.xml.transform.TransformerFactory;import javax.xml.transform.stream.StreamSource;import org.dom4j.Document;import org.dom4j.DocumentHelper;import org.dom4j.io.DocumentResult;import org.dom4j.io.DocumentSource;

/*** @author Mark Macumber*/public class Hudson {

public Document getXMLHudsonQuery() { try {     String webUrl = "http://deadlock.netbeans.org/hudson/job/FindBugs/api/xml?depth=1&amp;wrapper=builds&amp;xpath=//build&amp;exclude=//build/artifact&amp;exclude=//build/culprit&amp;exclude=//build/changeSet";     Document xmlDocument = DocumentHelper.parseText(getDataFromUrl(webUrl));     xmlDocument = applyXsltStylesheet(xmlDocument);     return xmlDocument; } catch (Exception ex) {     System.err.println(ex.getMessage()); } return null;}

private Document applyXsltStylesheet(Document document){ try {     // load the transformer using JAXP     TransformerFactory factory = TransformerFactory.newInstance();

     InputStream is = this.getClass().getResourceAsStream("/hudsonremoteaccess/resources/styleSheet.xsl");     Transformer transformer = factory.newTransformer(new StreamSource(is));

     // now lets style the given document     DocumentSource source = new DocumentSource( document );     DocumentResult result = new DocumentResult();     transformer.transform( source, result );

     return result.getDocument(); } catch (TransformerException ex) {     Logger.getLogger(Hudson.class.getName()).log(Level.SEVERE, null, ex); } return null;}

private String getDataFromUrl(String webUrl) { try {     URL url = new URL(webUrl);     URLConnection connection = url.openConnection();     StringBuilder builder = extractDataFromStream(connection);     String response = builder.toString();     return response; } catch (Exception e) {     System.err.println("Something went wrong...");     e.printStackTrace(); } return null;}

private StringBuilder extractDataFromStream(URLConnection connection) throws IOException { String line; StringBuilder builder = new StringBuilder(); InputStream is = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); while ((line = reader.readLine()) != null) {     builder.append(line); } return builder;}}

</code></pre>
<p><span style="font-style: italic;">FYI, you will need to reference the jaxen and dom4j JAR files to run the XML parser and query the results&#8230;</span></p>
<p><span style="font-size:130%;"><span style="font-weight: bold;">#2, The JavaFX code&#8230;</span></span></p>
<p>This example will show the build time for the Hudson project, many many other graphs are possible, but for the purposes of this demo, I will just be doing one&#8230;</p>
<p>As you can see below, the code (with a reference to the Java library above) is very simple.</p>
<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"><code>package hudsongraphs;

import javafx.stage.Stage;import javafx.scene.Scene;import hudsonremoteaccess.Hudson;import org.dom4j.Document;import org.dom4j.Element;import javafx.scene.chart.BarChart;import javafx.scene.chart.part.CategoryAxis;import javafx.scene.chart.part.NumberAxis;import javafx.scene.text.Font;import javafx.scene.paint.Color;

/*** @author Mark Macumber*/var hudson:Hudson = new Hudson();var xmlDoc:Document = hudson.getXMLHudsonQuery();var buildNumbers = xmlDoc.selectNodes("//number");var buildDurations = xmlDoc.selectNodes("//duration");var numbers:String[] = [];var durations:Number[] = [];

for (bNumber in buildNumbers) {insert (bNumber as Element).getData() as String into numbers;var bDuration = buildDurations.get(indexof bNumber);var durationInMilliseconds = Number.valueOf((bDuration as Element).getData() as String);var durationInMinutes = ((durationInMilliseconds/1000)/60);insert durationInMinutes into durations;}

Stage {title: "Hudson Build Duration Timeline"width: 800height: 450scene: Scene {content: [ BarChart {   title: "Hudson Build Duration Timeline"   width: 750   titleFont: Font { size: 24 }   categoryGap: 2   categoryAxis: CategoryAxis {     categories: numbers   }   valueAxis: NumberAxis {     label: "Build Duration (minutes)"     upperBound: 500     tickUnit: 100   }   data: [     BarChart.Series {       name: "Build #'s"       fill: Color.GREEN       data: for (j in [0..&lt;sizeof durations]) {         BarChart.Data {           category: numbers[j]           value: durations[j]           fill: Color.GREEN         }       }     }   ] }]}}

</code></pre>
<p>Basically, you just get the XML, parse it, then build the graph pieces using the JavaFX sequences.</p>
<p>Simple!!!</p>
<p>The screen shot of what this produces is below:</p>
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_k_IbgsLtQiM/SlsTuJq2yuI/AAAAAAAAAWE/W7aFtoZ-Ks4/s1600-h/hudson-graph.gif"><img style="cursor: pointer; width: 400px; height: 225px;" src="http://4.bp.blogspot.com/_k_IbgsLtQiM/SlsTuJq2yuI/AAAAAAAAAWE/W7aFtoZ-Ks4/s400/hudson-graph.gif" alt="" id="BLOGGER_PHOTO_ID_5357897865277917922" border="0" /></a></p>
<p>Pretty huh? <img src='http://markmacumber.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The above could EASILY be turned into an Applet that could be actually put onto a hosted site within Hudson, just to make it more &#8220;integrated&#8221; (Netbeans has the easy option to make an Applet out of a JavaFX application).</p>
<p>You should have all of the data to make the application above work, but if not, please do not hesitate to contact me.</p>
<p>I love feedback, please, if you have any advice, comments, criticisms, improvements, etc&#8230; please drop me a line.</p>
<p>Cheers,<br />Mark</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2009/07/javafx-graphing-and-charting-with-hudson.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gwt FastTree and a spinner icon</title>
		<link>http://markmacumber.net/2009/05/gwt-fasttree-and-a-spinner-icon.html</link>
		<comments>http://markmacumber.net/2009/05/gwt-fasttree-and-a-spinner-icon.html#comments</comments>
		<pubDate>Wed, 20 May 2009 02:46:00 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[FastTree]]></category>
		<category><![CDATA[Gwt]]></category>
		<category><![CDATA[Incubator]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://markmacumber.net/2009/05/gwt-fasttree-and-a-spinner-icon.html</guid>
		<description><![CDATA[During a project that makes use of the Google Gwt Incubator project, I was using the FastTree widget pretty actively, and found that no matter how &#8216;fast&#8217; the FastTree could render the results, there were just some times when the async rpc calls would take a short while to complete, and it would look like [...]]]></description>
			<content:encoded><![CDATA[<p>During a project that makes use of the <a href="http://code.google.com/p/google-web-toolkit-incubator/">Google Gwt Incubator project</a>, I was using the <a href="http://code.google.com/docreader/#p=google-web-toolkit-incubator&amp;s=google-web-toolkit-incubator&amp;t=FastTree">FastTree</a> widget pretty actively, and found that no matter how &#8216;fast&#8217; the FastTree could render the results, there were just some times when the async rpc calls would take a short while to complete, and it would look like nothing was happening.</p>
<p>So I quickly came across the need to implement a &#8220;spinner&#8221; on the tree. Basically, what I wanted was a nice little gif animation that would replace the expander icon on the node that he user was expanding, which would allow the user to see that there is actually something happening while they wait for their results.</p>
<p>I was hoping that the <a href="http://code.google.com/docreader/#p=google-web-toolkit-incubator&amp;s=google-web-toolkit-incubator&amp;t=FastTree">FastTree</a> widget would provide this for free, but alas, this is not the case. So I started investigating different ways to implement this need, and my results were actually <span style="font-weight: bold;">very</span> simple!</p>
<p>I started by extending the <a href="http://collectionofdemos.appspot.com/javadoc/com/google/gwt/widgetideas/client/ListeningFastTreeItem.html"><span style="font-style: italic;">ListeningFastTreeItem</span> </a>class, which basically allows the developer to handle/listen to different events of the tree, like expanding, collapsing, clicking on, losing focus, etc&#8230;
<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"><code>public class MyTreeItem extends ListeningFastTreeItem</code></pre>
<p>This then allows you to override different methods, such as beforeOpen() (as seen below) which, as described by the java doc is &#8220;Called before the tree item is opened.&#8221; and is where I chose to implement the spinner icon.</p>
<p>The idea behind the implementation is that I simply want to add a CSS class to the expanding node while it waits for the results from the server, which I can then use in a custom CSS file to implement the icon. Then once my call to the server is complete, I simply remove that CSS class.</p>
<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"><code>@Overridepublic void beforeOpen() {this.addStyleName("loading");loadChildren(id);}</code></pre>
<p>The code above simply calls a the built in &#8220;addStyleName()&#8221; method, to, surprisingly, add a style name to the current element that is expanding. Then I call a custom defined method, loadChildren() which will call the server using a standard Gwt rpc call and get the results.</p>
<p>My custom CSS class is implemented below and is really the key to this implementation:</p>
<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"><code>.gwt-FastTreeItem .loading .open {background-image: url('treeLoaderIcon.gif');}</code></pre>
<p>The 2 styles, <span style="font-style: italic;">gwt-FastTreeItem</span> and <span style="font-style: italic;">open</span> are Google Gwt class names, and the <span style="font-style: italic;">loading</span> class name (as listed above) is my custom CSS class (also listed above).</p>
<p><span style="font-style: italic;">The treeLoaderIcon.gif is also a custom loading icon, you can use any old icon here!</span></p>
<p>At this point in time, while the server is still loading is data, you should have a spinner working.</p>
<p>The next part, is to remove the spinner once the child nodes have been loading and are back on the client.</p>
<p>Luckily, this is simply, as stated below:</p>
<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"><code>theTreeItem.removeStyleName("loading");</code></pre>
<p>removeStyleName() is a built in Gwt method to remove a given style name. This line of code should be put inside your callback onSuccess() method of your Gwt rpc call.</p>
<p>that&#8217;s it!</p>
<p>If you have any questions, please don&#8217;t hesitate to ask me, leave a comment or email me!</p>
<p>Till next time!</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2009/05/gwt-fasttree-and-a-spinner-icon.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Make a rectangle grow backwards in JavaFX</title>
		<link>http://markmacumber.net/2009/05/make-a-rectangle-grow-backwards-in-javafx.html</link>
		<comments>http://markmacumber.net/2009/05/make-a-rectangle-grow-backwards-in-javafx.html#comments</comments>
		<pubDate>Mon, 04 May 2009 09:40:00 +0000</pubDate>
		<dc:creator>Macca</dc:creator>
				<category><![CDATA[FX Script]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[Timeline]]></category>
		<category><![CDATA[animation]]></category>

		<guid isPermaLink="false">http://markmacumber.net/2009/05/make-a-rectangle-grow-backwards-in-javafx.html</guid>
		<description><![CDATA[I came across a small issue when I was developing some home projects that I&#8217;ve got going (namely JFXtras) and I wanted to make a rectangle &#8220;grow backwards&#8221;.
i.e. the rectangle needs to grow upwards, not downwards when increasing the &#8220;height&#8221; of a rectangle.
Actually, the solution is quite simple, all you need to do is to [...]]]></description>
			<content:encoded><![CDATA[<p>I came across a small issue when I was developing some home projects that I&#8217;ve got going (namely <a href="http://code.google.com/p/jfxtras/">JFXtras</a>) and I wanted to make a rectangle &#8220;grow backwards&#8221;.</p>
<p>i.e. the rectangle needs to grow <span style="font-style: italic;">upwards</span>, not downwards when increasing the &#8220;<a href="http://java.sun.com/javafx/1/docs/api/javafx.scene.shape/javafx.scene.shape.Rectangle.html">height</a>&#8221; of a rectangle.</p>
<p>Actually, the solution is quite simple, all you need to do is to create a simple <a href="http://java.sun.com/javafx/1/docs/api/javafx.animation/javafx.animation.Timeline.html">Timeline</a>,  that will do 2 things:
<ol>
<li>Increase the height of the rectangle</li>
<li>Decrease the y-position of the rectangle (at the same speed as the increase of the height)</li>
</ol>
<p>thats it!</p>
<p>Below is a quick code sample that you can cut and paste to see it in action.</p>
<pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"><code>package reversi;

import javafx.animation.Interpolator;import javafx.animation.KeyFrame;import javafx.animation.Timeline;import javafx.scene.paint.Color;import javafx.scene.Scene;import javafx.scene.shape.Rectangle;import javafx.stage.Stage;

def startYPos = 250.0;def desiredHeight = 200.0;

var rectYPosition = startYPos;var rectHeight = 100.0;

var rect = Rectangle {   x: 50,   y: bind rectYPosition,   height: bind rectHeight   width: 250,   height: 100   fill: Color.BLACK}

Timeline {   keyFrames: [       KeyFrame {           time: 0s           values: [rectYPosition => startYPos tween Interpolator.EASEOUT,                    rectHeight => 0 tween Interpolator.EASEOUT]       },       KeyFrame{           time: 2s           values: [rectYPosition => startYPos - desiredHeight tween Interpolator.EASEOUT,                   rectHeight => desiredHeight tween Interpolator.EASEOUT]       }   ]}.play();

Stage {   title: "Reverse Growing"   width: 350   height: 300   scene: Scene { content: rect }}</code></pre>
<p>Pretty simple really isn&#8217;t it?</p>
<p>If anyone has a cleaner, easier solution to this small, yet relevant problem, I would love to hear it.</p>
<p>Cheers till next time!<br />Mark</p>
]]></content:encoded>
			<wfw:commentRss>http://markmacumber.net/2009/05/make-a-rectangle-grow-backwards-in-javafx.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

