É frequentemente exigido a um utilizador faculte informações textuais num campo simples como, por exemplo, um campo de texto ou caixa de combinação. Apesar do código da aplicação que preenche estes campos ser normalmente muito mais simples do que o código que preenche um mecanismo complexo como, por exemplo, uma tabela ou uma árvore, estes campos "simples" tornam-se habitualmente um maior incómodo para o utilizador. O utilizador deverá identificar quais os campos que requerem conteúdo, se um campo contém conteúdo válido e quais as opções esperadas. O suporte de assistência de campo de JFace faculta classes que orientam o utilizador através das tarefas de introdução de dados.
O conjunto de programas org.eclipse.jface.fieldassist faculta assistência de duas formas. O suporte para campo decorados permite incluir decorações de imagem que fornecem indicações ao utilizador acerca do estado de um campo específico. O suporte Propostas do conteúdo permite facultar uma janela emergente de assistência de conteúdos que proporciona opções de conteúdo ao utilizador.
Campos decorados permite colocar decorações de imagem adjacentes a campos definidos numa janela ou caixa de diálogo. É possível colocar decorações adjacentes a um dos quatro cantos de um campo. À semelhança dos visualizadores, a intenção dos campos decorados é proporcionar funcionalidade a um controlo SWT, ao mesmo tempo em que faculta acesso ao controlo subjacente. A API para DecoratedField permite adicionar, ocultar e apresentar decorações adjacentes a um campo. O acesso ao controlo subjacente é facultado para que possa utilizar a API do SWT existente para afectar o controlo subjacente como, por exemplo, definir o seu conteúdo, a sua cor ou o seu tipo de letra.
A partir do exterior, um campo decorado comporta-se como um controlo individual. Internamente, os campos decorados utilizam um controlo composto para gerir o esquema do campo e as respectivas decorações. Na maioria das vezes, este facto não deveria ter relevância para a aplicação cliente. No entanto, significa que o campo decorado deverá executar a criação efectiva do controlo. Por exemplo, considere este fragmento no qual uma aplicação cria um controlo de texto no interior de uma caixa de diálogo:
... // Create a text field Text text = new Text(parent, SWT.BORDER); text.setText("some text"); ...
Para decorar este campo, este seria criado desta forma:
... // Create a decorated field for a text control DecoratedField field = new DecoratedField(parent, SWT.BORDER, new TextControlCreator()); Text text = (Text)field.getControl(); text.setText("some text"); ...
Os mesmos bits de estilo e ascendentes que seriam utilizados para criar o controlo básico são também utilizados para criar um campo decorado. A principal diferença no código é que é facultada uma ocorrência de IControlCreator que criar o tipo específico de controlo pretendido no campo. Para campos de texto, é possível utilizar a classe TextControlCreator para criar o controlo. No entanto, possui a flexibilidade para implementar IControlCreator de forma a criar qualquer outro tipo de controlo no campo como, por exemplo, uma caixa de combinação ou um controlo giratório.
Assim que um campo decorado é criado, as decorações podem ser adicionadas numa de quatro localizações. As constantes da localização do SWT são utilizadas para especificar onde deverá ser colocada a decoração. Para adicionar uma decoração, deverá especificar uma FieldDecoration, que define a imagem para a decoração e texto descritivo (opcional) que pode ser apresentado quando o utilizador colocar o ponteiro do rato sobre a decoração.
... // Create a field decoration and add it to the field Image image = JFaceResources.getImage("myplugin.specialimage"); FieldDecoration mySpecialDecoration = new FieldDecoration(image, "This field is special"); field.addFieldDecoration(mySpecialDecoration, SWT.TOP | SWT.LEFT, false); ...
O parâmetro booleano é utilizado para especificar se a decoração deverá ser apresentada apenas caso o controlo tenha ênfase ou se deverá ser apresentada sempre. Neste caso, a decoração será sempre apresentada. No entanto, poderão existir alturas em que a decoração poderá estar oculta ou apresentada. O seguinte fragmento oculta uma decoração que já tenha sido criada.
... // Something has occurred that makes me want to hide the decoration field.hideDecoration(mySpecialDecoration); ...
Se a imagem ou descrição de uma decoração for actualizada, o campo deveria ser notificado de forma a que a decoração possa ser recomposta.
... // Something has made the field extra special mySpecialDecoration.setDescription("This field is extra-special"); field.updateDecoration(mySpecialDecoration); ...
Ao esquematizar um campo decorado no interior de uma caixa de diálogo ou de uma janela, deverá esquematizar o controlo de esquema do campo e não o controlo simples subjacente. Tenha novamente em consideração o código para criar um controlo de texto. Ao esquematizar um controlo de texto, a aplicação define dados do esquema no controlo.
... // Create a text field Text text = new Text(parent, SWT.BORDER); text.setText("some text"); // Set the layout data GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH, SWT.DEFAULT); text.setLayoutData(data); ...
Ao esquematizar um campo decorado, a aplicação deverá colocar os dados correspondentes ao esquema no controlo de esquema do campo. Dependendo do esquema pretendido, o tamanho do campo poderá ter de ser ajustado ao tamanho da decoração.
... // Create a decorated field for a text control DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator()); Text text = (Text)field.getControl(); text.setText("some text"); // Set the layout data GridData data = new GridData(IDialogConstants.ENTRY_FIELD_WIDTH + FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(), SWT.DEFAULT); field.getLayoutControl().setLayoutData(data); ...
O suporte de assistência de campo não requer que utilize apenas campos decorados numa janela ou numa caixa de diálogo específica, nem assume que o está a fazer. No entanto, o esquema da janela poderá tornar-se um pouco mais complexo quando os campos decorados se misturam com controlos simples. Para alinhar campos decorados e não decorados, deverá ter em conta a indentação criada pela largura da decoração. A largura de uma decoração é simplesmente a largura da sua imagem. No entanto, tudo se poderá tornar mais complicado caso esteja a utilizar decorações com diferentes larguras. Neste caso, é possível simplificar registando todas as decorações em FieldDecorationRegistry.
O registo da decoração de campos permite registar as decorações de campos e aceder às mesmas utilizando um identificador. Esta é uma forma conveniente de consultar as decorações utilizadas ao longo da aplicação. Pode optar por definir a API que expõe a identificação das decorações caso as pretenda disponibilizar para outros plug-ins. Tenha em conta o facto de que o registo uma decoração não gere o ciclo de vida das imagens existentes nestas decorações. A aplicação pode decidir como gerir estas imagens. Por exemplo, o registo de imagens JFace pode ser utilizado para registar e gerir o ciclo de vida da imagem. Em alternativa, a aplicação pode pretender criar a imagem a pedido e livrar-se da mesma quando esta já não for necessária. O Javadoc para os métodos de registo em FieldDecorationRegistry explicam as diferentes formas de especificar imagens ao registar uma decoração.
O registo das decorações no registo da decoração de campos pode ainda simplificar o processo de esquematização ao misturar campos decorados (e não decorados). Por predefinição, um campo decorado consultará o registo da decoração de campos de forma a determinar a largura máxima de uma decoração e certificar-se de que todas as decorações utilizam esta mesma largura. Isto significa que todos os campos decorados ficarão alinhados de forma adequada, independentemente da largura de qualquer decoração em particular. Para alinhar campos não decorados, é possível utilizar o protocolo FieldDecorationRegistry para aceder à largura da maior decoração e criar a indentação necessária.
... // Create a text field Text text = new Text(parent, SWT.BORDER); text.setText("some text"); // Set the layout data GridData data = new GridData(); data.horizontalAlignment = SWT.FILL; data.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth(); text.setLayoutData(data); ...
Apesar do suporte de assistência de campo não ditar a forma como as decoração devem ser utilizadas, o registo define também decorações padrão que podem ser utilizadas por aplicações para apresentar certos estados para um campo. Por exemplo, o seguinte fragmento utiliza uma decoração padrão para os campos requeridos:
... // Create a decorated field with a required field decoration. DecoratedField field = new DecoratedField(main, SWT.BORDER, new TextControlCreator()); FieldDecoration requiredFieldIndicator = FieldDecorationRegistry.getDefault(). getFieldDecoration(FieldDecorationRegistry.DEC_REQUIRED); field.addDecoratedField(requiredFieldIndicator, SWT.BOTTOM | SWT.LEFT, false); ...
Além de anotar campos com decorações, as aplicações podem facultar um assistente de proposta de conteúdo que activa uma proposta de janela emergente para um campo. Poderá instalar um ContentProposalAdapter num controlo arbitrário de forma a possibilitar esta comportamento. O seguinte fragmento instala um adaptador de proposta de conteúdo num controlo de texto. Tenha em conta o facto de que este controlo de texto poderia ser um controlo criado directamente pela aplicação ou obtido a partir de um campo decorado.
... autoActivationCharacters = new char[] { '#', '(' }; keyStroke = KeyStroke.getInstance("Ctrl+Space"); // assume that myTextControl has already been created in some way ContentProposalAdapter adapter = new ContentProposalAdapter( myTextControl, new TextContentAdapter(), new SimpleContentProposalProvider(new String [] {"ProposalOne", "ProposalTwo", "ProposalThree"}), keyStroke, autoActivationCharacters);
Para obter e definir o conteúdo do controlo quando um utilizador escolhe uma proposta da janela emergente, o adaptador deverá possuir uma ocorrência do IControlContentAdapter, que pode obter e definir o conteúdo de um tipo de controlo específico. Para campos de texto, é possível utilizar a classe TextContentAdapter. No entanto, possui a flexibilidade para implementar IControlContentAdapter para utilizar o adaptador da proposta de conteúdo com qualquer outro tipo de controlo.
Ao criar um adaptador de propostas de conteúdo, deverá especificar ainda uma ocorrência de IContentProposalProvider, a partir da qual as próprias propostas são obtidas. Este fornecedor é responsável pela devolução de uma matriz de propostas de conteúdo. As propostas propriamente ditas são especificadas como ocorrências de IContentProposal, a partir das quais a etiqueta e o conteúdo da proposta podem ser obtidos, bem como outras informações como, por exemplo, uma descrição pormenorizada da proposta.
No exemplo acima, é utilizado SimpleContentProposalProvider. Este fornecedor é definido ao especificar uma matriz simples de Cadeias como as propostas de conteúdo. O fornecedor simples implementa o protocolo necessário para correlacionar todas as cadeias na esperada IContentProposal. A flexibilidade do IContentProposalProvider permite implementar um fornecedor de propostas com funções avançadas como, por exemplo, a filtração das propostas com base no conteúdo do controlo, o fornecimento de etiquetas explicativas na janela emergente em detrimento do conteúdo que será realmente introduzido e a especificação da posição esperada do cursor após a introdução de uma proposta. Consulte o Exemplo de assistência de campo e procure implementadores do IContentProposalProvider para utilização avançada.
Foi constatado que as definições básicas de um adaptador de propostas de conteúdo incluem o controlo para o qual as propostas são facultadas, o adaptador de conteúdo utilizado para alterar o conteúdo do controlo e o fornecedor de propostas que define a lista de propostas da janela emergente. Além das formas básicas, existem muitas outras de configurar o adaptador de propostas de conteúdo:
O suporte de assistência de campo ao nível de JFace proporciona à aplicação uma grande flexibilidade na determinação de formas de decorar campos e de apresentar propostas para conteúdos de campos. É essencialmente útil para aplicações JFace ou rich client autónomas. No entanto, caso faça intenções de integrar a aplicação com outros plug-ins como, por exemplo, Eclipse SDK ou outros plug-ins de terceiros, pretenderá provavelmente utilizar o suporte de assistência de campo de uma forma consistente com outros plug-ins. A área de trabalho define classes de utilitários que utilizam a assistência de campo para tipos específicos de interacções.
Por exemplo, a classe ContentAssistField cria um campo com uma decoração que inclui uma lâmpada, indicando ao utilizador que a assistência de conteúdos está disponível. Configura ainda um adaptador de propostas de conteúdo para a introdução do estilo da assistência de conteúdos. Por fim, faculta ainda uma rotina de tratamento para o comando de assistência de conteúdos ao nível da área de trabalho, para que a janela emergente seja apresentada quando o utilizador invocar o batimento de tecla ou a sequência activadora especificada nas associações de teclas da área de trabalho. Para obter mais informações sobre estas classes de utilitários, consulte o conjunto de programas org.eclipse.ui.fieldassist.
Espera-se que este conjunto de programas se desenvolva à medida que a área de trabalho expande a sua utilização da assistência de campo e normaliza a utilização de decorações para certos estados de campos.