Sunday, March 1, 2009

Custom commands

We presented ways to customize title and content with Canvas, but now it is time to also treat commands.
For our code lets define the following attributes:
private int leftCommandKey, rightCommandKey;
A good example of adaptive code to identify command keys can be found at LWUIT class com.sun.lwuit.Implementation, method setKnownSoftKeyCodes.
Below is an adapted snippet to treat Nokia and Motorola commands:


try {
Class.forName("com.nokia.mid.ui.FullCanvas");
this.leftCommandKey = -6;
this.rightCommandKey = -7;
return;
} catch (ClassNotFoundException _ex) { }
try {
Class.forName("com.motorola.phonebook.PhoneBookRecord");
this.leftCommandKey = -21;
this.rightCommandKey = -22;
return;
} catch (ClassNotFoundException _ex) { }

As there are more manufacturers you may keep adding try/catch clauses for specific classes.
One way to avoid this lot of try/catch blocks is the final loop in the method:


boolean leftInit = false;
boolean rightInit = false;
for(int i = -127; i <= 0 && !leftInit && !rightInit; i++) {
try {
if (getKeyName(i).indexOf("1") >= 0) {
this.leftCommandKey = i;
leftInit = true;
}
if (getKeyName(i).indexOf("2") >= 0) {
this.rightCommandKey = i;
rightInit = true;
}
} catch (Exception ex) { }
}

This only works because Implementation class extends Canvas and can use getKeyName method, so your class must extend Canvas too.
From getKeyName javadoc:
"Gets an informative key string for a key. The string returned will resemble the text physically printed on the key. This string is suitable for displaying to the user. For example, on a device with function keys F1 through F4, calling this method on the keycode for the F1 key will return the string "F1". A typical use for this string will be to compose help text such as "Press F1 to proceed."
This method will return a non-empty string for every valid key code.
There is no direct mapping from game actions to key names. To get the string name for game action GAME_A, the application must call
getKeyName(getKeyCode(GAME_A))"
From the loop above we can deduce that commands are SOFT keys and that number 1 is the left and number 2 is the right.
We will try to keep the same behavior and call CommandListener.commandAction when one of these keys is released, but first we need to know which Command will be used for each soft key.
Commands are set with Displayable.addCommand and the listener is set with Displayable.setCommandListener.
As there is no getter method for commands or listener it is necessary to override them.


private Command leftCommand, rightCommand;
public void addCommand (Command cmd) {
if (this.leftCommand == null) {
this.leftCommand = cmd;
} else if (rightCommand == null) {
this.rightCommand = cmd;
}
}
private CommandListener commandListener;
public void setCommandListener (CommandListener l) {
this.commandListener = l;
}

The final piece of code:


protected void keyReleased (int keyCode) {
if (this.commandListener != null){
if (keyCode == this.leftCommandKey && this.leftCommand != null) {
this.commandListener.commandAction(this.leftCommand, this);
} else if (keyCode == this.leftCommandKey && this.rightCommand != null) {
this.commandListener.commandAction(this.rightCommand, this);
}
}
}


Related topics:

No comments: