Visualizadores

Por que você desejaria utilizar um visualizador quando já vimos que as contribuições da UI do workbench como exibições, editores, assistentes e diálogos podem ser implementados diretamente com widgets do SWT?  

Os visualizadores permitem que você crie widgets e continue utilizando seus objetos de modelo.  Se utilizar diretamente um widget do SWT, será necessário converter seus objetos em cadeias e imagens esperadas pelo SWT.  Os visualizadores agem como adaptadores nos widgets do SWT, identificando o código comum para tratar eventos de widgets que você teria, por outro lado, que implementar sozinho. 

Vimos primeiro um visualizador na contribuição de visualização da ferramenta leia-me, dentro do ReadmeSectionsView.

   public void createPartControl(Composite parent) {
      viewer = new ListViewer(parent);
      ...
   }
Nota:  os visualizadores podem ser utilizados para fornecer a implementação para as visualizações do workbench e editores. O termo visualizador não implica que eles são úteis somente para implementar exibições. Por exemplo, o TextViewer é utilizado na implementação de vários editores de workbench e plug-in.

Visualizadores padrão

O JFace fornece visualizadores para a maioria dos widgets não triviais no SWT. Os visualizadores são mais comumente utilizados para widgets de lista, árvore, tabela e texto. 

Cada visualizador tem um widget do SWT associado. Esse widget pode ser criado implicitamente para fornecer a Combinação pai em um construtor do visualizador de conveniência, ou explicitamente criando-o primeiro e fornecendo-o para um visualizador no seu construtor.

Visualizadores Orientados pela Lista

Listas, árvores e tabelas compartilham muitas capacidades comuns a partir de um ponto de visualização do usuário, como população com objetos, seleção, classificação e filtragem. 

Esses visualizadores mantém uma lista de objetos e domínio (chamados elementos) e os exibem no seu SWT widget correspondente. Um visualizador de lista sabe como obter um rótulo de texto de qualquer elemento na lista.  Ele obtém o rótulo a partir de um ILabelProvider que pode ser definido no visualizador.  Os visualizadores de lista sabem como mapear a partir dos retornos de chamada do widget de volta ao mundo dos elementos conhecidos pelo visualizador cliente.

Os clientes que utilizam um widget do SWT pleno têm que operar em nível SWT - onde os itens são cadeias e eventos freqüentemente relacionados a um índice dentro da lista de cadeias. Os visualizadores fornecem semântica de alto nível. Os clientes são notificados de seleções e alterações na lista utilizando os elementos que eles forneceram ao visualizador. O visualizador identifica todo o trabalho para mapeamento de índices de volta aos elementos, ajustando para uma visualização filtrada de objetos e classificando novamente quando necessário.

A capacidade de filtragem e classificação é identificada designando um classificador de visualizador(ViewerSorter) e/ou filtro de visualizador(ViewerFilter) para o visualizador. (Esses podem ser especificados para visualizadores de árvore e tabela, além dos visualizadores de lista.) O cliente precisa somente fornecer uma classe que pode compara ou filtrar os objetos na lista. O visualizador identifica os detalhes de povoamento da lista de acordo com o pedido e filtro especificado e a manutenção do pedido e do filtro como elementos que são incluídos e removidos.

Os visualizadores não foram planejados para serem estendidos por clientes.  Para personalizar um visualizador, é possível configurá-lo com seus próprios fornecedores de conteúdo e rótulo.

Um ListViewer mapeia elementos em uma lista para um controle SWT Lista.

Um TreeViewer exibe objetos hierárquicos em um widget SWT Árvore. Isso identifica os detalhes para aumentar e comprimir itens. Há muitos tipos diferentes de visualizadores de árvore para controles de árvore SWT diferentes (árvore comum, árvore de tabela, árvore de caixa de entrada).

Um TableViewer é muito semelhante a um visualizador de lista, mas inclui a habilidade de exibir várias colunas de informações para cada elemento na tabela.  Os visualizadores de tabela estendem significativamente a função do widget de tabela do SWT introduzindo o conceito de edição de uma célula. Editores de célula especial podem ser utilizados para permitir que o usuário edite uma célula de tabela utilizando uma caixa de combinação, uma caixa de diálogo ou widget de texto. O visualizador de tabela trata da criação e posicionamento destes widgets quando necessário para edição pelo usuário.  Isso é feito utilizando as classes de CellEditor, tais como TextCellEditor e CheckboxCellEditor. Uma tabela virtual, preenchida apenas quando visualizada, o visualizador de tabela executa apenas um número designado de resultados, independentemente do que é criado realmente. O banco de dados pede JIT "preguiçosamente" e consulta um número predeterminado por vez.

Visualizador de Texto

Os widgets de texto possuem semântica muito comum como o comportamento de clique duplo, desfazer, colorir e navegar pelo índice ou pela linha.  Um TextViewer é um adaptador para um widget StyledText do SWT. Os visualizadores de texto fornecem um modelo de documentos para o cliente e gerenciam a conversão do documento para as informações do texto estilizado fornecidas pelo widget de texto.

Há mais detalhes sobre os visualizadores de texto nos Editores de Workbench.

Arquitetura do visualizador

Para entender um visualizador, você deve estar familiarizado com a relação entre um elemento de entrada do visualizador, seus conteúdos, sua seleção e as informações realmente exibidas no widget que ele está manipulando.

