O SWT proporciona um motor de conteúdos gráficos para desenhar gráficos e apresentar imagens em widgets. Poderemos ir longe sem ter de programar na interface de conteúdos gráficos, já que os widgets tratam de pintar ícones, texto e outros dados em vez do utilizador. Todavia, se a aplicação apresentar conteúdos gráficos personalizados ou se estiver a implementar um widget desenhado personalizado, terá de familiarizar-se com alguns objectos de desenho básicos no SWT.
O Contexto dos conteúdos gráficos, GC, é o ponto focal do suporte a conteúdos gráficos do SWT. A respectiva API descreve todas as capacidades de desenho em SWT.
Um GC pode ser utilizado para desenhar num controlo (o caso mais comum), numa imagem, num ecrã ou para impressora. Ao desenhar num controlo, utiliza-se o GC fornecido no evento de pintura do controlo. Ao desenhar numa imagem, num ecrã ou para impressora, é necessário criar um GC configurado para isso, e inutilizar o GC quando terminar de o utilizar.
Uma vez que tenha um GC, poderá definir-lhe os atributos como, por exemplo, cor, largura de linha, tipo de letra, os quais controlam a aparência dos conteúdos gráficos desenhados no GC.
A Referência de API para GC descreve o conjunto completo de funcionalidades de conteúdos gráficos.
As classes Font e FontData são utilizadas na manipulação de tipos de letra em SWT.
FontData descreve as características num tipo de letra. Poderá criar uma classe FontData especificando nome, estilo e tamanho de tipo de letra. FontData inclui uma API para consultar estes atributos. Dado que FontData não atribui nenhum recurso de SO, não é necessário inutilizá-la depois.
Font é o verdadeiro objecto de conteúdo gráfico que representa um tipo de letra utilizado na API de desenho. Cria-se uma classe Font para um Display (ecrã) especificando Display e FontData do tipo de letra pretendido. Também é possível consultar uma classe Font relativamente à sua FontData.
É necessário inutilizar uma Font atribuída depois de a utilizar.
As cores são semelhantes aos tipos de letra. Cria-se uma Color para um Display especificando os valores RGB da cor pretendida. É necessário inutilizar uma cor atribuída depois de a utilizar.
O método de Display getSystemColor(int)
permite consultar as cores de sistema predeterminadas para a plataforma do SO. Não se devem libertar cores obtidas com esta técnica.
O modelo de cores é debatido em pormenor no artigo Modelo de cores de SWT.
As classes Image, ImageData e ImageLoader são utilizadas na manipulação de Imagens em SWT.
ImageData descreve os pixéis reais na imagem, com a classe PaletteData para descrever os valores de cor utilizados. ImageData é uma descrição de uma imagem que não depende de dispositivos nem plataformas.
ImageLoader carrega e guarda ImageData em diferentes formatos de ficheiros. O SWT actualmente suporta carregamento e salvaguarda de formatos de imagens que incluem BMP (Mapa de Bits de Windows), ICO (Ícone de Windows), JPEG, GIF e PNG.
Image é o verdadeiro objecto de conteúdo gráfico que representa uma imagem utilizada na API de desenho. Cria-se uma imagem para determinado Display (ecrã), e tal pode realizar-se de várias maneiras:
Seja qual for o modo de criação da Imagem, compete ao utilizador inutilizá-la.
A maioria dos objectos gráficos utilizados para desenhar em SWT atribui recursos no SO subjacente e deve ser libertada explicitamente. Aplica-se aqui a mesma regra mencionada anteriormente. Se o criar com um construtor, deverá libertá-lo. Se tiver acesso ao mesmo de outra maneira qualquer, não o liberte.
Os objectos gráficos como, por exemplo, contextos de conteúdos gráficos, tipos de letra, cores e imagens são atribuídos no SO assim que o objecto for criado. a utilização que pretende dar aos objectos gráficos condiciona o momento da sua criação.
No caso de objectos gráficos que são muito utilizados em toda a aplicação, poderá criá-los na altura em que criar os widgets. É a abordagem habitualmente usada para cores e tipos de letra. Noutros casos, é mais apropriado criar os objectos gráficos de improviso. Por exemplo, poderá criar um contexto de conteúdo gráfico num dos processadores de eventos de widget para poder realizar alguns cálculos.
Se implementar um widget personalizado, normalmente atribuem-se objectos gráficos no construtor se os for utilizar sempre. Poderia atribuí-los de improviso se nem sempre os fosse utilizar ou se dependessem do estado de algum atributo.
Uma vez atribuídos os objectos gráficos, estamos prontos para pintar. Deve sempre proceder-se à pintura dentro de um ouvinte de pintura. Há casos raros, especialmente na implementação de widgets personalizados, em que se pinta ao reagir a outro evento. Todavia, na generalidade das situações não encorajamos este caso. Se precisar de pintar enquanto trata de outro evento, deverá primeiro utilizar o método redraw(), o qual irá gerar outro evento de pintura no SO. Desenhar fora do método de pintura colide com as optimizações da plataforma e pode causar falhas consoante o número de pinturas pendentes na fila de eventos.
Ao receber um evento de pintura, ser-lhe-á fornecido um GC pré-configurado para desenhar no widget. Não liberte este GC, pois não o criou.
Os outros objectos gráficos devem ser atribuídos enquanto se trata o evento (ou antecipadamente). De seguida é apresentada uma porção de código baseada no exemplo org.eclipse.swt.examples.HelloWorld5. A cor vermelha foi anteriormente atribuída ao criar o widget, de modo que pode ser usada aqui.
shell.addPaintListener (new PaintListener () { public void paintControl (PaintEvent event) { GC gc = event.gc; gc.setForeground (red); Rectangle rect = event.widget.getClientArea (); gc.drawRectangle (rect.x + 10, rect.y + 10, rect.width - 20, rect.height - 20); gc.drawString (resHello.getString("Hello_world"), rect.x + 20, rect.y + 20); } });
Cada objecto gráfico que atribuir deve ser libertado quando terminar de o utilizar.
O carácter oportuno da inutilização depende do momento de criação do objecto. Se criar um objecto gráfico enquanto criar o seu widget, regra geral deverá adicionar um ouvinte de inutilização ao widget e inutilizar os objectos gráficos quando o widget o for. Se criar um objecto de improviso enquanto pinta, deve inutilizá-lo quando terminar de pintar.
A porção de código seguinte mostra uma versão ligeiramente modificada do nosso ouvinte de pintura. Neste exemplo, atribui e liberta a cor vermelha durante a pintura.
shell.addPaintListener (new PaintListener () { public void paintControl (PaintEvent event) { GC gc = event.gc; Color red = new Color (event.widget.getDisplay (), 0xFF, 0, 0); gc.setForeground (red); Rectangle rect = event.widget.getClientArea (); gc.drawRectangle (rect.x + 10, rect.y + 10, rect.width - 20, rect.height - 20); gc.drawString (resHello.getString ("Hello_world"), rect.x + 20, rect.y + 20); red.dispose (); } });