Error con números negativos en TextField

This is my first time asking here so if you need further information than I'll provide, just ask me.

I've been learning Java for a few weeks now, and I finally decided to try and make my own program, it's the first one so the code will be all messy. It's basically a calculator for a game called Pangya, as I didn't know what else to do.

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);
   }
}

The problem is that when I'm trying to convert JTextField "ang" to an Int, I can't put negative numbers, for example I try to put the hole height at -12 and I get an error. I have no idea how to continue or fix it. So I humbly request your help.

Gracias de antemano.

preguntado el 10 de marzo de 12 a las 16:03

Para obtener una mejor ayuda antes, publique un SSCCE (to the question, as opposed to two pieces of code to pastebin). -

5 Respuestas

Utilizan Campo de texto con formato J en lugar de simple JTextField, JFormattedTextField con un formateador de números can reduce allowed characters to los números, separador decimal y signo negativo, then there isn't any reasons for parsing 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

Just tried it and It's still the same, I think the problem is in an = Integer.parseInt(dis.getText()) but I don't know how to fix it. - user1261239

Edit: Oh i'm sorry i was reading from my cellphone and it cropped you message at half, i'll remove the parse part to see what happends. - user1261239

@user1261239: see edit for example. mKorbel -- hope you don't mind the edit. Please feel free to correct it. 1+ by the way. - Aerodeslizador lleno de anguilas

I tried to do that and now I get an error just for clicking the text field. I've just discovered taht if I put a positive number, press "calculate" and then add a "-" before said number, it works fine. But I can't add it directly. - user1261239

@user1261239 in my answer is link to the tutorial about JFormattedTextField, and contains great example, please did you read this tutorial - mKorbel

Integer.parseInt(dis.getText()) 

tiros NumberFormatException. You can catch it and then tell the user that he input a wrong value.

A good way is to show a dialog box through JOptionPane.

JOptionPane.showMessageDialog(...)

I normally check the value in the ActionListener. Then when there is an error, I display the message and just return from the actionPerformed method. Then the user has another chance to input correct value.

You don't also need to have a DocumentListener for each text field. You can get the text later:

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

The problem is that I need to use negative values. - user1261239

Integer.parseInt should be able to parse negatives. Are those numbers really integers? If they contain a decimal dot, they won't parse as integers. - jakub zaverka

Your are listening for the inserts but you need to listen for the changes. Use the parseInt inside the changedUpdate() method like this:

        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) {
            }
        });

It works for me. Also you need to change all other listener methods like that.

respondido 10 mar '12, 16:03

If i do that it let me type negative numbers but It does not add or subtract in the formula. - user1261239

Ok, my bad. It does not catch the changedUpdate but it catches insertUpdate. The problem is when the user enters a character; before the Submit button the methods are called. So the '-' sign is first processed, and then '-1'. The first one obviously throws an exception. I don't think documentlistener is the best way to do this. But you can catch for the exception and move on if you want. I t should work. - risa loca

Yes, I just realized that if I let the exception go it works fine. The oly thing is that the numbers appears before the '-' if i put it first but it's a minor bug. - user1261239

prueba esto:

public void insertUpdate(DocumentEvent e) {
     try {
            an = Integer.parseInt(ang.getText());
     }
     catch(NumberFormatException ex) {
            // doNothing
     }
}

respondido 10 mar '12, 17:03

If the catch does nothing, it doesn't add or subtract from the final formula. - user1261239

First off, ALWAYS embed your Integer parsing in a try { } catch statement eg ..

try {
     int myInt = Integer.parseInt(someString);
} catch (NumberFormatException e) {
     // not a number/cannot parse it
}

Check the answer below this, as thats also an issue

respondido 11 mar '12, 12:03

This is a comment, not an answer ;) - Terraego

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.