Ajuda para terminar uma Classe oriunda de PlainDocument!

6 respostas
anjomal

Ai galera estou fazendo um classe que extende PlainDocument so que alem de limitar caratcteres, ele tb tem uma funções para so aceitar NUMEROS, ou so ALFA,entradas Somente MAIUSCULAS ou MINUSCULAS, minha duvida e na implementação da função de so aceitar numeros ou so alfa, em C/C++ eu trasformava o caracter em ascii e verificava seu intervalo para determinar se ele era um numero ou não em JAVA ou não sei como fazer isso ? ai galera da uma ajudinha, segue o codigo fonte abaixo, podem copiar e GPL :smiley: !!!

/*
 * DocumentPro.java
 *
 * Created on 29 de Janeiro de 2003, 09:10
 */

package util;

/**
 *
 * @author  William J. Oliveira
 */

import javax.swing.*;
import javax.swing.text.*;

public class DocumentPro extends PlainDocument {
    
    public static final int NORMAL      = 0;
    public static final int NUMERICO    = 1;
    public static final int TEXTO       = 2;
    public static final int MAIUSCULA   = 3;
    public static final int MINUSCULA   = 4;
    
    private int iMaxLength;
    private int iTipo;
    
    public DocumentPro() {
        super();
        this.iMaxLength = 0;
        this.iTipo = 0;
    }
    
    public DocumentPro(int maxlen) {
        super();
        this.iMaxLength = maxlen;
        this.iTipo = 0;
    }
    
    public DocumentPro(int maxlen, int tipo) {
        super();
        this.iMaxLength = maxlen;
        this.iTipo = tipo;
    }
    
    public void setMaxlen(int maxlen){
        iMaxLength = maxlen;
    }
    
    public int gettMaxlen(){
        return this.iMaxLength;
    }
    
    public void setTipo(int tipo) {
        this.iTipo = tipo;
    }
    
    public int getTipo() {
        return this.iTipo;
    }
    
    public void insertString(int offset, String str, AttributeSet attr)
    throws BadLocationException    {
        if (str == null) return;
        
        switch(this.iTipo) {
            case 0:                
                break;
            case 1:                
                break;
            case 2:
                break;
            case 3:                
                str=str.toUpperCase();
                break;
            case 4:
                str=str.toLowerCase();
                break;
        }
        
        if (iMaxLength <= 0) // aceitara qualquer no. de caracteres
        {
            super.insertString(offset, str, attr);
            return;
        }
        
        int ilen = (getLength() + str.length());
        if (ilen <= iMaxLength){ // se o comprimento final for menor...
            super.insertString(offset, str, attr); // ...aceita str
        } else {
            if (getLength() == iMaxLength) return; // nada a fazer
            String newStr = str.substring(0, (iMaxLength - getLength()));
            
        }
        
    }
}

falow

6 Respostas

dukejeffrie

Fala, Anjomal!!

A API tem uma classe java.lang.Character, que tem métodos para detectar esse tipo de coisa. Por exemplo, isDigit(), e isLetterOrDigit.

Aliás, muito legal a sua idéia, vou te dar uma dica OO: construa a classe de movo que vc use um método para detectar se um caractere vale ou não. Assim, vc pode fazer subclasses, por exemplo, que aceitem conjuntos estranhos de caracteres. Ou vc pode delegar para uma interface “DocumentProFilter”, na linha do que acontece com o JFormattedTextField e seus Formatters.

Aquelão!!

mlopes

Seria legal tb se pudesse passar um mapa com alguns characteres proibidos.
Vc permitiria coisas como por exemplo Normal - %, ^, $

[]'s

dukejeffrie

Então, Marco,

a idéia é que em algum lugar do método insert tenha um código como o abaixo:

if (allowChar(ch)) {
     // insere
   }

O método allowChar() pode ser abstrato na mesma classe DocumentPro. Pode ser um método concreto, que sempre retorna true, como a implementação default (o que o iguala ao PlainDocument).

Podemos ter, por outro lado, uma interface assim:

public interface DocumentProFilter {

  public boolean allowChar(char ch);
}

E lá no DocumentPro teríamos:

if (filter.allowChar(ch)) {
    // insere
  }

O filtro pode ser criado dinamicamente, até, como a gente faz com Runnables:

DocumentPro dp = new DocumentPro();
   dp.setfilter(new DocumentProFilter() {
     public static final String forbiddenChars = "%^$";
     public boolean allowCharchar ch) {
        return (forbiddenChars.indexOf(ch) < 0);
     }
   });

