Skip to content

Blogs

Hookbox

Simon Willison’s Weblog - 5 hours 45 min ago

Hookbox (via). For most web projects, I believe implementing any real-time comet features on a separate stack from the rest of the application makes sense—keep using Rails, Django or PHP for the bulk of the application logic, and offload any WebSocket or Comet requests to a separate stack built on top of something like Node.js, Twisted, EventMachine or Jetty. Hookbox is the best example of that philosophy I’ve yet seen—it’s a Comet server that makes WebHook requests back to your regular application stack to check if a user has permission to publish or subscribe to a given channel. “The key insight is that all application development with hookbox happens either in JavaScript or in the native language of the web application itself”.

Categories: Blogs

canto.js: An Improved HTML5 Canvas API

Simon Willison’s Weblog - 5 hours 54 min ago

canto.js: An Improved HTML5 Canvas API (via). Improved is an understatement: canto adds jQuery-style method chaining, the ability to multiple coordinates to e.g. lineTo at once, relative coordinate methods (regular Canvas does everything in terms of absolute coordinates), the ability to use degrees instead of radians, a rounded corner shortcut, a more convenient .revert() method and a simple parser that can understand SVG path expressions! The only catch: it uses getters and setters so won’t work in IE.

Categories: Blogs

Focus Management with PrimeFaces

Cagatay Civici's Weblog - 6 hours 5 min ago

Managing focus on input components with JSF can require quite some work since you need to write your own javascript that set focus on fields, know about clientIds and handle cases where validation fails. Also you need to do this for every page that has different set of component. In order to make focus management easier, I’ve added p:focus component to PrimeFaces which is a handy component that manages focus for you in various cases.

Default Focus

When focus is placed on a page, it finds the first visible editable input component and sets focus on it. This is simple as;

<p:focus />
<h:inputText disabled="true"/>
<h:inputText />

In this case second inputText will receive focus as first one is disabled.

Explicit Focus

You can also define a particular component to apply focus.

<p:focus for="text" />

<h:inputText id="text" />

Failed validations

This is where things get interesting, when validations fail focus knows about the first invalid field in component tree and sets focus on it. You just need to update focus component as well.

<p:focus id="focus" />

<p:panel header="New User" id="pnl">
    <h:panelGrid columns="2">
        <h:outputLabel for="firstname" value="Firstname: *" />
        <h:inputText id="firstname" required="true" />

        <h:outputLabel for="surname" value="Surname: *" />
        <h:inputText id="surname" required="true" />
    </h:panelGrid>
</p:panel>

<p:commandButton value="Submit" update="pnl focus" />

If required validations on firstname or surname fail, focus will applied on the first invalid component. So if firstname is valid and surname is invalid, surname will get focus. By default FacesMessages with Error severity are considered, this can be tuned with severity attribute of focus, so as an example you can choose to apply focus if message level is at least warning by setting severity to warn.

Focus Context
By default focus considers the all input fields in JSF page, if you like focus to work on a specific part of your page, use the context option. This is very handy in cases where you have a dialog open and want p:focus to consider the input fields in dialog only.

<p:focus id="focus" context="dialog"/>

<p:dialog header="New User" id="dialog">
    <h:panelGrid id="grid" columns="2">
        <h:outputLabel for="firstname" value="Firstname: *" />
        <h:inputText id="firstname" required="true" />

        <h:outputLabel for="surname" value="Surname: *" />
        <h:inputText id="surname" required="true" />
    </h:panelGrid>
</p:dialog>

<p:commandButton value="Submit" update="grid focus" />

In this case, input fields outside of the dialog are not considered.

Live Example
That’s it, in summary using p:focus, you can come up with a generic solution and save user from one extra click. If you’d like to see focus in action, check out the online showcase of PrimeFaces.


Categories: Blogs

nodejitsu's node-http-proxy

Simon Willison’s Weblog - Thu, 07/29/2010 - 01:34

nodejitsu’s node-http-proxy (via). Exactly what I’ve been waiting for—a robust HTTP proxy library for Node that makes it trivial to proxy requests to a backend with custom proxy behaviour added in JavaScript. The example app adds an artificial delay to every request to simulate a slow connection, but other exciting potential use cases could include rate limiting, API key restriction, logging, load balancing, lint testing and more besides.

Categories: Blogs

Flex Addon for Spring Roo

Marco Casario | RIAvolutionize the web - Wed, 07/28/2010 - 15:47

This Flex Addon is a serious plugin for who is using Spring Roo in enterprise enviroment.

Have a look at the Flex Addon documentation:

Spring Roo brings brings a whole new level of productivity to building Java applications. From the Spring Roo Reference Guide:

"Spring Roo is an easy-to-use productivity tool for rapidly building enterprise applications in the Java programming language. It allows you to build high-quality, high-performance, lock-in-free enterprise applications in just minutes. Best of all, Roo works alongside your existing Java knowledge, skills and experience. You probably won't need to learn anything new to use Roo, as there's no new language or runtime platform needed. You simply program in your normal Java way and Roo just works, sitting in the background taking care of the things you don't want to worry about."

To learn more about Spring Roo itself, you'll find numerous resources from the project's homepage at http://www.springsource.org/roo

The Flex Addon for Spring Roo aims to raise the bar for developer productivity in building Spring-based RIAs with a Flex client by meeting the following goals:

  1. Provide the fastest way to get a Spring project configured to use Spring BlazeDS Integration set up and running.
  2. Eliminate the need to manually perform repetitive tasks such as keeping ActionScript and Java domain objects in sync.
  3. Automate round-tripping code-generation of Flex artifacts with a focus on letting developers do what they do best - write code.

Categories: Blogs

360Flex DC Ticket Giveaway

Simeon Says - Simeon Bateman - Tue, 07/27/2010 - 17:49

Still haven’t bought your ticket to 360Flex in DC? Shame on you! But as usual your procrastination has paid off. Dan Florio (polygeek) has started a contest on his site to give a way a free ticket to 360Flex in DC. By buying your ticket through Dan’s affiliate link you become eligible to win back your fee for buying the ticket. Which is always great.

The really fantastic part of this giveaway is that if Dan gets enough signups he intends to start a scholarship for the next 360 so that someone who would not have previously had the ability to attend such an amazing and empowering conference would be granted the chance.

So again, if you have not bought your ticket to 360Flex in DC, Please do so through Dan Florio’s site.

Categories: Blogs

Determining if an object property exists

NCZOnline - Nicholas C. Zakas - Tue, 07/27/2010 - 15:00

One of the most basic tests developers perform in JavaScript is whether or not a particular property exists on an object. Since feature detection is the preferred method of code forking, developers are encouraged to test for the existence of properties before using them. There is a lot of buggy JavaScript code out there as inexperienced developers try to use feature detection. A lot of the problems reside with a lack of understanding as to the nature of object properties in JavaScript.

Where do properties come from?

Before attempting to detect properties, it’s important to understand from where they originate. There are two basic types of properties in JavaScript: those that exist on the object (also known as “own” properties) and those that are inherited through the prototype chain (often called “prototype” properties). Consider the following:

var person = {
    name: "Nicholas"
};

alert(person.name);        //"Nicholas"
alert(person.toString());  //"[object Object]"

In this code, the object person has only one own property, which is name. You can still access other methods on the object such as toString(), but these are inherited through the prototype chain. Object literals inherit from the Object type, so all of the basic methods of Object are accessible on the instance.

The big difference between own properties and prototype properties is the difference between unique and shared values. Own properties belong to that single object instance and can’t be affected by other instances of the same type; prototype properties belong to the prototype of the object, and since the prototype can be shared amongst multiple instances, these properties are also shared amongst multiple instances. Here’s another example:

var person2 = Object.create(person);
var person3 = Object.create(person);

alert(person2.name);   //"Nicholas"
alert(person3.name);   //"Nicholas"

person.name = "Adam";

alert(person2.name);    //"Adam"
alert(person3.name);    //"Adam"

This example uses the Object.create() method from ECMAScript 5 to create two objects, person2 and person3, that inherit from person. The prototype for both person2 and person3 is person, and so name is actually a prototype property that is accessible through person2 and person3. This is why displaying the values of name on both objects results in the same value: they are both sharing the prototype property name. That means when person.name is changed directly, the change is accessible from the instances.

It’s important to understand that name is a prototype property for both person2 and person3, but it’s an own property for person. You can only assign values to own properties, so attempting to assign a value to a prototype property actually causes a new own property of the same name to be created. Example:

alert(person2.name);    //"Nicholas"
alert(person3.name);    //"Nicholas"

person2.name = "Adam";

alert(person2.name);    //"Adam"
alert(person3.name);    //"Nicholas"

Since you can’t assign to prototype properties, assigning a new value to person2.name actually creates a new own property on person2 called name. Own properties always shadow prototype properties, so the next time you access person2.name, you’re accessing the own property instead of the prototype property. That will continue until the own property is removed using delete, such as:

delete person2.name;

alert(person2.name);    //"Nicholas"

You can only call delete on an own property to remove it (calling on a prototype property does nothing). Once the own property name is removed, there is nothing shadowing the prototype property name and so person2.name now refers to the prototype property.

Note: While all native object types (Array, Boolean, Date, all Error variants, Function, Number, RegExp, and String) inherit from Object, non-native object types, such as those that represent the DOM in browsers, don’t necessarily inherit from Object in all browsers.

Detecting properties

Let’s say you want to determine if a given object has a property of name. In experienced developers tend to write code like this:

//doesn't accurately test for existence
if (person.name){
    //yay! property exists!
}

At first glance, this seems okay. However, understanding how JavaScript works reveals some problems with this approach. First, this will only succeed if the value of person.name is truthy, meaning it’s an object, a non-empty string, a non-zero number, NaN, false, and not null or undefined. That means if person.name is the empty string (”"), this check will fail. Failing, in this case, doesn’t mean that the property doesn’t exist. In fact, the property does exist and contains a value, but the value is falsy and so doesn’t pass this test.

Detecting own properties

Keeping in mind that this is about testing for the existence of the property and not for the usability or data type, there are a couple of options. The first option is to detect own properties, and it comes via a method on the Object type called hasOwnProperty(). Since native objects inherit from Object, this property is inherited by these objects and can be used to detect the existence of own properties:

alert(person.hasOwnProperty("name"));   //true
alert(person2.hasOwnProperty("name"));    //false

person2.name = "Adam";

alert(person2.hasOwnProperty("name"));    //true

delete person2.name;

alert(person2.hasOwnProperty("name"));    //false

Initially, person2 has a prototype property name, so hasOwnProperty() returns false. Once an own property is created, calling hasOwnProperty() returns true. And after the property is removed via delete, this method again returns false.

JSON serialization works only for own properties, and non-native JSON serialization utilities used hasOwnProperty() to ensure that only the properties defined on object literals were included in the resulting string.

Detecting all properties

If you only care that the object has a property and don’t care whether it’s an own property or a prototype property, you can use the in operator to determine the existence of the property. Example:

if ("name" in person){
    //property exists
}

The in operator returns true when the named property exists on the object. In many cases, the in operator is all that you’ll need (especially when dealing with DOM objects). In fact, Mark Pilgrim’s All-In-One Almost-Alphabetical No-Bullshit Guide to Detecting Everything for HTML5 makes extensive use of in for detecting the new HTML5 features on DOM objects.

Conclusion

If you just want to check for the existence of properties, and not necessarily what their value might be, then you have two safe options: hasOwnProperty() and the in operator. The hasOwnProperty() property method should be used if you want to detect own properties only. If you want to test property existence and don’t care if it’s an own property or an object property, then the in operator is the one to use.

Update (27 July 2010): Added false and NaN to list of falsy values.
Related posts

P.S. My new book, High Performance JavaScript is now out! If you want more than performance, check out Professional JavaScript, 2nd Edition.

Categories: Blogs

Microsoft: Stop the shiny object syndrome.

The MossyBlog Times - Scott Barnes - Tue, 07/27/2010 - 04:51

image

It’s soon time for yet another product roll out, you’re in the marketing team and faced with a urgent issue – we need example demos to excite the developer base?. Like most other Product Managers you look for the nearest and latest vendor, drop a few hundred thousand in their laps and say the words “Can you make it WoW” and then proceed to wait.

The agency at times will come back with a result that’s either really fantastic or really short on execution – in my exp I’ve noticed more of the later. You then take that said demo, slap on the Microsoft branding on it then send it out into the wild as your own – don’t ask, don’t tell is your response on “how”.

Those of you who kind of know how the behind the scenes works on these kind of things are ok with it, as its part of the machine in which a market gets seeded with the said product. Those of you who look at the new shiny toy on offer are excited and are waiting for the final result. Waiting… waiting…and more waiting but it doesn’t often come.

You probably didn’t get the meme on why end of year reviews come internally come and go which in turn means that all work created in the first fiscal cannot be re-echoed in the second fiscal – so yes, the cool little agency built concept gets thrown out with the previous fiscals trash.

This is how Microsoft markets its products daily ranging from websites, applications through to random programs that are meant to simplify your world into a few bullet points or less.

The reality is this, it gets to a point where you simply just roll your eyes at every new announcement and essentially approach it with an element of contempt or cynicism. To be fair, you’re suffering from the old “fool me once, shame on you; fool me twice shame on me” effect.

Microsoft really needs to knock it off, its getting somewhat annoying for the customer base. At first I just ignored this overall effect as well I was like many part of the said machine. Now being on the outside of Microsoft and hanging out with the “customers” and “developers” I can see the negative effects it has on the perception of Microsoft today first hand.

I almost want to grab Steve Ballmer and make him sit down in frontline cubicles incognito – like that show where boss’s go undercover in their companies – and get him to see the negative impacts these poorly executed marketing strategies are having.

Disagree? how about this, what if someone were to create a timeline of all the new example apps and promises Microsoft has made in the last 5 years. Then if we were to look at the ones that have sustained beyond a fiscal year, how many do you think would be left?

Microsoft needs to re-focus, re-energize and re-think their current strategies as I think its getting to the point now where there is more noise less signal. I should know as I make a tidy profit right now decoding Microsoft to customers and once they get over the initial shock comes anger then acceptance.

example:

Customer:
“Why didn’t the team do xyz”

Me:
“Because the other team in the org didn’t like it so they had to work around the said team. It’s not an external factor, just an internal political thing”

Customer:
“but i loved it!”

Me:
“Yeah, it was a good idea, anyway..”

Think I’m wrong? ask Microsoft how its going with the design audience discussions? Ask the Windows team what they think of WPF / Silverlight and how HTML5 will play a role? you’ll be quite surprised at the answers of these two questions.

I call this “the shiny object syndrome” (ie once the shine leaves or it gets boring, you’re onto the next one and so on like its seasonal fashion)
Related Posts:


Categories: Blogs

Getting Started with Phidgets and ActionScript 3

Mike Chambers - Mon, 07/26/2010 - 23:41


Phidgets are a set of devices and sensors that provide a simple way for developers to create applications that both send and receiving information from external sensors, motors and pretty much anything else you can hook up via electronics. They are similar to the open source Arduino electronic platform.

Im not going to do a big comparison between Arduino and Phidgets in this post. I plan to do that in another post (along with an Arduino / Flash hello world article). Suffice it to say though, that one of the major benefits of Phidgets, is that the Phidgets devices are a bit higher level, both on the hardware, and software side and thus can be a little easier for a developer new to electronics to get started with.

If you are a Flash developer, Phidget’s are very attractive, as they provide a very well developed and documented ActionScript API for working with the Phidgets devices. The API works by connecting via a socket from Flash content, to a Phidgets local (or remote) server. The Phidgets server connects directly to the Phidgets devices over USB, and proxies communication between the Flash / ActionScript content, and the Phidgets devices and electronics.

In this post, I will cover everything you need to know in order to get started integrating Phidgets electronics and Flash / ActionScript content.


You can grab all of the code for the example from my GitHub Example repository.

First, here is what you will need to get started:

  • An ActionScript 3 compiler (such as Flash Builder, Flash Professional, or the open source MXMLC compiler included in the Flex 4 SDK).
  • An IDE or text editor to edit ActionScript (such as Flash Builder, Flash Authoring, FDT, TextMate or any other general text editor).
  • The Phidgets ActionScript 3 library. You can find the library’s SWC in Flex 3 Code Sample ZIP file, and can find the source in the Flash AS3 Code Sample Zip file, both on the Phidgets programming resources page.
  • The Phidgets drivers for your platform. This will install the drivers for the devices, as well as the proxy application / server that Flash will use to communicate with the devices. You can download these from the Phidgets driver page.
  • At least one Phidgets device that can connect directly to your computer USB. If you are just getting started, then I would recommend the 1018 – PhidgetInterfaceKit 8/8/8 as it is the most flexible and extensible. This article will assume you are using this kit.
  • One LED to test the kit with.

For this article I will be using TextMate on a Mac and compiling with the free mxmlc compiler included in the Flex 4 SDK. We will be running the example via Adobe AIR (via ADL included in the Flex 4 SDK) (although the SWF we create will also work in the Flash Player in the browser).

Install Drivers

First, download and install the Phidgets drivers for your platform. This will install the drivers to interface with the devices via USB, and will also install a standalone application / server that will proxy calls between Flash and the devices.

Test Installation

Once you have installed the drivers, download the manual for the 1018 – PhidgetInterfaceKit 8/8/8. I strongly recommend you read through the entire PDF document, but at a minimum, you will want to read the “Product Features” and “Getting Started”" sections.

Connect your Phidget via USB to your computer and then read and follow the steps under the Getting Started > Testing section in the 1018 docs. This will show you how to ensure that your Phidgets and software are setup and functioning correctly. Make sure to run the sample program as described in the docs.

Download Phidget ActionScript Library

In order to communication with the Phidgets devices / proxy application via ActionScript, we need to download the Phidgets ActionScript library. There are two Flash related libraries on the Phidgets Programming Resources page. The Flash AS3 download contains example FLAs to be run in Flash Authoring (4 or 5), as well as the source code for the Phidgets ActionScript library. The Flex AS3 download contains both Flex / MXML and pure ActionScript examples, as well as the Phidget AS3 Library SWC. You can also download API references and a getting started guide on the page.

You can use either the Phidget library source from the Flash AS3 download, or the Phidget library SWC from the Flex AS3 download. Just make sure to link them in when compiling your ActionScript. For this article I will be using the compiled SWC.

Configure the Phidget

For our simple hello world example, we are going to connect an LED to our Phidget and then turn it on via ActionScript. In order to do this, we need to connect an LED to the PhidgetInterfaceKit. Connect an LED to output pins G (Ground) and 0. Make sure that the long wire (anode) of the LED is connected to pin 0, and the short wire (cathode) is connect to the ground (G).

Next, make sure that the Phidget is connected to the computer via USB. You can test that everything is connected and hooked up correctly by opening the Phidget preferences, and selecting output 0 on the Phidget Interface Kit screen. This should turn on the LED (make sure to turn it off once you are done).

Turn on Phidget Proxy / Server

The last step before we can write our code is to make sure that the Phidget proxy / web server is running. This is a simple socket server that runs locally and proxies calls between Flash and the Phidget.

On Mac, you can start this in System Preferences > Phidgets > Web Service > Start Web Service. Check the documentation for how to start it on other platforms.

For now you can leave the ServerID and Password blank, and leave the port at its default value of “5001″.

Write ActionScript Code

We are finally ready to write the ActionScript code to interface with the Phidget.

Open you ActionScript editor, and type in the following code in a file named PhidgetsHelloWorld.as. The code below is fully commented and explains what is going on.

/*
	The MIT License

	Copyright (c) 2010 Mike Chambers

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.
*/

package
{
	import flash.display.Sprite;
	import flash.events.Event;

	//import the Phidget classes we need for this example
	//from the Phidget's library / SWC
	import com.phidgets.Phidget;
	import com.phidgets.PhidgetInterfaceKit;
	import com.phidgets.events.PhidgetEvent;	

	public class PhidgetsHelloWorld extends Sprite
	{		

		//reference to the Phidget Interface Kit we are connecting to
		private var interfaceKit:PhidgetInterfaceKit;

		//constructor
		public function PhidgetsHelloWorld()
		{
			//listen for when we are added to the stage
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}

		private function onAddedToStage(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

			//create instance of PhidgetInterfaceKit
			interfaceKit = new PhidgetInterfaceKit();

			//listen for event that we need for this example

			//connected to proxy
			interfaceKit.addEventListener(PhidgetEvent.CONNECT,	onConnect);

			//device attached
			interfaceKit.addEventListener(PhidgetEvent.ATTACH,	onAttach);

			//device detached
			interfaceKit.addEventListener(PhidgetEvent.DETACH,	onDetach);

			//disconnected from proxy
			interfaceKit.addEventListener(PhidgetEvent.DISCONNECT, onDisconnect);

			//proxy address. Usually localhost / 127.0.0.1, but can be any server
			//on any computer. The proxy returns proper security policy file
			var serverAddress:String = "127.0.0.1";

			//port the proxy is listening on
			var serverPort:uint = 5001;

			//connect to the proxy and device
			interfaceKit.open("127.0.0.1", 5001);
		}

		//called when we connect to the proxy server
		private function onConnect(e:PhidgetEvent):void
		{
			//note, we cannot access any devices here yet, since
			//we have not connected to them. You have to wait for the
			//onAttach event
			trace("-------onConnect------- ");
		}

		//called when we attach / connect to the actual Phidget
		private function onAttach(e:PhidgetEvent):void
		{
			trace("-------onAttach------- ");

			//get a reference to the device we connected to
			var device:Phidget = e.Device;

			//print out a bunch of information about it
			trace(device.Name + " : " + device.Label);
			trace("Version : " + device.Version);
			trace("Serial : " + device.serialNumber);

			//output number / pin that the LED is connected to
			var outputPin:uint = 0;

			//state to set the output pin. true = on, false = off
			var state:Boolean = true;

			//set the output state for pin 0 to true / on.
			//this will turn on the LED
			interfaceKit.setOutputState(outputPin, state);

			//note, you have to explicitly turn it off, or else
			//it will stay on, even after the program has stopped running
		}

		//called when a device is detached. i.e. the USB cable is disconnected
		//while the program is running
		private function onDetach(e:PhidgetEvent):void
		{
			//you cannot access the devices here.
			trace("-------onDetach------- ");
		}		

		//called once the connection to the proxy server is closed.
		private function onDisconnect(e:PhidgetEvent):void
		{
			//you cannot access the devices here
			trace("-------onAttach------- ");
		}
	}
}

 

I am going to run this via ADL (Adobe AIR) included in the Flex SDK, and thus also need the following PhidgetHelloWorld-app.xml file:

<?xml version ="1.0" encoding="utf-8" ?>
<application xmlns="http://ns.adobe.com/air/application/2.0">
	<id>PhidgetsHelloWorld</id>
	<version>1.0</version>
	<filename>PhidgetsHelloWorld</filename>
	<description></description>
	<name>PhidgetsHelloWorld</name>
	<copyright></copyright>
	<initialWindow>
		<content>PhidgetsHelloWorld.swf</content>
		<systemChrome>standard</systemChrome>
		<transparent>false</transparent>
		<visible>true</visible>
		<fullScreen>false</fullScreen>
		<autoOrients>false</autoOrients>
		<aspectRatio>portrait</aspectRatio>
		<renderMode>auto</renderMode>
	</initialWindow>
	<customUpdateUI>false</customUpdateUI>
	<allowBrowserInvocation>false</allowBrowserInvocation>
	<icon>
	</icon>
</application>

 

I am running it via ADL / Adobe AIR as it will easily allow me to see the trace output on the command line.

Here is the command to compile the program using MXMLC:

mxmlc -library-path+=Phidget21Library.swc PhidgetHelloWorld.as

 

You may receive a warning about runtime shared libraries. You can safely ignore this.

If you get an error that mxmlc cant be found, then make sure you have added the FLEXSDK/bin directory to your system’s path.

If you receive any errors, make sure you are linking in the Phidget library correctly. Once it compiles, you can test it on the command line with the following command:

adl PhidgetHelloWorld-app.xml

 

When I run this on my machine the LED turns on on the Phidget, and I get the following output on the command line:

-------onConnect-------
-------onAttach-------
Phidget InterfaceKit 8/8/8 :
Version : 900
Serial : 116799

 

If you run the SWF in the player, then you should see the LED turn on. If you run in Flash Authoring (FLA included) or FlashBuilder, then you should also see the trace output in the output panel.

Notice that once you close the program, the LED is still on. You have to explicitly turn off the LED. You can do this by modifying the code to turn it off, and then run it again.

This is an important point. The device may maintain its state even after the program has stopped running. Because of this, you should always set the device to a known state when your application starts up, and make sure it is in the correct state when you shut down your program.

Once you are at this point, it is just a matter of hooking up additional sensors, motors and outputs. The Phidgets ActionScript library is very well written, and makes it easy to work with additional Phidgets.

Make sure to check out all of the Phidgets and ActionScript related docs on the Phidgets site, as well as the Phidgets ActionScript forum.

If you find any errors, or have any questions or suggestions, then please leave them in the comments.

Categories: Blogs, Companies

Building Client / Cloud Apps with Flash Builder for Force.com

James Ward - RIA Cowboy - Mon, 07/26/2010 - 21:15

I have a theory. The majority of people who use enterprise software today use old school Client / Server apps. We’ve been trying to move these apps to the web for more than ten years. The ease of deployment of web apps is a clear motivator. Yet the client capabilities of the plain old web browser have not been sufficient for many apps to make the leap. This is why I love Flex and the Flash Platform. It provides a way to use web technologies and the web deployment model but adds many of the critical things needed for mission critical apps that people use all day long.

But no one wants to go back to the Client / Server architecture. We want to embrace Cloud Computing architectures but not lose the client capabilities. What we really need is the Client / Cloud architecture. We need a web deployment model that provides ease of deployment but also the ability to install applications on our desktops and mobile devices.

This is why I’m so excited about the new Adobe Flash Builder for Force.com. In a nutshell this is a tool that Adobe and Salesforce.com built together to enable developers to build great software using Flex for the UI and Force.com for the Cloud back-end. It’s a wonderful combination of technologies that will help many Client / Server apps make the switch to Client / Cloud.

Applications created with Flash Builder for Force.com can be run in the browser, on the desktop, and on mobile devices. These applications can be assembled from the hundreds of Flex components that are out there (check out many of them in Tour de Flex).

Check out this video to see how to use Flash Builder for Force.com to build a simple app:

As you can see, it’s very easy to get started. But I wanted to go a step further and try to build something real–something that shows a genuine use case for extending beyond the out-of-the-box Salesforce.com UI. I wanted to keep it really simple so that I could post the code here. What I came up with is this (in user story form):

  • As a Salesforce.com user I want to take a photo, using my phone, of one of my contacts so that the photo can be saved to their contact record for future reference.
  • As a Salesforce.com user I want to see photos I’ve taken of my contacts so that I can be reminded of what they look like.

Simple enough. So here is what I came up with:

To build these two apps I first downloaded and installed Flash Builder for Force.com. I used the Adobe AIR for Android prerelease to build the mobile app. Here is how I created these apps.

First I added a new field to Contact to store the photo. Salesforce.com doesn’t have a binary field so I used a large text field (32k limit). I’ll store the photo Base64 encoded.

Then in Salesforce.com I saved my enterprise.wsdl file. Check out a great video from Dave Carroll to see how to do this.

Now in Flash Builder for Force.com I created a new Force.com Flex Project for the mobile app. If you do this on your own and want to run on a mobile device then you will need to overlay the AIR for Android SDK on top of a Flex 4.1 SDK. Select Desktop Application as the app type. Replace WindowedApplication with just Application. And replace the F3DesktopApplication with F3WebApplication since F3DesktopApplication uses APIs that are not available on AIR for Android. (BTW: Flash Builder, Flex, and Force.com Flex Projects do not officially support mobile deployment yet. It works but there is no support and no guarantees.) If you are building a standard Web Application or Desktop Application then you can just leave the generated code as is.

Using the Data/Services wizard I connected to Salesforce.com using my enterprise.wsdl file. After the services and value objects have been generated I modified the Contact object and added a Bindable account property. The generated application already included the F3DesktopApplication Declaration used to connect to Salesforce. Due to an incompatibility with that API and AIR for Android I switched it to use F3WebApplication. In F3WebApplication’s loginComplete event handler I query Salesforce.com for Accounts and then Contacts, associate contacts with their account, and then store the contacts:

app.wrapper.query("select Id, Name from Account", new AsyncResponder(function(data:ArrayCollection, token:Object):void {
    accounts = data;
    app.wrapper.query("select Id, AccountId, FirstName, LastName, Phone, MobilePhone, Email, Title, Department, MailingCity, photoData__c from Contact", new AsyncResponder(function(data:ArrayCollection, token:Object):void {
        for each (var contact:Contact in data)
        {
            for each (var account:Account in accounts)
            {
                if (account.Id == contact.AccountId)
                {
                    contact.account = account;						
                }
            }
        }
        contacts = data;
    }, handleError));
}, handleError));

Notice in the query that I’m fetching photoData__c, which is the custom field I created on Contact to store the photo.

In the renderer for a contact I need to either display the photo if there is one or let the user add one. Here is the simple UI code to handle that:

<s:Group width="92" height="92" top="8" right="8">
    <s:Rect width="92" height="92">
        <s:fill>
            <s:SolidColor color="#cccccc"/>
        </s:fill>
    </s:Rect>
    <s:Label id="addPhoto" text="Add a photo" width="92" height="92" verticalAlign="middle" textAlign="center"/>
    <s:BitmapImage id="photo" width="92" height="92"/>
</s:Group>

When the contact is set I check to see if there is a photo and if so display it:

if (contact.photoData__c == null)
{
    photo.visible = false;
    return;
}
 
var decoder:Base64Decoder = new Base64Decoder();
decoder.decode(contact.photoData__c);
 
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(event:Event):void {
    photo.source = event.target.content;
    photo.visible = true;
});
loader.loadBytes(decoder.toByteArray());

The data from the photoData__c field is Base64 decoded and then displayed using the Flex BitmapImage component.

Now when the user clicks on the photo or empty photo box I use the AIR for Android CameraUI to grab a photo, resize it, covert it to a PNG, Base64 encode it, set it on the contact, and then save the contact to Salesforce.com:

if (CameraUI.isSupported)
{
    cameraUI = new CameraUI();
    cameraUI.addEventListener(MediaEvent.COMPLETE, function(event:MediaEvent):void {
        var loader:Loader = new Loader();
        loader.load(new URLRequest(event.data.file.url));
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(event:Event):void {
            var bitmap:Bitmap = event.target.content as Bitmap;
 
            var result:BitmapData = new BitmapData(46, 46, false);
            var matrix:Matrix = new Matrix();
            matrix.scale(46 / bitmap.width, 46 / bitmap.height);
            result.draw(bitmap, matrix);
 
            var pngEncoder:PNGEncoder = new PNGEncoder();
            var pngBytes:ByteArray = pngEncoder.encode(result);
 
            var base64Encoder:Base64Encoder = new Base64Encoder();
            base64Encoder.encodeBytes(pngBytes);
            var encodedImage:String = base64Encoder.flush();
 
            contact.photoData__c = encodedImage;
 
            displayPhoto();
 
            F3WebApplication.getInstance().wrapper.save(contact, new AsyncResponder(function(data:Object, token:Object=null):void {
            }, FlexGlobals.topLevelApplication.handleError));
        });
    });
    cameraUI.addEventListener(ErrorEvent.ERROR, function(event:ErrorEvent):void {
        FlexGlobals.topLevelApplication.handleError(event);
    });
    cameraUI.launch(MediaType.IMAGE);
}

That’s it for the mobile app! I compiled it, exported it to an Android app, and then copied it to my phone. Pretty simple and as you can see it works! One limitation with my approach is the 32k limit of the photoData__c field. However, I think I could easily get around that by striping the Base64 encoded data across multiple fields. It’s not ideal but it would work.

To display the photo when I view a contact on Salesforce.com I created a very simple Flex app using another Force.com Flex Project. I could have also added photo upload to this application but chose to keep it simple. All it does is display the selected contact’s photo. Here is the complete code (after generating the required services in Flash Builder):

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:flexforforce="http://flexforforce.salesforce.com">
 
    <fx:Script>		
    import mx.rpc.AsyncResponder;
    import mx.utils.Base64Decoder;
    </fx:Script>
 
    <fx:Declarations>
        <flexforforce:F3WebApplication id="app" requiredTypes="Contact">
            <flexforforce:loginComplete>
                app.wrapper.query("select photoData__c from Contact where Id = '" + this.parameters.contactId + "'", new AsyncResponder(function(data:Object, token:Object):void {
                    if (data.length == 1)
                    {
                        if (data[0].photoData__c == null)
                        {
                            photo.visible = false;
                            noPhoto.visible = true;
                            return;
                        }
 
                        var decoder:Base64Decoder = new Base64Decoder();
                        decoder.decode(data[0].photoData__c);
 
                        var loader:Loader = new Loader();
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(event:Event):void {
                            photo.source = event.target.content;
                            photo.visible = true;
                        });
                        loader.loadBytes(decoder.toByteArray());
                    }
                }, function(fault:Object):void {
                    // ignored
                }));
            </flexforforce:loginComplete>
        </flexforforce:F3WebApplication>
    </fx:Declarations>
 
    <s:applicationComplete>
        app.serverUrl = this.parameters.serverUrl;
        app.loginBySessionId(this.parameters.sessionId);
    </s:applicationComplete>
 
    <s:Rect width="92" height="92">
        <s:fill>
            <s:SolidColor color="#cccccc"/>
        </s:fill>
    </s:Rect>
 
    <s:Label id="noPhoto" text="No Photo" width="92" height="92" textAlign="center" verticalAlign="middle" visible="false"/>
 
    <s:BitmapImage id="photo" width="92" height="92"/>
 
</s:Application>

Finally I created a custom S-Control to run the Flex app:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="ContactPhoto" width="92" height="92" 
codebase="https://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"> 
    <param name="movie" value="{!Scontrol.JavaArchive}" /> 
    <param name="flashvars" value="sessionId={!API.Session_ID}&serverUrl={!API.Partner_Server_URL_90}&contactId={!Contact.Id}" /> 
    <embed src="{!Scontrol.JavaArchive}" width="92" height="92" name="ContactPhoto" 
flashvars="sessionId={!API.Session_ID}&serverUrl={!API.Partner_Server_URL_90}&contactId={!Contact.Id}" 
type="application/x-shockwave-flash" 
pluginspage="http://www.adobe.com/go/getflashplayer"> 
    </embed> 
</object>

I uploaded the compiled Flex app to the S-Control and added it to the Contact page. And that’s it! In just a few hours I extended Force.com and built a cool mobile app. I could also have easily created a desktop widget for browsing contacts and adding photos. If you are looking for a fun project to use as a way to learn this stuff that would be a good one! :)

Here are some resources to help you get started with Flash Builder for Force.com:

Have fun building the next generation of software! Let me know how it goes.

Categories: Blogs

Frame rate counters in Windows Phone

Jeff Wilcox - Mon, 07/26/2010 - 18:29

While developing Windows Phone applications, it’s good to have some simple but important performance tips and tricks in your back pocket. Here’s a quick reference to enabling frame rate counters plus an overview of what the values represent.

Enable frame rate counters in code

In your App.xaml.cs or MainPage.xaml.cs, in the constructor, set the host property to true for this diagnostic mode:

Application.Current.Host.Settings.EnableFrameRateCounter = true;
Make sure the System Tray is not visible

By default in the beta tools, the MainPage.xaml sets the system tray to be visible. When this happens, the frame rate counters are hidden by the operating system shell.

Method 1: XAML

The default page template includes an XMLNS declaration for “shell”, and has this in the phone application page constructor:

shell:SystemTray.IsVisible="true"

Just change the IsVisible property to False:

shell:SystemTray.IsVisible="false"
Method 2: Code
Microsoft.Phone.Shell.SystemTray.IsVisible = false;

In a future release of the phone tools, this is actually going to be less of an issue, as the counters will actually be right-aligned on the screen instead.

Adding a simple check box to toggle the counters

A lot of app developers add a check box to debug builds that lets them toggle this sort of diagnostic display. In one of our ‘Scenarios’ test applications, we have a check box on the first page, and in XAML it connects the Checked and Unchecked events to this method.:

private void FrameRateCounters_Checked(object sender, RoutedEventArgs e)
{
    var checkbox = (CheckBox)sender;
    var newValue = checkbox.IsChecked.GetValueOrDefault();

    Application.Current.Host.Settings.EnableFrameRateCounter = newValue;
    SystemTray.IsVisible = !newValue; // Hides frame rate counter otherwise
}
Enabling frame rate counters only on debug builds

You can also use conditional compilation to just have your debug builds display this information. Add this to your App.xaml.cs:

#if DEBUG
    Application.Current.Host.Settings.EnableFrameRateCounter = true;
    Microsoft.Phone.Shell.SystemTray.IsVisible = false;
#endif

This assumes you remember to eventually ship your app on the marketplace with a release build Smile.

Accelerated graphics note: If you still don’t see a frame rate counter

The frame rate counter only appears when your system has a supported DirectX 10 graphics card that allows the Windows Phone emulator to use accelerated graphics.

If you set the frame rate counter visibility to True, the system tray is hidden, and you still don’t’ see the counters, then unfortunately your system does not have a supported card for displaying this information.

All Windows Phone devices will show the frame rate counter, so once phone hardware is more widely available, you’ll still have an option to test the performance of your apps.

Exploring the frame rate counter data

This has been covered countless times, but I figure if you’re [using your search engine of choice to find this] here that it doesn’t hurt to duplicate.

BetaCounters

The Beta tools display frame counter information on the top of the page.

NewerCounters

Shipping frame counter information is displayed on the right of the screen.

So moving through the counters, we have the following.

Render Thread FPS: The number of frames per second that the independent simple animations and rendering thread is using. Keeping around 60 will provide a great experience, while a number of 30 fps will begin to show a poor experience to the end user.

Under 30 fps this counter will turn red in post-beta builds.

User Interface Thread FPS: The number of fps that the primary user interface thread is experiencing. Property change notifications, data binding, primary managed code execution, and animations not handled on the render thread use this threads’ resources.

Turns red when the count is at or below 15 fps.

Texture Memory Usage: A specialized memory counter indicating the video memory used for storing application textures.

Surface Counter: A count of the number of surfaces that are passed to the graphics chip.

Intermediate Texture Count: The number of intermediate textures created for compositing.

