You first need an object that will act as a "container" for a Smarties object and will listen for Smarties events. Typically you create this object in the initialization phase of your application. It should contain (i) enough information to initialize Smarties (e.g. your wall size), and (ii) objects that will help link the container to the rest of your application. The container can be your application window.

SmartiesContainer smarties_container = new  SmartiesContainer(info on your app);

Now we will describe an example SmartiesContainer class.

First import the Smarties classes (details in javadoc):

import fr.lri.smarties.libserver.Smarties;
import fr.lri.smarties.libserver.SmartiesColors;
import fr.lri.smarties.libserver.SmartiesEvent;
import fr.lri.smarties.libserver.SmartiesPuck;
import fr.lri.smarties.libserver.SmartiesDevice;
import fr.lri.smarties.libserver.SmartiesWidget;
import fr.lri.smarties.libserver.SmartiesWidgetHandler;

The SmartiesContainer class must be an Observer. As a Smarties object is an Observable, it can send events to the SmartiesContainer.

class SmartiesContainer implements Observer
{
	Smarties m_smarties;        // the Smarties object
	double appWidth, appHeight; // width & height of your wall or window  
	
	... other code of the class ...
	
} // class SmartiesContainer

The skeleton of a constructor:

SmartiesContainer(...some objects and variables...)
{
	... initialize int appWidth, int appHeight ...
	... initialize int tileX, int tileY that describe your
	... screens tile (not very important)
	... 
	// create the Smarties object 
	Smarties m_smaties = new Smarties( (int)appWidth, (int)appHeight, gridX, gridY)

	// change some defaults here if you want
	// the defaults are good for a tutorial !

	// initalize the Smarties widgets area into a 3 x 3 grid
	m_smarties.initWidgets(3,3);

	// add some Smarties widgets in the widget area
	// see below

	// this class observes the Smarties 
	m_smarties.addObserver(this);

	// run the Smarties thread
	m_smarties.Run();
	System.out.println("Smarties running");
}

An Observer must implement an update method. This is where you receive events from the mobile interfaces (via the Smarties object):

public void update(Observable obj, Object arg)
{

	if ( !(arg instanceof SmartiesEvent) ) 
	{
		// should not happen, unless you observe other observables
		// with this class
		return;
	}

	// note that obj == m_smarties (if m_smarties is the only observed observable
	// of this class)

	SmartiesEvent e = (SmartiesEvent)arg;
	SmartiesPuck p = e.p;  // the puck atteched to the event (could be null)
	SmartiesDevice dev = e.device; // the mobile device that send the event
	float x = e.x, y = e.y; // a relative position ([0,1]x[0,1]) w.r.t. the mobile touch area
	                        // (0,0) is top left and (1,1) is botom-right 
	// etc see below and SmartiesEvent for more
	// transform mobile coordinates to your application coordinates
	float app_x = x*appWidth;
	float app_y = x*appHeight;

	// then we should switch w.r.t. the event type 
	switch (e.type)
	{
		...
		// handles all or some Smarties events
		...


		default:
		{
			// events you do not care about
			break;
		}
	} // end switch
}

