Como centralizar a navegação num controller
Propósito. Espalhar new X().show() e hide() pelas telas acopla a UI ao grafo de navegação. Um controller concentra push/pop, dá um ponto único para logging/guardas e permite “fechar até a raiz”. Ele apenas orquestra a pilha real do EventsProcessor.
APIs usadas
Window.show()/Window.hide()— push/pop na pilha (o controller apenas delega a eles).EventsProcessor.topWindow()— método estático que retorna a janela do topo (instance.windows.peek()).EventsProcessor.instance.getLastWindow()— método de instância; retorna o topo real da pilha (ounullse vazia). Use quando precisar checar se há algo empilhado sem lançar exceção.
Nomes confirmados na fonte de
EventsProcessor:topWindow()(estático) egetLastWindow()(instância).topWindow()fazwindows.peek()e lança se a pilha estiver vazia;getLastWindow()retornanullnesse caso — prefira este para verificações defensivas.
Exemplo completo (copiar, colar e rodar)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** Tela principal executável: usa o controller Nav para empilhar/desempilhar telas. */
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 via controller
}
}
/** Tela empilhada: fecha via controller (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 via controller
}
}
/** Controller: fachada fina sobre a pilha real do EventsProcessor. */
final class Nav
{
private Nav() {}
/** push: empilha e exibe. */
public static void push(Window w)
{
w.show();
}
/** pop: fecha a janela do topo, se houver. */
public static void pop()
{
Window top = EventsProcessor.instance.getLastWindow(); // null-safe
if (top != null)
top.hide();
}
/** janela atualmente no topo (pode ser null). */
public static Window current()
{
return EventsProcessor.instance.getLastWindow();
}
}
O trecho abaixo mostra só o miolo. Para rodar, coloque-o no esqueleto
MainWindowacima.
Trecho mínimo
// verificado na fonte: EventsProcessor.topWindow() (static) e instance.getLastWindow() (retorna null se vazia)
public final class Nav
{
private Nav() {}
/** push: empilha e exibe. */
public static void push(Window w)
{
w.show();
}
/** pop: fecha a janela do topo, se houver. */
public static void pop()
{
Window top = EventsProcessor.instance.getLastWindow(); // null-safe
if (top != null)
top.hide();
}
/** pop repetido até sobrar apenas 1 janela (a raiz). */
public static void popToRoot()
{
Window top;
// enquanto houver mais de uma janela empilhada, some com o topo
while ((top = EventsProcessor.instance.getLastWindow()) != null
&& top != EventsProcessor.topWindow()) { top.hide(); }
// (para "voltar à raiz", cada hide() desempilha uma; ajuste o critério de parada à sua app)
}
/** janela atualmente no topo (pode ser null). */
public static Window current()
{
return EventsProcessor.instance.getLastWindow();
}
}
// uso nas telas:
Nav.push(new DetalheTela());
// ...
Nav.pop();
Boas práticas:
- Não reimplemente a pilha: o
EventsProcessorjá é a fonte da verdade. O controller é uma fachada fina sobreshow()/hide(). - Guardas de navegação (ex.: “há alterações não salvas?”) ficam naturais aqui: cheque antes de
pop()e, se preciso, dispare umAlertde confirmação. - Cuidado com
topWindow()quando a pilha pode estar vazia — ele fazpeek()e lança. Para código defensivo usegetLastWindow().
Aprofunde-se
- A pilha de janelas · Navegar entre telas
- Receita irmã: Abrir e fechar uma tela
Esta página foi útil?Obrigado pelo feedback!