Screen Fill Rate: A metric representing the number of complete phone screens being painted each and every frame.

This counter was not present in the Beta tools and is a new metric for post-Beta use.

Target frame rates for good performance

When testing on a Windows Phone device, here are key performance metrics to try for. Understand that the emulator (XDE) performance may not be indicative of actual device performance.

Frame rate counters may be 0 when there is no animation being updated on the thread at any particular moment. You can add a very simple, continually animating and repeating, animation to your application during development & testing if you want to ensure that there is always some frame rate value available.

Counter Ideal Minimum Best Experience Theoretical Max Render Thread 30 fps 60 fps 120 fps UI Thread 15 fps > 15 fps 120 fps Screen Fill Rate 1.0 <= 2.0 N/A

Future posts will cover tips for improving the frame rate and application performance. Hope this helps.

Categories: Blogs

CFUnited Session: Building Multiplayer games on the Flash Platform with ColdFusion, Flex and Data Services

Greg Wilson's Ramblings - Mon, 07/26/2010 - 15:10

On Thursday, I’m presenting a session at CFUnited titled, “Building Multi-Player games on the Flash Platform with ColdFusion, Flex and Data Services“.   As you can see, I’m trying to do something a bit more fun than my usual topics!   Yes, I’m talking about ColdFusion powering a multiplayer game!  Over the past 18 months, I’ve been involved in a fun weekend project called ChessJam with a couple of friends.  ChessJam is a multiplayer chess game that is seeing some incredible traffic over the past few months.  The entire app is powered on the back-end by ColdFusion.  The front-end is built in Flex and deployed on Adobe AIR.  This will be the first public sharing of any internals.  Even if you are not interested in building games, there are some techniques that I will share in this session that you will find useful in any collaboration application.

Topics:

  • Find out why we chose the technology stack:  Ubuntu Linux, MySQL, ColdFusion, LiveCycle Data Services, Flex, AIR
  • Learn how to use publish/subscribe messaging techniques to enable multi-player communications
  • Hear about the challenges we faced as we dealt with users in remote areas of the globe with poor networking conditions and how we addressed it (we have users from more than 200 countries)
  • Learn how to take advantage of ColdFusion remoting in Adobe Flex — soooo easy and soooo fast!
  • Explore various collaboration techniques employed throughout ChessJam from in-game chat to synchronized views

I’m really looking forward to presenting this session.  This project has been a lot of fun and I am excited to share.  To prepare for this session, go grab the app and play! — http://chessjam.com

CFUnited Session: 7/29 Thursday 4:00PM – 5:00PM Faulkner


Filed under: Adobe AIR, Adobe ColdFusion, Adobe Flex, Adobe LiveCycle Data Services, chessjam Tagged: Adobe AIR, Adobe Flex, AIR, BlazeDS, CF9, CFUnited, chessjam, ColdFusion, Flex, LCDS, LiveCycle Data Services, online chess
Categories: Blogs, Companies

CFUnited Session: Adding real-time data visualization to your application or website

Greg Wilson's Ramblings - Mon, 07/26/2010 - 14:47

On Friday, I’m presenting a session at CFUnited titled, “Adding real-time data visualization to your application or website“.   In this session, I’m going to demonstrate how to take data from your web site or application and turn it into a real-time data feed that can be used to feed a dashboard that will impress your boss!  ;-)

Topics:

  • Explore multiple techniques to tap into your app/site’s activity data (swf, “magic png”, server-side, etc.)
  • Learn how to convert an IP Address to latitude, longitude, city and country
  • Use ColdFusion’s sendGatewayMessage() to broadcast the data
  • Learn how to configure publish/subscribe messaging using BlazeDS (included with CF9) and LiveCycle Data Services (I’ll explain the differences)
  • Learn how to build amazing data visualizations using Adobe Flex
  • Take a deep dive into two visualization examples:
    • Use Google Map Flash 3D APIs (amazing features)
    • Use IBM ILOG Elixir’s heat map component and gauges

I’ll be sharing the full source-code for the whole thing.

CFUnited Session: 7/30 Friday 3:15PM – 4:15PM Ballroom A

I hope to see you there!


Filed under: Adobe ColdFusion, Adobe Flex, Adobe LiveCycle Data Services, Data Visualization Tagged: Adobe Flex, BlazeDS, CFUnited, ColdFusion, Data Visualization, Flex, google maps, google maps flash api, ibm ilog, ILOG Elixir, LCDS, LiveCycle Data Services
Categories: Blogs, Companies

PrimeFaces 1.1 and 2.1 Released

Cagatay Civici's Weblog - Mon, 07/26/2010 - 14:06

I’m glad to announce that PrimeFaces 1.1 and 2.1 are released.

The versions include maintenance on the previous released release candidates;

  • 20 issues targeting RCs are fixed and closed.
  • Enhancements to wizard component.

See the full changelog of 1.1 and 2.1 for detailed information.

This is the last release of PrimeFaces 1.x branch targeting JSF 1.2, from now on we will focus on JSF 2.0 to make PrimeFaces even more lightweight and compatible. See the roadmap for more information.


Categories: Blogs

JavaOne 2010: So Many Interesting Sessions, So Few Time Slots

JavaOne 2010 has so many presentations that I want to see that even my current alternatives list ("My Interests" in Schedule Builder) is full of presentations that sound compelling.  The following presentations are currently in "My Interests" because I have (as of today) selected another presentation at the same time to "Enroll" in.  I think this list speaks for itself.  Of course, it is likely that I will change my mind several times between now and JavaOne and it's almost certain that I'll attend some of these.  For now, though, these are the presentations I wish I could attend, but currently think I'll have to miss because there's something else also scheduled at the same time.

[CS] - [S318719] MySQL Performance Tuning Best Practices
[CS] - [S318720] You Know Databases, So How Hard Can MySQL Be?
[CS] - [S313185] Writing Stunning Cross-Platform Applications Using LWUIT
[CS] - [S314273] Groovy: To Infinity and Beyond
[CS] - [S314588] Java Context Dependency Injection and OSGi to Help with Modularity
[CS] - [S313657] Tips and Tricks for Building JavaFX Applications
[CS] - [S313504] Project Coin: Small Language Changes for JDK 7
[CS] - [S313431] Java Persistence API 2.0: An Overview
[CS] - [S314629] HTML5 and Java: Opening the Door to New Possibilities
[CS] - [S315885] Ten Easy Ways to Improve Java EE Performance
[CS] - [S314362] Time to Improve: JSR 310 Date and Time API
[CS] - [S314039] Google Web Toolkit (GWT) Cloud Applications: Fast, Fun, and Easier Than Ever
[CS] - [S312988] Unit Testing That's Not That Bad: Small Things That Make a Big Difference
[CS] - [S313520] Funky Java, Objective Scala Available 2:30-15:30 Parc 55, Cyril Magnin III
[CS] - [S313839] Using the File System API in JDK 7
[CS] - [S314492] Java Persistence API (JPA) 2.0 with EclipseLink
[BOF] - [S314416] The Collections Connection: Special "It Goes Up to the 11th" Edition
[BOF] - [S314190] The Better RESTful Web Services Framework: Jersey or Spring Framework
[CS] - [S313557] The Java EE 6 Programming Model Explained: How to Write Better Applications
[CS] - [S317739] Java Persistence API: Tips, Patterns, and Best Practices
[CS] - [S313248] Creating Lightweight Applications with Nothing but Vanilla Java EE 6
[CS] - [S314395] WebSockets Versus Comet: What Are the Differences, and Why Should I Care?
[CS] - [S312989] Comparing Groovy and Jruby
[CS] - [S313831] Breaking Up Is Hard to Do: Modularizing the JDK and Lessons Learned
[CS] - [S313189] Complete Tools Coverage for the Java EE 6 Platform
[CS] - [S314168] What's New in Enterprise JavaBean Technology
[PAN] - [S315029] Java API for Keyhole Markup Language
[CS] - [S314408] Java Puzzlers: Scraping the Bottom of the Barrel
[CS] - [S314696] The Secret Power of JavaFX Script
[CS] - [S314286] Dual-Pivot Quicksort and Timsort, or Sorting on Steroids
[CS] - [S314665] A Journey to the Center of the Java Universe
[CS] - [S314256] Securing RESTful Web Services in Java
[CS] - [S314491] Effective XML: Leveraging JAXB and SDO
[CS] - [S314424] Polyglot Programming in the Java Virtual Machine (JVM)
[BOF] - [S314475] 10 Years of The Java Specialists' Newsletter
[CS] - [S314822] Myths, Misconceptions, and Hidden Gems in Java Platform Security
[CS] - [S313960] JavaFX Graphics
[CS] - [S313501] The Merging Point of Android and Swing
[CS] - [S314405] Google Web Toolkit Versus Rich Ajax Platform: Which Java-Based Ajax Is for You?
[HOL] - [S313277] Beginning with the Java EE 6 Platform
[HOL] - [S313674] Building a JavaFX-Based Monitoring App, Using the GlassFish REST Monitoring API
[CS] - [S314403] Java Transaction API Caching: Consistent, Distributed, and Coherent
[CS] - [S314385] Ninety-Seven Things Every Programmer Should Know
[CS] - [S313005] Domain-Specific Language Versus Library API Shootout
[CS] - [S314359] Remote Compiling and Performance Analysis Using the NetBeans IDE
[CS] - [S313819] What's Happening with My Application?: Java Virtual Machine Monitoring Tool
[CS] - [S314154] Writing Domain-Specific Languages (DSLs), Using Groovy
[CS] - [S314334] Static Analysis in Search for Performance Antipatterns
[CS] - [S314226] SomeSQL: Combining NoSQL Technologies with Existing RDBMS Architectures

