Tela inicial do módulo. Controla a navegação lateral (sidebar), o breadcrumb do header e o roteamento entre as entidades via parâmetro MID. É a primeira action instanciada quando o usuário abre o módulo.
package br.xt.app.departamento;
import br.jasap.core.Effect;
import br.jasap.effect.Response;
import br.jasap.gui.JasapPage;
import br.jasap.gui.SideMenu;
import br.jasap.gui.Table;
import br.jasap.gui.TableRow;
import br.jasap.util.Js;
import br.xt.AppsRootAction;
import br.xt.acore.view.XtPage;
public class DepartamentoHome extends AppsRootAction {
public static final String MID = "__DEPARTAMENTO_MID";
@Override
public Effect execute() throws Exception {
render();
return new Response();
}
public void render() throws Exception {
XtPage page = new XtPage(getManager());
if (isAjaxCall()) {
eval(Js.CLOSE_SUB_WINDOWS);
} else {
page.getBody().append(page.content("", "", false));
page.setWinTitle("Departamento");
page.getCommands().add(link(MenuItem.class).putInteger(MID, 0).ajax());
getOutput().write(this, page);
}
}
public static class Title extends DepartamentoHome {
@Override
public Effect execute() throws Exception {
int mid = getInput().getInteger(MID, 0);
Table aux = new Table(getManager());
TableRow line = aux.row();
line.col().setStyle("padding: 0 5 0 5;").setContent(ui().btTitleActive("DEPARTAMENTO", ""));
update(JasapPage.DIV_HEADER_LEFT, aux);
update(JasapPage.DIV_HEADER_CENTER, "");
return new Response();
}
}
public static class MenuItem extends DepartamentoHome {
@Override
public Effect execute() throws Exception {
int mid = getInput().getInteger(MID, 0);
if (mid > 0) {
eval(link(Title.class).putInteger(MID, mid).ajax());
eval(link(Title.class).putInteger(MID, mid).ajax(false));
} else {
eval(link(MenuInicial.class).ajax(false));
eval(link(Title.class).putInteger(MID, mid).ajax(false));
}
return new Response();
}
}
public static class MenuInicial extends DepartamentoHome {
@Override
public Effect execute() throws Exception {
SideMenu m = new SideMenu();
update("sidebar", m.toHtml());
return new Response();
}
}
}
throws ExceptionAparece em quase todos os métodos deste arquivo (e de qualquer arquivo do Jasap). O Java obriga a declarar quando um método pode dar erro. Coisas que podem dar erro: acessar dados da requisição HTTP, montar componentes visuais, escrever a resposta pro browser, criar links pra actions.
Quando um método chama outro que pode dar erro, ele precisa declarar throws Exception também. É como uma corrente: se o método A chama o método B que pode falhar, o método A precisa avisar que também pode falhar.
No Jasap, quase tudo pode falhar (acesso a dados, reflexão Java, I/O de rede). Por isso quase todo método tem throws Exception. Regra simples: se o método chama qualquer coisa do Jasap (ui(), link(), getInput(), update(), eval()), precisa ter throws Exception.
Essa regra vale pra todos os arquivos daqui pra frente.
@OverrideCada subclass (Title, MenuItem, MenuInicial) tem @Override public Effect execute(). Por quê? Porque cada subclass é uma action independente — quando o Jasap recebe uma requisição para Title, ele chama o execute() dela, não o da mãe.
O @Override é uma anotação de segurança: garante que você está sobrescrevendo um método que realmente existe na classe mãe. Se errar o nome (ex: excute() em vez de execute()), o compilador avisa na hora em vez de deixar passar.
Sem sobrescrever, todas as subclasses executariam o execute() da mãe — que chama render() e montaria a página inteira de novo, em vez de fazer o trabalho específico da subclass.
public static classAs subclasses Title, MenuItem e MenuInicial são inner classes estáticas. Isso significa que elas vivem dentro do arquivo DepartamentoHome.java, mas o Jasap as trata como actions independentes — cada uma tem sua própria URL no framework e é instanciada separadamente.
O extends DepartamentoHome existe para herdar os métodos utilitários (ui(), link(), eval(), update()), as constantes (MID) e o contexto (session, manager, input/output). Sem essa herança, seriam classes soltas sem acesso a nada do Home.
É como se fossem funcionários do mesmo departamento: trabalham independentes, mas compartilham as ferramentas e o espaço do departamento.
public class DepartamentoHome extends AppsRootAction {
public static final String MID = "__DEPARTAMENTO_MID";
}
| Elemento | O que significa |
|---|---|
DepartamentoHome | Nome da classe. Convenção do projeto: prefixo do módulo + Home. É a tela raiz — o ponto de entrada quando o usuário abre o módulo |
extends AppsRootAction | Herança — esta classe recebe todos os recursos de AppsRootAction: ui(), link(), eval(), update(), getInput(), getManager() e todos os métodos do framework ficam disponíveis automaticamente |
public static final String MID | Guarda o nome da chave usada para transportar o número do item clicado no menu entre o browser e o servidor. MID=0 abre o menu inicial; MID=1,2,3… abrirá cada entidade quando forem adicionadas |
@Override
public Effect execute() throws Exception {
render();
return new Response();
}
public void render() throws Exception {
XtPage page = new XtPage(getManager());
if (isAjaxCall()) {
eval(Js.CLOSE_SUB_WINDOWS);
} else {
page.getBody().append(page.content("", "", false));
page.setWinTitle("Departamento");
page.getCommands().add(link(MenuItem.class).putInteger(MID, 0).ajax());
getOutput().write(this, page);
}
}
Por que execute() não faz o trabalho direto? Porque ele delega para render(). Assim, qualquer inner class (Title, MenuItem, MenuInicial) pode chamar render() para re-renderizar a home sem duplicar código — basta chamar o método herdado.
O render() lida com dois cenários distintos:
| Cenário | O que acontece |
|---|---|
| Primeira abertura (não é Ajax) | Monta a página completa: cria a estrutura com sidebar, header e área de conteúdo (page.content), define o título da aba do browser (setWinTitle), agenda o disparo automático do MenuItem com MID=0 para preencher o sidebar assim que a página carregar, e envia tudo ao browser (getOutput().write) |
| Chamada Ajax (já está dentro do módulo) | Só fecha todos os modais abertos (Js.CLOSE_SUB_WINDOWS) — a página já existe no browser, não precisa recriar |
| Trecho | O que faz |
|---|---|
isAjaxCall() | Verifica se a requisição veio de Ajax (já está dentro do módulo) ou de abertura direta no browser (primeira vez) |
eval(Js.CLOSE_SUB_WINDOWS) | Fecha todos os modais abertos quando o usuário volta ao home via Ajax |
page.content("", "", false) | Cria a estrutura da página: sidebar vazio, header e área de conteúdo — preenchidos depois por Ajax |
page.setWinTitle("Departamento") | Define o texto da aba do navegador |
page.getCommands().add(...) | Dispara MenuItem com MID=0 automaticamente após a página carregar — sem isso o sidebar abriria vazio |
getOutput().write(this, page) | Envia a página completa ao browser. Só chamado na abertura inicial, não nas chamadas Ajax |
return new Response() | Avisa o Jasap que a action terminou — tudo que foi preparado com update(), eval() e getOutput().write() pode ser enviado ao browser |
public static class Title extends DepartamentoHome {
@Override
public Effect execute() throws Exception {
int mid = getInput().getInteger(MID, 0);
Table aux = new Table(getManager());
TableRow line = aux.row();
line.col().setStyle("padding: 0 5 0 5;").setContent(ui().btTitleActive("DEPARTAMENTO", ""));
update(JasapPage.DIV_HEADER_LEFT, aux);
update(JasapPage.DIV_HEADER_CENTER, "");
return new Response();
}
}
Responsável por atualizar o breadcrumb no topo da tela — o letreiro que mostra onde o usuário está. É uma inner class estática: o Jasap a registra e instancia como uma action independente, com sua própria URL. Quando o Jasap chama Title, executa o execute() dela — não o do DepartamentoHome. O extends DepartamentoHome existe apenas para herdar os métodos utilitários: update(), ui(), link(), getInput().
Por enquanto, sem entidades, o Title só mostra "DEPARTAMENTO" fixo. Quando a primeira entidade for criada, um switch(mid) será adicionado para variar o breadcrumb conforme a tela ativa (ex: "DEPARTAMENTO > Produtos").
| Trecho | O que faz |
|---|---|
getInput().getInteger(MID, 0) | Lê o MID da requisição. Padrão 0 se não vier. Está presente para quando entidades forem adicionadas e o breadcrumb precisar variar por tela |
new Table(getManager()) + aux.row() | O Jasap exige componentes de layout no header — não aceita HTML direto. Table e TableRow geram a estrutura esperada |
setStyle("padding: 0 5 0 5;") | Espaçamento interno da célula: top, right, bottom, left em pixels |
ui().btTitleActive("DEPARTAMENTO", "") | Botão de breadcrumb no estado ativo — texto sem link. Quando entidades forem adicionadas, "DEPARTAMENTO" virará btTitle (clicável) e o nome da entidade aparecerá ao lado |
update(DIV_HEADER_LEFT, aux) | Substitui o header esquerdo pelo breadcrumb montado |
update(DIV_HEADER_CENTER, "") | Limpa o centro do header para não sobrar conteúdo de outra tela |
public static class MenuItem extends DepartamentoHome {
@Override
public Effect execute() throws Exception {
int mid = getInput().getInteger(MID, 0);
if (mid > 0) {
eval(link(Title.class).putInteger(MID, mid).ajax());
eval(link(Title.class).putInteger(MID, mid).ajax(false));
} else {
eval(link(MenuInicial.class).ajax(false));
eval(link(Title.class).putInteger(MID, mid).ajax(false));
}
return new Response();
}
}
Roteador central do módulo. Toda navegação passa por aqui. Cada link do sidebar aponta para MenuItem com um MID diferente. O MenuItem recebe o número, decide o que fazer e dispara as actions necessárias. Nenhuma tela é aberta diretamente — tudo passa pelo MenuItem primeiro.
| Situação | O que acontece |
|---|---|
mid > 0 | Entidade solicitada. Quando entidades forem adicionadas, um switch(mid) com eval(preAjax(XxxList.class).modalMax()) será inserido aqui para abrir a tela correspondente. O Title é chamado para atualizar o breadcrumb |
mid == 0 | Menu inicial. Reconstrói o sidebar via MenuInicial e redefine o breadcrumb via Title — é o "voltar pra recepção" |
| Trecho | O que faz |
|---|---|
eval(...ajax()) | Executa imediatamente, no mesmo ciclo da requisição |
eval(...ajax(false)) | Enfileira para executar após o ciclo atual — garante a ordem correta quando múltiplas ações acontecem em sequência (ex: primeiro abre a tela, depois atualiza o breadcrumb) |
public static class MenuInicial extends DepartamentoHome {
@Override
public Effect execute() throws Exception {
SideMenu m = new SideMenu();
update("sidebar", m.toHtml());
return new Response();
}
}
Renderiza o conteúdo do sidebar via Ajax, após a página já estar no browser. Quando o render() monta a página pela primeira vez, o sidebar vem vazio — é o MenuInicial que preenche ele logo em seguida, chamado automaticamente pelo page.getCommands().add(...). E quando o usuário volta ao menu inicial (clica no breadcrumb "DEPARTAMENTO"), o MenuItem com MID=0 chama o MenuInicial de novo para reconstruir o sidebar — sem recarregar a página inteira.
No estado atual o SideMenu é criado vazio porque não há entidades. Conforme forem adicionadas, cada uma ganhará um m.add(...) aqui.
| Trecho | O que faz |
|---|---|
new SideMenu() | Cria o componente de menu lateral do Jasap com estilos e comportamento prontos |
m.add(visivel, label, link, null) | Quando entidades existirem: visivel controla a exibição, label é o texto, link aponta para MenuItem com o MID da entidade |
m.toHtml() | Converte o SideMenu em HTML |
update("sidebar", m.toHtml()) | Substitui o conteúdo do id="sidebar" na tela. O ID é definido pelo XtPage ao montar a estrutura da página |