Como usar separadores de milhares

Olá, pessoal,

Estou usando um JTextField, onde eu digito valores monetários grandes, como por exemplo, 4.765.832,53. Apenas para comparar, no Excel a gente digita os números sem precisar digitar os pontos separadores de milhares, apenas digita a vírgula antes das casas decimais, e quando dá enter, o número aparece com os pontos separadores de milhares.

Deixando o Excel para lá, já cansei de Excel, no meu aplicativo Java eu gostaria de poder digitar na minha JTextField os valores sem digitar os pontos, e ao dar enter ver o número com os separadores. Eu já sei que tenho que usar o método

addActionListener

e dentro do método ActionPerformed verificar qual dos componentes disparou o evento através de um ENTER , etc. Essa parte eu saberia fazer.
O que eu não manjo nada é sobre como formatar números para receber separadores de milhares, deve ser através da classe NumberFormat, mas não estou encontrando isso por lá na API.

Quem puder me dar uma ajuda, seria ótimo. Abraço, amigos.
Marco

Olá MarcoSenn,

Tente usar um JFormattedTextField:

JFormattedTextField ftf = new JFormattedTextField(NumberFormat.getNumberInstance());

Até mais,

Fiz essa classe de exemplo aí pra você, vê se ajuda:

[code]package com.jairelton;

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

import javax.swing.JFrame;
import javax.swing.JTextField;

public class Teste1 extends JFrame{
private JTextField campo = new JTextField();
public Teste1(){
setDefaultCloseOperation(EXIT_ON_CLOSE);

	campo.addFocusListener(new FocusAdapter(){
		public void focusLost(FocusEvent fevt){
			JTextField campo = (JTextField)fevt.getSource();
			Formatter formatador = new Formatter();
			formatador.format("%,.2f", Double.parseDouble(campo.getText().replace(',', '.')));
			campo.setText(formatador.toString());
		}
	});
	
	getContentPane().add(campo);
	
	pack();
	setVisible(true);
}
public static void main(String args[]) {
	new Teste1();	
}

}[/code]

O que importa mesmo é o que está no metodo focusLost()…

Ao Jair Elton,

Cara, agradeço muito sua ajuda, mas não estou conseguindo encaixar esse código que você fez expecialmente para mim no meu problema específico. Isto, porque estou com dificuldade de entender o código. Deve ser exatamente isto que você fez, mas sou novato em Java e a coisa tá difícil de entender.

Eu preciso apenas de um código bem simples, uma única JTextField, pode ser em um FlowLayout mesmo, e mais nada, de modo que ao digitar nela um número, como por exemplo, 84543762,75, sem digitar os separadores de milhares, ao dar ENTER, o número formataria para

84.543.762,75 - ou seja, com separadores.

Se não for abusar de sua boa vontade, se você puder mexer naquele código anterior seu , e adapta- lo para isso, eu agradeceria. Se não puder, não esquente, já valeu muito sua colaboração para comigo, aliás você tem me ajudado muito outras vezes!
Abraço,
Marco

Então Marco,

É exatamente isso que o codigo está fazendo, veja que é só um JFrame, pego o JTextField (campo) e adiciono nele, adiciono ao JTextField um FocusListener, para quando ele perder o foco, formatar o numero, então uso um Formatter pra formatar…

o que você precisa é só dessa parte campo.addFocus… é só pegar isso e substituir o campo pelo nome do seu JTextField…

seutextfield.addFocusListener(new FocusAdapter(){ public void focusLost(FocusEvent fevt){ JTextField campo = (JTextField)fevt.getSource(); Formatter formatador = new Formatter(); formatador.format("%,.2f", Double.parseDouble(campo.getText().replace(',', '.'))); campo.setText(formatador.toString()); } });

Ao Jair Elton,

Sobre o assunto como criar separadores de milhares, eu criei uma classe mais simples possível, chamei de Text1.class, com um JTextField apenas, mais nada. Eu desejo escrever números grandes, como por exemplo, o número 32765234,65 , e ao dar enter, ele converteria para

32.765.234,65

Na Text1.class eu apenas tenho um JTextField, mas não faz a conversão. Veja a minha classe:

import java.awt.*;
import javax.swing.*;

public class Text1 extends JFrame 
{
     JTextField T1;
               
      public Text1()
         {
            super("Título");
     
            Container tela = getContentPane();
          
            FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
            tela.setLayout(layout);
       
            JTextField T1 = new JTextField(10);
          
            tela.add(T1);

            setSize(300,100);
            setVisible(true);
        }

     public static void main(String args[])
        {
           Text1 app = new Text1();
           app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
}
      

Com base na sua resposta ao meu pedido de ajuda, eu criei uma outra classe Text2.class, utilizando seu código e coloquei a parte que faz a operação de criar separadores de milhares, e entrei com isto no meu código acima, e virou isto:

import java.awt.*;
import javax.swing.*;
import java.awt.event.FocusAdapter; 
import java.awt.event.FocusEvent; 
import java.util.Formatter;

public class Text2 extends JFrame 
{
     JTextField T1;
               
