martes, 18 de marzo de 2008

Problema con backCommand en Netbeans Mobility Pack

Una de las funcionalidades más interesante de esta herramienta es el editor visual del flujo.

Permite rápidamente manejar el cambio de pantallas y la navegación.

Sin embargo los comandos "Back" agregados con este método tienen un comportamiento que puede no ser el deseado.

Cada vez que se cambia de pantalla, el midlet guarda la pantalla a la que se va a acceder y la que se está dejando en una HashTable.
Al ejecutar un comando "Back" se llama a switchToPreviousDisplayable(), el cual recupera para la pantalla actual cual fue la anterior.
El problema es que cuando ejecuta switchToPreviousDisplayable() también escribe en la HashTable de manera que queda switcheando en forma permanente entre dos pantallas.

Es decir
1) Se ingresa a la pantalla A
2) Se ingresa a la pantalla B
3) Se ingresa a la pantalla C
4) Se presiona back y se regresa a la pantalla B
5) Se presiona back y se direcciona a la pantalla C de nuevo!

De esta forma el flujo no vuelve a la pantalla A y si se presiona Back queda alternando siempre entre B y C.

En muchos casos sería preferible que al presionar back sucesivamente llevara a todas las pantallas recorridas en la forma explicada al final de Uso de la clase java.util.Stack

Lamentablemente tanto el código de switchToPreviousDisplayable() como switchDisplayable() no se puede modificar desde el editor.

La mejor solución sería cambiar el comportamiento de NetBeans para que genere otro código. Y la solución más rápida sin perder la funcionalidad del editor de flujo es sobreescribir la HashTable para que no considere los cambios hechos por switchToPreviousDisplayable() .


public void switchDisplayable(Alert alert, Displayable nextDisplayable) {
// write pre-switch user code here
Displayable onePrevious = null;
Displayable twoPrevious = null;
try {
Displayable current = getDisplay().getCurrent();
onePrevious = (Displayable)__previousDisplayables.get(current);
twoPrevious = (Displayable)__previousDisplayables.get(onePrevious);
} catch(Exception e) {

}

Display display = getDisplay();
Displayable __currentDisplayable = display.getCurrent();
if (__currentDisplayable != null && nextDisplayable != null) {
__previousDisplayables.put(nextDisplayable, __currentDisplayable);
}
if (alert == null) {
display.setCurrent(nextDisplayable);
} else {
display.setCurrent(alert, nextDisplayable);
}
// write post-switch user code here
if (onePrevious != null) {
if (nextDisplayable == onePrevious) {
if (twoPrevious != null) {
__previousDisplayables.put(nextDisplayable, twoPrevious);
}
}
}
}
Lo que hace es antes de salir del procedimiento "restaurar" la referencia original si es que se está volviendo a una pantalla anterior.

Notese que en realidad no captura el comando "Back" si no que lo deduce cuando la pantalla a la que se va a acceder coincide con la previa. Esto puede no aplicar en el caso en que se acceda a una misma pantalla más de una vez en un mismo flujo de navegación.

Otra solución sería encapsular todo el código de este método en un if (1==2) y reescribirlo a gusto.

No hay comentarios: