Campo Monetario, Dinheiro, Money ;-)

Pessoal… aqui vai uma solução muito boa para
formatação de dinheiro no brasil…
O objetivo deste post é sanar algumas dificuldades
de quem não compreende muito bem o uso de Document
no swing.
E tb para otimização do mesmo por todo o forum

import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;

import javax.swing.JFormattedTextField;
import javax.swing.JTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
import javax.swing.text.SimpleAttributeSet;

/**
 * Component JMoneyField
 * @author Dyorgio da Silva Nascimento
 */
public class JMoneyField extends JFormattedTextField {
    
	private static final long serialVersionUID = -5712106034509737967L;
	private static final SimpleAttributeSet nullAttribute = new SimpleAttributeSet();
	
    /**
     * Creates a new instance of JMoneyField
     */
    public JMoneyField() {
    	this.setHorizontalAlignment( JTextField.CENTER );
    	this.setDocument(new MoneyFieldDocument());
        this.addFocusListener(new MoneyFieldFocusListener());
        this.setText("0,00");
        this.addCaretListener(new CaretListener(){
        	public void caretUpdate(CaretEvent e) {
        		if (e.getDot() != getText().length() ) {
        			getCaret().setDot(getText().length());
        		}
        	}
        });
    }
    
    private final class MoneyFieldFocusListener extends FocusAdapter{
    	public void focusGained(FocusEvent e) {
			selectAll();
		}
    }
    
    private final class MoneyFieldDocument extends PlainDocument {
    	
    	/**
		 * 
		 */
		private static final long serialVersionUID = -3802846632709128803L;

		public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
     		String original = getText(0,getLength());
     		
     		// Permite apenas digitar até 16 caracteres (9.999.999.999,99)
     		if (original.length()&lt16) {
     			StringBuffer mascarado = new StringBuffer();
     			if (a != nullAttribute) {
     				//limpa o campo
     				remove(-1,getLength());
     				
     				mascarado.append((original+str).replaceAll("[^0-9]",""));
         			for (int i = 0; i &lt mascarado.length(); i++){
         				if (!Character.isDigit(mascarado.charAt(i))){
         					mascarado.deleteCharAt(i);
         				}
         			}
         			Long number = new Long(mascarado.toString());
         			
         			mascarado.replace(0, mascarado.length(), number.toString());
         			
         			if ( mascarado.length() &lt 3 )
         			{
	         			if ( mascarado.length() == 1 ) {
	         				mascarado.insert(0,"0");
	         				mascarado.insert(0,",");
	         				mascarado.insert(0,"0");
	         			}else if ( mascarado.length() == 2 ) {
	         				mascarado.insert(0,",");
	         				mascarado.insert(0,"0");
	         			}
         			}else{
         				mascarado.insert(mascarado.length()-2,",");
         			}
         			
         			if ( mascarado.length() &gt 6 ) {
         				mascarado.insert(mascarado.length()-6, '.');
         				if (mascarado.length() &gt 10 ) {
         					mascarado.insert(mascarado.length()-10, '.');
         					if (mascarado.length() &gt 14 ) {
             					mascarado.insert(mascarado.length()-14, '.');
         					}
         				}
         			}
         			super.insertString(0, mascarado.toString(), a);
     			}else{
     				if (original.length() == 0){
     					super.insertString(0, "0,00", a);
     				}
     			}
     		}
     	}
    	
    	@Override
    	public void remove(int offs, int len) throws BadLocationException {
    		if ( len == getLength() ) {
    			super.remove(0, len);
    			if (offs != -1){
	    			insertString(0, "",nullAttribute);
    			}
    		}else{
    			String original = getText(0, getLength()).substring(0, offs) + getText(0, getLength()).substring(offs+len);
    			super.remove(0, getLength());
    			insertString(0,original,null);
    		}
    	}
    }
}

Muito bom! Parabens pela iniciativa! :smiley:

Ate…
:thumbup:

Poxa pessoal, estou desapontado…ninguem melhorou o código
será que já esta BEST OF THE BEST?

