Jformattedtextfield

4 respostas
jonasjgs2

fiz um jformattedtextfield e acho que ficou muito bom..
estou disponibilizando eles aqui para vcs....
ele pode ser colocado na paleta do netbeans e ser utilizando normalmente...
funciona da seguinte maneira:
ele tem tres propriedades e todas elas aparecem nas propriedades do netbeans normalmente...

propriedades:
numeroformato - onde vc passa a mascara desejada... a mascara deve ser #####.## ou -#####.##
esta propriedade faz com que sejam aceitos apenas numeros com a quantidade de # desejada e a quantidade de decimais conforme a mascara...
stringqtdchar - utilizada se o campo for uma string... e tratalha junto com a propriedade partipochar..
partipochar - 0-minusculas e maiusculas 1-apenas minusculas 2-apenas maiusculas 3 apenas numeros

ela tambem tem os metodos getDouble e getLong para facilitar a conversao dos valores do texto digitado...
ficou muito legal e como eu utilizo muito o forum aqui...
resolvi disponibilizar para todos...

para colocar ela no netbeans deve-se criar um projeto gerar o .jar e adicionar o jar na paleta do netbens...
acho que a maior dificudade do java e tratar campos .... entao resolvi disponibilizar ela para vcs...

aceito sugestoes de melhoria...
e aparentemente ela esta funcionando perfeitamente...

segue abaixo o codigo...

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package objetos;

import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import javax.swing.JFormattedTextField;
import javax.swing.JTextField;

/**
 *
 * @author Admin
 */
public class MasterText extends JFormattedTextField {

    private DecimalFormat df = new DecimalFormat();
    private boolean ParNumerico;
    private boolean ParSinal;
    private int ParTipoChar = 0;
    private int ParQtdCol;
    private int ParQtdInt;
    private int ParQtdDec;

    public MasterText() {
        super();
        AtivaEventos();
    }

    /**
     * Metodo Para Setar o Uso de Numeros No Componente
     *
     * @param formato formato do campo numerico. cacteres aceitos: "#,-"
     */
    public void setNumeroFormato(String formato) {
        if (formato.indexOf("#") == -1) {
            return;
        }
        SetaNumero(formato);

    }

    /**
     * Metodo Para Setar o Uso de Strings No Componente
     *
     * @param QtdCaracteres
     * @param TipoCaracter 0 - String mista 1 - String minúscula 2 - String
     *                     3 - apenas numeros
     * maiúscula
     */
    public void setStringQtdChar(int QtdCaracteres) {
        if (QtdCaracteres==0) {
            return;
        }
        ParNumerico = false;
        ParQtdCol = QtdCaracteres;
    }

    private void AtivaEventos() {
        this.addFocusListener(new FocusListener() {
            @Override
            public void focusLost(FocusEvent evt) {
                thisFocusLost(evt);
            }

            @Override
            public void focusGained(FocusEvent e) {
                MasterText.this.setForeground(null);
            }
        });

        this.addKeyListener(new java.awt.event.KeyAdapter() {
            @Override
            public void keyTyped(java.awt.event.KeyEvent e) {
                char k = e.getKeyChar();
                int i = k;
                e.setKeyChar(k);
                if (ParNumerico) {
                    if (!isNumeroAceito(e)) {
                        e.setKeyChar((char) KeyEvent.VK_CLEAR);
                    }
                } else {
                    if (!isStringAceita(e)) {
                        e.setKeyChar((char) KeyEvent.VK_CLEAR);
                    }
                }
            }
        });
    }

    private void SetaNumero(String formato) {
        int len = formato.length();

        int virgula = 1;
        int sinal = 1;
        int pv = 0;

        int i = formato.indexOf(".");
        if (i == -1) {
            i = formato.indexOf(",");
            if (i == -1) {
                i = 0;
                virgula = 0;
            }
            pv = i;
        }
        i = formato.indexOf("-");
        ParSinal = true;
        if (i == -1) {
            sinal = 0;
            ParSinal = false;
        }

        ParNumerico = true;
        ParQtdCol = len - virgula - sinal;
        ParQtdInt = pv - sinal;
        if (pv == 0) {
            ParQtdInt = ParQtdCol;
        }
        ParQtdDec = ParQtdCol - ParQtdInt;

        PreparaNumero();

    }

    private boolean isNumeroAceito(java.awt.event.KeyEvent e) {
        char c = e.getKeyChar();

        // se nao for numero nem ponto nem virgula retornar false

        if (c < 48 || c > 57) {
            if (c < 43 || c > 46) {
                return false;
            }
        }

        // substituindo a virgula por ponto
        if (c == 46) {
            c = 44;
            e.setKeyChar(c);
        }

        // se nao exitir casas decimais nao deve aceitar ponto
        if (ParQtdDec == 0) {
            if (c == 44) {
                return false;
            }
        }

        // se nao aceitar sinal nao deve aceitar + nem -
        if (!ParSinal) {
            if (c == 43 || c == 45) {
                return false;
            }
        }

        // se ja existir ponto decimal e foi digitado ponto nao permitir
        if (ParQtdDec != 0 && c == 44) {
            CharSequence cs = ",";
            if (getText().contains(cs)) {
                return false;
            }
        }

        int sinal = 0;
        int virgula = 0;

        if (getText().indexOf(",") != -1) {
            virgula = 1;
        }
        if (getText().indexOf("-") != -1) {
            sinal = 1;
        }


        if (getText().length() >= (ParQtdCol + sinal + virgula)) {
            return false;
        }

        return true;
    }

