Error con números negativos en TextField
Frecuentes
Visto 2,678 veces
1
Esta es la primera vez que pregunto aquí, así que si necesita más información de la que proporcionaré, solo pregúnteme.
He estado aprendiendo Java durante algunas semanas, y finalmente decidí intentar hacer mi propio programa, es el primero, así que el código estará todo desordenado. Básicamente es una calculadora para un juego llamado Pangya, ya que no sabía qué más hacer.
Código:
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Pangya {
public static void main(String[] args) {
GUI g = new GUI();
g.setSize(500, 600);
g.setVisible(true);
g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class GUI extends JFrame {
private JLabel distance;
private JLabel altura;
private JLabel slope;
private JLabel wind;
private JLabel angle;
private JLabel cheat;
private JLabel toma;
private JLabel spike;
private JLabel result;
public JTextField dis;
public JTextField alt;
public JTextField sl;
public JTextField w;
public JTextField ang;
private JButton res;
int d;
int al;
int s;
int win;
int an;
double H;
public GUI() {
super("Pangya Calculator");
setLayout(null);
distance = new JLabel("Enter hole distance:");
altura = new JLabel("Enter hole height:");
slope = new JLabel("Enter slope resistance:");
wind = new JLabel("Enter wind power:");
angle = new JLabel("Enter wind angle:");
cheat = new JLabel("Are you using cheat?");
toma = new JLabel("Tomahawk");
spike = new JLabel("Spike");
result = new JLabel("You must hit with backspin:");
dis = new JTextField();
alt = new JTextField();
sl = new JTextField();
w = new JTextField();
ang = new JTextField();
res = new JButton("Calculate");
Dimension size1 = distance.getPreferredSize();
Dimension size2 = altura.getPreferredSize();
Dimension size3 = slope.getPreferredSize();
Dimension size4 = wind.getPreferredSize();
Dimension size5 = angle.getPreferredSize();
Dimension size6 = cheat.getPreferredSize();
Dimension size7 = toma.getPreferredSize();
Dimension size8 = spike.getPreferredSize();
Dimension size9 = result.getPreferredSize();
Dimension size10 = res.getPreferredSize();
distance.setBounds(12, 50, size1.width, size1.height);
altura.setBounds(12, 150, size2.width, size2.height);
slope.setBounds(12, 250, size3.width, size3.height);
wind.setBounds(12, 350, size4.width, size4.height);
angle.setBounds(12, 450, size5.width, size5.height);
cheat.setBounds(250, 50, size6.width, size6.height);
toma.setBounds(250, 150, size7.width, size7.height);
spike.setBounds(350, 150, size8.width, size8.height);
result.setBounds(250, 350, size9.width, size8.height);
dis.setBounds(12, 75, size1.width, size1.height);
alt.setBounds(12, 175, size1.width, size1.height);
sl.setBounds(12, 275, size1.width, size1.height);
w.setBounds(12, 375, size1.width, size1.height);
w.setEditable(true);
ang.setBounds(12, 475, size1.width, size1.height);
ang.setEditable(true);
res.setBounds(200, 500, size10.width, size10.height);
dis.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
}
public void removeUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
d = Integer.parseInt(dis.getText());
}
});
alt.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
}
public void removeUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
al = Integer.parseInt(alt.getText());
}
});
sl.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
}
public void removeUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
s = Integer.parseInt(sl.getText());
}
});
ang.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
}
public void removeUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
an = Integer.parseInt(ang.getText());
}
});
w.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
}
public void removeUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
win = Integer.parseInt(w.getText());
}
});
res.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
H = d + al + Math.ceil(Math.sin(an) * win);
JOptionPane.showMessageDialog(null, "You must hit " + H
+ "y with backspin.", "Hit", JOptionPane.PLAIN_MESSAGE);
}
});
add(distance);
add(altura);
add(slope);
add(wind);
add(angle);
add(cheat);
add(toma);
add(spike);
add(result);
add(dis);
add(alt);
add(sl);
add(w);
add(ang);
add(res);
}
}
El problema es que cuando trato de convertir JTextField "ang" a un Int, no puedo poner números negativos, por ejemplo, trato de poner la altura del agujero en -12 y me sale un error. No tengo idea de cómo continuar o solucionarlo. Así que humildemente solicito su ayuda.
Gracias de antemano.
5 Respuestas
3
Utilice la herramienta Campo de texto con formato J en lugar de simple JTextField, JFormattedTextField
con un formateador de números puede reducir los caracteres permitidos a números, separador decimal y signo negativo, entonces no hay ninguna razón para analizar Integer
, Long
or Double
Por ejemplo:
DecimalFormat format = new DecimalFormat("#");
JFormattedTextField formattedField = new JFormattedTextField(format);
formattedField.setColumns(15);
Respondido el 26 de diciembre de 20 a las 12:12
Lo acabo de probar y sigue igual, creo que el problema está en un = Integer.parseInt(dis.getText()) pero no sé cómo solucionarlo. - user1261239
Editar: Oh, lo siento, estaba leyendo desde mi teléfono celular y recortó su mensaje a la mitad, eliminaré la parte de análisis para ver qué sucede. - user1261239
@ user1261239: vea editar, por ejemplo. mKorbel: espero que no te importe la edición. Por favor, siéntase libre de corregirlo. 1+ por cierto. - Aerodeslizador lleno de anguilas
Traté de hacer eso y ahora aparece un error solo por hacer clic en el campo de texto. Acabo de descubrir que si pongo un número positivo, presiono "calcular" y luego agrego un "-" antes de dicho número, funciona bien. Pero no puedo agregarlo directamente. - user1261239
@ user1261239 en mi respuesta es un enlace al tutorial sobre JFormattedTextField, y contiene un gran ejemplo, ¿leyó este tutorial? mKorbel
1
Integer.parseInt(dis.getText())
tiros NumberFormatException
. Puede atraparlo y luego decirle al usuario que ingresó un valor incorrecto.
Una buena manera es mostrar un cuadro de diálogo a través de JOptionPane.
JOptionPane.showMessageDialog(...)
Normalmente verifico el valor en ActionListener. Luego, cuando hay un error, muestro el mensaje y simplemente vuelvo desde el método actionPerformed. Entonces el usuario tiene otra oportunidad de ingresar el valor correcto.
Tampoco necesita tener un DocumentListener para cada campo de texto. Puedes obtener el texto más tarde:
class GUI extends JFrame {
private JLabel distance;
private JLabel altura;
private JLabel slope;
private JLabel wind;
private JLabel angle;
private JLabel cheat;
private JLabel toma;
private JLabel spike;
private JLabel result;
public JTextField dis;
public JTextField alt;
public JTextField sl;
public JTextField w;
public JTextField ang;
private JButton res;
int d;
int al;
int s;
int win;
int an;
double H;
public GUI() {
super("Pangya Calculator");
setLayout(null);
distance = new JLabel("Enter hole distance:");
altura = new JLabel("Enter hole height:");
slope = new JLabel("Enter slope resistance:");
wind = new JLabel("Enter wind power:");
angle = new JLabel("Enter wind angle:");
cheat = new JLabel("Are you using cheat?");
toma = new JLabel("Tomahawk");
spike = new JLabel("Spike");
result = new JLabel("You must hit with backspin:");
dis = new JTextField();
alt = new JTextField();
sl = new JTextField();
w = new JTextField();
ang = new JTextField();
res = new JButton("Calculate");
Dimension size1 = distance.getPreferredSize();
Dimension size2 = altura.getPreferredSize();
Dimension size3 = slope.getPreferredSize();
Dimension size4 = wind.getPreferredSize();
Dimension size5 = angle.getPreferredSize();
Dimension size6 = cheat.getPreferredSize();
Dimension size7 = toma.getPreferredSize();
Dimension size8 = spike.getPreferredSize();
Dimension size9 = result.getPreferredSize();
Dimension size10 = res.getPreferredSize();
distance.setBounds(12, 50, size1.width, size1.height);
altura.setBounds(12, 150, size2.width, size2.height);
slope.setBounds(12, 250, size3.width, size3.height);
wind.setBounds(12, 350, size4.width, size4.height);
angle.setBounds(12, 450, size5.width, size5.height);
cheat.setBounds(250, 50, size6.width, size6.height);
toma.setBounds(250, 150, size7.width, size7.height);
spike.setBounds(350, 150, size8.width, size8.height);
result.setBounds(250, 350, size9.width, size8.height);
dis.setBounds(12, 75, size1.width, size1.height);
alt.setBounds(12, 175, size1.width, size1.height);
sl.setBounds(12, 275, size1.width, size1.height);
w.setBounds(12, 375, size1.width, size1.height);
w.setEditable(true);
ang.setBounds(12, 475, size1.width, size1.height);
ang.setEditable(true);
res.setBounds(200, 500, size10.width, size10.height);
res.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
d = Integer.parseInt(dis.getText());
...etc for all fields
}
catch(NumberFormatException e){
JOptionPane.showMessageDialog(GUI.this, "One of the values is not a number.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
H = d + al + Math.ceil(Math.sin(an) * win);
JOptionPane.showMessageDialog(null, "You must hit " + H
+ "y with backspin.", "Hit", JOptionPane.PLAIN_MESSAGE);
}
});
add(distance);
add(altura);
add(slope);
add(wind);
add(angle);
add(cheat);
add(toma);
add(spike);
add(result);
add(dis);
respondido 10 mar '12, 17:03
El problema es que necesito usar valores negativos. - user1261239
Integer.parseInt debería poder analizar negativos. ¿Son esos números realmente enteros? Si contienen un punto decimal, no se analizarán como enteros. - jakub zaverka
0
Está escuchando las inserciones, pero necesita escuchar los cambios. Use parseInt dentro del método changesUpdate() de esta manera:
ang.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
an = Integer.parseInt(ang.getText());
}
public void removeUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
}
});
Esto funciona para mi. También debe cambiar todos los demás métodos de escucha de esa manera.
respondido 10 mar '12, 16:03
Si hago eso, me deja escribir números negativos pero no suma ni resta en la fórmula. - user1261239
Ok, mi mal. No detecta la actualización modificada, pero detecta la actualización insertada. El problema es cuando el usuario ingresa un carácter; antes del botón Enviar, se llaman los métodos. Entonces, primero se procesa el signo '-' y luego '-1'. El primero obviamente lanza una excepción. No creo que documentlistener sea la mejor manera de hacer esto. Pero puede atrapar la excepción y continuar si lo desea. Deberia de funcionar. - risa loca
Sí, me acabo de dar cuenta de que si dejo ir la excepción, funciona bien. Lo único es que los números aparecen antes del '-' si lo pongo primero, pero es un error menor. - user1261239
0
prueba esto:
public void insertUpdate(DocumentEvent e) {
try {
an = Integer.parseInt(ang.getText());
}
catch(NumberFormatException ex) {
// doNothing
}
}
respondido 10 mar '12, 17:03
Si la captura no hace nada, no suma ni resta de la fórmula final. - user1261239
0
En primer lugar, incruste SIEMPRE su análisis de enteros en un try { } catch
declaración por ejemplo..
try {
int myInt = Integer.parseInt(someString);
} catch (NumberFormatException e) {
// not a number/cannot parse it
}
Verifique la respuesta debajo de esto, ya que eso también es un problema
respondido 11 mar '12, 12:03
Este es un comentario, no una respuesta ;) - Terraego
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas java swing jtextfield parseint or haz tu propia pregunta.
Para obtener una mejor ayuda antes, publique un SSCCE (a la pregunta, a diferencia de dos piezas de código para pastebin). - Andrew Thompson