Como pegar um valor digitado num JTextField?

Pessoal primeiro vou explicar meu projeto, assim qualquer duvida que tiver eu pergunta nesse tópico mesmo.

È o seguinte, o professor quer que eu faça uma interface com dois botões, e uma caixa de texto, um botão é o “gerar número aleatório”. Na caixa de texto o usuário vai digitar um numero de 1 a 100, se o número estiver longe do que foi gerado aleatoriamente eu mudo a cor do background da janela para azul simbolizando está frio, se estiver perto eu mudo a cor do background para vermelho simbolizando esta quente. :smiley: além disso eu tenho que tratar as exceções, se por exemplo o usuário colocar uma letra no lugar de um número ou um número maior que 100.
.
Uma dúvida que surgiu é como eu vou ler oque o usuário colocar no TextField? Eu estava pensando em ler o valor que o usuário colocou no TextField no evento do segundo botão(botão OK). O usuário digita o valor e clica no botão Ok, aí no evento eu pego o número e também comparo com o que foi gerado aleatoriamente. Mais o meu problema é mesmo como pegar o valor digitado. Alguém tem uma dica?
.
Olha como ficou a parte gráfica:
.
http://img816.imageshack.us/img816/4336/jogoadivinhacao.jpg

Olha oque eu fiz até agora no programa:

Esta primeira classe é a interface propriamente dita:

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AdvinhaNum extends MyActionListener
	
	{
	public static void main(String[] args) {
			JFrame frame = new JFrame("Jogo: Advinhação"); 
			JPanel pane = new JPanel(); 
			JButton button1 = new JButton("Gerar Número");
			JTextField text = new JTextField(4);
			/*text.setEnabled(false);*/ 
			JButton button2 = new JButton("OK");
			JLabel label = new JLabel("Existe um número de 1 a 100, tente advinhar qual:");
			
		 	pane.setLayout(new FlowLayout(FlowLayout.CENTER,4,4));
		 	
		 	pane.add(button1);
		 	ActionListener listener2 = new MyActionListener();
			button2.addActionListener(listener2);
		 	pane.add(label);
		 	pane.add(text);
		 	pane.add(button2);
		 	ActionListener listener = new MyActionListener2();
		 	button1.addActionListener(listener);
		 	pane.setBackground(Color.orange);
		 	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		 	
		 	frame.getContentPane().add(pane);
	        frame.pack(); frame.setVisible(true);

		}
	}
	

Aqui criei duas classes para tratar os eventos:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextField;

public class MyActionListener implements ActionListener {
	public static void pegarValorTextField(JTextField text) {
		System.out.println(text.getText());
	}
	public void actionPerformed(ActionEvent event) {
		MyActionListener t = new MyActionListener();
		t.pegarValorTextField(text);
		System.out.println("Está bem frio");
		}
			
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class MyActionListener2 extends NoAleatorio implements ActionListener{

	public void actionPerformed(ActionEvent event) {
		NoAleatorio N = new NoAleatorio();
		N.gerarNoAleatorio();    
  }
	
}

Aqui criei uma classe só para gerar um número aleatório:

public class NoAleatorio {

