A missão do Swing Application Framework (JSR-296), segundo os seus criadores, é definir uma infraestrutura que é comum à maioria dos aplicativos Desktop:
- gerenciamento do ciclo de vida dos aplicativos, especialmente GUI startup e shutdown
- gerenciamento e carregamento de recursos, como strings, mensagens formatadas, cores, fontes e outros, em componentes Swing
- apoio para a definição, gerenciamento e ligação de Actions
- Actions assíncronos (executam em "background")
- Estado da sessão persistente.
Inicialização e Gerenciamento do Ciclo de Vida de Aplicativos
Através da classe
Application, a base desse framework, é possível executar tarefas específicas de acordo com o ciclo de vida do aplicativo.O aplicativo deve estender essa classe e implementar ao menos o método
startup, responsável por preparar a GUI inicial e torná-la visível. A implementação dos outros métodos que lidam com o ciclo de vida dos aplicativos - initialize, ready e shutdown - é opcional.Use
initialize se precisar configurar propriedades do sistema antes da construção da GUI. Utilize ready se precisar executar trabalho extra depois que a GUI estiver pronta e visível. O objetivo é fazer com que startup execute menos tarefas, tornando a GUI visível o mais rápido possível. O método shutdown fecha a GUI e executa outras tarefas de limpeza antes de encerrar o aplicativo.A subclasse concreta de
Application inicia o aplicativo por meio de seu método launch.public final class OhMyApplication extends Application {
.....private SingleFrame mainFrame;
.....@Override
.....protected void initialize(final String [] args) {.....}
.....protected void startup() {
..........mainFrame = new SingleFrame();
..........mainFrame.addWindowListener(new MainFrameListener());
..........mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
..........mainFrame.pack();
..........mainFrame.setVisible(true);
.....}
.....@Override
.....protected void ready() {
..........TipOfTheDay.show(mainFrame);
.....}
.....@Override
.....protected void shutdown() {
..........mainFrame.setVisible(false);
.....}
.....public static void main(final String[] args) {
..........PlasticLookAndFeel.setPlasticTheme(new ExperienceBlue());
..........Application.launch(OhMyApplication.class, args);
.....}
.....private class MainFrameListener extends WindowAdapter {
..........public void windowClosing(final WindowEvent e) {
...............exit(e);
..........}
.....}
}
Se o aplicativo em questão contar com apenas um
JFrame principal, há a opção de criar uma subclasse concreta de SingleFrameApplication, ao invés de estender Application.Os aplicativos devem ter um arquivo de propriedades com o mesmo nome da classe que estende
Application ou SingleFrameApplication num subpacote denominado resources. Esse ResourceBundle irá compartilhar seus recursos por todo o aplicativo e deverá contar com as seguintes propriedades padrões:Application.name = Nome do aplicativo
Application.id = Apropriado para identificadores específicos do aplicativo
Application.title = Título para dialogs e frames.
Application.version = Versão pode ser incorporada em mensagens
Application.vendor = Nome da organização/pessoa responsável pelo software
Application.vendorId = Apropriado para identificadores específicos do aplicativo
Application.homepage = Uma URL como http://rafaelfiume.wordpress.com
Application.description = Breve descrição sobre o software.
Application.lookAndFeel = system, default, ou uma classe LookAndFeel
Estado da Sessão Persistente
É interessante manter o estado da interface gráfica entre sessões do aplicativo. Para isso existe a classe
SessionStorage. O estado da sessão é armazenado baseado em componentes, desde que estes tenham definidos a propriedade name e uma classe SessionState.Property equivalente.Por padrão,
SessionStorage possui implementações de SessionState.Property para os componentes Window, JTabbedPane, JSplitPane, e JTable, armazenado as propriedades bounds (posição e tamanho da janela) da classe Rectangle para Window's, dividerLocation para JSliderPane's, selectedIndex para JTabbedPane's e width (tamanho das colunas) para JTable's.SessionStorage é obtido através do método getSessionStorage de ApplicationContext, um Singleton utilizado para encontrar variáveis e serviços globais, o que corresponde a maior parte dos componentes do Swing Application Framework.Durante a inicialização do software (startup),
restore é chamado para restaurar o estado da sessão anterior da GUI. Ao encerrar a execução do programa (shutdown), store é invocado para persisitir a sessão atual da GUI.@Override
protected void startup() {
...... . .
.....ApplicationContext.getInstance().getSessionStorage().restore(mainFrame, "session.xml");
...... . .
}
@Override
protected void shutdown() {
...... . .
.....ApplicationContext.getInstance().getSessionStorage().save(mainFrame, "session.xml");
...... . .
}
O estado da sessão é armazenado a partir do diretório do usuário. As propriedades
vendorId e applicationId (veja a seção Inicialização e Gerenciamento do Ciclo de Vida de Aplicativos) devem estar definidas para garantir que o diretório correto seja acessado em diferentes plataformas (de acordo com a seção Persistência Local, logo abaixo).A classe
SingleFrameApplication implementa rotinas para persistir / restaurar o estado da sessão da GUI, inclusive de janelas secundárias, como dialogs, livrando o programador dessa tarefa.Persistência Local
SessionStorage utiliza a classe LocalStorage para persistir / restaurar um java.util.Map com dados sobre o estado da GUI numa sessão, por meio de seus métodos save e load.public void save(Component root, String fileName) throws IOException {
...... . .
.....LocalStorage lst = ApplicationContext.getInstance().getLocalStorage();
.....lst.save(stateMap, fileName);
}
public void restore(Component root, String fileName) throws IOException {
...... . .
.....LocalStorage lst = ApplicationContext.getInstance().getLocalStorage();
.....Map
...... . .
}
LocalStorage deve ser obtido através do método getLocalStorage de ApplicationContext, e pode ser utilizado para persistir / restaurar outros dados, desde que estejam de acordo com os mecanismos da API Java Beans Persistence, o que inclui Java Beans, bem como a maioria dos tipos primitivos. O método save é implementado com a ajuda de java.beans.XMLEncoder, enquanto load utiliza java.beans.XMLDecoder.Como visto na seção acima Estado da Sessão Persistente, as propriedades
vendorId e applicationId devem estar definidas para garantir que o diretório correto seja acessado em diferentes plataformas. O diretório onde os dados serão persistidos dependem do sistema operacional. No Windows esse diretório poderá ser:${userHome}\Application Data\${vendorId}\${applicationId}no Mac OS X:
${userHome}/Library/Application Support/${applicationId}por fim, em sistemas UNIX e derivados será:
${userHome}/.${applicationId}/Cenas dos Próximos Capítulos...
Nas partes seguintes serão explicadas as funcionalidades de Injeção de Recursos, definição de Actions e Tasks (tarefas que executam em background).
Fontes e Referências utilizadas:
- Swing Application Framework Home Page
- JSR 296: Swing Application Framework
- Javadoc e código fonte do Swing Application Framework
- An Introduction to Swing Application Framework API (JSR-296)


