A BasicInputStateMachine allows to handle all mouse and keyboard Java events. BasicInputStateMachine implements java.awt.MouseListener, java.awt.MouseMotionListener, java.awt.MouseWheelListener and java.awt.KeyListener. Thus, it can be attached to any Java graphical component: using the method sm.addAsListenerOf(component). (this method attaches the machine as a listener for each type of mouse and keyboard events: component.attachMouseListener(sm) ; component.attachMouseMotionListener(sm) ; ...)
Here is the list of transitions supported by BasicInputStateMachine:
Press, Click, Drag, Release, Move, Enter and Leave to handle java events of respective types MOUSE_PRESSED, MOUSE_CLICKED, MOUSE_DRAGGED, MOUSE_RELEASED, MOUSE_MOVED, MOUSE_ENTERED and MOUSE_EXITED.
They optionally take the mouse button (except Move transitions) and the modifier as parameters. If no button is specified, transitions are triggered whatever the button. If no modifier is specified, transitions are triggered whatever the modifier.
The button can be one of the following value: BUTTON1, BUTTON2, BUTTON3 or ANYBUTTON. The modifier can be one of the following value: SHIFT, CONTROL, ALT, CONTROL_SHIFT, ALT_SHIFT, ALT_CONTROL or ALT_CONTROL_SHIFT, NOMODIFIER or ANYMODIFIER.
Wheel to handle java events of type MOUSE_WHEEL. They optionally take the modifier as parameter.
KeyPress, KeyTyped and KeyRelease to handle java events of respective types KEY_PRESSED, KEY_TYPED and KEY_RELEASED.
They optionally take the character or the key code as parameters. To see Java available key codes, see KeyEvent Java API.
In the following example, we use two BasicInputStateMachines to define an original interaction with a numeric text field (javax.swing.JTextField). When the mouse cursor is over the text field, user can:
See applet sources.
Here is the code of the state machine:
BasicInputStateMachine interaction = new BasicInputStateMachine(){
Point2D ptInit = null;
JTextField tf;
public State out = new State() {
Transition enter = new Enter(">> in") {
public void action() {
tf = (JTextField)(((MouseEvent)getEvent()).getComponent());
// tf.hilite()
}
};
};
public State in = new State() {
Transition leave = new Leave(">> out") {
public void action() {
// tf.unhilite()
}
};
Transition pressPlus = new KeyPress('+') {
public void action() {
// increment tf.value
}
};
Transition pressMinus = new KeyPress('-') {
public void action() {
// decrement tf.value
}
};
Transition press = new Press(BUTTON1, ">> control") {
public void action() {
// ptInit <-- current point
// arm a timer to update value even if mouse does not move
armTimer(200, true);
}
};
};
public State control = new State() {
Transition drag = new Drag(BUTTON1) {
public void action() {
disarmTimer();
// update tf.value according to vector (pInit, current point)
// arm a timer to update value even if mouse does not move
armTimer(200, true);
}
};
Transition timeout = new TimeOut() {
public void action() {
// update tf.value according to vector (pInit, current point)
}
};
Transition release = new Release(BUTTON1, ">> out") { };
public void leave() {
// tf.unhilite()
}
};
};
};
...
JTextField text = new JTextField("0");
interaction.addAsListenerOf(text);
...