      public Text2()
         {
            super("Título");
     
            Container tela = getContentPane();
          
            FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
            tela.setLayout(layout);
       
            JTextField T1 = new JTextField(10);
          
            tela.add(T1);

            T1.addFocusListener(new FocusAdapter(){ 
            public void focusLost(FocusEvent fevt){ 
            JTextField T1 = (JTextField)fevt.getSource(); 
            Formatter formatador = new Formatter(); 
            formatador.format("%,.2f", Double.parseDouble(T1.getText().replace(',', '.'))); 
            T1.setText(formatador.toString()); 
         } 
      }); 

            setSize(300,100);
            setVisible(true);
        }

     public static void main(String args[])
        {
           Text2 app = new Text2();
           app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
}
      
  

Mas está dando erro ao tentar compilar a Text2.java. O erro é:

Cannot resolve symbol Formatter.

Se você souber onde está este erro, agradeço Jair.
Abraço,
Marco

public void focusLost(FocusEvent fevt){
JTextField T1 = (JTextField)fevt.getSource();
Formatter formatador = new Formatter();
formatador.format("%,.2f", Double.parseDouble(T1.getText().replace(',', '.')));
T1.setText(formatador.toString()); }
formatador.format("%,.2f", Double.parseDouble(T1.getText().replace(',', '.')));

No seu casso o metodo esta esperando uam string e um object e você esta passando uma String e um Double.

Como resolver? Boa pergunta. Mas talvez com isso você encontre algo.

Ao Rangel,

Agradeço sua explicação, Rangel, entendi parte dela, mas essa coisa tá difícil mesmo, e eu preciso demais encontrar essa saída, porque não tem como o usuário digitar um número grande sem que ele possa ver os separadores de milhares, o número fica confuso.

No Excel, tanto faz o cara digitar sem os pontos, ou com os pontos, ao dar enter, o número aparece com os pontos separadores. Isso tá certo, não pode deixar de ser assim. Mas eu estou com essa dificuldade.

Mas, toda dificuldade tem um ganho, e o ganho é que eu estou caindo dentro dos livros, da API, pra ver se entendo um pouco mais essa linguagem Java!

Valeu sua ajuda, amigo. Abraço
Marco

[quote]Mas está dando erro ao tentar compilar a Text2.java. O erro é:

Cannot resolve symbol Formatter.[/quote]

Falta:

import java.util.Formatter;

Ao Jair Elton,

Não, Jair, o erro que está dando é sobre Formatter, mas eu já havia colocado na minha Text2.class o pacote

import java.util.Formatter;

Veja 3 mensagens acima, nesta mesma página o meu Text2.class, eu já tinha colocado esse pacote como você aconselhou, e o erro continua. Veja abaixo como estou fazendo:

import java.awt.*; 
import javax.swing.*; 
import java.awt.event.FocusAdapter; 
import java.awt.event.FocusEvent; 
import java.util.Formatter; 

public class Text2 extends JFrame 
{ 
     JTextField T1; 
                
      public Text2() 
         { 
            super("Título"); 
      
            Container tela = getContentPane(); 
          
            FlowLayout layout = new FlowLayout(FlowLayout.LEFT); 
            tela.setLayout(layout); 
        
            JTextField T1 = new JTextField(10); 
          
            tela.add(T1); 

            T1.addFocusListener(new FocusAdapter(){ 
            public void focusLost(FocusEvent fevt){ 
            JTextField T1 = (JTextField)fevt.getSource(); 
            Formatter formatador = new Formatter(); 
            formatador.format("%,.2f", Double.parseDouble(T1.getText().replace(',', '.'))); 
            T1.setText(formatador.toString()); 
         } 
      }); 

            setSize(300,100); 
            setVisible(true); 
        } 

     public static void main(String args[]) 
        { 
           Text2 app = new Text2(); 
           app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        } 
} 
      
  

O que pode estar errado neste código?
Marco

Não há nada de errado com a classe, está compilando e funcionando como você quer…

Verifique se você está usando JDK 5.0, a classe java.util.Formatter só existe a partir da versão 5.0, se estiver usando 1.4 terá que usar outra DecimalFormat, ou instalar o 5.0!

Ao Jair Elton,

Então certamente é isso, Jair. Eu instalei o J2SDK-1_4_11.

E agora, como fazer para instalar essa versão 5 ? Basta instalar e ela desinsta-la a anterior 1_4_11?

Provavelmente deve ser preciso configurar novamente CLASSPATH, JAVA_HOME e PATH nas variáveis de ambiente? Sou muito indeciso pra fazer essas coisas, porque não tenho 1 mês de contato com Java.

Como meu J2SDK-1_4_11 funciona perfeitamente, será que não tem um modo de fazer isso usando essa versão?

Obrigado pela ajuda, Jair.
Abraço,
Marco

Ao Jair Elton,

O assunto ainda está rendendo, mas está quase. Eu fiz o que você aconselhou, desinstalei a versão sdk1.4.6_11, e instalei a versão jdk1.5.0_06. Eu uso Windows XP, configurei as variáveis de ambiente através do Painel de Controle, e já está tudo funcionando normalmente, já compilei vários aplicativos pequenos. Mas está acontecendo o seguinte, com esse código Text2.class que eu adaptei da sua mensagem me ajudando, para colocar separadores de milhares. Só para relembrar o código:

import java.awt.*;
import javax.swing.*;
import java.awt.event.FocusAdapter; 
import java.awt.event.FocusEvent; 
import java.util.Formatter;

public class Text2 extends JFrame 
{
     JTextField T1;
               
