O SWT inclui muitos recursos excelentes, mas é necessário um conhecimento básico do núcleo do sistema - widgets, layouts e eventos - para implementar aplicativos úteis e robustos.
Quando se está fornecendo elementos da UI utilizando as extensões do workbench da plataforma, os mecanismos de inicialização do SWT são manipulados por você através do workbench.
Se você for gravar um aplicativo de SWT desde o início (fora do workbench), precisará saber mais sobre a estrutura de aplicativo do SWT.
Um aplicativo de SWT autônomo típico tem a seguinte estrutura:
Criar um Display que representa uma sessão do SWT.
Criar um ou mais Shells, os quais servem como janela principal para o aplicativo.
Criar qualquer outro widget necessário dentro do shell.
Inicializar os tamanhos e outros estados necessários dos widgets. Registrar atendentes dos eventos do widget que precisam ser manipulados.
Abrir a janela do shell.
Executar o evento fazendo o dispatch do loop até ocorrer uma condição de saída (geralmente quando a janela principal do shell é fechada pelo usuário).
Descartar o display.
O snippet de código a seguir foi adaptado do aplicativo org.eclipse.swt.examples.helloworld.HelloWorld2. Como o aplicativo exibe somente a cadeia"Hello World", não é necessário registrar qualquer evento do widget.
public static void main (String [] args) {
Display display = new Display ();
Shell shell = new Shell (display);
Label label = new Label (shell, SWT.CENTER);
label.setText ("Hello_world");
label.setBounds (shell.getClientArea ());
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
O Display representa a conexão entre o SWT e o sistema de GUI da plataforma subjacente. Os displays são utilizados principalmente para gerenciar o loop de eventos da plataforma e para controlar a comunicação entre o encadeamento da UI e outros encadeamentos. (Consulte Problemas de encadeamento nos clientes para obter uma discussão completa sobre problemas de encadeamento da UI).
Na maioria dos aplicativos é possível seguir o padrão utilizado acima. Você deve criar um display antes de criar qualquer janela e deve descartar o display quando o shell for fechado. Não é necessário pensar muito sobre o display, a menos que você esteja fazendo o design de um aplicativo com vários encadeamentos.
Um Shell é uma "janela" gerenciada pelo gerenciador de janelas da plataforma do sistema operacional. Os shells de nível superior são aqueles criados como filho do display. Essas janelas são aquelas que os usuários movem, redimensionam, minimizam e maximizam enquanto estão utilizando o aplicativo. Os shells secundários são aqueles criados como um filho de outro shell. Geralmente, essas janelas são utilizadas como janela de diálogo ou outra janela transitória que existe somente no contexto de outra janela.
Todos os widgets que não são shells de nível superior têm um pai. Os shells de nível superior não têm um pai, mas são criados em associação com um Display específico. Você pode acessar esse display utilizando getDisplay(). Todos os outros widgets são criados como descendentes (diretos ou indiretos) dos shells de nível superior.
Widgets Compostos são aqueles que possuem filhos.
Quando você vê uma janela de aplicativo, pode pensar nela como uma árvore ou hierarquia de widgets, cuja raiz é o shell. Dependendo da complexidade do aplicativo, pode haver um único filho do shell, vários filhos ou camadas aninhadas de compostos com filhos.
Quando o aplicativo cria um widget, o SWT imediatamente cria o widget da plataforma subjacente. Isso elimina a necessidade de código que opera de forma diferente dependendo se existe ou não o widget do sistema operacional subjacente. Permite também que a maioria dos dados do widget seja mantida na camada da plataforma, em vez de ser replicada no kit de ferramentas. Isso significa que o conceito de ciclo de vida de um widget do kit de ferramentas deve estar de acordo com as regras do sistema de GUI subjacente.
A maioria das plataformas da GUI exige a especificação de um pai na criação de um widget. Como o SWT cria o widget de uma plataforma assim que você cria um widget do kit de ferramentas, o widget pai deve ser especificado no construtor do widget.
Algumas propriedades do widget devem ser definidas pelo sistema operacional no momento em que um widget é criado e não podem ser alteradas mais tarde. Por exemplo, uma lista pode ser uma seleção única ou várias seleções e pode ou não ter barras de rolagem.
Essas propriedades, chamadas de estilos, devem ser definidas no construtor. Todos os construtores de widget utilizam um argumento int que especifica o operador bit a bit OU de todos os estilos desejados. Em alguns casos, um estilo específico é considerado uma dica, o que significa que talvez ele não esteja disponível em todas as plataformas, mas será facilmente ignorado nas plataformas que não o suportam.
As constantes de estilo estão na classe SWT como campos públicos estáticos. Uma lista de constantes aplicáveis em cada classe de widget encontra-se na Referência da API para SWT.
As plataformas do sistema operacional abaixo do SWT exigem alocação e liberação explícitas de recursos do sistema operacional. Ao manter a filosofia de design do SWT de refletir a estrutura de aplicativo da plataforma no kit de ferramentas de widget, o SWT exige a liberação explícita de qualquer recurso do sistema operacional que não tenha sido alocado. No SWT, o método dispose() é utilizado para liberar recursos associados a um objeto específico do kit de ferramentas.
O princípio básico é: se você cria o objeto, deve descartá-lo. Eis aqui algumas regras básicas específicas que explicam melhor essa filosofia:
Se você criar um widget ou objeto gráfico utilizando um construtor, deverá descartá-lo manualmente quando terminar de utilizá-lo.
Se você obtiver um widget ou objeto gráfico sem utilizar um construtor, não deverá descartá-lo manualmente pois não o alocou.
Se você passar uma referência para o widget ou objeto gráfico para outro objeto, deverá tomar cuidado para não descartá-lo enquanto ainda estiver em uso. (Vimos esta regra em prática anteriormente em Padrões de plug-in para utilização de imagens).
Quando o usuário fecha um Shell, ele e todos os seus widgets filho são descartados de forma recursiva. Neste caso, não é necessário descartar os próprios widgets. No entanto, é preciso liberar os recursos gráficos alocados juntamente com esses widgets.
Se você criar um objeto gráfico para utilizar durante o ciclo de vida de um dos widgets, terá que descartá-lo quando o widget for descartado. Isso pode ser feito registrando um atendente de descarte no widget e liberando o objeto gráfico quando o evento dispose for recebido.
Não há exceção para essas regras. Objetos de dados simples, como Retângulo e Ponto, não utilizam recursos do sistema operacional. Eles não têm um método dispose() e você não precisa liberá-los. Se estiver em dúvida, consulte o javadoc para obter uma classe específica.