Por que razão se pretende utilizar um visualizador quando já vimos que os contributos da UI da área de trabalho como, por exemplo, vistas, editores, assistentes e caixas de diálogo podem ser implementados directamente com widgets de SWT?
Os visualizadores permitem criar widgets mantendo a utilização de objectos modelo. Se utilizar um widget de SWT directamente, terá de converter os seus objectos nas cadeias e imagens esperadas pelo SWT. Os visualizadores servem de adaptadores em widgets de SWT, processando o código comum para tratamento de eventos de widget que de outro modo teria de ser o utilizador a implementar.
Vimos primeiramente um visualizadores no contributo da vista da ferramenta readme, dentro de ReadmeSectionsView.
public void createPartControl(Composite parent) { viewer = new ListViewer(parent); ... }
Nota: Os visualizadores podem ser utilizados para facultar a implementação tanto de vistas como de editores de área de trabalho. O termo visualizador não implica que só sejam úteis para implementar vistas. Por exemplo, o TextViewer é utilizado na implementação de muitos dos editores de plug-ins da área de trabalho.
O JFace faculta visualizadores para a maioria dos widgets de SWT não triviais. Os visualizadores são utilizados mais para widgets de lista, árvore, tabela e texto.
Cada visualizador tem um widget de SWT associado. Este widget pode ser criado implicitamente facultando o Composite ascendente num construtor de visualizadores de conveniência ou explicitamente criando-o primeiro e depois facultando-o ao visualizador no seu construtor.
Listas, árvores e tabelas partilham muitas capacidades comuns na perspectiva do utilizador como, por exemplo, preenchimento com objectos, selecção, ordenação e filtragem.
Estes visualizadores mantêm uma lista de objectos de domínio (denominados elementos) e apresentam-nos no widget de SWT correspondente. Um visualizador de listas sabe como obter uma etiqueta de texto de qualquer elemento na lista. Obtém a etiqueta junto de um ILabelProvider, o qual pode ser definido no visualizador. Os visualizadores de listas sabem como correlacionar as chamadas do widget com o mundo dos elementos conhecido do cliente visualizador.
Os clientes que utilizam um widget de SWT simples têm que funcionar ao nível de SWT - onde os artigos são cadeias e os eventos se costumam relacionar com um índice na lista de cadeias. Os visualizadores proporcionam semântica de nível superior. Os clientes são notificados das selecções e alterações à lista através dos elementos que facultaram ao visualizador. O visualizador realiza todo o trabalho de campo na correlação de índices com elementos, ajustando uma vista filtrada de objectos e reordenando quando necessário.
A capacidade de filtrar e ordenar é processada mediante designação de um ordenador de visualizador (ViewerSorter) e/ou filtro de visualizador (ViewerFilter) para o visualizador. (Estes podem ser especificados para visualizadores de árvore e tabela além dos visualizadores de listas.) O cliente só precisa de facultar uma classe que possa comparar ou filtrar os objectos na lista. O visualizador processa os detalhes do preenchimento da lista segundo a ordem e o filtro especificados, bem como da manutenção da ordem e do filtro à medida que os elementos são adicionados e removidos.
Os visualizadores não se destinam a serem estendidos pelos clientes. Para personalizar um visualizador, poderá configurá-lo com o seu próprio conteúdo e fornecedores de etiquetas.
Um ListViewer correlaciona elementos numa lista com um controlo List de SWT.
Um TreeViewer apresenta objectos hierárquicos num widget Tree de SWT. Processa os detalhes de expansão e contracção de artigos. Há vários tipos de visualizadores de árvores diferentes para controlo de árvore de SWT diferentes (árvore simples, árvore em tabela, árvore em caixa de verificação).
Um TableViewer é muito semelhante a um visualizador de listas, mas adiciona a capacidade de ver várias colunas de informações para cada elemento na tabela. Os visualizadores de tabelas estendem significativamente as funcionalidades do widget de tabelas de SWT mediante introdução do conceito de edição de uma célula. Os editores de células especiais podem ser utilizados para permitir ao utilizador editar a célula de uma tabela através de caixa combo, caixa de diálogo ou widget de texto. O visualizador de tabelas trata da criação e colocação destes widgets quando necessários para edição por parte dos utilizadores. Tal realiza-se com as classes CellEditor como, por exemplo, TextCellEditor e CheckboxCellEditor. Uma tabela virtual, somente preenchida quando visualizada, o visualizador de tabelas só executa um número de resultados designado, seja qual for aquele realmente criado. A base de dados solicita "ociosamente" ao JIT e só consulta um número predeterminado de cada vez.
Os widgets de texto podem ter muita semântica comum como, por exemplo, comportamento de duplo clique, anulação, coloração e navegação por índice ou linha. Um TextViewer constitui um adaptador para um widget StyledText de SWT. Os visualizadores de texto facultam um modelo de documentos ao cliente e gerem a conversão do documento nas informações de texto estilizadas facultadas pelo widget de texto.
Os visualizadores de texto são debatidos em mais detalhe na secção Editores de Área de Trabalho.
Para compreender um visualizador, é necessário conhecer a relação entre o elemento de entrada de dados de um visualizador, o seu conteúdo, a sua selecção e as informações realmente apresentadas no widget que estiver a manipular.
Um elemento de entrada de dados é o principal objecto que o visualizador estiver a apresentar (ou a editar). Na perspectiva do visualizador, um elemento de entrada de dados pode ser qualquer objecto, pois não parte do princípio de que está implementada uma interface em particular pelo elemento de entrada de dados. (Veremos porquê quando abordarmos os fornecedores de conteúdos.)
Um visualizador deve ser capaz de processar uma alteração de elemento de entrada de dados. Se novo elemento de entrada de dados for definido num visualizador, deverá preencher outra vez o seu widget segundo o novo elemento e desassociar-se do anterior elemento de entrada de dados. A semântica para registo enquanto ouvinte num elemento de entrada de dados e preenchimento do widget com base no elemento é diferente para cada tipo de visualizador.
Um visualizador de conteúdos é um visualizador que tem um protocolo bem definido para obter informações do respectivo elemento de entrada de dados. Os visualizadores de conteúdos são duas classes ajudantes especializadas, IContentProvider e ILabelProvider, para preencher o respectivo widget e apresentar informações sobre o elemento de entrada de dados.
IContentProvider faculta protocolo de ciclo de vida básico para associar um fornecedor de conteúdos um elemento de entrada de dados e processar uma alteração de elemento de entrada de dados. Os fornecedores de conteúdos mais especializados são implementados para diferentes tipos de visualizadores. O fornecedor de conteúdos mais comum é IStructuredContentProvider, o qual pode facultar uma lista de objectos mediante determinado elemento de entrada de dados. É utilizado em visualizadores do tipo lista como, por exemplo, listas, tabelas ou árvores. Regra geral, o fornecedor de conteúdos sabe como correlacionar o elemento de entrada de dados com o conteúdo de visualizador esperado.
O ILabelProvider vai mais além. Mediante o conteúdo de um visualizador (derivado do elemento de entrada de dados e do fornecedor de conteúdos), pode produzir os elementos específicos à UIcomo, por exemplo, nomes e ícones, que sejam necessários para apresentar o conteúdo no visualizador. Os fornecedores de etiquetas podem ajudar a poupar recursos de ícones visto que podem assegurar que seja utilizada a mesma instância do ícone para todos os tipos semelhantes num visualizador.
Nota: As instâncias de determinados fornecedores de conteúdos e etiquetas não se destinam a ser partilhadas por vários visualizadores. Mesmo que todos os visualizadores utilizem o mesmo tipo de fornecedor de conteúdos ou etiquetas, cada visualizador deve ser inicializado com a sua própria instância da classe fornecedora. O protocolo de ciclo de vida do fornecedor é designado para uma relação de 1 para 1 entre um fornecedor e o respectivo visualizador.
Elementos de entrada de dados, fornecedores de conteúdos e fornecedores de etiquetas permitem aos visualizadores ocultar a maioria dos detalhes de implementação para preenchimento de widgets. Os clientes de um visualizador só precisam de se preocupar que o preenchimento de um visualizador seja feito com o tipo certo de entrada de dados e fornecedor de conteúdos. O fornecedor de etiquetas deve saber como derivar as informações da UI do conteúdo do visualizador.
Um fornecedor de etiquetas pode mostrar mais do que simples texto e uma imagem. O JFace faculta várias classes e interfaces para suportar as funcionalidades adicionais. As classes seguintes são suportadas pelo TableViewer, AbstractTreeViewer e TableTreeViewer.
É possível afectar a cor dos artigos contidos numa vista a partir do fornecedor de etiquetas da vista ou através de um decorador. Regra geral, é melhor utilizar o suporte de cores e tipos de letra em fornecedores de etiquetas dado que os decoradores afectam cada vista que mostre determinado tipo. Se utilizar um decorador de cores ou tipos de letra assegure-se de que os respectivos valores podem ser definidos na página de preferências Cores e Tipos de Letra.
A flexibilidade proporcionada pelos visualizadores, fornecedores de conteúdos e fornecedores de etiquetas pode ser demonstrada vendo a utilização que a área de trabalho deles faz.
O WorkbenchContentProvider é um fornecedor de conteúdos estruturado que obtém conteúdos de um elemento de entrada de dados pedindo os seus descendentes. O conceito de adaptadores é usado novamente para implementar funcionalidades genéricas. Quando lhe pedem a lista de elementos do seu elemento de entrada de dados, o WorkbenchContentProvider obtém um IWorkbenchAdapter do elemento de entrada de dados. Se tiver sido registado um IWorkbenchAdapter para o elemento de entrada de dados, o fornecedor de conteúdos pode presumir em segurança que o elemento pode ser consultado relativamente aos seus descendentes. O WorkbenchContentProvider também realiza o trabalho necessário para manter o seu visualizador actualizado em caso de alterações no espaço de trabalho.
O WorkbenchLabelProvider é um fornecedor de etiquetas que obtém um IWorkbenchAdapter junto de um objecto para localizar os respectivos texto e imagem. O conceito de um fornecedor de etiquetas é particularmente útil para objectos de área de trabalho porque permite que um único fornecedor de etiquetas coloque em memória cache etiquetas que sejam utilizadas habitualmente num visualizador. Por exemplo, assim que o WorkbenchLabelProvider obtém uma imagem para utilizar num IProject, pode colocá-la em memória cache e utilizá-la para todos os objectos do IProject mostrados no visualizador.
Ao definir um adaptador comum, o IWorkbenchAdapter e ao registá-lo para muitos dos tipos de plataformas, possibilitamos a estes tipos que sejam correctamente representados em muitos dos visualizadores comuns e vistas de área de trabalho que os contêm.