The first acronyms listed on each line in square braces have the following meanings: BOF (Birds of a Feather), CS (Conference Session), ESS (Executive Solution Session), GS (General Session), HOL (Hands-On Lab), KEY (Keynotes Session), and PAN (Panel).

The alternative sessions listed above are the result of my first run-through with the Schedule Builder and that list does not even include potential OracleDevelop presentations of interest related to subjects such as Oracle Fusion, JDeveloper, Java in the Oracle Database, Oracle ADF, etc.

There are so many interesting-sounding presentations to choose from at JavaOne 2010 that it is very difficult to decide on which to attend.
Categories: Blogs

One From The Vault: Ranting About Editors

Jesse Liberty - Silverlight Geek - Mon, 07/26/2010 - 03:37

This week’s One From The Vault is a rant on arbitrary and incorrect “rules” of English insisted upon by some teachers, editors and pedants:

There is no excuse for thinking that you can’t start a sentence with “There is.”  And I should add that I think it is fine to start a sentence with “and.” But not just and, even but.

Here’s the link

Categories: Blogs

Data Validation And Templating in Silverlight 4

Jesse Liberty - Silverlight Geek - Sun, 07/25/2010 - 21:26

MiniTutorial

This is the fifth in a series on Templates and DataValidation.
[ First In Series Previous In Series ]

In this and the next posting I will create an application that will demonstrate how to modify the Visual State for invalid data. Along the way we will review:

  • Binding form elements to data
  • The binding engine and MVVM
  • Using the binding engine for data validation
  • Data validation and the Visual State Manager
  • Using the MVVM Light Toolkit
  • Best practices in application development
  • Creating Child Windows

The project we’ll build will be based on the project built in this video about asynchronous data validation, but we will modify and extend it a bit.

Probably the biggest structural change is that we’ll implement this as a MVVM project.  Here are a couple good quick references on MVVM if this is new for you:

MVVM – It’s Not Kool-Aid
Video: MVVM Introduction

Note that this example assumes you have MVVM Light installed. This is a free library, and while I don’t usually add an external library, the simple fact is that writing MVVM by hand when you could use a library is an absurd waste of energy. As my buddy David Platt has said (paraphrasing): You can do an appendectomy through your mouth, but it takes longer and it hurts more.

In this first approach, we’ll create the MVVM project as well as the editing form and we’ll populate it with data from an object.  To get started, open Expression Blend 4 (or Visual Studio 2010)  and select MvvmLight (SL4)  Name the project Validation and make sure Language is set to C# (or VB if you are transposing) and the Version is set to 4.0.  Click OK.

Layout and Prompts

DataValidationForm Our design calls for an outer grid to hold the entire form, and an inner grid to hold the data gathering elements.  The outer grid has two rows and no columns defined,

<Grid.RowDefinitions>
   <RowDefinition
      Height="Auto" />
   <RowDefinition
      Height="Auto" />
</Grid.RowDefinitions>

The inner grid has 8 rows and two columns, with the first column is 1/2 the size of the second (that is, set the first column’s width to 1* and the second column’s width to 2*).

[ For this and all images, click on the image to see it full size ]

Add the seven prompts to the rows:

  • First Name
  • Last Name
  • Street Address
  • City, State Zip
  • Renewal Date
  • Yearly Fee

On the seventh row add a TextBlock that spans both columns, is flush left and either has no text or says “Ready…”

The final row has a button that says “Show Log”

Using Styles and Resources

Because you are using styles, all of the prompts will be identical , except for the text to display and the row:

<TextBlock
   Text="First Name"
   Grid.Row="0"
   Grid.Column="0"
   Style="{StaticResource PromptStyle}" />
<TextBlock
   Text="Last Name"
   Grid.Row="1"
   Grid.Column="0"
   Style="{StaticResource PromptStyle}" />
<!-- etc. –>
Data Entry

Let’s turn now to the data entry fields. For these, we need a few more styles, familiar from the previous example, so I’ll just remind you that TextBoxStyle sets TextWrapping to on and the Width to 150 and the Height to Auto.  It is based on InputControlStyle which sets the FontFamily to Georgia, the FontSize to 10 and the FontWeight to Normal, and InputControlStyle is in turn based on FWEStyle which can be applied to any Framework Element and sets a Margin of 5 all aound, and sets the Horizontal and Vertical Alignment to Right and Bottom respectively.]

You can see in the illustration above that all of the input controls are TextBoxes except for the one used for Renewal Date, which is of type DatePicker.  This last is not part of the core Silverlight control set, and so you will need to create a namespace for System.Windows.Controls

xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
DataBinding

With the form created we can go about the business of obtaining data and binding properties of that data to the form.  I have delegated responsibility for obtaining the data (or, more accurately, pretending to obtain the data) to the WebServiceMock class in my Model folder.

Here is the mock web service, which simply uses a timer to create a delay and then “flips a coin” to return an answer on whether or not the “submitted” data is valid.

using System;
using System.Collections.Generic;
using System.Windows.Threading;

namespace DataValidation.Model
{
   public class WebServiceMock
   {
      private const int MinDelay = 10;
      private const int MaxAddedDelay = 10;
      private static readonly Random RandomGenerator = new Random();

      private static readonly Dictionary<DispatcherTimer, ViewModel.EditCustomerViewModel.CustomerCallBack> CallBacks =
          new Dictionary<DispatcherTimer, ViewModel.EditCustomerViewModel.CustomerCallBack>();

      public static void StateTest(
          string state,
          ViewModel.EditCustomerViewModel.CustomerCallBack callBack )
      {
         var timer = new DispatcherTimer
         {
            Interval = new TimeSpan(
               0,
               0,
               0,
               MinDelay +
               RandomGenerator.Next( MaxAddedDelay ),
               0 )
         };
         timer.Tick += TimeElapsed;
         CallBacks.Add(
             timer,
             callBack );
         timer.Start();
      }

      private static void TimeElapsed(
          object sender,
          EventArgs e )
      {
         var t = sender as DispatcherTimer;
         if ( t == null )
            return;

         t.Stop();
         var custCallBack = CallBacks[ t ];

         var isValid = RandomGenerator.Next() % 2 == 0;
         custCallBack( isValid );
      }

   }
}

the interesting thing to note about this code is that it creates a dictionary that uses a DispatchTimer as the key and an EditCustomerViewModel.CustomerCallBack as the value.  This is a generic solution to the problem of creating an unknown number of callbacks that can be accessed by using the particular timer that “fired.” It is overkill for this example, but since I had it “lying around” it was easier to just use it as is.

The Model

The other occupant of the Model folder is Customer.cs, which defines the rudimentary customer object, but not any of the rules for data validity for customers.  Rules for how customers will respond to and be displayed in the UI belong in the ViewModel, which we will cover below.  Here is the entire contents of Model.Customer:

using System;

namespace DataValidation.Model
{
   public class Customer
   {
       public string FirstName { get; set; }
       public string LastName { get; set; }
       public string Street { get; set; }
       public string City { get; set; }
       public string State { get; set; }
       public string Zip { get; set; }
       public DateTime RenewalDate { get; set; }
       public Decimal YearlyFees { get; set; }
       public string Email { get; set; }

       public Customer(
          string firstName,
          string lastName,
          string street,
          string city,
          string state,
          string zip,
          DateTime renewalDate,
          Decimal yearlyFees,
          string email )
       {
           FirstName = firstName;
           LastName = lastName;
           Street = street;
           City = city;
           State = state;
           Zip = zip;
           RenewalDate = renewalDate;
           YearlyFees = yearlyFees;
           Email = email;
       }
   }
}
The View Model

Mediating between the Model and the View, is the ViewModel.

For this posting, I assume you’ve read at least MVVVM – It’s Not Kool-Aid and understand the basic role of the ViewModel and the relationship between databinding and MVVM

The key job of EditCustomerViewModel is to provide properties to which the controls in the form will be bound.  Thus, you will find public properties that correspond to an individual form field and a property of a Customer (e.g., there will be a FirstName field on the form, and a FirstName public property in the VM and, as well a FirstName property in the Customer.)  The relationship could of course be made more complex and less isomorphic (that is, you could have a FullName field in the form, a FirstName and LastName field in the VM and a Customer in the Model that has many other fields, including a Person base class), but there is no need to muddy the waters

We will also ask the View Model to take on some additional responsibilities:

  • Informing the view when to change its status ( in progress, completed, error, ok ) while data is checked against both the internal rules and policies and against server based rules accessed via a web service
  • Informing the view when the Log should be updated, and passing along a string for that purpose
  • Informing the view when the underlying data has changed and the view must be updated

All of this will be accomplished using the standard binding mechanism, including implementing (indirectly) INotifyPropertyChanged)

Finally, we’ll look at various ways to communicate errors to the View, including throwing exceptions, implementing INotifyDataErrorInfo and handling error checking asynchronously.

Once all of that is done, in the next tutorial, we’ll look at how to change the display of the error via the Visual State Manager.

Data Binding

The first step in databinding is to mark the databound controls with the binding syntax:

<TextBox
   x:Name="FirstName"
   Grid.Column="1"
   Text="{Binding Path=FirstName, Mode=TwoWay,
           ValidatesOnExceptions=true, NotifyOnValidationError=true}"
   Style="{StaticResource TextBoxStyle}" />

The Binding property here has four attributes: Path, Mode, ValidatesOnException and NotifyOnValidationErrors.  We’ll look at the latter two in just a bit, the first two are used to indicate the name of the property to bind to and whether the binding is OneTime, OneWay or TwoWay.  TwoWay binding allows for the entries in the UI to update the underlying data, OneWay is display only, and OneTime is for setting once never to be changed.

The View Model Classes

Let’s start with the classes needed to provide binding and validation support for the Customer…

public class EditCustomerViewModel :
     ViewModelBase,
     INotifyDataErrorInfo