eu acho que fica muito maleável…

[]s!

mlopes

Concordo,

Já até tinha feito isso numa versão modificada do FixedLengthDocument que foi apresentada aqui.

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


/**
 * Creates a fixed length string Document model to be used with JTextComponent. <br />
 * This document will limit the number of characters that the user can insert in the
 * JTextComponent. <br />
 * Example:
 * <xmp>
 * import java.awt.*;
 * import java.awt.event.*;
 * import javax.swing.*;
 *
 * public class Test
 * {
 *     public static void main(String[] args)
 *     {
 *         JFrame f = new TestFrame();
 *         f.setVisible(true);
 *     }
 * }
 *
 * class TestFrame extends JFrame
 * {
 *     private JTextField textField;
 *
 *     public TestFrame()
 *     {
 *         this.setTitle("Example");
 *         this.setSize(200, 180);
 *
 *         this.addWindowListener(new WindowAdapter() {
 *             public void windowClosing(WindowEvent e) {
 *                 System.exit(0);
 *             }
 *         });
 *
 *         textField = new JTextField(10); // 10 columns
 *
 *         // here we change the document, it will accept a maximum of 5 numbers.
 *
 *         textField.setDocument(new FilterDocument(5), new IDocumentFilter() {
 *                     public boolean isCharacterValid(char character) {
 *                         return Character.isDigit(character);
 *                     }
 *             });
 *
 *         this.getContentPane().add(textField, "South");
 *     }
 * }
 * </xmp>
 * <p> When used together with a IDocumentFilter, this document will filter all invalid
 * entered strings. If the String comes with length > 1, for example from a paste and at least one
 * character is not valid, The string won't be pasted at all. </p>
 * @see javax.swing.text.JTextComponent#setDocument
 * @see javax.swing.JTextField
 */
