Opinião sobre Classe de validação de JTextField

3 respostas
Scorsatto

Boa tarde pessoal, tive que validar alguns textFields e cheguei a este artigo http://www.guj.com.br/articles/29.

Peguei o mesmo e dei uma “melhorada”, na verdade adaptei o mesmo para as minhas necessidades.

Gostaria de saber dos programadores mais experientes se o modo que fiz as melhorias esta adequado ou se haveria uma outra forma de fazer estas melhorias.

Tenho pouca experiência na área de desenvolvimento e acredito que opiniões construtivas seriam ótimas para que eu possa desenvolver boas praticas de programação.

A classe valida a quantidade de caracteres aceitos pelo campo, o tipo de carácter aceito, os caracteres especiais aceitos além do tipo setado e se o JTextField aceitara um carácter especial na primeira posição.

Classes:

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

/**
 * Classe baseada no artigo Controlando um JTextField criado por Daniel Gonçalves. 
 * @author Scorsatto
 * @Artigo http://www.guj.com.br/articles/29
 */
public class TextDocument extends PlainDocument {

	private static final long serialVersionUID = 1L;

	/**
	 * <b>Tipos:</b>
	 * <p style="margin-left: 16">Tipos de caracter aceitos.</p>
	 * <br> <b>LIVRE</b> - Aceita qualquer caracter.
	 * <br> <b>SOMENTE_NUMERO</b> - Aceita apenas números (juntamente aos caracteres passados como parâmetro).
	 * <br> <b>SOMENTE_TEXTO</b> - Aceita apenas texto (juntamente aos caracteres passados como parâmetro).
	 */ 
	public enum Tipo {
		LIVRE,
		SOMENTE_NUMERO,
		SOMENTE_TEXTO;
	}
	
    private int tamanhoMaximo;
    private Tipo tipo = Tipo.LIVRE;
    private Character[] caracterEspecial;
    private String caracterAnterior;
    private boolean caracterEspecialPrimeiraPosicao = false;
    
    /**
     * Construtor TextDocument.
     * @param tamanhoMaximo (int) - Tamanho máximo do TextField.
     */
    public TextDocument(int tamanhoMaximo) {
        //super();
        this.tamanhoMaximo = tamanhoMaximo;
    }

    /**
     * Construtor TextDocument.
     * @param tamanhoMaximo (int) - Tamanho máximo do TextField.
     * @param tipo (Tipo) - Tipo de caracter aceito.
     */
    public TextDocument(int tamanhoMaximo, Tipo tipo) {
        super();
        this.tamanhoMaximo = tamanhoMaximo;
        this.tipo = tipo;
    }
    
    /**
     * Construtor TextDocument.
     * @param tamanhoMaximo (int) - Tamanho máximo do TextField.
     * @param tipo (Tipo) - Tipo de caracter aceito.
     * @param caracterEspecial (Character[]) - Caracteres especiais aceitos além do tipo.
     */
    public TextDocument(int tamanhoMaximo, Tipo tipo, Character[] caracterEspecial) {
        super();
        this.tamanhoMaximo = tamanhoMaximo;
        this.tipo = tipo;
        this.caracterEspecial = caracterEspecial;
    }
    
    /**
     * Construtor TextDocument.
     * @param tamanhoMaximo (int) - Tamanho máximo do TextField.
     * @param tipo (Tipo) - Tipo de caracter aceito.
     * @param caracterEspecial (Character[]) - Caracteres especiais aceitos além do tipo.
     * @param primeiroCaracterEspecial (boolean) - Primeiro caracter possa ser especial ou não.
     */
    public TextDocument(int tamanhoMaximo, Tipo tipo, Character[] caracterEspecial, boolean primeiroCaracterEspecial) {
        super();
        this.tamanhoMaximo = tamanhoMaximo;
        this.tipo = tipo;
        this.caracterEspecial = caracterEspecial;
        this.caracterEspecialPrimeiraPosicao = primeiroCaracterEspecial;
    }

    @Override
    public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
    	
    	if (str == null)
            return;

    	// Se o "tamanhoMaximo" for "0" não delimita o tamanho do textField.
        if (this.tamanhoMaximo <= 0) { 
        	verificador(offset, str, attr);
            
            return;
        }

        int ilen = (getLength() + str.length());
        
        // Se o tamanho de "ilen" for menor ou igual ao "tamanhoMaximo" faz as verificações para o retorno.
        if (ilen <= this.tamanhoMaximo) 
        	verificador(offset, str, attr);
            
