Inserir Centavos no DecimalFormat

Caros amigos, é a primeira vez que eu faço uma pergunta e espero estar no lugar certo.
Primeiro quero parabenizar a todos do forum. Para mim este é o melhor do mundo.
Sempre que preciso venho buscar soluções aqui.
Minha dúvida é a seguinte: Consegui formatar um JFormattedTextfield para ficar tipo moeda e ir acrescentado os pontos automaticamente ao digitar. Ele funciona bem, mas da forma como coloquei o DecimalFormat ele não permite inserir os centavos. Não consegui resolver por nada. Por favor me ajudem. Segue o código abaixo…

DecimalFormat decimal = new DecimalFormat ("#,###,###.00");                                         
NumberFormatter numFormatter = new NumberFormatter(decimal); 
numFormatter.setFormat(decimal);   
numFormatter.setAllowsInvalid(false);   //impossibilita digitação diferente de números

            final JFormattedTextField txtValorMerc = new JFormattedTextField();
txtValorMerc.setFormatterFactory(new DefaultFormatterFactory(numFormatter));     
txtValorMerc.setBounds(125,140,110,20);
txtValorMerc.setFont(new Font("Times New Roman",Font.BOLD,14));
this.add(txtValorMerc); // adicionando no JInternalframe...

Do jeito que está o código funciona perfeitamente, porém não consigo adicionar os centavos, pois o “00” é fixo.
E também não funciona se colocar tudo com “#”, já tentei também…

Eu uso dessa maneira:

Então quando eu quero por exemplo colocar o valor 15.250,59, eu digito no campo ‘15250,29’ e quando perde o focus, o valor é transformado.

Abraços!

Valeu ajFilho, já tinha feito isto e realmente funciona, mas eu queria mesmo era já poder digitar o valor na mesma formatação do restante do JTEXTFIELD. Mas mesmo assim valeu por tentar ajudar. Por acaso alguém sabe por que é que quando se muda o “,00” para ## não funciona mais???

Oi Sidney, tenta esse código abaixo e vê se resolve seu problema:

[code]
@SuppressWarnings(“serial”)
public static NumberFormatter getFormatadorDecimal() {
DecimalFormat decimalFormat = new DecimalFormat("###,###,##0.00");
NumberFormatter numberFormat = new NumberFormatter(decimalFormat) {
@Override
public Object stringToValue(String text) throws ParseException {
if (text.equals(“0,00”) || text.equals(“0.00”) || text.equals("")) {
return null;
} else {
return super.stringToValue(text);
}
}
};
numberFormat.setAllowsInvalid(true);

    return numberFormat;       
}[/code]

Até +

Obrigado pela atenção Leandro. É por isso que eu sempre digo que esse é o melhor forum do mundo. A galera sempre tenta ajudar… Vou tentar implementar e depois eu digo o que e consegui… valeu…

tente tb com
DecimalFormat decimalFormat = new DecimalFormat("###,###,###\.##");

Já vi vários outros posts como esse aqui pelo Guj, mas nunca encontrei um interface que se comportasse como eu queria para valores de moeda. Então decidi fazer um TextField que se comportasse de forma parecida ao funcionamento de caixas eletrônicos. Segue o código:

