Ao trabalhar com um kit de ferramentas de widgets, é importante compreender o modelo de módulos subjacente que é utilizado para ler e despachar eventos de GUI de plataforma. A implementação do módulo da UI afecta as regras que as aplicações devem seguir ao utilizar módulos Java no seu código.
Subjacente a qualquer aplicação de GUI, seja qual for a sua linguagem ou o seu kit de ferramentas de UI, a plataforma do SO detecta eventos de GUI e coloca-os em filas de eventos de aplicações. Embora a mecânica seja ligeiramente diferente em diferentes plataformas de SO, a base é semelhante. À medida que o utilizador faz clique com o rato, introduz caracteres ou passa por janelas, o SO gera eventos de GUI de aplicações como, por exemplo, cliques de rato, batimentos de teclas ou eventos de pintura de janelas. Determina qual a janela e aplicação que deve receber cada evento e coloca-o na fila de eventos da aplicação.
A estrutura subjacente para qualquer aplicação de GUI com janelas é um ciclo de eventos. As aplicações inicializam-se e depois iniciam um ciclo que lê simplesmente os eventos de GUI na fila e responde em conformidade. O trabalho que for feito ao tratar de um destes eventos deve acontecer rapidamente para manter o sistema da GUI contactável para o utilizador.
As operações longas desencadeadas por eventos de UI devem ser realizadas num módulo separado para permitir que o módulo do ciclo de eventos devolva rapidamente e busque o evento seguinte na fila da aplicação. Todavia, o acesso aos widgets e à API da plataforma a partir de outros módulos deve ser controlado com bloqueio e serialização explícitos. Uma aplicação que não cumpra as regras pode causar falhas numa chamada de SO ou ainda pior, pode bloquear o sistema da GUI por inteiro.
O SWT segue o modelo de módulos suportado directamente pelas plataformas. O programa de aplicação executa o ciclo de eventos no seu módulo principal e despacha eventos directamente a partir do seu módulo. O módulo da UI é aquele onde foi criado o Display. Todos os outros widgets devem ser criados no módulo da UI.
Dado que todo o código de eventos é desencadeado pelo módulo da UI da aplicação, o código da aplicação que tratar eventos pode aceder livremente aos widgets e realizar chamadas de gráficos sem técnicas especiais. No entanto, a aplicação é responsável pela ramificação de módulos de cálculo quando executar operações longas em resposta a um evento.
Nota: O SWT irá desencadear uma SWTException para chamadas efectuadas de um módulo alheio à UI que devam ser feitas do módulo da UI.
O módulo principal, incluindo o ciclo de eventos, para uma aplicação de SWT tem a seguinte estrutura:
public static void main (String [] args) { Display display = new Display (); Shell shell = new Shell (display); shell.open (); // iniciar o ciclo de eventos. Paramos quando o utilizador fizer algo // para inutilizar a nossa janela. while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } display.dispose (); }
Uma vez criados os widgets e a shell (interface) aberta, a aplicação lê e despacha eventos da fila do SO até que a janela da shell seja inutilizada. Se não houver eventos disponíveis para nós na fila, indicamos ao ecrã que entre em estado dormente para dar às outras aplicações ocasião de executar.
O SWT faculta métodos de acesso especial para chamar código de widgets e gráficos de um módulo em segundo plano.
As aplicações que pretendam chamar código de UI a partir de um módulo alheio à UI devem indicar um Executável que chame o código da UI. Os métodos syncExec(Runnable) e asyncExec(Runnable) na classe Display são utilizados para executar estes executáveis no módulo da UI durante o ciclo de eventos.
A porção de código seguinte demonstra o padrão para utilizar estes métodos:
// fazer cálculos que resultam em dispêndio de tempo ... // actualizar agora a UI. Não dependemos do resultado, // por isso utilize assíncrono. display.asyncExec (new Runnable () { public void run () { if (!aMinhaJanela.isDisposed()) aMinhaJanela.redraw (); } }); // agora fazer mais cálculos ...
É boa prática verificar se o widget foi inutilizado de dentro do executável ao utilizar asyncExec. Dado que podem acontecer outras coisas no módulo da UI entre a chamada de asyncExec
e a execução do executável, nunca se tem a certeza do estado em que os widgets estão na altura em que o executável é executado.
As regras de módulos são muito claras quanto à implementação de uma aplicação de SWT de raiz, dado que se controla a criação do ciclo de eventos e a decisão de ramificar módulos de cálculo na nossa aplicação.
Tudo se complica um pouco quando contribuímos com código de plug-in para a área de trabalho. As regras seguintes podem ser consideradas "regras de compromisso" ao utilizar classes de UI de plataforma, embora de edição para edição estas possam constituir excepções a estas regras: