| By James L. Weaver | Article Rating: |
|
| February 21, 2008 06:30 AM EST | Reads: |
13,769 |
Kevin Nilson, the leader of the Silicon Valley Web Developer JUG, relayed to me the idea of creating an application in JavaFX Script that consists of a wheel that has the names of JUG attendees on it. The wheel would revolve and land on a name, who would then receive a prize. Today's post is a first cut at this, which also demonstrates several compiled JavaFX Script features.
Here's a screenshot of the application:

When the program starts up, a wheel with some fictitious names appears. The user can click the dot in the center of the circle and enter a list of names (up to 60) in a dialog box, shown below:
Clicking the OK button causes the names entered to appear in the wheel, as shown in the screenshot above. Clicking the arrow on the left causes the wheel to spin, landing on a name, and showing a dialog box with the winner:
Presumably, since the JUG is in California, the rock bands in this list regularly attend the Silicon Valley JUGs :-)
The Source Code with a Caveat
Here's the source code for the application, but please keep in mind that the Key-Frame animation capability in compiled JavaFX Script is still under development. The syntax planned is very succinct, as referred to in the Key-Frame Animation post in Chris Oliver's Weblog. The syntax shown here uses Key-Frame animation, but is more verbose. It also exposes an underlying compiled JavaFX Script feature (pointers), that won't be exposed when the Key-Frame animation implementation is fully baked.
With that in mind, here is the source for our WinnerWheelJFX custom component. Notice that it extends CompositeNode, so it is a graphical component:
/*
* WinnerWheelJFX.fx -
* A wheel with names on it that spins
* and lands on a random name. This will
* be used initially by Java Users Groups
* to give a away door prizes. It will be
* improved upon over time, serving as an
* example of compiled JavaFX 2D graphics
* and animation.
*
* Note: The compiled JavaFX Script Key-Frame
* implementation isn't complete, so the
* animation syntax is more verbose than it
* will be in the near future.
*
* Initially developed 2008 by James L. Weaver
* (jim.weaver at lat-inc.com)
*/
import javafx.ui.*;
import javafx.ui.animation.*;
import javafx.ui.canvas.*;
import java.io.BufferedReader;
import java.io.StringReader;
import java.lang.Math;
import java.lang.System;
import com.sun.javafx.runtime.PointerFactory;
public class WinnerWheelJFX extends CompositeNode {
public attribute names:String[];
public attribute chosenName:String;
public attribute chosenIdx:Integer;
public attribute running:Boolean = true;
private static attribute maxNames = 60;
private attribute dlg:Dialog;
private attribute rand:Number;
private attribute stopValue = 1100;
private attribute a:Integer on replace (olda) {
chosenIdx = (((a * rand) % 360)
/ 360.0 * sizeof names).intValue();
chosenName = names[chosenIdx];
if (a >= stopValue) {
running = false;
MessageDialog {
title: "And the Winner Is..."
visible: true
message: chosenName
}
}
}
private attribute pf = PointerFactory {};
private attribute bpa = bind pf.make(a);
private attribute pa = bpa.unwrap();
private attribute interpolate = NumberValue.LINEAR;
private attribute t =
Timeline {
keyFrames: [
KeyFrame {
keyTime: 0s;
keyValues:
NumberValue {
target: pa;
value: 0;
interpolate: bind interpolate
}
},
KeyFrame {
keyTime: 10s;
keyValues:
NumberValue {
target: pa;
value: 700;
interpolate: bind interpolate
}
},
KeyFrame {
keyTime: 20s;
keyValues:
NumberValue {
target: pa;
value: stopValue
interpolate: bind interpolate
}
}
]
};
public function spin() {
running = true;
rand = Math.random() + .5;
interpolate = NumberValue.LINEAR;
t.start();
}
public function composeNode():Node {
var margin = 20;
var canvas = getCanvas();
var cX = bind canvas.width / 2;
var cY = bind canvas.height / 2;
var rad = bind Math.min(cX, cY) - margin;
var origX = bind cX - rad;
var origY = bind cY - rad;
return
Group {
content: [
Polygon {
var spinFillColor = Color.PURPLE
points: bind [
cX - rad,
cY,
origX / 2,
cY - (origX / 4),
origX / 2,
cY + (origX / 4)
]
cursor: Cursor.HAND
fill: bind spinFillColor
onMouseEntered:
function(cme:CanvasMouseEvent):Void {
spinFillColor = Color.YELLOW;
}
onMouseExited:
function(cme:CanvasMouseEvent):Void {
spinFillColor = Color.PURPLE;
}
onMouseClicked:
function(cme:CanvasMouseEvent):Void {
spin();
}
},
Circle {
var editFillColor = Color.RED
cx: bind cX
cy: bind cY
radius: bind rad / 30
cursor: Cursor.HAND
fill: bind editFillColor
onMouseEntered:
function(cme:CanvasMouseEvent):Void {
editFillColor = Color.BLUE;
}
onMouseExited:
function(cme:CanvasMouseEvent):Void {
editFillColor = Color.RED;
}
onMouseClicked:
function(cme:CanvasMouseEvent):Void {
dlg = Dialog {
var ta = TextArea {
rows: 10
columns: 20
background: Color.WHITE
text: ""
}
modal: true
title: "Enter Up to {maxNames} Names"
visible: true
content: ta
buttons: [
Button {
text: "OK"
defaultButton: true
action:
function():Void {
names = [];
var peopleStr:String = ta.text;
var br = new BufferedReader
((new StringReader(peopleStr)));
var line:String;
var i = 0;
while ((line = br.readLine())
<> null and i <= maxNames) {
insert line into names;
i++;
}
dlg.hide();
}
},
Button {
text: "Cancel"
defaultCancelButton: true
action:
function():Void {
dlg.hide();
}
}
]
};
}
},
Group {
transform: bind [
Rotate.rotate(if (running) (a * rand) % 360
else chosenIdx.doubleValue()
/ sizeof names * 360.0, cX, cY)
]
content: bind [
for (name in names)
Text {
transform: [
Rotate.rotate(((sizeof names
- indexof name).doubleValue() /
sizeof names * 360) % 360, cX, cY)
]
font:
Font {
face: FontFace.SANSSERIF
size: 16
style: FontStyle.BOLD
}
fill: if ((indexof name % 3) == 1) Color.RED
else if ((indexof name % 3) == 2) Color.BLUE
else Color.GREEN
x: cX - rad + 5
y: cY
content: "{name}"
}
]
}
]
};
}
}
Published February 21, 2008 Reads 13,769
Copyright © 2008 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By James L. Weaver
James L. (Jim) Weaver is founder and president of jMentor, formed in 2000 to provide Java programming-related training to companies and individuals. He has served as a system architect and developer for over 25 years, specializing in leading-edge software development. His specialties include Java, object-oriented, and web-based technologies. He has authored books on the Java programming language, including most recently JavaFX Script, published by Apress.
![]() |
Tattoo Designs 07/24/08 07:03:37 PM EDT | |||
Interesting little idea. I'd like to see it made into a more useful example, or used for a more practical purpose. |
||||
![]() |
MICR Toner 06/23/08 01:51:54 AM EDT | |||
So, this is sort of like a wheel of fortune interface for random selection of a bunch of names we can enter? I'll try it out. It could come in handy one day. |
||||
- Ubuntu-based Open Source Linux Mint Tests KDE Version
- Linux Virtualization and Tired Open Source Myths
- IGEL Supports Red Hat Enterprise Virtualization 3.0
- CloudLinux Announces Support for Atomia
- Amazon Kindle Fire Gets Its Own 'Personal Cloud Desktop' with AlwaysOnPC App Launch
- SPIRIT DSP Receives 2011 INTERNET TELEPHONY Product of the Year Award
- Hadoop Quickstart: Use Whirr to automate standup of your distributed cluster on Rackspace
- Jury Gets Novell Antitrust Case Against Microsoft
- The Utility Infrastructure Security Market 2012-2022: Cybersecurity & Smart Grids
- FORTUNE Magazine Names Rackspace Among “100 Best Companies to Work For”
- iFollowOffice Turns to Virtual Bridges and Savvis for On-Demand Virtual Desktop Services
- Convirture Reports Strong 2011 as Virtualization Management Takes Off
- i-Technology in 2012: Five Industry Predictions
- Ubuntu-based Open Source Linux Mint Tests KDE Version
- Amazon to Rent Out Supercomputers
- Amazon Émigré Starts Network Monitoring Firm
- HP’s Putting a Back Door in the Itanium Alamo
- Linux Virtualization and Tired Open Source Myths
- CloudLinux Announces Preferred Partner Program
- MapR Pushes the Hadoop Envelope
- Rightware Announces Gaming Performance Benchmark for OpenGL ES 3.0/Halti
- IGEL Supports Red Hat Enterprise Virtualization 3.0
- CloudLinux Announces Support for Atomia
- 3Dconnexion Announces its Newest 3D Mouse - the SpaceMouse Pro
- The i-Technology Right Stuff
- Linux.SYS-CON.com Exclusive: Linus Discloses *Real* Fathers of Linux
- After Ubuntu, Windows Looks Increasingly Bad, Increasingly Archaic, Increasingly Unfriendly
- A Closer Look at Damn Small Linux
- Linus' Top Ten SCO Barbs
- SCO CEO Posts Open Letter to the Open Source Community
- Netscape Co-Founder's 12 Reasons for Growth of Open Source
- Where Are RIA Technologies Headed in 2008?
- *POINT - COUNTERPOINT SPECIAL* What's Wrong with the Open Source Community?
- Introducing "Cooperative Linux" - Linux for Windows, No Less
- Linux.SYS-CON.com Exclusive: What Would UserLinux Look Like?
- Why Recovering a Deleted Ext3 File Is Difficult . . .






















