Ao trabalhar com um kit de ferramentas de widget, é importante compreender o modelo de encadeamento subjacente utilizado para leitura e dispatch de eventos da GUI da plataforma. A implementação do encadeamento da UI afeta as regras que os aplicativos devem seguir ao utilizarem encadeamentos Java em seus códigos.
Debaixo de qualquer aplicativo da GUI, independentemente de sua linguagem ou seu kit de ferramentas da UI, a plataforma do S.O. detecta eventos da GUI e os coloca em filas de eventos de aplicativos. Embora os mecanismos sejam um pouco diferentes em plataformas de sistema operacional diferente, os fundamentos são semelhantes. Conforme o usuário clica com o mouse, digita caracteres ou acerta janelas, o sistema operacional gera eventos da GUI do aplicativo, como cliques do mouse, pressionamentos de teclas ou eventos de pintura da janela. Ele determina qual janela e qual aplicativo devem receber cada evento e coloca-o na fila de eventos do aplicativo.
A estrutura subjacente de qualquer aplicativo da GUI na janela é um loop de eventos. Os aplicativos são inicializados e começam a fazer um loop que simplesmente lê os eventos da GUI na fila e reage de maneira adequada. Qualquer trabalho feito durante a manipulação de um desses eventos deve ocorrer rapidamente para manter o sistema da GUI pronto para responder ao usuário.
As operações longas disparadas por eventos da UI devem ser executadas em um encadeamento separado para permitir que o encadeamento do loop de eventos retorne rapidamente e busque o próximo evento na fila do aplicativo. No entanto, o acesso aos widgets e à API da plataforma a partir de outros encadeamentos deve ser controlada com bloqueio e serialização explícitos. Um aplicativo que falha em seguir as regras pode provocar a falha de uma chamada do sistema operacional ou, o que é pior, bloquear o sistema da GUI inteiro.
O SWT segue o gabarito de encadeamento diretamente compatível com as plataformas. O programa aplicativo executa o loop de eventos no seu segmento principal e faz o dispatch dos eventos diretamente desse encadeamento. O encadeamento da UI é o encadeamento no qual o Display foi criado. Todos os outros widgets devem ser criados no encadeamento da UI.
Como todo o código de evento é disparado do código de evento da UI do aplicativo, o código do aplicativo que manipula os eventos pode acessar livremente os widgets e fazer chamadas de gráfico sem qualquer técnica especial. No entanto, o aplicativo é o responsável por bifurcar os encadeamentos computacionais durante a execução de operações longas, em resposta a um evento.
Nota: O SWT acionará uma SWTException para quaisquer chamadas feitas de um encadeamento que não seja da UI e que devam ser feitas de um encadeamento da UI.
O encadeamento principal de um aplicativo do SWT, incluindo o loop de eventos, possui a seguinte estrutura:
public static void main (String [] args) { Display display = new Display (); Shell shell = new Shell (display); shell.open (); // iniciar o loop de eventos. Paramos quando o usuário faz // algo para descartar nossa janela. while (!shell.isDisposed ()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose (); }
Assim que os widgets são criados e o shell é aberto, o aplicativo lê e faz o dispatch dos eventos na fila do sistema operacional até a janela do shell ser descartada. Se não há eventos disponíveis para nós na fila, dizemos ao vídeo para dormir, a fim de dar aos outros aplicativos a chance de serem executados.
O SWT fornece métodos de acesso especiais para chamada de código de widget e de gráfico de um encadeamento em segundo plano.
Os aplicativos que desejam chamar o código da UI de um encadeamento que não é da UI devem fornecer 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 esses executáveis no encadeamento da UI durante o loop de eventos.
O fragmento de código a seguir demonstra o padrão para utilização desses métodos:
// faça computações que consumam bastante tempo ... // agora atualize a UI. Não dependemos do resultado, // portanto, utilize assincronamente. display.asyncExec (new Runnable () { public void run () { if (!myWindow.isDisposed()) myWindow.redraw (); } }); // agora faça mais computações ...
É recomendável verificar se o widget está descartado de dentro do executável,
quando utilizar asyncExec. Visto que outras coisas podem acontecer no encadeamento da UI entre
a chamada para asyncExec
e a execução do executável,
você nunca pode ter certeza em que estado os widgets se encontram pela hora de sua
execução.
As regras de encadeamento são bastante claras quando se está implementando um aplicativo SWT desde o início, pois você controla a criação do loop de eventos e a decisão de bifurcar os encadeamentos computacionais no aplicativo.
As coisas tornam-se um pouco mais complicadas quando você está contribuindo com o código de plug-in para o workbench. As regras a seguir podem ser consideradas "regras de compromisso" ao utilizar as classes de UI de plataforma, embora de release para release pode haver exceções para estas regras: