Pular para o conteúdo
CrossFly é 100% open sourceSiga no GitHub
CrossFlyCrossFly
Começar

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 (ou null se vazia). Use quando precisar checar se há algo empilhado sem lançar exceção.

Nomes confirmados na fonte de EventsProcessor: topWindow() (estático) e getLastWindow() (instância). topWindow() faz windows.peek() e lança se a pilha estiver vazia; getLastWindow() retorna null nesse 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 MainWindow acima.

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 EventsProcessor já é a fonte da verdade. O controller é uma fachada fina sobre show()/hide().
  • Guardas de navegação (ex.: “há alterações não salvas?”) ficam naturais aqui: cheque antes de pop() e, se preciso, dispare um Alert de confirmação.
  • Cuidado com topWindow() quando a pilha pode estar vazia — ele faz peek() e lança. Para código defensivo use getLastWindow().

Aprofunde-se

Esta página foi útil?