[code]/*Classe desenvolvida por Renzo Nuccitelli

  • para fazer validação de valores monetários

  • em Real
    */
    public class TextFieldMoedaReal extends JTextField implements KeyListener {
    private StringBuilder lastValidNumber;

    /**

    • Aceita um BigDecimal com escala 2.
    • Outras escalas não são serão aceitas
    • @param BigDecimal
      */

    public void setNumber(BigDecimal decimal){
    System.out.println("escala: "+decimal.scale());
    if(decimal.scale()==2){
    lastValidNumber=new StringBuilder(decimal.unscaledValue().toString());
    super.setText(getRealFormat());
    }
    }
    /**Retorna um BigDecimal com o valor encontrando no campo

    • e com escala igual a 2
    • @return BigDecimal
      */
      public BigDecimal getNumber(){
      BigDecimal number;
      if(lastValidNumber.length()==0)
      number=new BigDecimal(“0”);
      else
      number=new BigDecimal(lastValidNumber.toString());
      number.setScale(2);
      return number.divide(new BigDecimal(100));
      }

    /**Aceita valor em centavos.

    • O valor não deve possuir ponto ou vírgula
    • @param String
      */
      public void setText(String number){
      if(isNumber(number))
      lastValidNumber=new StringBuilder(number);
      super.setText(getRealFormat());

    }

    private boolean isNumber(String number){
    for(char c: number.toCharArray()){
    if(!Character.isDigit©)
    return false;
    }
    return true;
    }
    public TextFieldMoedaReal() {
    super();
    this.setCaretPosition(this.getText().length());
    this.addKeyListener(this);
    lastValidNumber=new StringBuilder();
    super.setText(getRealFormat());
    }

    @Override
    public void keyPressed(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {
    if(Character.isDigit(e.getKeyChar())){
    lastValidNumber.append(e.getKeyChar());
    }
    else if(e.getKeyCode()==KeyEvent.VK_BACK_SPACE){
    if(lastValidNumber.length()>0){
    lastValidNumber.deleteCharAt(lastValidNumber.length()-1);
    }
    }

     this.setText(getRealFormat());
    

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    private String getRealFormat(){
    if(lastValidNumber.length()==0)
    return “0,00”;
    else if(lastValidNumber.length()==1)
    return “0,0”+lastValidNumber;
    else if(lastValidNumber.length()==2)
    return “0,”+lastValidNumber;
    else
    return buildPrefixSeparateWithDots()+lastValidNumber.substring(lastValidNumber.length()-2);
    }

    private String buildPrefixSeparateWithDots(){
    StringBuilder builder=new StringBuilder();
    for(int index=0;index<lastValidNumber.length()-2;++index){
    builder.append(lastValidNumber.charAt(index));
    if((lastValidNumber.length()-index)%3==0&&lastValidNumber.length()-index>5)
    builder.append(".");
    }
    builder.append(’,’);
    return builder.toString();
    }

}[/code]

Obrigado Renzo, pra falar a verdade eu pensei que seria mais simples… mas vou tentar assim mesmo… valeu… até mais…

[quote=renzonuccitelli]Já vi vários outros posts como esse aqui pelo Guj, mas nunca encontrei um interface que se comportasse como eu queria para valores de moeda. Então decidi fazer um TextField que se comportasse de forma parecida ao funcionamento de caixas eletrônicos. Segue o código:

[code]/*Classe desenvolvida por Renzo Nuccitelli

  • para fazer validação de valores monetários

  • em Real
    */
    public class TextFieldMoedaReal extends JTextField implements KeyListener {
    private StringBuilder lastValidNumber;

    /**

    • Aceita um BigDecimal com escala 2.
    • Outras escalas não são serão aceitas
    • @param BigDecimal
      */

    public void setNumber(BigDecimal decimal){
    System.out.println("escala: "+decimal.scale());
    if(decimal.scale()==2){
    lastValidNumber=new StringBuilder(decimal.unscaledValue().toString());
    super.setText(getRealFormat());
    }
    }
    /**Retorna um BigDecimal com o valor encontrando no campo

    • e com escala igual a 2
    • @return BigDecimal
      */
      public BigDecimal getNumber(){
      BigDecimal number;
      if(lastValidNumber.length()==0)
      number=new BigDecimal(“0”);
      else
      number=new BigDecimal(lastValidNumber.toString());
      number.setScale(2);
      return number.divide(new BigDecimal(100));
      }

    /**Aceita valor em centavos.

    • O valor não deve possuir ponto ou vírgula
    • @param String
      */
      public void setText(String number){
      if(isNumber(number))
      lastValidNumber=new StringBuilder(number);
      super.setText(getRealFormat());

    }

    private boolean isNumber(String number){
    for(char c: number.toCharArray()){
    if(!Character.isDigit©)
    return false;
    }
    return true;
    }
    public TextFieldMoedaReal() {
    super();
    this.setCaretPosition(this.getText().length());
    this.addKeyListener(this);
    lastValidNumber=new StringBuilder();
    super.setText(getRealFormat());
    }

    @Override
    public void keyPressed(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {
    if(Character.isDigit(e.getKeyChar())){
    lastValidNumber.append(e.getKeyChar());
    }
    else if(e.getKeyCode()==KeyEvent.VK_BACK_SPACE){
    if(lastValidNumber.length()>0){
    lastValidNumber.deleteCharAt(lastValidNumber.length()-1);
    }
    }

     this.setText(getRealFormat());
    

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    private String getRealFormat(){
    if(lastValidNumber.length()==0)
    return “0,00”;
    else if(lastValidNumber.length()==1)
    return “0,0”+lastValidNumber;
    else if(lastValidNumber.length()==2)
    return “0,”+lastValidNumber;
    else
    return buildPrefixSeparateWithDots()+lastValidNumber.substring(lastValidNumber.length()-2);
    }

    private String buildPrefixSeparateWithDots(){
    StringBuilder builder=new StringBuilder();
    for(int index=0;index<lastValidNumber.length()-2;++index){
    builder.append(lastValidNumber.charAt(index));
    if((lastValidNumber.length()-index)%3==0&&lastValidNumber.length()-index>5)
    builder.append(".");
    }
    builder.append(’,’);
    return builder.toString();
    }

}[/code][/quote]

Valeu! :smiley:
Aprovado, funciona perfeitamente!

Olá pessoal, desculpa a ignorância :cry:, mas como eu adiciono esse código ( classe ) no meu código, pois, já tenho o formulário pronto mas não sei como usar esse exemplo passado aqui no meu código, agradeço desde já. :lol:

troque as declarações dos jtextfields que você precisa que sejam do tipo “moeda”, já que:

public class TextFieldMoedaReal extends JTextField 

Por exemplo, se no seu código você tem um JTextField declarado assim:

private JTextField jtfCustoOperacional = …;

troque por

private TextFieldMoedaReal jtfCustoOperacional = …;

Ok, valeu pela ajuda, vou testar aqui. :lol:

Renzo,

Muito obrigado!

Você não sabe o quanto me ajudou! O que eu estava procurando era exatamente uma máscara igual ao dos caixas eletrônicos e como ainda não tenho “cacife” para isso…

enantiomero, naquela ocasião não consegui usar essa classe no meu código, não consegui mudar o que você mandou, pois, aqui no netbeans não consegui achar esse código que você postou aqui:

[quote]Por exemplo, se no seu código você tem um JTextField declarado assim:

private JTextField jtfCustoOperacional = …;

troque por

private TextFieldMoedaReal jtfCustoOperacional = …;[/quote]

e agora preciso usar essa classe em um programa, mas está difícil aqui. Se alguém puder ajudar eu agradeço, valeu.

Boa tarde a todos.

Meu caro amigo Renzonuccitelli.

Voce está de parabéns, essa classe “TextFieldMoedaReal” pra mim caiu como um luva.

Entretanto, precisei fazer uma pequenina correção no código abaixo, pois quando setava o foco no TextField, estava dando erro de “Null Pointer”.

  @Override
  public void setText(String number){  
          if(isNumber(number))  
              lastValidNumber=new StringBuilder(number);  
          super.setText(getRealFormat());  
            
  }

Esse método eu o substitui por este e funcionou beleza.

  @Override
     public void setText(String number){
         if (number==null){  // Aqui que estava dando null pointer
             lastValidNumber=new StringBuilder("");
         } else if(isNumber(number)){
             lastValidNumber=new StringBuilder(number);
         }
         super.setText(getRealFormat());

     }