Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.
Cómo centralizar la navegación en un controller
Propósito. Esparcir new X().show() y hide() por las pantallas acopla la UI al grafo de navegación. Un controller concentra push/pop, da un punto único para logging/guardas y permite “cerrar hasta la raíz”. Solo orquesta la pila real del EventsProcessor.
APIs usadas
Window.show()/Window.hide()— push/pop en la pila (el controller solo les delega).EventsProcessor.topWindow()— método estático que retorna la ventana de la cima (instance.windows.peek()).EventsProcessor.instance.getLastWindow()— método de instancia; retorna la cima real de la pila (onullsi está vacía). Úsalo cuando necesites comprobar si hay algo apilado sin lanzar excepción.
Nombres confirmados en la fuente de
EventsProcessor:topWindow()(estático) ygetLastWindow()(instancia).topWindow()hacewindows.peek()y lanza si la pila está vacía;getLastWindow()retornanullen ese caso — prefiere este para verificaciones defensivas.
Ejemplo completo (copiar, pegar y ejecutar)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** Pantalla principal ejecutable: usa el controlador Nav para apilar/desapilar pantallas. */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
add(new Label("Tela raiz"));
add(new Button("Abrir detalhe").onAction(e -> Nav.push(new OutraTela()))); // push mediante el controlador
}
}
/** Pantalla apilada: cierra mediante el controlador (pop). */
class OutraTela extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
add(new Label("Detalhe"));
add(new Button("Voltar").onAction(e -> Nav.pop())); // pop mediante el controlador
}
}
/** Controlador: fachada fina sobre la pila real del EventsProcessor. */
final class Nav
{
private Nav() {}
/** push: apila y muestra. */
public static void push(Window w)
{
w.show();
}
/** pop: cierra la ventana superior, si la hay. */
public static void pop()
{
Window top = EventsProcessor.instance.getLastWindow(); // null-safe
if (top != null)
top.hide();
}
/** ventana actualmente en la cima (puede ser null). */
public static Window current()
{
return EventsProcessor.instance.getLastWindow();
}
}
El fragmento de abajo muestra solo el núcleo. Para ejecutarlo, colócalo en el esqueleto
MainWindowde arriba.
Fragmento mínimo
// verificado en la fuente: EventsProcessor.topWindow() (static) e instance.getLastWindow() (devuelve null si está vacía)
public final class Nav
{
private Nav() {}
/** push: apila y muestra. */
public static void push(Window w)
{
w.show();
}
/** pop: cierra la ventana superior, si la hay. */
public static void pop()
{
Window top = EventsProcessor.instance.getLastWindow(); // null-safe
if (top != null)
top.hide();
}
/** pop repetido hasta que quede solo 1 ventana (la raíz). */
public static void popToRoot()
{
Window top;
// mientras haya más de una ventana apilada, elimina la de la cima
while ((top = EventsProcessor.instance.getLastWindow()) != null
&& top != EventsProcessor.topWindow()) { top.hide(); }
// (para "volver a la raíz", cada hide() desapila una; ajusta el criterio de parada a tu app)
}
/** ventana actualmente en la cima (puede ser null). */
public static Window current()
{
return EventsProcessor.instance.getLastWindow();
}
}
// uso en las pantallas:
Nav.push(new DetalheTela());
// ...
Nav.pop();
Buenas prácticas:
- No reimplementes la pila: el
EventsProcessorya es la fuente de la verdad. El controller es una fachada fina sobreshow()/hide(). - Las guardas de navegación (ej.: “¿hay cambios sin guardar?”) quedan naturales aquí: comprueba antes de
pop()y, si es necesario, dispara unAlertde confirmación. - Cuidado con
topWindow()cuando la pila puede estar vacía — hacepeek()y lanza. Para código defensivo usagetLastWindow().
Profundiza
- La pila de ventanas · Navegar entre pantallas
- Receta hermana: Abrir y cerrar una pantalla