    private boolean isStringAceita(java.awt.event.KeyEvent e) {
        char c = e.getKeyChar();

        if (getText().length() >= ParQtdCol) {
            return false;
        }

        if (ParTipoChar == 1) {
            if (c >= 65 && c <= 90) {
                c = (char) (c + (char) 32);
                e.setKeyChar(c);
                return true;
            }
        }
        if (ParTipoChar == 2) {
            if (c >= 97 && c <= 122) {
                c = (char) (c - (char) 32);
                e.setKeyChar(c);
                return true;
            }
        }

        if (ParTipoChar == 3) {
            if (c < 48 || c > 57) {
                return false;
            }

        }
        return true;
    }

    private void thisFocusLost(FocusEvent evt) {
        if (ParNumerico) {
            String s = this.getText();
            int i = s.indexOf(",");
            int l = s.length();
            if (i < 0) {
                i = 0;
            }
            int qi = l - i;
            int dif = qi - ParQtdInt;
            String s2 = s;
            if (qi > ParQtdInt) {
                Erro();
                if (s.substring(0, 1).equals("-")) {
                    s2 = "-" + s2.substring(dif, s2.length());
                } else {
                    s2 = s2.substring(dif, s2.length());
                }
            }
            double d;
            try {
                d = Double.parseDouble(s2.replace(",", "."));
            } catch (NumberFormatException e) {
                Erro();
                d = 0;
            }
            this.setText(df.format(d).replace(",", "."));
        }
    }

    private void Erro() {
        this.setForeground(Color.red);
    }

    @Override
    public void setText(String text) {
        if (ParNumerico) {
            double d;
            try {
                d = Double.parseDouble(text);
            } catch (NumberFormatException e) {
                d = 0;
            }
            super.setText(df.format(d).replace(".", ","));

        } else {
            super.setText(text);
        }
    }

    public double getDouble() {
        double d;
        try {
            d = Double.parseDouble(this.getText().replace(",", "."));
        } catch (NumberFormatException e) {
            d = 0;
        }

        return d;
    }

    public long getLong() {
        double d;
        try {
            d = Double.parseDouble(this.getText().replace(",", "."));
        } catch (NumberFormatException e) {
            d = 0;
        }
        return (long) d;
        
    }

    public int getParTipoChar() {
        return ParTipoChar;
    }

    public void setParTipoChar(int ParTipoChar) {
        this.ParTipoChar = ParTipoChar;
//        this.setDocument(new DocumentStringX(ParQtdCol, ParTipoChar));
    }

    private void PreparaNumero() {
        ParQtdInt = ParQtdCol - ParQtdDec;
        this.setHorizontalAlignment(JTextField.RIGHT);
        df.setRoundingMode(RoundingMode.UP);
        String s = GeraMascara();
        df.applyPattern(s);
    }

    private String GeraMascara() {
        int i = 5;
        int d = 0;

        String ni = "";

        for (int a = 0; a < ParQtdInt - 1; a++) {
            ni = ni + "#";
        }

        String nd = "";

        if (ParQtdDec != 0) {
            if (ParQtdInt != 0) {
                nd = "0.";
            } else {
                nd = ".";
            }
            for (int a = 0; a < ParQtdDec; a++) {
                nd = nd + "0";
            }
        } else {
            if (ParQtdInt != 0) {
                ni = ni + "0";
            }
        }


        String s = ni + nd;

        if (ParSinal) {
            return s + ";-" + s;
        } else {
            return s;
        }
    }
}

4 Respostas

gabrielemidio

jonasjgs2, não seria mais viável utilizar um Document em suas JTextField?

Não sei se você já chegou a ler esse artigo.

Controlando um JTextField : http://www.guj.com.br/articles/29

abraços
:smiley:

jonasjgs2

eu ja tentei com document…
o problema e que tem varias situacoes…
como digitar a direita para numeros,
a esquerda para strings,
e outros pontos
e esta classe quando eu seto numero ou string
ja faz isso diretamente pra mim…
achei que ficou mais simples…

gabrielemidio

Compreendo.

WellingtonRamos

Apesar de desenvolver utilizando um Document ser um pouco mais complexo, ele deixa teu componente muito mais profissional e menos propenso a erros quando você utiliza outros listeners (especialmente os do mesmo tipo que você usou).

Passei a usar exclusivamente Document para máscara após ter enfrentado uma série de problemas quando precisava de um campo formatado e que tivesse comportamentos específicos usando KeyListeners e FocusListeners. As ações do Document ocorrem antes de ocorrer, de fato, a chamada aos listeners, o que melhorou muito o tratamento.

Sobre teu código, notei que você usa nomes de atributos iniciados em maiúscula e as boas práticas “ditadas” para quem desenvolve com java dizem para que iniciem em minúscula.

Criado 16 de janeiro de 2013
Ultima resposta 16 de jan. de 2013
Respostas 4
Participantes 3