We assume here that we have an AppCursor class that updates cursor movements on the wall. Here is an example code from update() that manages pucks.

	// -------- SmartiesPuck Management -----------------
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_CREATE:
	{
		// p is a new puck!
		p.app_data = new AppCursor(app_x, app_y);
		break;   
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_SELECT:
	{
		// the puck p has been selected (on device dev)
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_STORE:
	{
		// p has been stored
		AppCursor ac = (AppCursor)p.app_data;
		ac.hide();
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_UNSTORE:	
	{
		// p has been un-stored
		AppCursor ac = (AppCursor)p.app_data;
		ac.show();
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_DELETE:
	{
		// p has been deleted, maybe do some stuff with p ...
		AppCursor ac = (AppCursor)p.app_data;
		ac.hide();
		// and then allow the library to forget about it:
		m_smarties.deletePuck(p);
		break;
	}

Puck movement (simple pointing)

	// -------- Gestures -------------
	// note that p could be null (gesture with no selected puck)
	// note also that all these events are exclusive
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_MULTI_TAPE:
	{
		// a multi tape event (e.num_tapes and e.num_fingers for last tape)
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_START_MOVE:
	{
		// p start to move (one finger!)
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_MOVE:
	{
		// p move (one finger!)
		if (p != null) {
			AppCursor ac = (AppCursor)p.app_data;
			ac.moveTo(app_x, app_y);
		}
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_END_MOVE:
	{
		//  p end move (one finger)
		break;
	}

Multi-touch Smarties events:

	case SmartiesEvent.SMARTIE_EVENTS_TYPE_START_MFPITCH:
	{
		// start of a multi fingers pinch: e.num_fingers, e.num_tapes before
		// pinch start, e.d = sum of the distances from the fingers to the barycenter  
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_MFPITCH:
	{
		//  multi fingers pinch: as above 
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_END_MFPITCH:
	{
		// end of a multi fingers pinch (one of the fingers up)
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_START_MFMOVE:
	{
		// start of a multi fingers move: e.num_fingers, e.num_tapes before
		// move start, e.x and e.y position of the fingers barycenter  
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_MFMOVE:
	{
		// multi fingers move, as above
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_END_MFMOVE:
	{
		// end of a multi fingers move (one of the fingers up)
		break;
	}

Keybooard events. See below to see how to map a keybaord, and note that there are also two special "text" widgets (see below again). Smarties use X Window keycode.

	// -------- keyboard -------------
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_KEYDOWN:
	{
		// e.keycode
		break;
	}
	case SmartiesEvent.SMARTIE_EVENTS_TYPE_END_KEYUP:
	{
		// e.keycode
		break;
	}

Widgets callback should be explecitly called in the switch:

	case SmartiesEvent.SMARTIE_EVENTS_TYPE_WIDGET:
	{
		// We must call by ourself the widgets handler. Here a piece
		// of generic code, the only special thing is that you can pass some
		// "data"
		Object SomeData = null; // or whatever that can help the widget handler
		if (e.widget.handler != null)
		{
			e.widget.handler.callback(e.widget, e, SomeData);
		}
		break;
	}

Pucks

The central tools in the Smarties

Widgets

In the constructor you add some widgets in the widget area of the mobile device. But first you should define the grid used to place and define the size of the the widgets:

// initalize the Smarties widgets area into a 3 x 3 grid
m_smarties.initWidgets(3,3);	

Then, you can start to add widget. For example, let us create a slider on the top left of the widget area with an handler that will be use when the slider is manipulated in on of the mobile devices.

sliderWidget = m_smarties.addWidget(
		SmartiesWidget.SMARTIES_WIDGET_TYPE_SLIDER, "Size", 1, 1, 1, 1);
sliderWidget.handler = new sliderHandler();

The above code apply for all the widgets. Depending of the widget type you can or you should set other values, for instance for a slider its default value:

sliderWidget.value = 50; // in between 0 and 100	

In the above code, we have defined a "handler". Such handler should be coded as follow:

public class sliderHandler implements  SmartiesWidgetHandler
{
	public boolean callback(SmartiesWidget w, SmartiesEvent e, Object user_data)
	{
		System.out.println("slider value " + w.value);
		if (e.p != null) {
			AppCursor ac = (AppCursor)e.p.app_data;
			ac.setSize(w.value);
			return true;
		}
	}
}

Note that it is possible to put such an handler in an other class or in internal class (of an other class).

Now let us add a "large" button (in the middle-bottom of the widget area) that map a keyboard

w = m_smarties.addWidget(
		SmartiesWidget.SMARTIES_WIDGET_TYPE_BUTTON, "Keyboard", 1.5, 3, 2, 1);
w.handler = new  keyboardButtonClicked();

with the code for the handler:

public class keyboardButtonClicked implements  SmartiesWidgetHandler
{
	public boolean callback(SmartiesWidget w, SmartiesEvent e, Object user_data)
	{
		System.out.println("keyboardButtonClicked");
		// map a keyboard in the device that ask for it
		m_smarties.showKeyboard(e.id, e.device); 
		return true;
	}
}