newfoo2010-07-12T09:i:1278939657-05:00http://newfoo.net/Jim Connelljames.d.connell@gmail.comGood Practices for Big iPhone Projects2010-07-07T00:i:1278475200-05:00http://newfoo.net/2010/07/07/good-practices-for-big-iphone-projects.html
<p>Developing a high-quality iPhone app can be tricky stuff for new and veteran developers alike - especially on larger projects. In this article, I'll discuss several tools & techniques that have helped my teams and me to produce high quality work and helped save a lot of time.</p>
<h2>Use Multiple Build Configurations</h2>
<p>Build configurations are an excellent way to separate configuration elements depending on the type of build you’re producing. For instance, you might want to use different names for each version of your app: Development, Staging, and Production. By giving each version a different name, you can install multiple versions of the app on the same device. I like prepending greek letters such as δ, β to the app names for different builds. Here’s a <a href="http://piyo.piyocast.com/example_image/changeproductname.png">helpful visual diagram</a> I found that shows how to change your app’s product name. Different build configurations are also useful for a number of other tips presented in this article.</p>
<p>To enable a new build configuration, use “Project -> Edit Project Settings.” and click on the “Configurations” tab. Pick the configuration “most like” the configuration you’d like to make. You can then make changes to your individual configurations that suit that particular build such as modifying the CFLAGs used (see the logging tip below for an example).</p>
<h2>Use an Enhanced UIColor</h2>
<p>The designers I work with usually express colors as hex strings, so it’d be nice to use hex strings with UIColor. The default UIColor class doesn’t have this capability, but you can fix this by adding a custom Category to UIColor. </p>
<p>
<pre class="brush: cpp">
// file: UIColor+NFColors.h
@interface UIColor (NFColors)
// Create a new UIColor instance using the following long value (see
// UIColor#colorWithHex for an example) and desired alpha value.
// 1.0 for opaque, 0.0 for transparent.
// Example: Light gray color of EFEFEF [UIColor colorWithHex:0xefefef alpha:1.0]
+ (UIColor *)colorWithHex:(long)hexColor alpha:(float)opacity;
@end
// file: UIColor+NFColors.m
@implementation UIColor(NFColors)
+ (UIColor *)colorWithHex:(long)hexColor alpha:(float)opacity
{
float red = ((float)((hexColor & 0xFF0000) >> 16))/255.0;
float green = ((float)((hexColor & 0xFF00) >> 8))/255.0;
float blue = ((float)(hexColor & 0xFF))/255.0;
return [UIColor colorWithRed:red green:green blue:blue alpha:opacity];
}
@end
</pre>
</p>
<p>With this category installed in your project, you can simply invoke <code>[UIColor colorWithHex:0xefefef]</code> to produce a light gray (#efefef) color.</p>
<h2>Use isEmpty Instead of Nil and Length Checks</h2>
<p>It’s amazing how often you’re looking at an object to determine if it’s empty input. Depending on the context, you might have an NSString variable that can be “nil” when not set in one place OR an empty string in another. Sometimes either nil or empty strings are acceptable “NULL” values. In these cases, you’ll want to do a test similar to this:</p>
<p>
<pre class="brush: cpp">
if (mystring == nil || [mystring length] == 0) {
// handle empty string
}
</pre>
</p>
<p>That kind of code can get very repetitive and error-prone though. A nicer way would be to define a function that does the same thing but with out all the typing. Below is a isEmpty function that does just that. I stole it from <a href="http://www.wilshipley.com/blog/2005/10/pimp-my-code-interlude-free-code.html">Wil Shipley</a>. Wil explains a number of other reasons why isEmpty is better than manually checking all over the place. If you place this function in one of your headers, it’ll be placed “inline” in your program where ever it’s used. That means there will be no extra overhead for this call — it’ll behave as fast as if you’d written this code inline yourself every where.</p>
<p>
<pre class="brush: cpp">
// some globally used header
static inline BOOL isEmpty(id thing) {
return thing == nil
|| [thing isKindOfClass:[NSNull class]]
|| ([thing respondsToSelector:@selector(length)]
&& [(NSData *)thing length] == 0)
|| ([thing respondsToSelector:@selector(count)]
&& [(NSArray *)thing count] == 0);
}
// in code later on:
if (isEmpty(mystring)) {
// handle empty string.
}
</pre>
</p>
<h2>Use Logging</h2>
<p>Logging is a critical tool for quickly debugging apps as you build them. You can use the Objective-C’s logging function to print out application state all over your program. If you run your logging enabled app in the debugger, you can watch how the app state changes. Objective-C’s default logging statement is NSLog(NSString *, ...). You can pass a formatted string and a variable list of arguments. </p>
<p>NSLog is a great way to quickly see debug information about your app in real-time, but there is one problem you should be aware of — NSLog will always log your output even in production builds. If you’re using logging judiciously, then your production app will be <em>very</em> slow. With a little work though, we can enhance logging so that we can use it everywhere, but without the performance problems on our production builds.</p>
<h3>A Better NSLog</h3>
<p>You can work around the performance problems of NSLog using C macros. Using C macros, we can create a version of NSLog that’s simply not compiled into production versions of our app. Macros are “executed” at compile time and not at runtime, so we can use them to conditionally compile in or out code according to our own rules. We’ll use a C macro for our logging function that expect a macro called NF_DEBUG_ENABLED to defined when we want to log, otherwise we don’t want it to do anything. The C compiler will simply replace our macro with no operation for production builds when the NF_DEBUG_ENABLED macro value is not defined. For our debug builds, we’ll just optionally define NF_DEBUG_ENABLED so that we can see our desired debug output. One way to do this is to enable change CFlags our Development build configuration. In Xcode you can do that by changing the appropriate build configuration’s “Other C Flags” settings to include “-DNF_DEBUG_ENABLED=1”. Below is the source for a simple Logging Utility.</p>
<p>
<pre class="brush: cpp">
#ifdef NF_DEBUG_LEVEL
#define NFDebug( s, ... ) NSLog( @"DEBUG: %s: %@", __PRETTY_FUNCTION__, \
[NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define NFDebug( s, ...)
#endif
</pre>
</p>
<p>You’d use the macro just as you would use NSLog. You can even extend this idea to make different logging levels too — you can make a version for Trace, Debug, Warn, Error — as many levels as you like. This macro also the very useful side-effect that it will include the object & method name where this debug statement was printed from.</p>
<p>
<pre class="brush: cpp">
NFDebug(@"Name is %@ and age is %d", [myobject name], [myobject age]);
// this might produce a line in your log such as: DEBUG: [MYClass myfunction]: Name is Mike and age is 41
</pre>
</p>
<h2>Treat Compile Warnings as Errors</h2>
<p>Objective-C allows you to get away with a lot of things its more static cousins such as Java, C# and C++ do not. By default, many of the things you can “get away with” are simply marked as warnings and not hard errors. For instance, you can invoke selectors directly on an object even if its public interface doesn’t declare the selector. If the object actually implements the selector, there will be no runtime error. This can sometimes be a very useful feature. Unfortunately, I’ve found that on bigger teams and codebases, this also leads to many innocuous warnings that bury warnings we should really see.</p>
<p>I’ve found it a better policy to simply treat these warnings as errors in Xcode right from the start. That way, it becomes easier to spot warnings that are really errors. To enable this feature, enable “Treat Warnings as Errors” under “<span class="caps">GCC</span> x.x Warnings” in your build configuration.</p>
<p>Okay, you’re probably thinking — <strong>hey I actually <em>need</em> to access a selector dynamically</strong>, but now the compiler won’t let me because I’m treating warnings as errors! Well, there’s an option for that too. In my opinion, this option is also a more robust way of invoking unspecified selectors. You can use the respondsToSelector/performSelector option instead:</p>
<p>
<pre class="brush: cpp">
@class Apple < NSObject {
}
- (void)consume;
@end
// apple.m
@implementation Apple {
// part of the "private" interface
- (void)chopFirst {
// ...
}
}
// in some method somewhere:
- (void)eatFruit:(Fruit *)fruit {
[fruit chopFirst]; // generates compile warning / error depending on your settings
[fruit consume];
// a safer way to execute chopFirst without a compile warning / error!
SEL chopFirst = @selector(chopFirst:);
if ([application respondsToSelector:chopFirst]) {
[application performSelector:chopFirst];
} else { // our object doesn't handle this selector, need to fall back
}
}
</pre>
</p>
<p>The performSelector method also has a few variants that can be used if your selectors take an argument or two. If your needs are more complicated, you can also use NSInvocations for complete flexibility on how a method is dynamically invoked on an object.</p>
<h2>Use Static Analysis Frequently</h2>
<p>Somewhat related to treating errors as warnings, it’s very useful to run Xcode’s static analysis as frequently as you can. Though it won’t help you find virtually every memory leak like Instruments will, it will help you find a large majority of memory leaks with almost no effort. It’s well worth taking the time to run this type of build every day or two during a heavy development cycle. To perform static analysis, simply select Build and Analyze from the Build menu in Xcode.</p>
<h2>Learn Apple’s Rules for Memory Management</h2>
<p>Most of the time I come across memory issues in codebases, it’s because teams aren’t using Apple’s memory management rules consistently or even at all. The worst type of memory issue is are crashes where a program attempts to invoke a method on an object that’s been released already. 99% of the time, this type of issue has come down to disobeying the <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH">fundamental rule of memory management in Objective-C</a> in some way:</p>
<blockquote>
You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.
</blockquote>
<p>Apple’s documentation has <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH">several useful corollaries</a> to this fundamental rule too. In addition to their corollaries, I have a few other useful corollaries, that apply to situations I’ve seen frequently enough:</p>
<ul>
<li>Name <strong>your own methods</strong> according to the fundamental rule. If your methods are returning an object that’s now owned by its invoker, make sure your method name begins with “alloc”, “new”, or “copy.” Another plug for Static Analysis — it’ll warn you if you if you disobey this corollary!</li>
<li>In a class hierarchy, if you have more than one ivar referring to the same instance, make sure either both classes are retaining/releasing the object OR it’s clear which object owns the memory.</li>
</ul>
Introducing Kelvin for Static Websites2010-04-21T00:i:1271822400-05:00http://newfoo.net/2010/04/21/introducing-kelvin-for-static-websites.html
<p>About a year ago when I was blogging more, I discovered a neat static website generation tool called Jekyll. I really liked being able to edit my files in my favorite text editor. Unfortunately, it was difficult to add a few of the features I wanted, and I wasn't crazy about the Liquid template language Jekyll used, so I decided to spin off a Python version. The result of this work was Kelvin, the engine powering this blog. In this post, I'll describe Kelvin and how I use it.</p>
<h2>Features</h2>
<p>Even though Kelvin is a small python program, it packs enough features to make it suitable for people writing a static blog. Kelvin has the following features:</p>
<ul>
<li>Template framework (currently supporting jinja2 templates)</li>
<li>A blog model that can be accessed within any template</li>
<li>Small dependency list: pyyaml, jinja2</li>
<li>Simple, but powerful extension mechanism for adding custom features</li>
<li>Flexible metadata in posts so you can add data to your posts and retrieve them in your templates.</li>
</ul>
<p>My own blog takes advantages of all these features and handles comments using disqus.</p>
<h2>Usage</h2>
<p>Kelvin steals a bunch of ideas from Jekyll. Kelvin operates on an input directory structure that looks similar to the following and produces a rendered website:</p>
<p><strong>input:</strong></p>
<ul>
<li>_layouts</li>
<li>_posts
<ul>
<li>python
<ul>
<li>YYYY-MM-DD-article-title.html</li>
</ul></li>
<li>category2</li>
</ul></li>
<li>_extensions</li>
<li>about
<ul>
<li>index.html</li>
</ul></li>
<li>index.html</li>
</ul>
<p><strong>output</strong></p>
<ul>
<li><span class="caps">YYYY</span>
<ul>
<li>MM
<ul>
<li>DD
<ul>
<li>article-title.html</li>
</ul></li>
</ul></li>
</ul></li>
<li>about
<ul>
<li>index.html</li>
</ul></li>
<li>index.html</li>
</ul>
<p>The directories beginning with an underscore (”_”) all have special meaning, much like they do with Jekyll. The _layouts directory holds all of the templates. The _posts directory holds all of the categories and blog posts under each category. The _extensions directory allows for customization. You can do pretty much anything you want with extensions. On my site, I made a simple extension for creating a category page generator and a textile filter for my jinja2 templates.</p>
<p>The Kelvin engine will traverse through all folders/files on the site. For all posts and other regular files, it’ll look for a special metadata block beginning and ending with three dashes. Each of these files (pages) will be sent through the template engine. All other files, such as <span class="caps">CSS</span>, JavaScripts, or even non-template <span class="caps">HTML</span> files, will be copied to the output directory.</p>
<p>A sample Kelvin website that contains two blog posts, a home page and a simple Atom feed file is included with the project is.</p>
<h3>Invoking Kelvin</h3>
<p>Invoking Kelvin is very simple; it expects a source directory and an output directory. It’ll overwrite files as necessary in the output directory. </p>
<p>
<pre class="brush: bash">
myserver% kelvin.py [path to source] [path to output]
</pre>
</p>
<h3>Page File Format</h3>
<p>Below is an example page for Kelvin. It’s broken into two blocks: the <span class="caps">YAML</span> descriptor block (at the top) and the content block. The <span class="caps">YAML</span> descriptor block contains all the metadata for the page. Kelvin exposes all of these metadata attributes to the page template. The engine only interprets the layout attribute. If Kelvin encounters a page, but doesn’t find a layout property, it assumes the page itself <em>IS</em> the template. This is handy for producing an <span class="caps">RSS</span> template for example.</p>
<p>
<pre><code>
---
layout: post.html
title: My Cool Story
blurb: "Here is a blurb that I've written."
---
<h1>HTML Header</h1>
<p>A simple paragraphy</p>
etc.
</code></pre>
</p>
<h4>Page Properties</h4>
<p>The following properties are available to all pages.</p>
<ul>
<li>layout: Kelvin will look for a template under the _layouts directory matching this name</li>
<li>body: This is the translated body after. It’s useful when using template inheritance.</li>
</ul>
<h4>Post Properties</h4>
<p>Blog posts expose several other properties to templates in addition to the page properties:</p>
<ul>
<li>url: The rendered <span class="caps">URL</span> relative to site root</li>
<li>date: The date of the post</li>
</ul>
<h2>Developing Against</h2>
<p>It’s fairly straightforward to get setup using Kelvin. You’ll just need to grab the source from github and install its dependencies. Kelvin requires the following packages: pyyaml 3.09, Jinja2 2.4.1. You should be able to install both of these using <i>pip</i>.</p>
<p>
<pre class="brush: bash">
myserver% pip install pyyaml jinja2
</pre>
</p>
<h2>What’s Next</h2>
<p>I’m using Kelvin for a larger project I’m working on, so I’ll be adding a few features as I go:</p>
<ul>
<li>A proper python setup script</li>
<li>Support for multiple python template engines</li>
<li>Category (and possibly tag) support in the main engine (it’s currently an extension on my site).</li>
<li>More examples, including the source to my site.</li>
</ul>
Building An Analytics Dashboard with JavaFX2009-05-12T00:i:1242100800-05:00http://newfoo.net/2009/05/12/building-an-analytics-dashboard-with-javafx.html
<p>One of the interesting features of JavaFX is its ability to leverage existing Java APIs. Accessing pure Java APIs in JavaFX applications is almost as simple as it would be in a pure Java application. This means that your JavaFX application can not only access all of the standard JavaSE APIs, but any Java API as well. In this article, I'll show you how to leverage an existing Java API to build a complex web services user-interface with JavaFX. As always, I'll point out how some of the more interesting parts of the application work.</p>
<h2>Google Analytics Dashboard</h2>
<p>For those of you not familiar with <a href="http://www.google.com/analytics/">Google Analytics</a>, it’s a service that allows you to analyze just about anything you might want to track on your web site. The service provides a number of different pre-built reports and graphs that allow you to quickly examine how your web site is meeting your goals. </p>
<div style="float: right">
<img style="float: left;" src="/2009/05/analytics-dashboard.png" alt="Capture of Analytics Dashboard"/>
<br />
<a style="float: left;" href="/2009/05/AnalyticsDashboard/AnalyticsDashboard.jnlp">
<img border="0" title="Webstart.small2" src="/images/jnlp_launch.gif" alt="Webstart.small2"/>
</a>
</div>
<p>I often find myself wanting to quickly view three things about sites: how many people are visiting, where they’re coming from and which pages are the most popular. It’s possible to get this information from Google Analytics, but it requires a few clicks every time. So, when Google recently <a href="http://analytics.blogspot.com/2009/04/attention-developers-google-analytics.html">announced</a> it had <a href="http://code.google.com/apis/analytics/docs/gdata/1.0/gdataJava.html">released a GA API</a>, there was a new opportunity to make a dashboard that showed exactly what I needed on one screen. Naturally, I created the dashboard using JavaFX. The demo application provides a real login prompt to the Google Analytics <span class="caps">API</span>. Try it out yourself! If you have more than one site attached to your google account, you’ll have the chance to pick a site before viewing your dashboard. If you don’t have a GA account, no sweat — there’s a “fake login” button that produces random data to give you an idea of what the application does.</p>
<p>If you’d like to check out the source code of the application, I’ve released it under the <span class="caps">MIT</span> open source license <a href="http://github.com/jcon/Analytics-Dashboard">here</a> on <a href="http://github.com">GitHub</a>.</p>
<h2>Implementing The Dashboard</h2>
<p>The application is divided into two major pieces: the Analytics <span class="caps">API</span> client is written in Java and the user-interface in JavaFX. The <span class="caps">API</span> client takes care of all the plumbing required by the GData client APIs to provide a simple facade for the the user-interface to pull the information it needs. The JavaFX user-interface is responsible for displaying the data graphically, coordinating events and applying effects.</p>
<h3>Java <span class="caps">API</span> for Analytics Client Logic</h3>
<p>There are a number of approaches you can use to integrate Java <span class="caps">API</span> calls into your JavaFX application. In this application, I chose to design a Java facade to encapsulate the necessary <span class="caps">API</span> calls. This approach is useful for two reasons: it helps cleanly separate the middleware of the application from the user-interface and it allows us to show that you can mix Java <span class="caps">API</span> wrappers in the same project as the rest of your JavaFX code. Below is the interface that’s used by JavaFX. As far as our UI is concerned, this is about as simple an interface to our GA data as we might hope for.</p>
<p>
<pre class="brush: java">
public interface AnalyticsClient {
/** Authenticate a user */
void login(String user, String pass);
/** After logging in, provide the list of sites to which the
user is subscribed. */
List<Site> getSites();
/** Set a valid GA profileID obtained from one of the sites in getSites() */
void setProfileId(String profileId);
/** provide a list of hits for a given date range */
List<TimeEntry> hits(String start, String end);
/** list pages ordered by # of visitors for date range */
List<Pair<String, Long>> topPages(String start, String end);
/** list referrers ordered by # visits for date range */
List<Pair<String, Long>> topReferrers(String start, String end);
}
</pre>
</p>
<p>There are two implementations of this interface: GdataAnalyticsClient and FakeAnalyticsClient. The fake client merely produces random data in a form expected by the UI in the event that a GA login is not available. The GData client authenticates users using their google accounts and issues the appropriate GData queries required to produce the dashboard. Accessing a given implementation is pretty easy. In this application, a LoginController is responsible for choosing which implementation of AnalyticsClient the application should use depending on which button the user clicks on. Here’s the code:</p>
<p>
<pre class="brush: java">
// ...
loginAction: function(username, password) {
client = GdataAnalyticsClient{ };
// .. Gdata Specific logic
}
fakeAction: function(username, password) {
client = FakeAnalyticsClient{ };
//
}
// ...
</pre>
</p>
<p>With an appropriate instance of AnalyticsClient, our JavaFX program is free to call any of the methods in its interface using familiar <em>dot</em> notation to invoke them. For instance to see which pages were our top pages for a given period we’d invoke the following method:</p>
<p>
<pre class="brush: java">
// hits will refer to a List<TimeEntry> instance
var hits = client.topPages(start, end);
</pre>
</p>
<h3>JavaFX Script for User Interface</h3>
<p>Much like many of the <a href="/2009/03/24/game-design-with-javafx-production-suite.html">other</a> <a href="/2009/01/14/creating-a-javafx-design-without-programming.html">examples</a> I’ve produced so far, the majority of the user-interface was built using a graphics suite (this time I used InkScape). The interface was then converted to native JavaFX using the Production Suite. Unlike the other Production Suite examples I’ve shown in the past, this application uses JavaFX code directly to draw some things: the chart’s graph and the login form.</p>
<p>The JavaFX code to produce the chart is remarkably simple. The main portion that draw’s the graph’s outline is below:</p>
<p>
<pre class="brush: java">
Path {
elements: [
// start with the first point
MoveTo {
x: minX
y: minY
},
// Draw a line to each subsequent point
for (i in [1..values.size() - 1]) {
LineTo {
x: parentBounds.minX + padding + ((values[i].x - 1) * xIncrement)
y: (parentBounds.minY + (parentBounds.height - values[i].y * yIncrement))
}
},
// close out the path so that it fills the bottom of the chart's container
LineTo {
x: maxX
y: parentBounds.maxY
},
LineTo {
x: minX
y: parentBounds.maxY
},
LineTo {
x: minX
y: minY
}
]
stroke: null
fill: fill,
}
</pre>
</p>
<p>This application also uses a few UI controls and Swing Components. In the main screen, I used InkScape to decide where these controls should be placed using placeholder rectangles. After the application starts up, I overwrite the placeholder rectangles with the real controls. Here’s the code that replaces the refresh button in the design with a real Swing Button. The overwrite() and align() functions are used to place the date range text fields and the login button as well.</p>
<p></notextile>
<pre class="brush: java">
// ...
public-read var refreshButton = SwingButton {
text: “Refresh”
action: function() {
refresh(startDate.text, endDate.text);
}
}
// ...
init {
//...
// ui.refreshButton is our place-holder node
overwrite(ui.refreshButton, refreshButton);
//...
}</p>
function overwrite(dest: Node, target: SwingComponent) {
var d = dest.boundsInScene;
target.width = d.width;
target.height = d.height;
align(dest, target);
}
function align(dest: Node, target: Node) {
var d = dest.boundsInScene;
var t = target.boundsInScene;
var leftX = d.minX + dest.translateX;
var topY = d.minY + dest.translateY;
target.translateX = leftX – t.minX;
target.translateY = topY – t.minY;
}
</pre>
</notextile>
<p>Unlike the main screen in the application, the login form used by the application was created in pure JavaFX without any design tools. If you follow <a href="http://learnjavafx.typepad.com">Jim Weaver’s excellent blog</a>, you might recognize much of the code that follows. I used his <a href="http://learnjavafx.typepad.com/weblog/2009/02/miglayout-comes-to-javafx.html">Mig Layout example</a> as the basis of the login form.</p>
<p>
<pre class="brush: java">
public class LoginForm extends CustomNode {
var username: SwingTextField = SwingTextField {
action: function() {
password.requestFocus();
}
};
// there is currently no Swing Password Field, so we use
// a pure swing component instead.
var password = new JPasswordField() on replace {
password.setAction(RequestFocus {
node: loginButton
});
}
var loginButton = SwingButton {
text: "Login"
action: function() {
if (action != null) {
action(username.text, new String(password.getPassword()));
}
}
};
// ... snip
public override function create(): Node {
return Group {
content: [
// ... snip
MigLayout {
width: bind width
height: bind height
layout: "fill, wrap"
rows: "push[]8px[][][]4px[]push"
columns: "[][]"
migContent: [
MigNode {
node: Text {
textAlignment: TextAlignment.LEFT
content: "Analytics Login"
fill: Color.WHITE
font: Font.font("Georgia", FontWeight.BOLD, 24)
}
constraints: "span"
},
MigNode {
node: SwingLabel {
foreground: Color.RED
text: bind errorMessage
visible: bind (errorMessage != null and errorMessage.length() > 0)
font: Font.font("Georgia", FontWeight.BOLD, 20)
}
constraints: "span"
},
MigNode {
node: SwingLabel {
foreground: Color.WHITE
text: "Email"
}
constraints: "ax right"
},
MigNode {
node: username
constraints: "growx"
},
MigNode {
node: SwingLabel {
foreground: Color.WHITE
text: "Password"
}
constraints: "ax right"
},
MigNode {
node: SwingComponent.wrap(password)
constraints: "growx"
},
MigNode {
node: loginButton
constraints: "ax right"
},
MigNode {
node: fakeButton
constraints: "ax left"
},
]
}
]
// ... snip
</pre>
</p>
<h2>The Power of Java Integration</h2>
<p>The Analytics Dashboard is just a hint of the power available to JavaFX/Java hybrid applications. There are a number of enhancements we could apply to the dashboard to make it even more useful. We could add a Feed Burner client to track <span class="caps">RSS</span> subscriptions, or an interface into Google’s <a href="http://google.com/webmasters/tools">web master tools</a>. Each of these enhancements is fairly trivial because robust Java APIs already exist for this purpose.</p>
<p>Many tutorials and articles you’ll find about JavaFX have focused on how easy it is to create user-interfaces in JavaFX. If you’ve read them, you’ve seen that it is indeed pretty easy! I believe making user-interfaces easier to build is necessary for JavaFX’s success, but not sufficient. JavaFX’s integration with existing Java APIs will ultimately help it<br />emerge as a premier graphical application development tool. More and more applications are accessing data through existing services and many of these services already provide robust Java clients to access their data. With the creation of more powerful <a href="http://blogs.sun.com/theplanetarium/entry/the_state_of_javafx_tooling">JavaFX tools for producing UIs</a>, JavaFX’s case will become even stronger.</p>
<p class="note">After writing my article on creating a <a href="/2009/03/24/game-design-with-javafx-production-suite.html">JavaFX game</a>, many people sent excellent questions to me via email. Please don’t hesitate to leave a comment below with any question you might have.</p>
Performance Tuning Android Applications2009-04-18T00:i:1240027200-05:00http://newfoo.net/2009/04/18/performance-tuning-android-applications.html
<p>Recently while testing an Android mobile application our team was developing, we encountered some performance issues in two of our List Views. Fortunately, the Android SDK provides mature debugging tools to help investigate performance problems. In this post, I'll describe how we used Android's toolset to locate the source of our problems and verify the optimizations we made were correct. I'll also share a few tips to keep in mind while tracing your own Android applications. </p>
<h2>Some Background</h2>
<p><img src="/2009/04/games-view.png" style="float: right" alt="Capture of Scores View"/> Our team recently had the privilege of partnering with Turner Sports to deliver the Android <span class="caps">NBA</span> Game Time application for <span class="caps">NBA</span> digital. To date, the application has received a number of positive reviews including distinction as Gizmodo’s <a href="http://i.gizmodo.com/5205804/android-app-of-the-week-nba-game-time-tracks-the-playoffs">Android App of the Week</a> the first week of April.</p>
<p>Our road to success wasn’t without some effort though. During our testing of the application, we found some undesirable performance when scrolling on the Scores listing screen and the Scheduled games screens, both of which are custom ListView Activities. If you’re not familiar with the application, a screenshot of the Scores view is included here. Because we receive data from live feeds and the views are more complicated than traditional Android ListViews, we needed to write our own ListView Adapter. Unfortunately, this implementation didn’t scroll as smoothly as we wanted and it would eat up more memory than we expected it to. The immediate thought was we had a memory leak somewhere, but we needed to use some tools to confirm that possibility.</p>
<h2>How We Found the Problem</h2>
<p>We used Android’s tracing <span class="caps">API</span> to investigate where the problems were. If you’re familiar with Java profiling tools such as JProbe, Android’s TraceView provides basic method tracing functionality, albeit with more work required by the developer. I followed guidance of the <a href="http://developer.android.com/guide/developing/tools/traceview.html">TraceView documentation</a> to configure our application for tracing. Here are the steps I took.</p>
<p>In our Scores activity, I added start & stop tracing calls to trigger tracing. Below is a code snippet of how I accomplished this in our ListActivity. I decided to start tracing before we did anything on our activity and after we’d finished all of our shutdown code to ensure we’d trace everything our superclasses were doing too.</p>
<pre class="brush: java">
public class ScoresActivity extends ListActivity {
public void onStart() {
// start tracing to “/sdcard/scores.trace”
Debug.startMethodTracing(“scores”);
super.onStart();
// other start up code here…
}
public void onStop() {
super.onStop();
// other shutdown code here
Debug.stopMethodTracing();
}
// Remainder of activity implementation
}
</pre>
<p>After adding the tracing statements to the target activity, I rebuilt the application and deployed it on a developer phone. If you don’t have a developer device available, you can also use the built-in emulator, but you’ll need to follow a few steps. The TraceView documentation details the additional steps <a href="http://developer.android.com/guide/developing/tools/traceview.html#creatingtracefiles">here</a>. Once installed, I began performing the actions that were producing the undesirable results. Once I’d finished running the activity, a trace file was available for me to download to my development machine. I pulled the trace file and loaded it in TraceView using the following commands:</p>
<pre class="brush: bash">
localhost$ adb pull /sdcard/scores.trace scores.before.trace
localhost$ traceview scores.before.trace
</pre>
<p>Below is a screenshot of TraceView showing the profiling results before applying the fixes. Looking at the output, you can see our application was spending almost 50% of it’s entire running time in the method that’s responsible for drawing each game tile in Scores view. These results showed that we could improve upon our original design, which was based on the <a href="http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List14.html">Efficient List View Adapter example</a> in the <span class="caps">SDK</span> documentation.</p>
<p><img src="/2009/04/games-before-fix.png" title="Scores View Profiling Results before Fixes" alt="Scores View Profiling Results before Fixes" /></p>
<p>Eventually we settled on some enhancements that we believed would improve the performance and memory usage of the application. Of course, we needed to confirm that our fixes addressed the problems we were seeing and more importantly didn’t make performance worse. Normal testing with the heap analyzer included with the <span class="caps">SDK</span> showed that the performance was noticeably better for the Scores view now. We still needed further proof that the fixes worked, so I again enabled tracing for the application, performed similar testing as I’d done before our fixes were applied. Below is a screenshot of our results in TraceView.</p>
<p><img src="/2009/04/games-after-fix.png" title="Scores View Profiling Results after Fixes" alt="Scores View Profiling Results after Fixes" /></p>
<p>TraceView confirms that we improved relative timing considerably. Not only do 19 other Android methods take more time than our first implemented method (we were 7th before the fixes), we decreased the relative time spent in our ListViewAdapter#getView() to 10%! Further testing confirmed our fixes were solid, so they became part of the release version of the application. In a future post, I’ll share our solution as I suspect other Android developers will run into the types of problems we did when using complicated list view items. </p>
<h2>Performance Tuning Tips</h2>
<p>If you’re not familiar with method tracing tools, the information available can be daunting at first. Here are a few tips you can use to ensure you’re able to spot issues quickly using the profiling tools.</p>
<h3>Remember, Timing is not Absolute</h3>
<p>When tracing, the application will run much more slowly than it would under normal operation, so you cannot rely on the exact timing provided. You can use the percentage of time spent to track relative gains and losses in performance to the rest of your application though. Percentages will give you a fairly reliable metric to use in between runs.</p>
<h3>Be Wary of Expensive Methods </h3>
<p>If you notice a large percentage of time being spent in one or more of your methods, it’s likely there is a bottleneck you can improve. In Android’s TraceView, these methods will often appear towards the top of the list. There are no hard rules on what percentage is too high, but it’s worth investigating methods that monopolize more than 15-20% of total running time.</p>
<h3>Don’t Optimize Unless You Need it</h3>
<p>I’ve had tremendous success in all types of applications by first keeping the design simple and optimizing later (only when needed). Unless there are painfully obvious performance issues during development, I’ve found it better to defer tuning until after the majority of application functionality is written. This approach works well for the majority of applications because it ensures that most of the time is spent on developing features the user directly notices. </p>
Google App Engine Will Change Java Web Development2009-04-08T00:i:1239163200-05:00http://newfoo.net/2009/04/08/google-app-engine-will-change-java-web-development.html
<p>With the announcement that Google App Engine is now supporting Java as its second language, Google has significantly altered the face of web development. Typically considered a poor choice for many web development projects, Java will now be considered more seriously for new web site projects. Google's announcement will undoubtably create a chain reaction that will only improve the adoption of Java-based web applications in other cloud services. In this post, I'll talk about why Java hasn't been a good choice for a web development platform until now and why Google has changed that.</p>
<p>One of the the most often cited reasons I’ve heard others tell me why they chose another platform for their web projects is that takes too long to develop web applications in Java. I’d whole-heartedly agree – it takes way too long to develop Java web applications. As it stands, other platforms provide highly productive frameworks such as Ruby on Rails or Django. You can often create robust web sites in these platforms with very little effort. <span class="caps">PHP</span> has long been known to be a highly productive web development language — it was originally created for that task!</p>
<p>The underlying reason that it takes too long to develop Java applications is not the language itself, rather it’s the lack of productive and well-adopted web frameworks instead. Sure Java has a number of well-known web frameworks such as Struts, Spring <span class="caps">MVC</span>, and Seam (and <strong>MANY</strong> more). Their tremendous flexibility comes at the high cost of numerous configuration options which make them more difficult to pick up. These frameworks are just plain complicated compared to the popular frameworks of other platforms. There are other emerging Java Virtual Machine platforms that do provide productive web development environments. These other <span class="caps">JVM</span> platforms leverage many of the great ideas from the other web platforms, but they have not seen large-scale adoption yet.</p>
<p>Why aren’t there any widely adopted, productive web frameworks in Java or <span class="caps">JVM</span> based platforms? Simply put, it’s always been more expensive to host Java web applications than other platforms. <strong>Starter</strong> packages on most web hosts start at $20 per month or <strong>more</strong>. Other platforms start at much lower prices though. For instance, you can find <span class="caps">PHP</span> hosting starting at $3 per <em>month</em>. Without cheap hosting options for Java-based web sites, few developers are going to use it for their hobby or semi-serious web projects. I speak with experience on the matter. My own wedding web site from a few years back, complete with an online meal selection page, was built with Ruby on Rails simply for the reasons of cost and productivity.</p>
<p>Larger web projects have often chosen other platforms for similar reasons. It’s expensive to develop Java web applications (because there are no productive platforms) and it’s expensive to host these applications. Large-scale Java web sites are often also complicated beasts. These web applications require complex web and application servers and gobs of memory. Web application servers can be very complicated to administer for production applications. The complexity to develop and administer large Java-based websites made it a difficult platform to choose.</p>
<p>Google app engine now removes many of the barriers that prevented Java or <span class="caps">JVM</span> based languages being chosen as the web platform. Google has now introduced a solution that is not only fairly inexpensive, it conforms to the many <a href="http://code.google.com/appengine/docs/java/overview.html">underlying standards</a> Java developers already know. Google also provides an infrastructure that allows progressively more complicated applications to magically grow their resources as they require – the dream of everyone’s favorite-buzzword-of-the-moment, cloud computing.</p>
<p>Now that reasonably priced Java web application hosting is available, I predict we will see an explosion of hobbyist Java web development. Here’s why: according to the <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"><span class="caps">TIOBE</span> index</a>, there are still <strong>two</strong> times as many Java developers as there are <span class="caps">PHP</span> developers, the most popular web development platform according to <span class="caps">TIOBE</span>. Many of these Java developers will at least more strongly consider Java as their platform of choice for tinkering with their web projects. The increase of hobbyist Java web development will lead to more innovation on productive web frameworks. Developers are going to want simple to use frameworks that allows them to get stuff done fast, so some will inevitably be created due to this need. In addition, many Java developers are now going to begin experimenting with other <span class="caps">JVM</span> based web frameworks such as Groovy on Grails and Lift.</p>
<p>As the hobbyist development leads to productive web frameworks, the adoption of Java in commercial web sites will only increase. For all of the negative aspects Java has been known for, raw speed in server applications and stability are not among them. That is, at least in the minds of educated technologists of course. Java’s main advantages as a server platform will now shine that much more brightly when it also becomes seen as a more productive environment. These advantages will lead to an increasing adoption of Java and Java will finally realize the vision I suspect the creators of Java Servlets had when they created servlets more than 10 years ago — that of a premier web development platform. I believe we’ll ultimately have Google app engine to thank for all these changes.</p>
Game Design with the JavaFX Production Suite2009-03-24T00:i:1237867200-05:00http://newfoo.net/2009/03/24/game-design-with-javafx-production-suite.html
<p>A lesser known, but powerful feature of JavaFX is its Production Suite. The production suite allows graphics designers to produce designs using tools familiar to them that are readily consumable by JavaFX programs. Using the production suite leads to simpler programs that focus only on the logic and effects and leaves the heavy lifting of the design to the graphic artists who know how to do that best. In fact, incorporating the production suite into your toolbox provides you with a JavaFX UI design tool that rivals any other. In this post, I'll show you how to create a simple dice game using an elegant UI produced by a real designer. Accomplishing a design like this in pure JavaFX would be almost unthinkable. Using the production suite though, this task becomes not only possible, but almost trivial.</p>
<p>Before we dissect our Production Suite powered game, let’s take a look at the demo first. Here’s a screen shot and a Web Start link:</p>
<p><img src="/2009/03/PigBoard.png" alt="" /></p>
<p><a style="display: inline;" href="/presentations/introduction-to-javafx/Pig.jnlp">
<img border="0" title="Webstart.small2" src="/images/jnlp_launch.gif" alt="Webstart.small2"/><br /></a></p>
<p>The rules for the game are pretty straight-forward. From <a href="http://en.wikipedia.org/wiki/Pig_(dice)">Wikipedia</a>: </p>
<blockquote>
<p>Each turn, a player repeatedly rolls a die until either a 1 is rolled or the player holds and scores the sum of the rolls (i.e. the turn total). At any time during a player’s turn, the player is faced with two options:</p>
</blockquote>
<blockquote>
<p> <ul>
<li>roll – If the player rolls a
<ul>
<li>1: the player scores nothing and it becomes the next player’s turn.</li>
<li>2 – 6: the number is added to the player’s turn total and the player’s turn continues.</li>
</ul></li>
<li>hold – The turn total is added to the player’s score and it becomes the next player’s turn.</li>
</ul></p>
</blockquote>
<blockquote>
<p>The first player to score 100 or more points wins.</p>
</blockquote>
<p>The entire look & feel of the game was created in Adobe Illustrator by Jonathan Wei. What remained was merely wiring up the interactive elements of the game using JavaFX script. During development, we had a couple short design iterations that were greatly simplified by using the production suite.</p>
<h2>Before Starting</h2>
<p>If you’d like to follow along, make sure you’ve installed the following software:</p>
<ul>
<li>NetBeans <span class="caps">IDE</span> 6.5 for JavaFX</li>
<li>JavaFX 1.1 Production Suite</li>
<li>(Optional) Adobe Illustrator CS3. If you’d like to open the asset and manipulate it yourself. <strong>You can also gain limited viewing of the assets by double-clicking on DesignerBoard.fxz in NetBeans.</strong></li>
</ul>
<p>Both NetBeans and the Production Suite are available at <a href="http://javafx.com">JavaFX.com</a>.</p>
<h2>Structure of the Application</h2>
<p>The source code for the application is available at <a href="http://github.com/jcon/pig-game">Git Hub</a>. The structure of our app is a standard NetBeans project layout, with the addition of a directory to hold the artwork.</p>
<ul>
<li><strong>art</strong> <em>The assets for the game in their native formats</em>
<ul>
<li><strong>PIG_theDiceGame_cs3.ai</strong> <em>The game assets in Illustrator format</em></li>
</ul></li>
<li><strong>src</strong>
<ul>
<li><strong>net</strong>
<ul>
<li><strong>newfoo</strong>
<ul>
<li><strong>pig</strong> <em>Main package for the game code and the design in JavaFX format.</em>
<ul>
<li><strong>Button</strong> <em>Reusable control for the buttons on screen</em></li>
<li><strong>DesignerBoard.fxz</strong> <em>Assets converted from Illustrator to native JavaFX</em></li>
<li><strong>DesignerBoardAdapter.fx</strong> <em>Helper class to enhance the auto-generated UI stub</em></li>
<li><strong>DesignerBoardUI.fx</strong> <em>Auto-generated helper providing access to named JavaFX nodes in the design</em></li>
<li><strong>Game.fxz</strong> <em>The logic for the game</em></li>
<li><strong>Main.fxz</strong> <em>The main program and controller</em></li>
<li><strong>PlayerMarker.fxz</strong> <em>Provides UI transitions for player switching</em></li>
<li><strong>ScoreControl.fxz</strong> <em>Manages UI changes to player scores</em></li>
</ul></li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<p>The application structure is illustrated below:</p>
<p><img src="/2009/03/PigGameUML.png" alt="" /></p>
<h2>Dissecting the Code</h2>
<h3>DesignerBoardUI.fx</h3>
<p>This file is maintained through the production suite. As the design is updated with new named nodes, we can re-generate this file by right-clicking on DesignerBoard.fxz and selecting the “Generate UI Stub” menu item.</p>
<h3>DesignerBoardAdapter</h3>
<p>The Production Suite allows us to conveniently connect to assets designed in illustrator through the UI stub. Often though, we’ll want to modify the design programatically before using it in our application. We might also want to include some small animations without making full-fledged classes for each animation and effect. In this game for instance, we need to apply some translations and also hook up the button states. One way to isolate the changes you need to make from the DesignerBoardUI stub, is to place them in an adapter. Our adapter will be responsible for picking which nodes go where. </p>
<p>Using an adapter also has the added benefit that we could use multiple designs in the same application <em>even if the names of the nodes don’t quite match in each design</em>. This way we could potentially add more than one design to the application. As long as each adapter provides the same interface to the rest of the application, we can simply plug in the appropriate adapter on the fly. Using this approach we could produce designs targeted for specific devices such as the Desktop or Mobile.</p>
<h3>Controls</h3>
<p>The PlayerMarker, ScoreControl and Button controls encapsulate the behavior and animation functionality for those visual elements. The PlayerMarker and ScoreControl use triggers to kick off visual changes in their state. For instance, the ScoreControl has a trigger on its value attribute. Whenever that value changes, we kick off a small animation to temporarily grow the score on the screen. The code for animating updates to scores looks like this:</p>
<p>
<pre class="brush: java">
public var value : Integer = -1 on replace {
if (value != -1) {
if (value < 10) {
text.content = "00{value}";
} else if (value < 100) {
text.content = "0{value}";
} else {
text.content = "{value}";
}
// when the value is updated, create a small scaling animation
var t = ScaleTransition {
repeatCount: 2
autoReverse: true
node: text
fromX: 1, toX: 1.3, byX: .05
fromY: 1, toY: 1.3, byY: .05
interpolate: Interpolator.EASEIN
duration: 175ms
}
t.playFromStart();
}
}
</pre>
</p>
<p>The above example demonstrates how we can apply a JavaFX Scale Transition to a node. Unlike many other animation examples on the web though, we applied this transition to a node created in Production Suite.</p>
<p>The button code is the same generic button code used in a <a href="/2009/01/14/creating-a-javafx-design-without-programming.html">previous tutorial</a>. There are two differences though in this application worth calling out. The first is that the visual button states were defined in one spot on the design to save the designer from having to copy the button states to every button. In the final design, we’ll see only the normal state of the button in the correct spot to make it easier on the designer. This isn’t a problem as we can introduce some JavaFX code to do the heavy lifting of copying the button states over to our buttons after we’ve loaded our design. The second difference to the original tutorial is that these buttons only have normal, hover and pressed states in the design. To get around this, we’ll simply copy the normal state button and darken its colors to represent our disabled button.</p>
<p>To create all of our buttons, we’ll introduce a createButton function inside our DesignerBoardAdapter to do all the heavy lifting. Inside the function, it’ll 1.) duplicate the other button state nodes so that we can use copies throughout our game. 2.) visually align the duplicate copies with the “normal” state buttons 3.) replace the text on the prototype button states with text from the real buttons. The final step is to create a Group of nodes that contain all of the states of the button as expected by our control: the active area and the disabled, pressed, hovered and normal states of the button. The code looks like this:</p>
<p>
<pre class="brush: java">
function createButton( normal:Node, hoveredSource:Node, pressedSource:Node ) {
var hovered = Duplicator.duplicate(hoveredSource);
align(normal, hovered);
hovered.visible = true;
var pressed = Duplicator.duplicate(pressedSource);
align(normal, pressed);
pressed.visible = true;
var disabled = Duplicator.duplicate(normal);
align(normal, disabled);
// active area could have been any node with the same shape
var active = Duplicator.duplicate(normal);
align(normal, active);
replaceText(normal, hovered);
replaceText(normal, pressed);
Group {
content: [
active,
disabled,
pressed,
hovered,
normal
]
}
}
function replaceText( text:Node, dest:Node ) {
var group = (dest as Group);
var newText = Duplicator.duplicate((text as Group).content[2]);
newText.translateX = -1 * group.translateX;
newText.translateY = -1 * group.translateY;
(dest as Group).content[2] = newText;
}
function align( target:Node, dest:Node ) {
var destBounds = dest.boundsInScene;
var targetBounds = target.boundsInScene;
dest.translateX = (targetBounds.minX - destBounds.minX) - dest.translateX;
dest.translateY = dest.translateY + (targetBounds.minY - destBounds.minY);
}
</pre>
</p>
<h3>Game Logic</h3>
<p>The entire game logic is implemented in the <code>net.newfoo.pig.Game</code> class. The Game#roll method has all of the logic for determining what to do next. The Game class itself contains two callback functions it uses to communicate after a roll has occurred and when the game is over. This design, typical in Model View Controller designs, allows us to define the game logic in one spot without having to worry about any UI repercussions.</p>
<p>
<pre class="brush: java">
package net.newfoo.pig;
import java.lang.Math;
public class Game {
public-read var player1Score : Integer;
public-read var player2Score : Integer;
public-read var turnScore : Integer;
public-read var isPlayerOne = true;
public-init var gameOver : function( isPlayerOne : Boolean ) : Void;
public-init var afterRoll : function( lastRoll : Integer ) : Void;
public function roll() : Boolean {
var r = ((Math.random() * 6) as Integer) + 1;
if (r == 1) {
turnScore = 0;
} else {
turnScore += r;
}
afterRoll(r);
if (isPlayerOne and turnScore + player1Score >= 100) {
player1Score = turnScore + player1Score;
gameOver(true);
return false;
} else if (not isPlayerOne and turnScore + player2Score >= 100) {
player2Score = turnScore + player2Score;
gameOver(false);
return false;
} else {
return r != 1;
}
}
public function switchPlayer() {
if (isPlayerOne) {
player1Score += turnScore;
} else {
player2Score += turnScore;
}
turnScore = 0;
isPlayerOne = not isPlayerOne;
}
public function reset() {
turnScore = player1Score = player2Score = 0;
}
}
</pre>
</p>
<h3>Main</h3>
<p>Tying everything together is the Controller class inside <code>net.newfoo.pig.Main.fx</code>. The controller is responsible for creating instances of the UI, the controls and the game logic. The Controller then wires everything together. For instance, the game is hooked up with afterRoll and gameOver callbacks. The roll button triggers the Game#roll method to be called. Once the controller is setup and has wired the controls and game logic, we merely have to add it to our main stage. The JavaFX event loop will take care of the rest for us. </p>
<p>Below are a couple of important snippets from the Controller class. This snippet configures the game class with its callbacks. The gameOver callback in this case will lighten the rest of the game board and display the game over dialog. The afterRoll will update the scores and kickoff the dice roll animation. </p>
<p>
<pre class="brush: java">
var game: Game = Game{
afterRoll: function rolled( lastRoll:Integer ) : Void {
hideSides();
var side = ui.sides.content[lastRoll - 1];
side.visible = true;
ui.rollDice(side);
if (game.isPlayerOne) {
player1Score.value = player1Score.value + lastRoll;
} else {
player2Score.value = player2Score.value + lastRoll;
}
}
gameOver: function( player1Wins:Boolean ) {
println("Game over Player {if (player1Wins) 1 else 2}");
ui.pigWinsScore.content = "{game.player1Score} vs. {game.player2Score}";
var name = if (player1Wins) ui.player1NameText.content else ui.player2NameText.content;
ui.pigWinsText.content = "{name} Wins!";
rollButton.disable = true;
holdButton.disable = true;
ui.gameOverDialog.visible = true;
ui.boardGroup.opacity = .4;
}
}
</pre>
</p>
<p>In this game, there is no real benefit to creating a controller class to group together all of this work other than for organization. In this example game, the Controller shows that a game could be grouped together in one class and easily added to main stage. For larger games however, the controller class would likely exist in its own class file. To add the game to our main stage, we simply have to add the following code:</p>
<p>
<pre class="brush: java">
Stage {
title: "Pig the Dice Game"
width: 640
height: 500
scene: Scene {
content: controller.ui
}
}
</pre>
</p>
<p>Since the controller orchestrated all the event handling, we don’t need to do anything else when we add the UI to the stage. The JavaFX event handling loop will take care of the rest for us.</p>
<h2>The Power of the Production Suite</h2>
<p>The JavaFX code for the entire application is around 800 lines of code. If you consider that number includes all of the comments, the <em>automatically</em> generated DesignerBoardUI.fx and the re-usable Button code, the source code would be less than 500 lines of code! So with approximately 500 lines of “new” code, we were able to put together a complete game. Of course the game <em>was</em> pretty simple, but you’d be hard-pressed to achieve something similar in any other free platform right now! The production suite freed us from the burden of laying out the UI. It allowed us to go through several designer/developer iterations with almost no effort. Our code merely focused on the game logic and the dynamic aspects of the game itself. </p>
<p>Though this example was fairly simple for a real application, you can see that constructing elegant JavaFX UIs in the Production Suite is significantly easier than manually writing JavaFX code for everything. Since the Production Suite also generates JavaFX code, you also have the flexibility to produce portions of the UI manually in JavaFX code should you ever need that option. If you also consider that the Production Suite works with the industry standard design tools, the choice to use it becomes almost automatic. In addition, should your team prefer an <em>all free</em> toolkit, you can even use the Production Suite with free graphical editors capable of producing <span class="caps">SVG</span> such as Inkscape. In the end, choosing the production suite in your graphically oriented JavaFX application should be automatic.</p>
Removing Open Source Project Barriers2009-02-07T00:i:1233982800-05:00http://newfoo.net/2009/02/07/removing-open-source-project-barriers.html
<p>Earlier today I spent some time debugging an issue I was encountering with a free software package. While I searched for where the problem might lie, something interesting occurred to me. Even though the software was free in the Free Software Foundation sense, was it truly free? In order for software to be truly free, it not only needs to satisfy what FSF classifies as free, but should also lack any prohibitive barriers to modification. In this post, I'm going to examine some barriers that I've found on projects I've contributed to and provide some suggestions for making projects more accessible to small contributors.</p>
<h2>FSF’s Definition of Free Software</h2>
<p>To get a better understanding of what it means to be free software, I checked out FSF’s own site. <span class="caps">FSF</span> <a href="http://www.gnu.org/philosophy/free-sw.html">says</a> that software is free if its user have:</p>
<blockquote>
<p>
<ul>
<li>The freedom to run the program, for any purpose (freedom 0).</li>
<li>The freedom to study how the program works, and adapt it to your needs (freedom 1). Access to the source code is a precondition for this.</li>
<li>The freedom to redistribute copies so you can help your neighbor (freedom 2).</li>
<li>The freedom to improve the program, and release your improvements (and modified versions in general) to the public, so that the whole community benefits (freedom 3). Access to the source code is a precondition for this.</li>
</ul></p>
</blockquote>
<p>My particular issue today was with Eclipse. I was able to trace the problem back to some corrupt project metadata, so I didn’t need to actually dig in and fix it this time. The issue today had me wondering though: does Eclipse really satisfy freedom 3? Had my issue been due to a bug, I could probably have located the source by looking through Eclipse’s site, or maybe even google if the site is hard to navigate. But then, wait, where do I find all the dependencies for building it? After I have the dependencies, how do I actually build it? Once I’ve fixed the problem, how do I share my fixes back with the community? Granted Eclipse is a very large open source project, these things are commonly difficult for many open-source systems. </p>
<p>It seems to me that the more time it takes to make a first change, the less likely or <em>free</em> we are to modify the software. After I had my big epiphany, it made me wonder if OpenOffice.org’s <a href="http://www.gnome.org/~michael/blog/ooo-commit-stats-2008.html">apparent developer community decline</a> could also be attributed to diminished <em>freedom</em>. I can’t say for certain that OpenOffice.org is still difficult to build today, but it was difficult for me to build in 2003. The difficulty in building didn’t appear to be for any lack of knowledge of the various platforms OpenOffice employed. My main difficulties were in setting up the build environment and installing Solaris’ C++ compiler (instead of GNU’s). With much effort, I was able to eventually compile OpenOffice, but not after I’d wasted a number of hours setting everything up. If projects really want as many contributions as possible, they might prioritize developer ramp-up over bug fixes and feature requests.</p>
<h2>Really Satisfying Freedom #3</h2>
<p>So how do we become <em>freer</em> to improve open source programs? I don’t intend to point any fingers at any projects here. To be honest, I’ve guilty in the past of every single one of the following suggestions in the past. Instead, here are some things we can do provide our users with more of that special freedom #3.</p>
<ol>
<li>Make it easy to find the source</li>
<li>Don’t make me suffer dependency hell</li>
<li>Let me build everything with one command</li>
<li>Make it easy for me to contribute</li>
</ol>
<h3>Help Me Find Your Source</h3>
<p>Developer will download the source if it’s easy to locate the software’s source. Lately, I’ve noticed there some fairly popular open-source projects out there where it’s difficult to find the sources for the project. Alternatively, it’s easy to find some of the source, but not all of the components. If the project doesn’t have a big <strong>download source here</strong> link blinking on the project’s homepage, it’s likely the project could make it easier to find the source.</p>
<h3>Don’t Make me Suffer Dependency Hell</h3>
<p>Users shouldn’t suffer <a href="http://en.wikipedia.org/wiki/Dependency_hell">dependency hell</a> just to setup the build environment. For instance many people find entry into open-source Java projects prohibitive because of all the external <span class="caps">JAR</span> dependencies. I’ve seen similar problems in other platforms as well. Most large Ruby project will inevitably require its developers to install a bunch of gems before starting. Many projects are getting around this particular issue by using dependency management systems such as <a href="http://maven.apache.org">Maven</a>. Maven makes downloading the project’s dependencies part of the build process. If you’ve never tried using Maven and you’re a Java developer, check out <a href="http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html">Getting Started with Maven in 5 minutes</a>.</p>
<h3>Let Me Build Everthing … with Just One Command!</h3>
<p>Building the entire system should be as simple as typing: make, ant, rake, [insert something simple here] and grabbing some coffee. Preferably that command should be the standard for that project’s platform (e.g. ant & Java, make & C/C++, etc). Now, I <em>might</em> just be the biggest fan of one step building there is, but if it’s easy to build an open-source project, more people are likely to build it. If more people can build the software, then you have more potential people to contribute to it. I think you can see where I’m going here. To allow users to freely modify the software, they shouldn’t be restricted by a 20 minute build configuration system. </p>
<h3>Help Me Share my Work With You</h3>
<p>Oh yeah, contributing back to the community shouldn’t be hard either! I think this is probably the biggest barrier for me personally contributing to more open-source projects. If I’m motivated enough to fix or enhance something, I’m usually willing to slog through dependency hell and a multi-step build processes. Far too often though, I have been stopped in my tracks when it’s time to submit my work. Sometimes it’s difficult to register as a developer for the project. Even then it’s rarely instantaneous. Sometimes you can’t even register, so you have to do a weird patchset dance with a developer that is registered with the project. Relying on patchsets will add a chance that the other developer will have trouble merging in the work — especially if it’s anything substantial. </p>
<p>It should be easy to obtain an account on the project’s source code management repository and push contributions to a branch at the very least. If the project really wants to receive contributions, it should have a way to allow anyone to submit reliably to its source code repository with minimal effort. At the very least anyone should be able to submit patches to another branch of the project. One solution I’ve seen to the contribution problems above is the Social Code site <a href="http://www.github.com">GitHub</a> (think SourceForge, but way better). Not only is it easy get the source code, it’s also easy to <em>contribute</em> source back through their simple web-interface. In fact, I recently submitted a small patch to <a href="http://github.com/mojombo/jekyll">Jekyll</a>, the software I use to make this blog, through GitHub! I plan to write a separate post about GitHub soon because I think they’re really on to something!</p>
<h2>Final Thoughts</h2>
<p>All of the points I mention in this article are simple, almost silly really. If your project isn’t doing these though, you’re loosing out on a chance for a much larger developer base. By lowering the barriers for entry to your projects, your developer base will grow with a large number of people contributing small bug fixes and features they personally need. It’s likely your other users will appreciate this work too. </p>
JavaFX Path Animation2009-02-01T00:i:1233464400-05:00http://newfoo.net/2009/02/01/javafx-path-animation.html
<p>A few people at work have Nohohon Zoku solar powered bobble heads. I like watching them bob their heads all day, so I thought it'd be fun to make a virtual bobble head. In this post, I'll show you how to create your very own bobble head using the JavaFX Production Suite tools and a simple JavaFX script to tie everything together. If you'd like, you can download the source code from GitHub and play with it or follow along and create your own new project.</p>
<p>To achieve this effect, we can use JavaFX’s <a href="http://java.sun.com/javafx/1/docs/api/javafx.animation.transition/javafx.animation.transition.PathTransition.html">PathTransition</a> with an indefinite repeat count. Path transitions allow us to define a rail on which a node can slide across. In our image, we just need to name two nodes specially: one for the head and one to represent the track on which the head will “bobble.” Here’s a diagram of what the two nodes look like:</p>
<p><img src="/2009/02/smileyDiagram.png" title="Diagram of Smiley Nodes" alt="Diagram of Smiley Nodes" /></p>
<p>Here is the actual <a href="/2009/02/Smiley.svg"><span class="caps">SVG</span> source</a> file I’m using for this example. In our animation, we want the <em>head</em> node to simply travel back and forth along the <em>rotatePath</em> as illustrated above. Once we’ve drawn our illustration using an <span class="caps">SVG</span> editor (I’m using InkScape), we need to convert it a JavaFX-ready asset by using Production Suite’s <strong><span class="caps">SVG</span> Converter</strong> that we can import into our project.</p>
<p>Below is a picture of what our final animation will look like. Click on the image if you want to see it in action (NOTE: the page may require you to install JavaFX runtime libraries).</p>
<p><a href="/2009/02/Smiley/Smiley.html" class="img"><img src="/2009/02/Smiley.png" title="The Full Smiley Scene" alt="The Full Smiley Scene" /></a></p>
<h2>Production Suite UI Stub: SmileyUI.fx</h2>
<p>To use the <span class="caps">FXZ</span> file that we generate using <strong><span class="caps">SVG</span> Convter</strong>, first make sure your project references the <strong>javafx-fxd-runtime</strong> library. We can then generate our stub by right clicking on the <span class="caps">FXZ</span> file and choosing <strong>Generate UI Stub…</strong> The UI Stub Generator will add to our stub among other fields, the <em>head</em> and <em>rotatePath</em> nodes. Below is a snippet of the automatically generated stub. I removed the extraneous nodes that the UI Stub generated also added.</p>
<p>
<pre class="brush: java">
package net.newfoo.smiley;
import java.lang.Object;
import java.lang.System;
import java.lang.RuntimeException;
import javafx.scene.Node;
import javafx.fxd.UiStub;
public class SmileyUI extends UiStub {
override public var url = "{__DIR__}Smiley.fxz";
public var head: Node;
public var rotatePath: Node;
override protected function update() {
lastNodeId = null;
try {
head=getNode("head");
rotatePath=getNode("rotatePath");
} catch( e:java.lang.Exception) {
System.err.println("Update of the attribute '{lastNodeId}' failed with: {e}");
throw e;
}
}
}
</pre>
</p>
<h2>Main Script</h2>
<p>Tying it together is fairly straightward. We just need to create an instance of our UI stub and then setup an appropriate PathTransition. For the path property of the transition, you’ll notice that we’re just using rotatePath from our <span class="caps">FXZ</span> asset. The orientation was set to _ORTHOGONAL_TO_TANGENT_ so that head would rotate slightly as it travels along the rail. Here’s the pertinent code to do that:</p>
<p>
<pre class="brush: java">
var scene = SmileyUI{ };
var node = scene.head;
var path = scene.rotatePath as SVGPath;
var pathTransition = PathTransition {
duration: 4s node: scene.head
path: AnimationPath.createFromPath(scene.rotatePath)
orientation: OrientationType.ORTHOGONAL_TO_TANGENT
repeatCount: Timeline.INDEFINITE, autoReverse: true
interpolate: Interpolator.EASEBOTH
}
pathTransition.play();
</pre>
</p>
<h2>The Production Suite Potential</h2>
<p>Once the scene was drawn with InkScape, this example really only saved us some small time in creating this particular animation. This example hints at the raw potential of the Production Suite for producing much larger projects however. This technique would allow a non-programmer to define the behavior. You can also use the same techniques in more complicated scenarios. For instance, you could control the paths of sprites in a video game. You could use this technique to control the the transition between one screen to another in an application.</p>
Really Learning Design Patterns2009-01-19T00:i:1232341200-05:00http://newfoo.net/2009/01/19/really-learning-design-patterns.html
<p>I've had a tumultuous relationship with design patterns over the last 10 years. Our relationship started out pretty rocky as I tried to navigate the murky waters of the infamous Gang of Four (GoF) book, Design Patterns, Elements of Reusable Object-Oriented Systems. With some luck and the help of a mentor early-on though, I was able to avoid some common patterns problems before they caused a serious rift between design patterns and me. In this post, I'm going to share what works for me. I hope this advice will help you avoid some of the difficulties I've encountered with design patterns over time.</p>
<h2>An Approach to Learning</h2>
<p>Here is the rough approach I’ve taken in learning design patterns. To this day, I try many of these ideas when I encounter new patterns.</p>
<h3>Seek Patterns in Core APIs</h3>
<p>When I started with design patterns, the GoF book was the only book available for learning about them. The style of the GoF book is elegant, but a difficult read. If you don’t approach the material as an active reader, it can be difficult to consume. In order to help the patterns set in better, I searched for as many real world examples that I could find. Fortunately for me, the core Java <span class="caps">API</span> was chockfull of patterns. Once I learned to seek them out, they were pretty easy to spot. One easily spotted example is the <a href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator pattern</a> in java.io’s <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/InputStream.html">Input</a> and <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/io/OutputStream.html">Output</a> Streams APIs. Users of java.io are able to seamlessly add capabilities to their stream instances by simply wrapping the streams with another stream implementing the functionality they need such as buffering, compression, object serialization and many others. The beauty of the Decorator pattern in this case is that you are able to pass any instance of the stream in the hierarchy to methods that require Input and Output streams. The receiver doesn’t need to know any of the details.</p>
<p>Another interesting example of design patterns is <a href="http://java.sun.com/docs/books/tutorial/rmi/index.html">Java’s Remote Method Invocation</a> (<span class="caps">RMI</span>) API’s use of the Proxy design pattern. Users of <span class="caps">RMI</span> enabled applications can simply program to an agreed upon interface and the <span class="caps">RMI</span> subsystem takes care of all the gritty details of marshaling and unmarshaling objects and invoking methods remotely. Users of an <span class="caps">RMI</span> enabled service are actually working with a class instance that implements their shared interface, yet it shields them from all of the complexity.</p>
<h3>Don’t Be Afraid to Experiment</h3>
<p>I often experiment with design patterns as I develop non-critical portions of systems. I like to try out the patterns without the risk of breaking something important. For instance, I was able to thoroughly learn how to apply the <a href="http://en.wikipedia.org/wiki/Prototype_pattern">Prototype</a> pattern for instance using this method. Our team was conducing a proof of concept on a card management system. Our card agreements shared a lot of details, but still needed to be customizable for each customer. By cloning an instance of a standard agreement, we were able to create a object hierarchy that allowed for customizing any number of the agreement’s details.</p>
<h3>Ask Your Friendly Pattern Zealot</h3>
<p>Some times I’m not always sure if I need to use a pattern to a solve design problem. In these cases, it helps to reach out to experts. I’ve had good success so far reaching out to other experts. It saves me the pain of misapplying a pattern or making a design more complicated than it needs to be. If you’re not comfortable asking knowledgeable co-workers directly, it doesn’t hurt to include them in your architecture reviews. Your co-workers will be able to see the big picture of the design and provide useful feedback to you. Regardless of how you include an expert in your design process, doing so will help improve the design quality.</p>
<h2>What I’ve Learned So Far</h2>
<p>I’ve already learned a number of important lessons while working with patterns:</p>
<ul>
<li>Wait until you repeat yourself.</li>
<li>Use common names for pattern collaborators</li>
<li>You can always apply a pattern later</li>
</ul>
<h3>Wait Until You Repeat Yourself</h3>
<p>A number of times I found myself applying patterns to problems that didn’t need them. Instead of designing an elegant subsystem, I ended up with something resembling more of a <a href="http://en.wikipedia.org/wiki/Rube_Goldberg_machine">Rube Goldberg Machine</a>. The main problem in these cases was that I didn’t need design patterns in the first place. For instance, a few times I used the <a href="http://en.wikipedia.org/wiki/State_pattern">State</a> pattern to model simple state systems. When your objects need to alter their behavior and have many states, the state pattern is often a useful choice. In a simple state system however (say 2 or 3 states at most), it’s usually easier to maintain a couple of if-else blocks then full-fledged context and state instances. For instance, if you were writing a Button <span class="caps">GUI</span> component, it would likely be overkill to use the State pattern for each of the button’s different states.</p>
<h3>Use Common Names for Pattern Collaborators</h3>
<p>Though you can choose any name for your collaborators when you apply patterns, you should do your best to choose the collaborator names used in the pattern description. Sticking with consistent names allows other developers (and even future <em>you</em>) to get a good understanding of how the system fits together without needing to trace through all of the source. </p>
<p>For example, suppose you were designing an authentication subsystem that needs to authenticate users against a database and an <span class="caps">LDAP</span> store. In addition, you will need to support a proprietary authentication system in the future. The <a href="http://en.wikipedia.org/wiki/Strategy_pattern">Strategy</a> pattern is a great choice in this scenario. Each strategy might implement a simple interface such as this:</p>
<pre class="brush: java">
public interface AuthenticationStrategy {
boolean authenticate(String user, String password);
}
</pre>
<p>In this scenario, you might use class names such as <em>DatabaseAuthenticationStrategy</em> and <em>LdapAuthenticationStrategy</em> for your concrete strategies. These names are useful as they describe the class intent without the viewer needing to open the class source file.</p>
<h3>You Can Always Apply a Pattern Later</h3>
<p>Sometimes you see a problem that you <em>know</em> could be simplified by <em>some</em> pattern, but you just can’t find a pattern to help you out. If you can’t find a pattern now, it’s often better to wait until a good candidate emerges later. Often, I’ve found that when it’s hard to apply a pattern to a design problem, I don’t really need one in the first place. The benefit of waiting is that you’re not forcing yourself to shoehorn a solution into your design. You’ll be less likely to pick the wrong pattern this way. Unit tests and powerful refactoring tools present in many modern IDEs make it fairly easy to modify existing designs into patterns later.</p>
<h2>What Next?</h2>
<p>Hopefully you’ll find my strategies above useful. Now that you have a game-plan in place, you should make sure you have a good book handy to aid your quest for pattern nirvana. The GoF book is a true technology masterpiece, but it’s probably not the best place to start if you’re just starting out with patterns. Instead you should consider finding a popular patterns book that talks about applying design patterns for your particular platform of choice. These books are great because they show you how to handle the various peculiarities of your platform. In many cases, these platform specific books are often easier than mapping examples written in Smalltalk to your platform of choice (assuming that Smalltalk isn’t your platform of choice of course!). Once you’ve mastered the core design patterns, the GoF provides a concise and solid reference that I’ve yet to find in any other book.</p>
Creating a JavaFX Design Without Programming2009-01-14T00:i:1231909200-05:00http://newfoo.net/2009/01/14/creating-a-javafx-design-without-programming.html
<p>There are already numerous tutorials that show you how to develop JavaFX user interfaces programatically. Many of the tutorials on Sun's own site show you how to build your UIs programatically. I would like to show you another option available to JavaFX developers: the JavaFX Production Suite (aka Project Nile). Project Nile is a suite of tools capable of exporting to JavaFX native format from Adobe Illustrator, Photoshop or any software capable of creating SVG illustrations. To demonstrate the power of the Production Suite, I'm going to show you how to create a button component. The interesting part about this button is that the design will be produced entirely in an SVG design tool. We will use JavaFX to only manage the state of the button and control its behavior.</p>
<h2>Downloading The Source</h2>
<p>If you would just like to play around with a working sample button project, you can download the <a href="http://github.com/jcon/jfx-button-sample">complete source</a> from <a href="http://github.com">GitHub</a>. If you’re unfamiliar with git, there’s a direct download link on the GitHub project page. The rest of the tutorial will show you how the project was put together.</p>
<h2>Before Starting</h2>
<p>Before you start to follow along, please be sure you have the following installed on your computer:</p>
<ul>
<li><a href="http://java.sun.com/javafx/downloads/">NetBeans 6.5 with JavaFX 1.0</a></li>
<li><a href="http://java.sun.com/javafx/downloads/">The JavaFX Production Suite 1.0</a></li>
<li>(optionally) <a href="http://inkscape.org">InkScape</a>. An open-source vector illustration application that uses <span class="caps">SVG</span> as its native format. Though any tool that produces <span class="caps">SVG</span> files should suffice. You won’t need InkScape to setup and run the sample application we build.</li>
</ul>
<p>Once you have the required software, create a new project in NetBeans called: Button. Choose a default package for your project. This tutorial assumes you’ve chosen <em>net.newfoo.button</em> for your package. To add production suite capabilities to your project, you’ll also need to <em>JavaFX <span class="caps">FXD</span> 1.0</em> library to your Library list.</p>
<h2>Working With the Design</h2>
<p>The design we receive should provide 4 different views for each state of the button: normal, hovered, pressed and disabled. The code behind our button will simply ensure that only the correct button state is showing at any given time. In order to simplify our event handling, we should also have a graphical element available in our design that can capture all mouse events. In our design, we’re going to place another graphical element below all other elements for this purpose. The element will always be visible, but obscured by the active button state. This allows us to capture our mouse events. All five elements should be stacked on top of each other in this order: active area, disabled, pressed, hovered, normal. These elements should be placed in a group called: <em>button</em>.</p>
<p><img src="/2009/01/5buttonlayers.png" style="text-align:left;" title="5 Layers of our Button" alt="5 Layers of our Button" /></p>
<p>You should save the <span class="caps">SVG</span> asset in our project folder in a file called <em lang="project root">/art/button.svg</em>. If you don’t want to work with the button in an <span class="caps">SVG</span> editor, you can simply download the file to your project.</p>
<h2>Converting to JavaFX</h2>
<p>Once the design has been saved to <em lang="project root">/art/button.svg</em>, we need to convert it to a format consumable by our JavaFX code. Open the <em><span class="caps">SVG</span> Converter</em> program in the Production Suite. Locate your button asset in <span class="caps">SVG</span> format using browse button in the <em>Source File (.svg)</em> field. To populate the <em>Destination File (.fxz)</em> field, click the browse button and navigate to <em lang="project root">/src/net/newfoo/button</em>. Type <em>button.fxz</em> in the <em>Save As</em> field. Click on the <em>Convert</em> button.</p>
<p>In your Button project in NetBeans, you should now see a <em>button.fxz</em> file under <em>Source Files/net/newfoo/button</em>. We’re going to create a UI Stub, a bridge between this asset file and our application, that makes it easier to work the different layers of our design. You can generate your UI stub, by right-clicking on the <em>button.fxz</em> file and selecting “Generate UI Stub…” When prompted, you should name your stub, “ButtonUI.fx.”</p>
<p>Once the the <em>ButtonUI</em> Stub has been created, open it in your editor and make the following changes:</p>
<ul>
<li>import javafx.scene.Group</li>
<li>Change the line <code>public var button: Node</code> to <code>public var button: Group</code>.</li>
<li>Change the line <code>button=getNode("button")</code> to <code>button=getGroup("button")</code></li>
</ul>
<p>These changes make it a little easier to define some re-usable JavaFX code to model the button’s state. After making that change to the stub we’re able to use any button asset in a file called <em>button.fxz</em> as long as it conforms the same layer structure as our original button. In a larger application, the stub will often provide a gateway to all graphical assets of the application. </p>
<h2>Writing the Button Code</h2>
<p>With a little effort we can develop a generic button control that places minimal restrictions on how the graphic assets should be defined. Our button has placed the constraint that the asset should be a group of nodes called “button” and that it should have 5 items in this order: the active area and the disabled state, pressed, hovered and normal states. These two constraints allow us to develop a re-usable JavaFX class that can be used for any button in our application! Without further ado, let’s create a new JavaFX class in our NetBeans project called Button. Here is the code you should place in there:</p>
<p>
<pre class="brush: java">
package net.newfoo.button;
import javafx.scene.CustomNode;
import javafx.scene.input.MouseEvent;
import javafx.scene.Node;
import javafx.scene.Group;
import javafx.scene.text.Text;
public class Button {
public-init var group : Group on replace {
normal = group.content[4];
hovered = group.content[3];
pressed = group.content[2];
disabled = group.content[1];
activeArea = group.content[0];
}
public-init var pressed : Node;
public-init var hovered : Node;
public-init var normal : Node;
public-init var disabled : Node;
public-init var activeArea : Node;
public var action : function ():Void;
public var disable = false on replace {
activeArea.disable = disable;
if (disable) {
isPressed = isHovered = false;
normal.visible = hovered.visible = pressed.visible = false;
} else {
normal.visible = hovered.visible = pressed.visible = true;
}
}
var isPressed : Boolean on replace {
updateUI ();
}
var isHovered : Boolean on replace {
updateUI ();
}
init {
if (activeArea != null) {
activeArea.onMouseEntered = function (e) {
if (not disable) {
isHovered = true;
}
}
activeArea.onMouseExited = function (e) {
if (not disable) {
isHovered = false;
}
}
activeArea.onMousePressed = function (e) {
if (not disable) {
isPressed = true;
}
}
activeArea.onMouseReleased = function (e) {
if (not disable) {
isPressed = false;
action();
}
}
}
isPressed = false;
isHovered = false;
updateUI ();
}
function updateUI () {
if (pressed != null)
pressed.visible = isPressed;
if (hovered != null)
hovered.visible = not isPressed and isHovered;
if (hovered != null)
normal.visible = not isPressed and not isHovered;
}
}
</pre>
</p>
<h2>Putting It All Together</h2>
<p>Now that you’ve designed the button and written the code to control the button behavior, we need to put it all together and make a running application. To link everything together we’ll write a simple JavaFX stage:</p>
<p>
<pre class="brush: java">
package net.newfoo.button;
import javafx.stage.Stage;
import javafx.scene.Scene;
var buttonUI : ButtonUI = ButtonUI{ }
var button = Button{ group: buttonUI.button };
Stage {
title: "My Button"
width: 300
height: 300
scene: Scene {
content: button.group
}
}
</pre>
</p>
<p>Lines 6 & 7 in the above example are the only code that’s needed to bind our designer’s vision for the button to our generic button code. The designer is now free to update the design as he/she sees fit. As long as the designer sticks to our 2 constraints, the button should have 5 layers and be placed inside a group called “button”, our button will work no matter how fancy the design becomes.</p>
<h2>Final Thoughts</h2>
<p>This tutorial only scratches the surface of the JavaFX Production Suite’s capabilities. Using the steps outlined above, you can create an entire application using this method. The button code above can be used to generically control any kind of button regardless of the button’s look and feel. </p>
<p>Unlike many of the other multimedia platforms, you can create your applications without tedious design handoffs or expensive design tools. All of the tools used to create this design were either free or open source. With a few conventions and proper project setup, you can completely automate design updates. In a future post I’m going to demonstrate how to leverage the production suite to build a fully working game.</p>
<p>To find out more information about the Production Suite you should visit Sun’s <a href="http://javafx.com/docs/gettingstarted/production_suite/">Getting Started</a> page. The page has helpful information for designers using Adobe tools to create design assets. You can also see working examples leveraging the Production Suite in your Samples folder under your Production Suite installation directory.</p>
Writing & Running JavaFX Unit Tests2009-01-07T00:i:1231304400-05:00http://newfoo.net/2009/01/07/writing-and-running-javafx-unit-tests.html
<p>Based on some of the Sun JavaFX forums questions, there is uncertainty around writing unit tests for JavaFX classes. Since unit testing is an important part of a balanced developer diet, this post aims to remedy that. I will show you how to write unit tests for your JavaFX classes and even show you how to run them!</p>
<p>To write unit tests, we’re going to use the popular Java unit testing framework, <a href="http://junit.org">JUnit</a>. Most of the steps in this article will be fairly familiar to those who’ve written unit tests for JUnit 3.x before. This post assumes you will be using NetBeans to write your unit tests.</p>
<h2>Getting Started</h2>
<p>Before you can write unit tests, you’ll need to update your project configuration first. You need to add the JUnit 3.x to your project’s library. To do so in NetBeans, follow these steps:</p>
<ul>
<li>Right click on your Libraries folder from your “Projects” view of your project.</li>
<li>Select “Add Library”.</li>
<li>In the resulting dialog, select JUnit 3.x or 4.x (e.g. JUnit 3.8.2) and click “Add Library.”</li>
</ul>
<p>Now you’re ready to start writing tests!</p>
<h2>The Functionality</h2>
<p>Before we start writing our test cases, let’s write our functionality first. We’re going to write a simple JavaFX class that produces the value of the Nth <a href="http://en.wikipedia.org/wiki/Fibonacci_number">Fibonacci number</a>. Create a new JavaFX class called net.newfoo.fib.Calculator and enter the following text:</p>
<p><pre class="brush: java">
package net.newfoo.fib;</p>
public class Calculator {
public function fib( n : Integer ) : Integer {
if (n <= 1) {
return n;
} else {
return fib(n – 2) + fib(n – 1);
}
}
}
</pre>
<h2>Writing The Tests</h2>
<p>If you’ve written JUnit tests before, these steps will be pretty familiar. To write JUnit test cases, we’ll need to create a class that extends the class <em>junit.framework.TestCase</em>. For each test case, we will add a class method in the form of testYYY(). The only differences between a Java JUnit test and a JavaFX JUnit test pertain to language differences between Java and JavaFX. In particular, our “test” methods and the variables we use will be defined in JavaFX syntax. Every other aspect of JUnit testing will be the same in JavaFX as it is for Java. Here is an example test in both Java and JavaFX that tests whether 2 + 2 = 4:</p>
<p><strong>Java Version:</strong><br /><pre class="brush: java">
import junit.framework.TestCase;</p>
public class MyTest extends TestCase {
public void testSomething() {
int x = 2;
int y = 2;
assertEquals(4, x + y);
}
}
</pre>
<p><strong>JavaFX Version:</strong><br /><pre class="brush: java">
import junit.framework.TestCase;</p>
public class MyTest extends TestCase {
// function declaration is different
public function testSomething() : Void {
// variable declarations are different.
var x : Integer = 2;
var y : Integer = 2;
assertEquals(4, x + y);
}
}
</pre>
<p>As you can see by the code snippets, the code is similar with the exception of how methods are defined and variables are declared. Now let’s write two JavaFX test cases to test our Fibonacci calculator. One test will confirm the value of <em>fib(3)</em> and one test will confirm the value of <em>fib(5)</em>. To write your test cases, create a new JavaFX class called <em>new.newfoo.fib.FibTests</em> and type in the following:</p>
<p><pre class="brush: java">
package net.newfoo.fib;</p>
import junit.framework.TestCase;
import junit.textui.TestRunner; // more on this in a moment
public class FibTests extends TestCase {
function testFib3() {
var f = Calculator{ };
assertEquals(2, f.fib(3));
}
function testFib5() {
var f = Calculator{ }
assertEquals(5, f.fib(5));
}
}
</pre>
<p>In the example above, we assert <em>fib(3)</em> is equal to 2 and that <em>fib</em> is equal to 5. The <em>assertEquals()</em> is one of the many useful methods that come from TestCase. When the assertion fails, the test fails and a stack trace is printed in the test output.</p>
<h2>Running The Tests</h2>
<p>Now that we wrote our tests, how do we actually run them? If you’ve written JUnit tests in Java using a popular <span class="caps">IDE</span>, you’ve probably come across a handy test runner. Unfortunately at the time of this writing, I cannot find any easy way to use NetBeans UI to run JavaFX test cases. I found that by using JUnit’s TestRunner facility though, we can still run our tests fairly easily from the <span class="caps">IDE</span>. We can setup FibTests to run by adding a small function to the FibTests.fx file that can be executed by the JavaFX runtime. Add the following code to the bottom of FibTests.fx:</p>
<pre class="brush: java">
function run() {
var r : TestRunner = TestRunner{ };
r.run(r.getTest(“net.newfoo.fib.FibTests”));
}
</pre>
<p>The above code creates a new JUnit TestRunner and adds all of the tests defined in the FibTests class (in this case the two we wrote above). We can execute the tests now by either right clicking on FibTests.fx in the Projects view and selecting “Run File” OR by pressing Shift+F6 while we have FibTests.fx open in our editor.</p>
<p>After running the tests, you should see a bunch of output including the words “OK (2 tests)” towards the bottom of your console. This output tells you that your two tests passed. Experiment by breaking your Fib class implementation and re-running the tests. You should see test failures when you re-run the tests.</p>
<h2>Conclusion</h2>
<p>I hope you found this method of writing JUnit tests in JavaFX straight-forward. As people begin to write more complicated JavaFX applications, proper unit testing will be a powerful tool to keep our application quality up to the standards people have come to expect of Java applications.</p>
<p>If you’re not already familiar with JUnit or unit testing in general, you should check out the <a href="http://junit.sourceforge.net/doc/testinfected/testing.htm">Test Infected</a> JUnit tutorial to learn more. Though the Test Infected tutorial pertains to writing unit tests in Java, the material is applicable to JavaFX if you make sure you define your functions and variables using JavaFX syntax instead of Java syntax.</p>