<?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>Steve On Java &#187; time</title>
	<atom:link href="http://steveonjava.com/tag/time/feed/" rel="self" type="application/rss+xml" />
	<link>http://steveonjava.com</link>
	<description>Hacking Java, JavaFX, and Flash with Agility</description>
	<lastBuildDate>Sun, 20 May 2012 16:57:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>30 Lines of JavaFX</title>
		<link>http://javafx.steveonjava.com/30-lines-of-javafx/</link>
		<comments>http://javafx.steveonjava.com/30-lines-of-javafx/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 07:49:43 +0000</pubDate>
		<dc:creator>steveonjava</dc:creator>
				<category><![CDATA[Contest]]></category>
		<category><![CDATA[JavaFX]]></category>
		<category><![CDATA[jfxstudio]]></category>
		<category><![CDATA[time]]></category>

		<guid isPermaLink="false">http://steveonjava.com/?p=621</guid>
		<description><![CDATA[What can you do in 30 lines of JavaFX?  JFXStudio is running a contest right now to find this out&#8230; http://jfxstudio.wordpress.com/2009/08/31/jfxstudio-challenge-small-is-the-new-big/ I strongly encourage you to give it a try.  So much so that I took a quick stab at putting together a sample myself this evening.  Welcome to the Time Wheel: Everything is rendered [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_blue" style="float: left;margin-right: 0.75em;; margin-top: 4px; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Fjavafx.steveonjava.com%252F30-lines-of-javafx%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%2230%20Lines%20of%20JavaFX%22%20%7D);"></div>
<!--S-ButtonZ 1.1.5 Start--><div style="float: left; width: 42px; padding-right: 10px; margin: 0 10px 0 0;">
		<script type="text/javascript">
		<!--
		var dzone_url = "http://javafx.steveonjava.com/30-lines-of-javafx/";
		var dzone_title = "30 Lines of JavaFX";
		var dzone_style = "1";
		var dzone_blurb = "";
		//-->
		</script>
		<script language="javascript" src="http://widgets.dzone.com/widgets/zoneit.js"></script></div><!--S-ButtonZ 1.1.5 End--><p>What can you do in 30 lines of JavaFX?  JFXStudio is running a contest right now to find this out&#8230;</p>
<p><a href="http://jfxstudio.wordpress.com/2009/08/31/jfxstudio-challenge-small-is-the-new-big/">http://jfxstudio.wordpress.com/2009/08/31/jfxstudio-challenge-small-is-the-new-big/</a></p>
<p>I strongly encourage you to give it a try.  So much so that I took a quick stab at putting together a sample myself this evening.  Welcome to the Time Wheel:</p>
<p><a href="http://javafx.steveonjava.com/30-lines-of-javafx/"><em>Click here to view the embedded video.</em></a></p>
<p>Everything is rendered using JavaFX Shape and Text primitives with clever PerspectiveTransform effects applied.  I also made use of an overlay gradient Flooded and Blended on an outer group in order to create the top and bottom shadow giving it a rounded 3d appearance.</p>
<p><span id="more-621"></span>Below is the full code for the application (clearly I was going for the 3000 character limit).  The formatted version was about 200 lines long and over 4000 characters, but by shortening variable names, removing white space, and merging lines, I was able to bring it down substantially.  This is definitely not a recommended coding practice, but met the contest constraints:</p>
<pre>import javafx.scene.*;import javafx.scene.effect.*;import javafx.scene.layout.*;import javafx.scene.paint.*;import javafx.scene.paint.Color.*;
import javafx.scene.shape.*;import javafx.scene.text.*;import javafx.stage.*;import javafx.util.Math;import javafx.animation.*;import javafx.scene.media.*;
var ez=Interpolator.EASEBOTH;class Slot{var n:Node[];var v:Number on replace{
Timeline{keyFrames:at(.9s){c =&gt; v tween ez}}.play();a();}
var a:function();var c:Number;var e:String[];var s:Number;var f:Number;
init{var entryHeight=bind Math.sin(Math.PI/sizeof e)*h;n=for(entry in e)Stack{
var textLine:Text;content:[Group{var w1=bind Math.max(w,textLine.boundsInLocal.width);
content:[Rectangle{width:bind w1,height:bind h/12,fill:bind if(indexof entry mod 3==0){LIGHTGRAY} else if(indexof entry mod 3==1){DARKGRAY}
else{hsb(360*Math.abs((indexof entry*2-sizeof e as Number)/sizeof e),.4,.7)}}]}
textLine=Text{content:bind entry font:bind Font.font(null,h/12*.75)}]
visible:bind Math.abs(indexof entry-(c mod sizeof e))&lt;=(sizeof e as Number)/4 or Math.abs(indexof entry-(c mod sizeof e))&gt;=(sizeof e as Number)*3/4
effect:PerspectiveTransform{var sw=bind 360.0/sizeof e;var a=bind(indexof entry-c mod sizeof e)/sizeof e*360 + 90-sw/2;def sr=bind Math.toRadians(a + 90);
def er=bind Math.toRadians(a + 90 + sw);def r=bind h/2;var uy=bind r + Math.sin(er)*r;uly:bind uy ury:bind uy var ly=bind r + Math.sin(sr)*r;
lly:bind ly lry:bind ly ulx:bind Math.cos(er)*r*s;llx:bind Math.cos(sr)*r*s;urx:bind w-Math.cos(er)*r*f;lrx:bind w-Math.cos(sr)*r*f;}}}}
var x=45;var y=10;var w=24;var h=200;var ss=for(i in [1..9])Slot{e:for(j in [0..9])"{j}"s:.3-indexof i*.07 f:-.25 + indexof i*.07}
var so=MediaPlayer{media:Media{source:"http://jfxtras.org/sounds/beep.wav";}}
var bg:Color;ss[5].a=function(){so.stop();so.currentTime=0s;so.play();
Timeline{keyFrames:[at(50ms){bg =&gt; GREEN tween ez}at(150ms){bg =&gt; BLACK tween ez}]}.play();}
var d:java.util.Date;
Timeline{repeatCount:Timeline.INDEFINITE keyFrames:KeyFrame{time:1ms canSkip:true action:function(){d=new java.util.Date();
ss[8].c=java.lang.System.currentTimeMillis()mod 10;ss[7].c=(java.lang.System.currentTimeMillis()mod 100 as Number)/10;
ss[6].c=(java.lang.System.currentTimeMillis()mod 1000 as Number)/100;ss[5].v=d.getSeconds()mod 10;ss[4].v=d.getSeconds()/10;
ss[3].v=d.getMinutes()mod 10;ss[2].v=d.getMinutes()/10;ss[1].v=d.getHours()mod 10;ss[0].v=d.getHours()/10;}}}.play();
Stage{width:400 height:300 title:"Time Wheel"scene:Scene{fill:bind bg content:Group{content:[for(s in ss)Panel{
translateX:x + indexof s*30 +(Math.min(indexof s,7)/2)*10 translateY:y content:s.n height:h width:w}Text{content:bind "The time is now: {d}",fill:WHITE,x:58,y:242}]
effect:Blend{mode:BlendMode.SRC_ATOP topInput:Flood{paint:LinearGradient{endX:0 stops:[
Stop{offset:0,color:color(0,0,0,.9)}Stop{offset:.3,color:TRANSPARENT}Stop{offset:.7,color:TRANSPARENT}Stop{offset:1,color:color(0,0,0,.9)}]}
y:y width:400 height:h}}}}}</pre>
<p>There is still time to get your own submission in for the contest.  The official deadline is Wednesday at midnight, so with a little hard work and determination you can easily crank out 30 lines of JavaFX goodness!</p>
<p><strong>Update</strong>:  By popular demand, here is a cleanly formatted version of the same code:</p>
<pre class="brush: java; title: ; notranslate">
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.paint.Color.*;
import javafx.scene.shape.*;
import javafx.scene.text.*;
import javafx.stage.*;
import javafx.util.Math;
import javafx.animation.*;
import javafx.scene.media.*;

class Slot {
    var node:Node[];
    var value:Number on replace {
            Timeline {keyFrames: at(.9s) {center =&amp;gt; value tween Interpolator.EASEBOTH}}.play();
        action();
    }
    var action:function();
    var center:Number;
    var entries:String[];
    var start:Number;
    var finish:Number;

    init {
        var entryHeight = bind Math.sin(Math.PI / sizeof entries) * height;
        node = for (entry in entries) Stack {
            var textLine: Text;
            content: [
                Group {
                    var w1 = bind Math.max(width,textLine.boundsInLocal.width);
                    content: [
                        Rectangle {
                            width: bind w1
                            height: bind height/12
                            fill: bind if (indexof entry mod 3 == 0) {
                                LIGHTGRAY
                            } else if (indexof entry mod 3 == 1) {
                                DARKGRAY
                            } else {
                                hsb(360 * Math.abs((indexof entry*2-sizeof entries as Number) / sizeof entries), .4, .7)
                            }
                        }
                    ]
                }
                textLine = Text {
                    content: bind entry
                    font: bind Font.font(null, height / 12 * .75)
                }
            ]
            visible: bind Math.abs(indexof entry - (center mod sizeof entries)) &amp;lt;= (sizeof entries as Number) / 4 or Math.abs(indexof entry - (center mod sizeof entries)) &amp;gt;= (sizeof entries as Number) * 3/4
            effect: PerspectiveTransform {
                var sweep = bind 360.0 / sizeof entries;
                var action = bind(indexof entry - center mod sizeof entries) / sizeof entries * 360 + 90 - sweep/2;
                def startRadians = bind Math.toRadians(action + 90);
                def endRadians = bind Math.toRadians(action + 90 + sweep);
                def radius = bind height/2;
                var uy = bind radius + Math.sin(endRadians) * radius;
                uly: bind uy
                ury: bind uy
                var ly = bind radius + Math.sin(startRadians) * radius;
                lly: bind ly
                lry: bind ly
                ulx: bind Math.cos(endRadians) * radius * start
                llx: bind Math.cos(startRadians) * radius * start
                urx: bind width-Math.cos(endRadians)*radius*finish
                lrx: bind width-Math.cos(startRadians)*radius*finish
            }
        }
    }
}
var x = 45;
var y = 10;
var width = 24;
var height = 200;
var slots = for(i in [1..9]) Slot {
    entries: for(j in [0..9]) &amp;quot; {j}&amp;quot;
    start: .3 - indexof i * .07
    finish: -.25 + indexof i * .07
}
var beep = MediaPlayer {
    media: Media {
        source: &amp;quot;http://jfxtras.org/sounds/beep.wav&amp;quot;;
    }
}
var bgColor: Color;
slots[5].action = function() {beep.stop();
    beep.currentTime = 0s;
    beep.play();
    Timeline {
        keyFrames: [
            at(50ms) {bgColor =&amp;gt; GREEN tween Interpolator.EASEBOTH}
            at(150ms) {bgColor =&amp;gt; BLACK tween Interpolator.EASEBOTH}
        ]
    }.play();
}
var d: java.util.Date;

Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames: KeyFrame {
        time: 1ms
        canSkip: true
        action: function() {
            d = new java.util.Date();
            slots[8].center = java.lang.System.currentTimeMillis() mod 10;
            slots[7].center = (java.lang.System.currentTimeMillis() mod 100 as Number) / 10;
            slots[6].center = (java.lang.System.currentTimeMillis() mod 1000 as Number) / 100;
            slots[5].value = d.getSeconds() mod 10;
            slots[4].value = d.getSeconds() / 10;
            slots[3].value = d.getMinutes() mod 10;
            slots[2].value = d.getMinutes() / 10;
            slots[1].value = d.getHours() mod 10;
            slots[0].value = d.getHours() / 10;
        }
    }
}.play();

Stage {
    width: 400
    height: 300
    title: &amp;quot;Time Wheel&amp;quot;
    scene: Scene {
        fill: bind bgColor
        content: Group {
            content: [
                for(start in slots) Panel {
                    translateX: x + indexof start*30 +(Math.min(indexof start,7)/2)*10
                    translateY: y content: start.node height: height width: width
                }
                Text {
                    content: bind &amp;quot;The time is now: {d}&amp;quot;
                    fill: WHITE
                    x: 58
                    y: 242
                }
            ]
            effect: Blend {
                mode: BlendMode.SRC_ATOP
                topInput: Flood {
                    paint: LinearGradient {
                        endX: 0
                        stops: [
                            Stop {offset: 0, color: color(0,0,0,.9)}
                            Stop {offset: .3, color: TRANSPARENT}
                            Stop {offset: .7, color: TRANSPARENT}
                            Stop {offset: 1, color: color(0,0,0,.9)}
                        ]
                    }
                    y: y
                    width: 400
                    height: height
                }
            }
        }
    }
}
</pre>
<div class="plus-one-wrap"><g:plusone href="http://javafx.steveonjava.com/30-lines-of-javafx/"></g:plusone></div><div style="clear:both;">&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://javafx.steveonjava.com/30-lines-of-javafx/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
<enclosure url="http://jfxtras.org/sounds/beep.wav" length="4562" type="audio/x-wav" />
		</item>
	</channel>
</rss>