public class FilterDocument
	extends PlainDocument
{
	/** the filter for the characteres */
	private IDocumentFilter documentFilter;

	/**
	 * keeps the maximum number of allowed characters
     */
	private int maxLength;

	/**
	 * creates a new FilterDocument with no limit.
	 */
	public FilterDocument()
	{
		this(-1);
	}

	/**
	 * creates a new FilterDocument that will limit the user input
	 * to a number of maxlen characters.
     * @param maxlen the maximum length of the inserted characters.
     */
	public FilterDocument(int maxlen)
	{
		this(maxlen, null);
	}

	/**
	 * creates a new FilterDocument that will limit the user input
	 * to a number of maxlen characters.
	 * @param maxlen the maximum length of the inserted characters.
	 * @param documentFilter the filter for the characteres.
	 */
	public FilterDocument(int maxlen, IDocumentFilter documentFilter)
	{
		super();
		maxLength = maxlen;
		this.documentFilter = documentFilter;
	}

	/**
	 * Sets the allowed max length of the string.
	 * @param maxLength the allowed max length of the string.
	 */
	public void setMaxLength(int maxLength)
	{
		this.maxLength = maxLength;
	}

	/**
	 * Returns the max length of the string.
	 * @return int the allowed max length of the string.
	 */
	public int getMaxLength()
	{
		return maxLength;
	}

	/**
	 * @see javax.swing.text.Document#insertString(int, String, AttributeSet)
	 * @param offset the starting offset >= 0
	 * @param str the string to insert; does nothing with null/empty strings
	 * @param attr the attributes for the inserted content
	 * @throws BadLocationException  If the given insert position is not a valid
	 *   position within the document     
     */
	public void insertString(int offset, String str, AttributeSet attr)
		throws BadLocationException
	{
		if (str == null) {
			return;
		}

		if (maxLength <= 0) // accept any number of characteres
		 {
			super.insertString(offset, checkString(str), attr);

			return;
		}

		int ilen = (getLength() + str.length());

		if (ilen <= maxLength) { // if the final length is longer
			super.insertString(offset, checkString(str), attr); // accept str
		} else {
			if (getLength() == maxLength) {
				return; // nothing to do
			}

			String newStr = str.substring(0, (maxLength - getLength()));

			super.insertString(offset, checkString(newStr), attr);
		}
	}

	/**
	 * Checks if the caracters in this String is valid accordingly to the IDocumentFilter.
     * @param toCheck The string to be checked.
     * @return the full string if all caracters are valid, an empty string otherwise.
     */
	private String checkString(String toCheck)
	{
		if (documentFilter != null) {
			char[] allChar = toCheck.toCharArray();

			for (int i = 0; i < allChar.length; i++) {
				if (documentFilter.isCharacterValid(allChar[i]) == false) {
					return "";
				}
			}
		}

		return toCheck;
	}

Aqui vai a interface:

/**
 * Interface to be used to filter valid strings in a LSFilterDocument
 * @author Last modified by $Author: mlopes $
 * @version $Revision: 1.1 $
 * @see LSFilterDocument
 */
public interface IDocumentFilter
{
	/**
	 * returns true if the input character is a valid one
	 * @param character the character to be checked
	 * @return true if the input character is a valid one
	 */
	boolean isCharacterValid(char character);
}

[]'s

anjomal

Ae galera firmão !!! ai vai a ultima implementação da Classe DocumentPro, mais ideias avise !!!

/*
 * DocumentPro.java
 *
 * Created on 29 de Janeiro de 2003, 09:10
 */

package util;

/**
 *
 * @author  William J. Oliveira
 */

import javax.swing.*;
//import java.lang.Character.*;
import javax.swing.text.*;

public class DocumentPro extends PlainDocument {
    
    public static final int NORMAL      = 0;
    public static final int NUMERICO    = 1;
    public static final int CHARMAP     = 2;
    public static final int MAIUSCULA   = 3;
    public static final int MINUSCULA   = 4;
    
    private int iMaxLength;
    private int iTipo;
    private char[] charMap;
    
    public DocumentPro() {
        super();
        this.iMaxLength = 0;
        this.iTipo = 0;
    }
    
    public DocumentPro(int maxlen) {
        super();
        this.iMaxLength = maxlen;
        this.iTipo = 0;
    }
    
    public DocumentPro(int maxlen, int tipo) {
        super();
        this.iMaxLength = maxlen;
        this.iTipo = tipo;
    }

    public DocumentPro(int maxlen, int tipo, char[] ch) {
        super();
        this.iMaxLength = maxlen;
        this.iTipo = tipo;
        this.charMap=ch;
    }
    
    public void setMaxlen(int maxlen){
        iMaxLength = maxlen;
    }
    
    public int gettMaxlen(){
        return this.iMaxLength;
    }
    
    public void setTipo(int tipo) {
        this.iTipo = tipo;
    }
    
    public int getTipo() {
        return this.iTipo;
    }
    
    public void setCharMap(char[] ch) {
        this.charMap=ch;
    }
    
    public char[] getCharMap() {
        return this.charMap;
    }
    
    public void insertString(int offset, String str, AttributeSet attr)
    throws BadLocationException    {
        
        if (str == null) return;                    
    
        
        switch(this.iTipo) {
            case 0:                
                break;
            case 1:                
               {
                Character ch=new Character(str.charAt(0));                        
                if (!ch.isDigit((str.charAt(0)))) return;
                break;
               } 
            case 2:
                if(!existCharMap(str)) return;
                break;
            case 3:                
                str=str.toUpperCase();
                break;
            case 4:
                str=str.toLowerCase();
                break;
        }
        
        if (iMaxLength <= 0) // aceitara qualquer no. de caracteres
        {
            super.insertString(offset, str, attr);
            return;
        }
        
        int ilen = (getLength() + str.length());
        if (ilen <= iMaxLength){ // se o comprimento final for menor...
            super.insertString(offset, str, attr); // ...aceita str
        } else {
            if (getLength() == iMaxLength) return; // nada a fazer
            String newStr = str.substring(0, (iMaxLength - getLength()));
            
        }
        
    }
    
    protected boolean existCharMap(String str) {
        for(int i=0;i<this.charMap.length;i++) {           
           if(str.indexOf(charMap[i])>=0) return true;                  
        }
        
        return false;
    }
}

Falow !!!

dukejeffrie

Verdade!!

Eu acabei usando o FixedLengthDocument aqui no trabalho, só tive que adaptá-lo para… só contar números!!

Pq acontecia o seguinte: eu queria um campo com 12 dígitos (um telefone). Só que era um JFormattedTextField, que acabava inserindo dois hífens na string, e eu acabava perdendo os dois últimos dígitos. Fiz uma adaptação do FixedLengthDocument para só incrementar o count se o caractere fosse um dígito.

Rolou legal!!

[]s

Criado 29 de janeiro de 2003
Ultima resposta 30 de jan. de 2003
Respostas 6
Participantes 3