5 comentários:
Legal o post (e o framework, embora eu estivesse com um pé atrás em relação a ele)!
Parece que, utilizar o Swing Framework em conjunto com o Beans Binding (JSR-295) tornará o desenvolvimento desktop em Java bem mais simples.
Voltando ao assunto, estou aguardando os próximos artigos sobre o Swing Framework!
[]s
Logo eles serão publicados, Daniel!
Seu blog é legal e desconfio que aborda assuntos interessantes.
.
Me desculpe a franqueza mas com este monte de propaganda no meio do texto fica muito difícil de ler.
.
Outro problema que me afasta dos blogs é quando me deparo com link "Leia mais...". Eu sempre vou embora.
Luca, não precisa pedir desculpas, porque o que eu mais quero é feedback.
O "Leia Mais..." é necessário porque em certas categorias existem mais de 15 artigos, com muitas figuras, e aumentando, como é o caso do SwingX. Isso facilita a navegação e poupa a preciosa banda do usuário.
Quanto às propagandas, tem muita gente que critica e talvez um dia eu as remova - tô falando do AdSense. Mas, por enquanto, nada mais justo do que tirar a grana pro fim de semana.
Eu me empenho bastante nesse blog, gostaria de tirar algo palpável também. Além disso, não há propaganda no meio do texto.
Agora, pra saber se é interessante, só lendo mesmo! :)
Aproveito pra dizer que leio o seu blog e até agora gostei da maior parte do que você publicou, especialmente os artigos sobre exceções.
Abraços!
Atenção: A API do Swing Application Framework está sujeita a mudanças, portanto o artigo pode encontrar-se fora de sincronia com a API mais recente. Ou seja, desatualizado.
O ModelMat utiliza o Swing Application Framework, portanto é possível consultá-lo como exemplo de aplicação desse framework.
Também é aconselhável estudar os exemplos contidos nas fontes do Swing Application Framework.
Postar um comentário