	public void gerarNoAleatorio() {
		int x = (1 + (int) (Math.random () * 100));
		System.out.println( "o número é: "+x);
		}
	public static void main(String[] args) {
		NoAleatorio N = new NoAleatorio();
		N.gerarNoAleatorio();
	}
}

Como vocês podem ver eu já andei tentando pegar o valor do JTextField criando um método dentro do listener do botão que vai ser pressionado e depois vou comparar o valor do JTextField.

public static void pegarValorTextField(JTextField text) {
		System.out.println(text.getText());

Depois criei uma instância:

MyActionListener t = new MyActionListener();
		t.pegarValorTextField(text);

Mas nessa linha da erro, o “text” fica dando erro, aparece assim: “text can’t be resolved”

Alguém pode me ajudar pessoal? Como pego o valor do JTextField?

Cara para que vc utilize uma JTextField quie só receba números vc pode criar um field que trate esse tipo de questão:

Exemplo:


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

public class NumberField extends JTextField {

	/**
	 * 
	 */
	private static final long serialVersionUID = -248911619613255316L;

	public NumberField() {
		this(null);
	}

	public NumberField(String text) {
		super(text);
		setDocument(new PlainDocument() {

			/**
			 * 
			 */
			private static final long serialVersionUID = 7218437003950972326L;

			public void insertString(int offs, String str, AttributeSet a)
					throws BadLocationException {
				for (int i = 0; i < str.length(); i++)
					if (!Character.isDigit(str.charAt(i)))
						return;

				super.insertString(offs, str, a);
			}
		});
	}
}

Esse bean só permite inserir números, ok ? 8)

Para o caso de vc ler e tratar automaticamente o que for digitado use o keyPressed.

Exemplo:


NumberField field = new NumberField();

field.addKeyListener(new KeyAdapter() {
   public void keyPressed(KeyEvent e) {
   // Aqui vc coloca o código
      if (Interger.valueOf(field.getText()) > 100){
       // Coloque a implementação da mudança de background se for maior que 100
      } else if (Interger.valueOf(field.getText()) < 100){
                // Coloque a implementação da mudança de background se for menor que 100
                } else {
                   // Coloque a implementação da mudança de background se for 100
                   }
   }
}

Vlw espero ter ajudado

Como faço para permitir só números até 100 tratando a exception? Desculpa cara mas eu realmente não entendi oque tu fez aí em cima. Eu consegui fazer todo o meu projeto, modifiquei algumas coisas do que eu botei lá em cima. Agora tenho só que tratar todas as exceptions. Vou botar aqui todo o projeto:

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AdvinhaNum
	
	{
			static JButton button2;
			static JPanel pane;
			static JTextField text;
			public void criaLayout(){
			JFrame frame = new JFrame("Jogo: Advinhação"); 
			pane = new JPanel(); 
			JButton button1 = new JButton("Gerar Número");
			text = new JTextField(4);
			/*button2.setEnabled(false);*/ 
			button2 = new JButton("OK");
			JLabel label = new JLabel("Existe um número de 1 a 100, tente advinhar qual:");
			
		 	pane.setLayout(new FlowLayout(FlowLayout.CENTER,4,4));
		 	
		 	pane.add(button1);
		 	ActionListener listener2 = new MyActionListener();
			button2.addActionListener(listener2);
		 	pane.add(label);
		 	pane.add(text);
		 	pane.add(button2);
		 	ActionListener listener = new MyActionListener2();
		 	button1.addActionListener(listener);
		 	pane.setBackground(Color.orange);
		 	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		 	
		 	frame.getContentPane().add(pane);
	        frame.pack(); frame.setVisible(true);

		}
	}
	

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class MyActionListener implements ActionListener {
	
	public static void pegarValorTextField(JTextField text) {
		System.out.println(text.getText());
	}
	public void actionPerformed(ActionEvent event) {
		int valorField = Integer.parseInt(AdvinhaNum.text.getText());
		int numGerado = MyActionListener2.recebeNumero();
		if(valorField > numGerado && valorField < (numGerado+10)) {
			System.out.println("***");
			System.out.println("Tá quente! Quase lá..Um pouco mais abaixo");
			AdvinhaNum.pane.setBackground(Color.red);
			System.out.println("Sua tentativa foi: "+valorField);
		}
		else if(valorField < numGerado && valorField > (numGerado-10)) {
			System.out.println("Tá Quente! Quase lá..Um pouco mais acima");
		 	AdvinhaNum.pane.setBackground(Color.red);
		 	System.out.println("Sua tentativa foi: "+valorField);
		}
		else if(valorField == numGerado) {
		 	AdvinhaNum.pane.setBackground(Color.red);
			System.out.println("*********PARABÉNS..ACERTOU!!*********");
			AdvinhaNum.button2.setEnabled(false);
			AdvinhaNum.text.setEnabled(false);
		}
		else {
			System.out.println("Chute muito longe!");
			AdvinhaNum.pane.setBackground(Color.cyan);
			System.out.println("Sua tentativa foi: "+valorField);
		}
	}			
}

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class MyActionListener2 implements ActionListener{

	static int x;
	public void actionPerformed(ActionEvent event) {
		gerarNoAleatorio();    
		AdvinhaNum.text.setEnabled(true);
		AdvinhaNum.pane.setBackground(Color.cyan);
		AdvinhaNum.button2.setEnabled(true);
	}
	public void gerarNoAleatorio() {
		x = (1 + (int) (Math.random () * 100));
		System.out.println( "O número é: "+x);
		}
	
	public static int recebeNumero() {
		return x;
	}
	
}


public class CriaLayout {
	public static void main(String[] args) {
		AdvinhaNum T = new AdvinhaNum();
		T.criaLayout();
		AdvinhaNum.button2.setEnabled(false);
		AdvinhaNum.text.setEnabled(false);
	}
}

Oque eu tentei fazer foi oque vi em outra thread aqui:

public void validaNumero(JTextField text) {
		long valorField;
		if (text.getText().length() != 0){
		try {
		valorField = Long.parseLong(text.getText());
		}catch(NumberFormatException ex){
		JOptionPane.showMessageDialog(null, "Esse Campo só aceita números" ,"Informação",JOptionPane.INFORMATION_MESSAGE);
		text.grabFocus();
				}
			}
		} 

Esse método foi criado dentro da classe MyActionListener.
O problema é que não consigo chamar esse método dentro do evento do botão. Como faço isso? Esse método está correto?

Cara o primeiro código é uma classe JTextField que eu alterei só para inserir valores numéricos nela. Ou seja, não permite utilizar nenhum caracter além de números. Crie essa classe no seu projeto.

// Ao invé de:
JTextField field = new JTextField();

//vc pode fazer assim:
NumberField field = new NumberField();

É praticamente a mesma coisa, a única diferença ja descrevi mais em cima.

O segundo código é para adicionar um evento no seu NumberField (JTextField), que a cada número que for digitado ele gerará o evento. Ou seja, se vc clicar 1, ele gerará o evento. Se vc clicar depois o 0, ficando 10; ele gerará o envento. Entendeu?

Não importa o que for digitar o método keyPressed() executa a cada vez que você digita alguma coisa. Então nessa perspectiva, vc pode tratar da forma que postei em cima.

Se for maior que 100 vc faz de um jeito, se menor de outro e se igual de um outro jeito ainda.

Está simples. É só criar uma classe NumberField no seu projeto. E adicionar o evento na forma que coloquei lá em cima. Claro, mudando os valores do comentário para a implementação que vc quizer. No caso, mudando a cor do background.

Espero ter ajudado

Pronto, criei a classe no meu projeto e colei o código que tu me deu mais acima. Só que oque eu queria fazer era tipo se o usuário digitar letras no JTextField e depois apertar o botão, queria que aparecesse uma tela dizendo que no campo só são permitidos números. Preciso tratar as exceptions mostrando uma tela para o usuário, pelo menos foi assim que o professor pediu pra fazer entende?
.
E outra coisa, acho que tu entendeu o meu problema errado, eu só mudo a cor do background se o valor que o usuário digitar for perto do valor gerado randomicamente. Se for muito longe a cor fica em azul. ou seja, preciso do evento do botão, não posso usar o evento de tecla pressionada.

Mas oque tu sugeriu me ajudou muito cara, obrigado mesmo. Se tiver alguma dica de como tratar com exceptions manda aew. :smiley:

Bom, não tratei com exception, achei esse código e deu certo:


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

public class OnlyNumberField extends PlainDocument
{

private int maxlength;

public OnlyNumberField(){}

public OnlyNumberField(int maxlength)
{
super();
this.maxlength = maxlength;
}

public void insertString(int offs, String str, AttributeSet a)
{
try
{
Integer.parseInt(str);
} catch (NumberFormatException ex)
{
str = "";
}
try
{
boolean fixedLengh = (!((getLength() + str.length()) > maxlength));
if (maxlength == 0 || fixedLengh)
super.insertString(offs, str, a);
} catch (BadLocationException e)
{
e.printStackTrace();
}
}

}

Só que agora preciso tratar o erro de o usuário colocar um número muito grande para int. Para isso pensei em limitar a quantidade de caracteres no JTextField para 3, levando em consideração que o número que eu botei para gerar automaticamente é de 1 a 100. Já tratei de o usuário não colocar maior que 100 nem menos que 1.

Podem me da alguma dica de como limitar a quantidade de caracteres no JTField?

Pronto, vi que essa mesma classe que botei aí em cima faz isso também. Sou burro viu.

Relaxa, o que eu tentei fazer era algo automático que para cada tecla que digitasse ele disparasse um evento. Para o botao, actionPerformed.

Mas de qualquer forma, isso é o de menos. são apenas disparadores de eventos. Para mudar ou limitar vc tem que implementar sua solução

OK

Me diz, tu sabe como colocar som quando o cara acertar? Tipo, o cara acertou o numero aí dispara umas palmas pra ele. Sabe como faço isso?

Me diz outra coisa aqui, como faço para tratar um erro e mostrando uma tela com a mansagem para o usuário?

Eu tava fazendo assim:

try{ 

          //código

}

catch(NumberFormatException e){

          System.out.println("Por favor coloque pelo menos um número no lugar especificado");
}

Só que esse código mostra a mensagem no prompt do Eclipse, eu quero que apareça uma janela para o usuário com a mensagem. Sei qe da para fazer mostrando num label mas quero mostrando uma outra janela mesmo.

Beleza, consegui já, é só fazer:

JOptionPane.showMessageDialog(null,"Digite pelo menos um número!");

Flw