      public Text2()
         {
            super("Título");
     
            Container tela = getContentPane();
          
            FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
            tela.setLayout(layout);
       
            JTextField T1 = new JTextField(10);
          
            tela.add(T1);

            T1.addFocusListener(new FocusAdapter(){ 
            public void focusLost(FocusEvent fevt){ 
            JTextField T1 = (JTextField)fevt.getSource(); 
            Formatter formatador = new Formatter(); 
            formatador.format("%,.2f", Double.parseDouble(T1.getText().replace(',', '.'))); 
            T1.setText(formatador.toString()); 
         } 
      }); 

            setSize(300,100);
            setVisible(true);
        }

     public static void main(String args[])
        {
           Text2 app = new Text2();
           app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
}
      

Antes, quando eu usava o sdk1.4.6, apresentava erro, não compilava, agora não apresenta mais , roda normal, mas quando eu digito um número na JTextField, exemplo, 67843921,45, e dou ENTER, nada acontece dentro da JTextField, o número permanece o mesmo, sem separadores de milhares, mas se eu clico no Prompt do DOS(que aparece ao lado do aplicativo) aí o número aparece com os separadores de milhares lá na JTextField. Parece uma doideira, mas deve haver um entendimento pra isso! Se puder ajudar, agradeço.
Marco

Aquele codigo da formatação é executado quando o campo perde o foco, como só tem ele dentro do frame, ele só perde o foco quando o frame vai pra segundo plano, não tem nada a ver com a janela do dos, se você clicar em qualquer coisa fora do frame, ele vai fazer isso, se você colocar outro componente no frame, aí você vai ver que ao sair do textfield ele formata…

Entendi perfeitamente, Jair. Vou fazer isto, colocar mais um JTextField ou um JButton, e entendi que ao perder o foco, quer dizer se eu clico em outro componente qualquer, ele acrescenta os formatadores de milhares como você diz.

Acho que esse assunto estamos encerrando, Jair, você me ajudou muito nesse entendimento. Eu só tenho um mês de Java, e me virando como posso, mas sua ajuda tem sido excelente, e eu agradeço demais.

Agora eu tô indo pra outro assunto, que é como gerar um arquivo .jar, para que o usuário clique em um ícone colocado na área de trabalho, e rode o arquivo .class. Vou abrir um tópico porque preciso aprender isto.

Abraço, Jair.
Marco

Pensei que o assunto separadores de milhares estivesse encerrado, mas quando mando a variável digitada na JTextField fazer uma operação matemática com outra variável parece que não está reconhecendo como double, e não efetua o cálculo. Veja o código que coloca os separadores de milhares, e em seguida, eu desejo que aquele valor digitado na JTextField(T1) seja somado com o valor 12.67:


       // aqui coloca separadores de milhares na T1

       T1.addFocusListener(new FocusAdapter()
              { 
                public void focusLost(FocusEvent fevt)
                 { 
                    JTextField T1 = (JTextField)fevt.getSource(); 
                    Formatter formatador = new Formatter(); 
                    formatador.format("%,.2f", Double.parseDouble(T1.getText().replace(',', '.'))); 
                    T1.setText(formatador.toString()); 
                 } 
             }); 

      // aqui ao clicar em um JButton(B1) soma o valor da T1 com 12.67         
      public void actionPerformed(ActionEvent e)
         {
            
            if (e.getSource() == B1 )
              {
                                  
                 String cap = T1.getText();   // captura a String na JTextField T1
                 double C = Double.parseDouble(cap);    //   converte para double C
                 double D = C + 12.67;                                //  soma a double C com 12.67
              } 

Mas não está fazendo essa operação de soma. O código compila mas não realiza a operação. O que pode ser de errado?

Marco

Antes de usar parseDouble() retire os pontos da String e substitua a virgula por ponto…

Entendi, Jair, mas acontece que a JTextField(T1) está com pontos (separadores de milhares) e a vírgula antes da casa decimal, eu não conheço o comando que extrai os pontos, se eu uso replace(’.’ , ’ '), ou seja, trocando ponto por vazio, como faço para fechar o buraco deixado pelo vazio, eu já tinha feito isso mas não deu certo.

Estou entendendo que tenho que usar duas linhas de código:

uma para trocar o ponto por vazio,
e outra para trocar vírgula por ponto.

Mas não sei a primeira operação, tirar o ponto e não ficar um vazio no lugar do ponto.
Abraço,
Marco