        else {
            if (getLength() == this.tamanhoMaximo)
                return; 
            
            String newStr = str.substring(0, (this.tamanhoMaximo - getLength()));

            super.insertString(offset, newStr, attr);
        }
    }
    
    /**
     * Método para verificar qual tipo de tratamento deve ser utilizado.
     */
    public void verificador(int offset, String str, AttributeSet attr) throws BadLocationException {
    	
    	// Verifica se o "offset" é maior do que 0 e armazena o ultimo caracter.
   		this.caracterAnterior = offset > 0 ? this.getContent().getString(0, offset) : "";
    	
    	// Verifica se o "Tipo" é igual a "SOMENTE_NUMERO".
    	if (this.tipo == Tipo.SOMENTE_NUMERO) {
    		for (int i = 0; i < str.length(); i++)  
                if (!Character.isDigit(str.charAt(i)) && !eCaracterEspecial(str.charAt(i)))  
                	return;
    	
    	// Verifica se o "Tipo" é igual a "SOMENTE_TEXTO".
    	} else if (this.tipo == Tipo.SOMENTE_TEXTO) {
    		for (int j = 0; j < str.length(); j++)  
                if (!Character.isLetter(str.charAt(j)) && !eCaracterEspecial(str.charAt(j))) 
                	return;
    	}
    	
    	// Caso o "Tipo" for igual a "LIVRE" ou os caracteres testados acima estejam em acordo com os parâmetros passados retorna a string.
    	super.insertString(offset, str, attr); 
    }
    
    /**
     * Método para verificar se é um caracter especial.
     */
    public boolean eCaracterEspecial(Character caracterAtual){
    	
    	if (this.caracterEspecial != null)
	    	for (Character caracter : this.caracterEspecial) 
				if (caracter.equals(caracterAtual) &&  verificadorEspecial(caracter))
					return true;
					
    	return false;
    }
    
    /**
     * Método para verificar se o primeiro caracter pode ser especial.
     */
	private boolean verificadorEspecial(Character comparador){
		
		if (caracterEspecialPrimeiraPosicao && caracterAnterior.length() == 0)
			return true;
		
		else if (caracterAnterior.length() > 0)
			if (comparador != caracterAnterior.charAt(caracterAnterior.length() -1))
				return true;

		return false;
	}
}

Classe de teste:

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JTextField;

import testes.TextDocument.Tipo;


public class Teste {
    public static void main(String args[]) {
        JFrame aFrame = new JFrame();
        aFrame.setLayout(new BorderLayout());
        JTextField txtTeste = new JTextField(); 
        JTextField txtTeste2 = new JTextField(); 
        JTextField txtTeste3 = new JTextField(); 
        
        // Seta o tamanho máximo em 20 caracteres.
        txtTeste.setDocument(new TextDocument(20));
        
        // Seta o tamanho máximo em 20 caracteres.
        // Seta o tipo para somente texto.
        // Adiciona o "5" como caracter especial.
        txtTeste2.setDocument(new TextDocument(20, Tipo.SOMENTE_TEXTO, new Character[] {'5'}));
        
        // Seta o tamanho máximo em 20 caracteres.
        // Seta o tipo para somente números.
        // Adiciona o "(" ")" "-" como caracter especial.
        // Seta o parametro primeiroCaracterEspecial como true.
        txtTeste3.setDocument(new TextDocument(20, Tipo.SOMENTE_NUMERO, new Character[] {'(', ')', '-'}, true));
        
        aFrame.add(txtTeste, BorderLayout.NORTH);
        aFrame.add(txtTeste2, BorderLayout.CENTER);
        aFrame.add(txtTeste3, BorderLayout.SOUTH);
        
        aFrame.setSize(300,100);
        aFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        aFrame.setLocationRelativeTo(null);
        aFrame.setVisible(true);
    }
}

3 Respostas

Gleidson_Henrique

Ficou bem fácil a utilização desta forma amigo.

Você tem que ver como irá implementar depois quando for desenvolver a partir de uma IDE.

O Netbeans permite voce editar os componentes. Basta clicar com o botao direito em cima e ir em Personalizar.

Dai voce define o setDocument do campo como voce fez no exemplo que colocou.

So tem que lembrar que campos do tipo Float no banco de dados, quando voce for salvar, nao podem ir com virgula. Imagine um campo valor em que a pessoa digite: 1.234,43.

Isso daria erro na hora de salvar pois o certo seria 1234.43

Mais a utilização ficou boa sim… parabens… :slight_smile:

Vale lembrar tambem que você pode criar componentes no NetBeans a partir de um JTextField por exemplo e nele setar, por exemplo, que apenas permitirá numeros. Com isso, sempre que tiver um campo que somente será numero, voce nao precisa clicar com o botao direito, ir em personalizar e inserir o document do campo… basta inserir o componente que voce criou ja formatado para isso… de uma olhada nisso tambem, é bem interessante…

Abraços

Scorsatto

Gleidson Henrique muito obrigado pela atenção/opinião, no momento utilizo o Eclipse, não conhecia essa funcionalidade do NetBeans, mas irei pesquisar achei isso muito interessante, quem sabe acabo até migrando para essa IDE.

Muito obrigado pelo lembrete do campo float, realmente não tinha pensado nisso.

Gleidson_Henrique

Utilize ambas… O netbeans é melhor para programar Swing…

O eclipse é melhor para se programar em web… deixe os dois instalados no pc…

Qualquer coisa estamos aqui… só falar…

Abraços

Criado 22 de setembro de 2012
Ultima resposta 23 de set. de 2012
Respostas 3
Participantes 2