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);
}
}