dyorgio, seu exemplo é bom, eu mesmo tenho algo muito parecido, só que se chama JRealField.O problema, é quando vc precisa de dois atributos inerentes a um Document.Veja meu problema aqui: http://www.guj.com.br/posts/list/72977.java
Eu tenho um campo, que conforme o usuário vai digitando, esse conteúdo é passado a uma fórmula, e atualiza um outro campo.Nessa fórmula podem haver 3 campos relacionados para atualizar um 4 campo.Sem formatação, fica “fácil”, pq eu uso o DocumentListener para atualizar o outro campo.Com formatação, o plaindocument funciona OK, mas a atualização dinâmica é perdida.Ou seja, um componente com o melhor dos dois mundos, sem UmzilhãoDeErrosDeFormataçãoException seria perfeito. :smiley:

amigo,

estou com problema nesta linha

        if (original.length()&lt16) {  

meu netbeans diz

C:\enviar\JMoney\src\JMoneyField.java:55: warning: unmappable character for encoding UTF-8
// Permite apenas digitar at? 16 caracteres (9.999.999.999,99)
^
C:\enviar\JMoney\src\JMoneyField.java:56: cannot find symbol
symbol : variable lt16
location: class JMoneyField.MoneyFieldDocument

como resolver?

Dario

[quote=cardosodario]amigo,

estou com problema nesta linha

        if (original.length()&lt16) {  

(…)
como resolver?
[/quote]

O operador & lt não existe.

            if (original.length() < 16) {  

blz

agora eu preciso saber como que eu faço para linkar ele no meu JTextField

tipo, to no netbeans criei o JMoneyField e coloquei o codigo, agora to criando um JFrame coloquei um JTextField e como eu linko ele pra usar este JMoneyField?

dario

[quote=dyorgio]Poxa pessoal, estou desapontado…ninguem melhorou o código
será que já esta BEST OF THE BEST?
[/quote]

o seu exemplo tah muito bom mesmo, parabéns !

eu fiz um component parecidissimo para um framework q estou a liberar …

eu acrescentei uma calculadorinha para o component quando o campo ganhar um double-clique.

vc termina e manda novamente ?

qq coisa estou à disposição!

Amigos,

Alguem pode me passar um exemplo em JAVA de como implementar o codigo acima?

Dario

para implementá-lo basta fazer assim?

JMoneyField mf = new JMoneyField(); mf.setValue(FieldValor.getText().toString());

nao consegui fazer dar certo…

se alguém souber posta ai…

valeu

Pode ser algo do tipo:

    JFormattedTextField mf = new JMoneyField();  
    mf.setValue(new Double(FieldValor));  

É bom vc lembrar que setValue recebe um Object

http://download.oracle.com/javase/7/docs/api/javax/swing/JFormattedTextField.html#setValue(java.lang.Object)

:wink:

[quote=dyorgio]Pessoal… aqui vai uma solução muito boa para
formatação de dinheiro no brasil…
O objetivo deste post é sanar algumas dificuldades
de quem não compreende muito bem o uso de Document
no swing.
E tb para otimização do mesmo por todo o forum

import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;

import javax.swing.JFormattedTextField;
import javax.swing.JTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
import javax.swing.text.SimpleAttributeSet;

/**
 * Component JMoneyField
 * @author Dyorgio da Silva Nascimento
 */
public class JMoneyField extends JFormattedTextField {
    
	private static final long serialVersionUID = -5712106034509737967L;
	private static final SimpleAttributeSet nullAttribute = new SimpleAttributeSet();
	
    /**
     * Creates a new instance of JMoneyField
     */
    public JMoneyField() {
    	this.setHorizontalAlignment( JTextField.CENTER );
    	this.setDocument(new MoneyFieldDocument());
        this.addFocusListener(new MoneyFieldFocusListener());
        this.setText(&quot;0,00&quot;);
        this.addCaretListener(new CaretListener(){
        	public void caretUpdate(CaretEvent e) {
        		if (e.getDot() != getText().length() ) {
        			getCaret().setDot(getText().length());
        		}
        	}
        });
    }
    
    private final class MoneyFieldFocusListener extends FocusAdapter{
    	public void focusGained(FocusEvent e) {
			selectAll();
		}
    }
    
    private final class MoneyFieldDocument extends PlainDocument {
    	
    	/**
		 * 
		 */
		private static final long serialVersionUID = -3802846632709128803L;

		public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
     		String original = getText(0,getLength());
     		
     		// Permite apenas digitar até 16 caracteres (9.999.999.999,99)
     		if (original.length()&lt16) {
     			StringBuffer mascarado = new StringBuffer();
     			if (a != nullAttribute) {
     				//limpa o campo
     				remove(-1,getLength());
     				
     				mascarado.append((original+str).replaceAll(&quot;[^0-9]&quot;,&quot;&quot;));
         			for (int i = 0; i &lt mascarado.length(); i++){
         				if (!Character.isDigit(mascarado.charAt(i))){
         					mascarado.deleteCharAt(i);
         				}
         			}
         			Long number = new Long(mascarado.toString());
         			
         			mascarado.replace(0, mascarado.length(), number.toString());
         			
         			if ( mascarado.length() &lt 3 )
         			{
	         			if ( mascarado.length() == 1 ) {
	         				mascarado.insert(0,&quot;0&quot;);
	         				mascarado.insert(0,&quot;,&quot;);
	         				mascarado.insert(0,&quot;0&quot;);
	         			}else if ( mascarado.length() == 2 ) {
	         				mascarado.insert(0,&quot;,&quot;);
	         				mascarado.insert(0,&quot;0&quot;);
	         			}
         			}else{
         				mascarado.insert(mascarado.length()-2,&quot;,&quot;);
         			}
         			
         			if ( mascarado.length() &gt 6 ) {
         				mascarado.insert(mascarado.length()-6, '.');
         				if (mascarado.length() &gt 10 ) {
         					mascarado.insert(mascarado.length()-10, '.');
         					if (mascarado.length() &gt 14 ) {
             					mascarado.insert(mascarado.length()-14, '.');
         					}
         				}
         			}
         			super.insertString(0, mascarado.toString(), a);
     			}else{
     				if (original.length() == 0){
     					super.insertString(0, &quot;0,00&quot;, a);
     				}
     			}
     		}
     	}
    	
    	@Override
    	public void remove(int offs, int len) throws BadLocationException {
    		if ( len == getLength() ) {
    			super.remove(0, len);
    			if (offs != -1){
	    			insertString(0, &quot;&quot;,nullAttribute);
    			}
    		}else{
    			String original = getText(0, getLength()).substring(0, offs) + getText(0, getLength()).substring(offs+len);
    			super.remove(0, getLength());
    			insertString(0,original,null);
    		}
    	}
    }
}

[/quote]

resolveu meu problema, vlw

[size=18]dyorgio [/size] Obrigado!!!

Resolveu meu problema!!

Boa Tarde achei bacana este código, estou usando é muito legal!

uma pergunta como que faço para adicionar da começo R$?

Funcionou perfeitamente, mais eu to com um pequeno problema, to fazendo um sistema para uma pizzaria, e quando cadastro uma pizza os dados dela são salvos um JTableModel, que seria o cardápio, se eu salvo uma pizza com um valor quebrado tipo, 22,35 salva normalmente, até ai tudo bem, o problema é q se eu salvo com um valor tipo 22,00, ele arredonda e salva como 22 sem os zeros, acredito que uma simples mexida no código deve resolver, mais não sei como fazer, alguém poderia fazer isso pra mim e me mandar a alteração no código, seria de grande ajuda, grato deis de já.

Sei que o post é velho mas resolvi assim o meu problema:

Para a entrada do usuário

Para receber de uma variável float/double:

Olá,

Em todas as partes onde tinha o “quot” apareceu erros no programa. Algué sabe o que pode ser?

Desde já agradeço!

Att,