Elementos de entrada

Um elemento de entrada é o objeto principal que o visualizador está exibindo (ou editando). A partir do ponto de vista do visualizador, um elemento de entrada pode ser qualquer objeto. Ele não assume qualquer interface em particular que seja implementada pelo elemento de saída. (Veremos por que em um momento quando olhamos para fornecedores de conteúdo.)

Um visualizador deve poder identificar uma alteração de elemento de entrada. Se um novo elemento de entrada for definido em um visualizador, ele deve reocupar seu widget de acordo com o novo elemento e desassociar-se do elemento de entrada anterior. A semântica para registrar como um ouvinte em um elemento de entrada e ocupar o widget com base no elemento são diferentes para cada tipo de visualizador.

Visualizadores de conteúdo

Um visualizador de conteúdo é um visualizador que possui um protocolo bem definido para obter informações a partir do seu elemento de entrada. Os visualizadores de conteúdo utilizam duas classes de auxiliares, a IContentProvider e a ILabelProvider, para ocupar o widget e exibir informações sobre o elemento de entrada.

IContentProvider fornece protocolo de ciclo de vida básico para associar com um fornecedor de conteúdo como um elemento de entrada e identificando uma alteração do elemento de entrada. Os fornecedores de conteúdo mais especializados são implementados para diferentes tipos de visualizadores. O fornecedor de conteúdo mais comum é IStructuredContentProvider, que pode fornecer uma lista de objetos dados a um elemento de entrada. É utilizado em visualizadores parecidos com lista, como listas, tabelas ou árvores. No geral, o fornecedor de conteúdo sabe como mapear entre o elemento de entrada e o conteúdo do visualizador esperado.

ILabelProvider vai para a próxima etapa. Dado o conteúdo de um visualizador (derivado do elemento de entrada e fornecedor de conteúdo), ele pode produzir os elementos UI específicos, como nomes e ícones, que são necessários para exibir o conteúdo no visualizador. Os fornecedores de rótulo podem salvar os recursos do ícone desde que eles possam garantir a mesma ocorrência do ícone que é utilizada para todos os tipos similares em um visualizador.

Nota:  as instâncias de conteúdo específico e provedores de etiquetas não são planejados para serem compartilhados com vários visualizadores. Mesmo se todos os visualizadores utilizarem o mesmo tipo de conteúdo ou fornecedor de rótulo, cada visualizador deve ser inicializado com sua própria ocorrência de classe de fornecedor. O protocolo de ciclo de vida do fornecedor é designado para relação 1-para-1 entre um fornecedor e seu visualizador.

Os elementos de entrada, fornecedores de conteúdo e fornecedores de rótulo permitem que os visualizadores ocultem a maioria dos dados de implementação para ocupar widgets. Os clientes de um visualizador precisam somente se preocupar com o povoamento de um visualizador com o tipo do direito de entrada e fornecedor de conteúdo. O fornecedor de rótulo deve saber como derivar as informações UI do conteúdo do visualizador.

Um provedor de etiquetas pode mostrar mais do que simplesmente texto e imagem. O JFace fornece várias classes e interfaces para suportar a funcionalidade extra mais popular. As classes a seguir são suportadas pelo TableViewer, AbstractTreeViewer e TableTreeViewer.

É possível afetar as cores de uma visualização de duas maneiras como no Eclipse 3.1 - com seu próprio provedor de etiquetas ou com um decorador que configura as cores e as fontes. Geralmente, é melhor utilizar o suporte de cor e fonte em provedores de etiquetas pois os decoradores afetam todas as visualizações que mostram um tipo específico. Se utilizar um decorador de cor ou fonte, verifique se seus valores podem ser configurados na página de preferências Cores e Fontes.

Visualizadores e o workbench

A flexibilidade fornecida pelos visualizadores, fornecedores de conteúdo e fornecedores de etiqueta pode ser demonstrada vendo como o workbench os utiliza.

O WorkbenchContentProvider é um fornecedor de conteúdo estruturado que obtém conteúdos de um elemento de entrada solicitando seus filhos. O conceito de placas é utilizado novamente para implementar funções genéricas. Quando solicitada a lista de elementos do seu elemento de entrada, o WorkbenchContentProvider obtém um IWorkbenchAdapter para o elemento de entrada. Se um IWorkbenchAdapter foi registrado para o elemento de entrada, o fornecedor de conteúdo pode assumir com segurança que o elemento pode ser consultado por seus filhos.  WorkbenchContentProvider também faz o trabalho necessário para manter seu visualizador atualizado quando o espaço de trabalho é alterado. 

O WorkbenchLabelProvider é o fornecedor de rótulo que obtém um IWorkbenchAdapter de um objeto para localizar seu texto ou imagem. O conceito de um fornecedor de rótulo é particularmente útil para os objetos do workbench porque permite um único fornecedor de rótulo para imagens de cache que são utilizadas comumente em um visualizador. Por exemplo, assim que oWorkbenchLabelProvider obtiver uma imagem para utilizar para um IProject, é possível ter o cache daquela imagem e utilizá-lo para todos os objetos IProject mostrados no visualizador.

Definindo uma placa comum, IWorkbenchAdapter, e registrando-a para vários tipos de plataforma, tornamos possível para estes tipos serem representados corretamente em vários dos visualizadores comuns e as exibições do workbench que os contém.