ViewModelBase The declaration indicates that our class derives from ViewModelBase (provided by MVVMLight) and implements INotifyDataErrorInfo (to which we’ll return later).

Since ViewModelBase is in a foreign library the best way to examine it is in Visual Studio’s Object browser (right click on it and choose “Go to declaration.”   Note that in this case, the source code is available so you are free to examine the code in detail, but the Object Browser provides exactly the information we need. We see in the left pane that ViewModelBase implements INotifyPropertyChanged and, in the right pane we see that we can access the associated event (PropertyChanged) directly or, even better, indirectly through RaisePropertyChanged or RaisePropertyChanged<T>.

For now I’m going to skip over all the members that support error handling and logging and begin at the constructors. I’ve created two, one that takes the individual values of a customer, and one that takes a customer object. They do the same thing, which is to initialize the public properties of the VM class:

public EditCustomerViewModel(
  string firstName,
  string lastName,
  string street,
  string city,
  string state,
  string zip,
  DateTime renewalDate,
  Decimal yearlyFees,
  string email )
{
    FirstName = firstName;
    LastName = lastName;
    Street = street;
    City = city;
    State = state;
    Zip = zip;
    RenewalDate = renewalDate;
    YearlyFees = yearlyFees;
    Email = email;
}

public EditCustomerViewModel(Customer customer)
{
    if ( customer == null )
    {
        throw new ArgumentNullException
            ( "customer",
              "EditCustomerViewModel passed a null customer" );
    }
    FirstName = customer.FirstName;
    LastName = customer.LastName;
    Street = customer.Street;
    City = customer.City;
    State = customer.State;
    Zip = customer.Zip;
    RenewalDate = customer.RenewalDate;
    YearlyFees = customer.YearlyFees;
    Email = customer.Email;
}

All of the data that will be represented in the UI is made available as public properties. The pattern we’ll be using is this:

  • Some data in the Customer class may not be in the UI in which case it will be ignored or handled automatically in the EditCustomerViewModel. That is now shown in this example
  • Some data is not validated, and will be implemented with automatic properties (e.g., RenewalDate, Street, YearlyFees).
  • The remaining data is validated, and so will have a getter that returns the value and a setter that
    • checks whether the data is valid
    • If the data is valid sets the value of the underlying private varaibles
    • Supports INotifyProperty indirectly by calling the base class method
Variations on Data Validation

As mentioned above, we’ll be examining three distinct ways to handle data validation.

  • Raising Exceptions
  • Implementing IDataErrorInfo
  • Implementing INotifyDataErrorInfo to support asynchronous (host-based) data validation  (next posting)
Errors With Exceptions

In earlier versions of Silverlight, the steps for handling data validation errors (still valid, if somewhat deprecated today) were:

  • pass the data to the object (or in our case the view model)
  • if it is not valid, throw an exception
  • Set the property ValidatesOnExceptions to true in the Xaml for the input element in the form
  • Set the property NotifyOnValidationError to true in the Xaml for the input element in the form
  • Set TwoWay binding on the input element in the form
  • Either the Binding Engine’s type converter or the source object’s setter function throws an exception, passing along a string to be displayed by the Visual State Manager

Let’s implement the validation test for the Email property using Exceptions….

private string email;
public string Email
{
    get { return email; }
    set
    {
        if ( string.IsNullOrEmpty( value ) )
        {
            return;
        }

        if ( !value.Contains( "@" ) )
        {
           throw new Exception( "Not a valid email address" );
        }
        email = value;
        RaisePropertyChanged( "Email" );
    }
}

We start by checking to ensure that the value passed in for the new email is neither blank nor null (you can certainly change this if a blank value is valid in your application).  We then check to see if we’ve been passed an invalid email address, defined as a string of characters absent the at-sign (@).  If it is invalid, we throw the exception.  Otherwise, we set the underlying email property to the new value and call MVVMLight’s RaisePropertyChanged method with the name of the property, which will in turn call the PropertyChanged event.

Because the Email form field was set with the necessary properties: Binding mode is TwoWay and the two interfaces ValidatesOnExceptions and NotifyOnValidationErrors are set to true, if an email address is entered that does not have an at-sign, an exception will be thrown, and that exception will be caught by the error handling system, and passed to the Visual State manager for error handling.

<TextBox
   x:Name="Email"
   Grid.Row="6"
   Grid.Column="1"
   Style="{StaticResource TextBoxStyle }"
   Text="{Binding Path=Email, Mode=TwoWay,
           ValidatesOnExceptions=true, NotifyOnValidationError=true}" />


The exception is caught and passed to the Visual State Manager as a Validation error, as shown here:

NotValidEmail

Logging and Status

Before we look at IDataErrorInfo, we need to take a slight tangent to cover the Logging and Status mechanisms I added to keep the user informed about what is happening in this demo code.

Logging

Each logged item will be added to the list box in the view, through the LogEntries collection which will serve as the bound ItemsSource property.

private ObservableCollection<string> logEntries = new ObservableCollection<string>();
public ObservableCollection<string> LogEntries
{
    get { return logEntries;  }
}

It is important to use an ObservableCollection as this will be bound to the ItemsSource property of the ListBox, which automatically invokes the CollectionChanged event handler when the ListBox’s items collection changes if it is bound to an ObservableCollection (but not if, for example, it were bound to a simple List<String>).

When the ViewModel wants to record something to the log it will pass a string to the private AddLogItem method,

private void AddLogItem(string item)
{
    if ( string.IsNullOrEmpty( item ) )
        return;
    logEntries.Add( item );
}

The View’s Log ListBox will be automagically updated through the CollectionChanged event.

Status

As the user’s entries are validated, we’ll want to update the UI to indicate if there is a problem or not, or if we are waiting for validation to return from the web service. We begin by declaring an enumeration:

public enum Status
{
InProgress,
Completed,
Error,
Ok
}

InProgress and Completed are used in the asynchronous error checking covered below. The TextBlock on the last line is bound to a property of the ViewModel,

<TextBlock
   x:Name="Message"
   Text="{Binding Path=ErrorCheckingStatus, Mode=OneWay}"
   Grid.Row="7"
   Grid.Column="0"
   Grid.ColumnSpan="2" />

Notice that the binding is “OneWay,” as this text is sent from the VM but never updated by the user (a TextBlock is inherently read only).

The TextBlock is bound to the ErrorCheckingStatus property of the VM,

private Status errorCheckingStatus = Status.Ok;
public Status ErrorCheckingStatus
{
    get { return errorCheckingStatus; }
    set
    {
        errorCheckingStatus = value;
        RaisePropertyChanged( "ErrorCheckingStatus" );
    }
}

When the VM wants to update the view with a new status, it changes the value of this property, In the following code, the status is changed to Error, the Log is updated with what has gone wrong, and an exception is thrown to invoke the data validation error handling,

AddLogItem( "Invalid email address, throwing exception" );
ErrorCheckingStatus = Status.Error;
throw new Exception( "Not a valid email address" );
IDataErrorInfo

While this validation with exceptions certainly works, there are many object oriented developers who argue that it makes for very confusing code when exceptions are used other than for the semantics for which they were originally intended.

They argue specifically that exceptions were invented for those conditions that we know might happen but which we cannot reliably predict, such as running out of memory.  To use exceptions for other purposes (such as a fast way to unwind the stack or, in this case, to pass a validation error to an error handler) distorts the semantics of exceptions and makes for less intuitive code that jumps unpredictably (the dreaded spaghetti code).

WPF had a mechanism, IDataErrorInfo, that solves this problem and which was brought into Silverlight 4.  Interestingly, Silvelright 4 also introduced the interface INotifyDataErrorInfo  for asynchronous validation which has not yet made it into WPF.

.

Move Data Validation Out Of The View Model?

Folks involved with unit testing, patterns and best practices have argued that validation should not be inside the ViewModel and should be in a dedicated class included using MEF

Doing so would allow you to support Bertrand Meyer’s well established  Open/Closed Principle which asserts that code is more manageable if it is “open for extension but not for modification” – that is behavior modification should not require changes to the source code of the existing code.

See Jag Reehal’s article Applying the Open Closed Principle In Silverlight and WPF Using MEF in his excellent blog Arrange Act Assert

This pattern is not implemented here, as doing it right requires MEF which is beyond the scope of this tutorial.

To see how IDataErrorInfo works, let’s look at the validation of the Ziip code field.

public string Zip
{
    get { return zip; }
    set
    {
        var zipErrors = new List<string>();
        // Full test would at least allow for extended zip code
        // and for non-US postal codes
        // and for numerals only - a regular expression would be useful
        if ( value == null || value.Length != 5 )
        {
            const string info = " Zip code must be five characters";
            zipErrors.Add( info );
            ManageErrors(
                    "Zip",
                    zipErrors,
                    true );
        }
        else
        {
            ManageErrors(
                "Zip",
                null,
                false );

            zip = value;
            RaisePropertyChanged( "Zip" );
        }
    }
}

We do a pretty simple test for the value passed in (it must not be null and it must be 5 characters – see comments for why this is barely adequate.  If it is not valid, we add an error string to an array of strings and pass that to the helper method ManageErrors, along with the name of the property and the boolean value set to true to indicate that this is an error. Otherwise, we still call ManageErrors, but we pass in false for the boolean and a null array of error messages.

private void ManageErrors(
    string property,
    List< String > errors,
    bool addingAnError )
{
    var raiseEventErrorsChanged = addingAnError;

    if ( property != null )
    {
        if ( currentErrors.ContainsKey( property ) )
        {
            AddLogItem( "Clearing errors & invoking errorsChanged for " + property );
            currentErrors.Remove( property );
            raiseEventErrorsChanged = true; // if we did remove it, we must raise the event
        }

        if ( addingAnError )
        {
            AddLogItem( "Writing error for " + property + " and calling status status change" ); // logging
            currentErrors.Add(
                property,
                errors ); // INotifyDataErrorInfo
            ErrorCheckingStatus = Status.Error;
        }
        else
        {
            AddLogItem( "Set Status OK" );
            ErrorCheckingStatus = Status.Ok;
        }

        // if the flag is set, see if anyone has registered (!= null)
        // and raise the event
        if ( raiseEventErrorsChanged && ErrorsChanged != null )
        {
            AddLogItem( "Invoking DataErrorsChangedEventArgs with property: " + property );

            ErrorsChanged(
                this,
                new DataErrorsChangedEventArgs( property ) );
        }
    }
}
Next Steps

In the next tutorial I’ll look at handling asynchronous error checking and then we’ll take a look at modifying the UI for error display provided by the Visual State Manager.

Categories: Blogs

How Much Time to Spend on JavaFX at JavaOne 2010?

For any conference that one attends, one of the difficult decisions is which presentations to attend.  This is particularly problematic when there are some really interesting-sounding presentations held during the same hour.  I find that I often change my plans for which presentations to see based on earlier presentations in the same conference.  A presentation (often an opening keynote) may stir my interest in a topic I had entered the conference not knowing or not caring much about.  On the other hand, an early presentation could equally dissuade me from attending further presentations on the same topic because I may realize that the subject is not as relevant to me as I thought it would be.

I am already struggling with this for JavaOne 2010, particularly when it comes to JavaFX presentations.  On the one hand, there are some abstracts for JavaFX-related presentations that look interesting.  On the other, I am still a little bitter about my time wasted looking into JavaFX after 2007 JavaOne and 2008 JavaOne.  I realize that I can only blame myself for any wasted time on a third failed attempt at learning to love JavaFX.  JavaOne 2010 gives me the opportunity to learn more about JavaFX in a potentially optimized way, reducing the risk of time wasted.  That being said, I could end up pretty disappointed if I miss some really good presentations to attend JavaFX presentations and then realize either during the conference or (even worse) realize later that JavaFX does not have a future.

This isn't to say that I wouldn't attend a presentation on something I don't know a lot about, because I would.  I feel that one of the best things about attending a conference is the ability in an hour or two to quickly identify whether something is worth further effort.  JavaFX, though, is different because I've already been burned by what I believe was hyperbole.  It's one thing to spend an hour in a session learning about something and realizing it has no immediate benefit for me.  That's actually positive because I only needed to spend an hour to learn that.  For JavaFX, I already have incurred a large tab for the time spent learning about it with little satisfaction.  There has been a huge net opportunity cost associated with time spent with JavaFX so far.

Max Katz, in his blog post JavaFX... does it have a future? (Sys-Con Media version), provides significant additional information for me to consider as I try to resolve the dilemma of deciding how much time to spend on JavaFX at JavaOne.  It is obvious from the tone and content of the writing in this post that Katz is an advocate of JavaFX.  Perhaps even more significantly in terms of considering JavaFX presentations to attend at JavaOne 2010, Katz is presenting at JavaOne 2010 on Enterprise JavaFX Applications with CDI (JSR299).  With all of this in mind, I found some quotes in this blog post particularly interesting.  I look at some of them in detail here in the context of trying to determine what number of JavaFX presentations to attend and which ones to attend.

First off, I appreciate that Katz is a realistic.  Some evangelists for a particular technology can see no wrong (or at least not admit any wrong) with their favorite technology.  This is, of course, ridiculous because nothing is perfect, everything has its flaws, everything has problems it fits better than others, and the natural difference of human beings' opinions means that nothing will ever be "perfect" for everyone.  In my opinion, this early quote from Katz's blog post provides him some credibility:
Don’t get me wrong, JavaFX is very far from perfect. It has it’s problems and challenges (listed below) and its future is hanging on life support right now.I believe my previous blog posts on JavaFX prove that I am in agreement here.  This is precisely why it's difficult for me to justify time spent on JavaFX (including in JavaOne presentations): I just cannot be sure that it's going to be around (at least in a form acceptable to me) for more than the near-term future.

Katz lists several benefits (the good) of JavaFX (such as "power" and "ease of use") first and states:
I have been working with JSF (JavaServer Faces) since its inception and I can tell you that using JavaFX Script to build the UI is probably simpler than using JSF.I have no doubt that this is true, but unfortunately being simpler than JavaServer Faces is the purview of just about every Java-based framework out there and non-Java Flex/ActionScript is, in my opinion, significantly less complicated than JSF.

Katz fairly addresses one of JavaFX's best known problems (the bad): deployment issues. He covers this pretty thoroughly and says exactly what needs to be done to remedy this: "Make it as simple and transparent as running a Flash application."  Well said.

I agree with Katz when he states that developers today need to learn new things all the time, so learning JavaFX Script as a new language should not be a big deal.  As long as everyone understands it is a new language, I think this is a fair statement.  My problem has been when anyone has pushed JavaFX as "Java."  You cannot have it both ways.  Is it Java or is it something else?  It may be Java in the same sense that JRuby and Groovy are Java, but Groovy is significantly more Java-like in syntax than is JavaFX Script.  Because it's not Java in terms of syntax and because there's no JSR (that I'm aware of) for it, its last hold on "being Java" seems to be the ability to run in the JVM, but every language and its brother seems to be doing that these days.

Katz makes several good points that I am skipping here (but I recommend reading his entire blog post if you have any interest in JavaFX whatsoever).  His conclusion, I believe, is objective and spot-on:
There is still time to make JavaFX successful, but the time is running out. First, fix the deployment issue as soon as possible.  ...  Second, Oracle needs to make it very clear what its plans are for JavaFX (maybe at JavaOne 2010?).  ...  I think Oracle has 6-12 months at the most to try and revive JavaFX. If nothing happens by then (which would be about 4 years since the technology was announced), we just might as well close the door on JavaFX. There's nothing I can add to that.  Probably the only debatable piece is the timeframe he provides of 6  to 12 months.  It might be longer (say 18 months), but it could be that Katz is right on.  With the seemingly increasing negative news regarding JavaFX and the strengthening of its competitors' positions, I do think there is a limited window for Oracle to turn things around for JavaFX in terms of it ever being mainstream popular.  There's always a possibility that it's already too late.

Katz's blog post increased my interest in attending his JavaOne 2010 presentation.  The two main reasons that I might not attend it are that there are several really good presentations of high level of interest to me and his topic is not really focused as much on the introduction to and examination of the future of JavaFX as I probably need and want.  Katz's presentation is scheduled for Monday, September 20, at 1 pm, at Golden Gate 2 in the Hilton San Francisco.  I currently have "Advanced Java API for RESTful Web Services (JAX-RS)" scheduled for that slot.  It's still a difficult dilemma because I am now really interested in Katz's presentation, but I think it's safer to bet my time and attention of JAX-RS and REST than it is on to bet them on JavaFX.  I am fairly confident what I learn from a JAX-RS/REST presentation will be of benefit for some time to come.

I hope that JavaOne 2010 provide some direction that allows us to be comfortable knowing how much time and effort to invest in it.  If I have a better idea of what JavaFX is going to become, then I can better make the decision about how much time to invest in JavaFX and what projects to build around it.
Categories: Blogs

Some fantastic demos of AIR on Android by Christophe Coenraets

Greg Wilson's Ramblings - Fri, 07/23/2010 - 17:11

Over the past few weeks, Christophe Coenraets has been working some late nights experimenting with the various beta builds of AIR for Android.   As a result, he has created some cool applications and shared them (with source) on his blog.   If you have a few minutes, you should check them out!

Here’s a list – check them out – the each include a video:

You can join the AIR on Android beta by going to http://labs.adobe.com/technologies/air2/android/

Even if you don’t yet have an Android devices capable of running AIR, you can use the emulator and still have fun!  I blogged about this recently.


Filed under: Adobe AIR, Adobe Flex, AIR for Android Tagged: Adobe AIR, Adobe Flex, air on android, android, coenraets, Flex
Categories: Blogs, Companies

Video Chat for Android in 30 Lines of Code

Christophe Coenraets - Fri, 07/23/2010 - 16:45

Here is a simple Video Chat application I built with Flex 4 and deployed on AIR for Android. The Application is just 30 lines of code and allows multiple users to join a chat room and “video chat”.

Video streaming is powered by LiveCycle Collaboration Services, a set of hosted Flash Services that enable developers to easily add real-time collaboration and social capabilities to their applications.

This application is obviously a bare-bones proof of concept. However, it is fully operational, and the same code can run on different runtime environments: AIR for Android, AIR on the Desktop, and Flash Player in the Browser. Users can participate in the same collaboration session regardless of the runtime environment they use.

Watch the video:

The 30 lines of code:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:cs="AfcsNameSpace" currentState="logon" fontSize="28">

	<fx:Script>
		[Bindable] private var roomURL:String = "http://connectnow.acrobat.com/YOUR_ROOM_NAME";

		protected function connect():void {
			auth.userName = userName.text;
			currentState = "default";
			session.login();
		}
	</fx:Script>

	<s:states>
		<s:State name="default"/>
		<s:State name="logon"/>
	</s:states>

	<fx:Declarations>
		<cs:AdobeHSAuthenticator id="auth"/>
	</fx:Declarations>

	<s:TextInput id="userName" includeIn="logon" top="200" horizontalCenter="0"/>
	<s:Button label="Connect" click="connect()" includeIn="logon" top="250" horizontalCenter="0" height="50" width="150"/>

	<cs:ConnectSessionContainer id="session" roomURL="{roomURL}" authenticator="{auth}" autoLogin="false" width="100%" height="100%" includeIn="default">
		<cs:WebCamera top="10" left="10" bottom="10" right="10"/>
	</cs:ConnectSessionContainer>

</s:Application>
Categories: Blogs