Adicionando funcionalidades a Componentes

 

O objetivo deste artigo é mostrar uma forma de se personalizar um componente gráfico para que ele passe a ter novas funcionalidades e comportamentos.

 

Introdução: partindo de uma necessidade

Suponha que uma interface gráfica precise indicar ao usuário que um campo obrigatório está vazio e deve ser preenchido. Para facilitar a indicação do campo, ele poderia ser destacado dos outros, mudando de cor, de borda, ou de outra propriedade que o diferencie.

 

Uma maneira de fazer com que a classe responsável pela interface gráfica não precise se preocupar com essa tarefa é criar um campo de texto personalizado. Para este artigo será usada como campo de texto a classe JTextField do pacote javax.swing.

 

O que irá se fazer é adicionar mais um comportamento aos campos de texto pois por padrão os JTextFields não vêm com métodos para se destacar.

 

Criando um campo de texto personalizado

A Listagem 01 demonstra os dois métodos necessários para as ações de destaque do campo de texto.

 

Obs.: O código-fonte montado e comentado está disponível para download. Ao longo do artigo será demonstrado por partes para facilitar a compreensão.

 

public class PJTextField extends JTextField{

 

      private void destaca(){

            super.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));

            super.setBackground(Color.RED);

      }

     

      private void normaliza(){

            JTextField jTextField = new JTextField();

            super.setBackground(jTextField.getBackground());

            super.setBorder(jTextField.getBorder());

      }

...

Listagem 01

 

A classe PJTextField herda JTextField; condição necessária para ser um campo de texto personalizado.

 

O método destaca() realiza o destaque do campo de texto. Primeiramente ajusta-se a borda para uma de espessura maior chamando o método de JTextField setBorder() e passando a ele uma borda gerada por BorderFactory, também do pacote javax.swing. Em seguida altera-se a cor com setBackground(). No caso passou-se a cor vermelha como cor de destaque.

 

Pronto, já tem-se um método capaz de alterar as propriedades do campo de texto e que irá destacá-lo dos demais no formulário. Mas agora precisa-se também de um método que faça-o voltar ao que era anteriormente.

O método normaliza() faz com que as propriedades voltem ao que eram antes do método destaca() ser chamado. Para isso cria-se uma instância local de JTextField e passa-se para os métodos setBackground() e setBorder() as propriedades tiradas do campo de texto criado, ou seja, valores padrões.

 

A Listagem 02 representa a maneira como será feita a verificação do campo para a classe. Vale ressaltar que as chamadas de destaca() e normaliza() podem ser feitas de acordo com as necessidades e comportamentos da interface gráfica. Neste caso será feita quando tentar-se ler o texto contido na mesma.

 

@Override

public String getText(){

      if(super.getText().equals("")){

            destaca();

            return null;

      }

      return super.getText();

}

Listagem 02

 

JTextField possui o método getText(). Ele foi sobrescrito para funcionar de uma maneira que possa interagir com o métodos de destaque do componente. Se nada estiver digitado no campo ele é destacado e retorna null. Caso contrário retorna o texto normalmente.

 

Durante a execução do programa, caso o usuário deixe algum campo obrigatório vazio, ele será destacado. Mas e se ele completar o campo, o mesmo continuará destacado? Para evitar esse tipo de comportamento, adiciona-se um KeyListener no campo para que ele se normalize caso receba um caracter, como mostra a Listagem 03.

 

public PJTextField(){

      this.addKeyListener(new KeyAdapter(){

            public void keyPressed(KeyEvent e){

                  normaliza();

            }

      });

}

Listagem 03 – Construtor de PJTextField

 

Agora tem-se um componente de texto personalizado com a capacidade de se destacar em caso de estar vazio e de voltar ao normal quando é preenchido. O próximo passo do artigo será utilizar o campo em uma interface gráfica bastante simples, apenas para demonstrar seu uso.

 

Note que no método keyPressed não foi tratado qual tecla o usuário pressionou. Pode-se personalizá-lo para não normalizar o campo no caso de teclas que não representem caracteres, como Shift, Alt, etc.

 

Trabalhando com o campo personalizado

Com o componente personalizado pronto, falta apenas testá-lo em uma interface gráfica para ver se o comportamento de destaque será bem sucedido. Para isso foi criado um formulário extremamente simples com apenas dois campos e um botão que, ou destaca os campos de texto caso estejam vazios ou exibe as informações digitadas em um messageDialog de JOptionPane.


Neste artigo será demonstrada apenas a criação do campo, sua adição e o tratamento de evento do botão principal para que ele possa trabalhar com a funcionalidade do componente personalizado criado. Os outros detalhes de implementação do formulário foram ignorados para manter a clareza. O código-fonte completo com a interface montada está disponível para download.

 

A Listagem 04 mostra os trechos relevantes do formulário:

 

PJTextField tFieldNome = new PJTextField();

PJTextField tFieldEndereco = new PJTextField();

 

JButton bOk = new JButton("Ok");

bOk.addActionListener(new ActionListener(){

      public void actionPerformed(ActionEvent e){

            String nome = tFieldNome.getText();

            String endereco = tFieldEndereco.getText();

            if(nome != null && endereco != null){

                  JOptionPane.showMessageDialog(null, nome + "\n" + endereco);

            } else{

                  String eString = "O(s) campo(s) destacado(s) é(são) obrigatório(s).";

                  JOptionPane.showMessageDialog(null, eString);

            }

      }

});

Listagem 04

 

Primeiramente se criam as instâncias de PJTextField e em seguida o botão responsável por tratar o evento principal que é o de exibição das informações digitadas.

 

O evento armazena as Strings ‘nome’ e ‘endereço’. Cada uma chama o método getText() que irá destacar o campo caso esteja vazio. Em seguida testa para ver se há Strings com valor nulo e, caso não haja, exibe as informações em um messageDialog.

 

Conclusão

Através da herança foi possível adicionar um comportamento extra a um campo de texto, fazendo com que se destaque caso seu valor tente ser recuperado e nada esteja preenchido. Tudo isso através da herança.

 

Um grande abraço e até a próxima.

Adriano S. Castro