I have a program where a user enters a number (which will be an integer) into a JTextField
. The program that uses Integer.parseInt()
to get whatever is typed into the JTextField
. Usually the program runs smoothly with no issues. However, every now and then I will get a NumberFormatException
even among the same numbers. For instance, on one run of the program I could type in 5 into the JTextField
. On another run I could do the same and type 5 into the JTextField
and I would get a NumberFormatException
. I didn't change the code or anything so I don't understand why this is happening. Here is a portion of the code:
JPanel an = new JPanel(new GridBagLayout());
JLabel assignNamesLabel = new JLabel("Assign Book Names");
JLabel bookNumberLabel = new JLabel("Book Number");
JLabel nameOfBookLabel = new JLabel("Book Name");
final JTextField bookNumber = new JTextField(20);
final JTextField bookName = new JTextField(20);
JButton assignName = new JButton("Assign");
assignNamesLabel.setFont(f);
gbc.gridx = 1;
gbc.gridy = 0;
an.add(assignNamesLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
an.add(bookNumberLabel, gbc);
gbc.gridx = 1;
an.add(bookNumber, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
an.add(nameOfBookLabel, gbc);
gbc.gridx = 1;
an.add(bookName, gbc);
gbc.gridy = 3;
gbc.gridx = 1;
an.add(assignName, gbc);
assignNamesPanel.add(an, BorderLayout.CENTER);
tabs.addTab("Assign Book Names", assignNamesPanel);
// function
assignName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int i = Integer.parseInt(bookNumber.getText());
if (shelf.book[i] == null) {
shelf.book[i] = new shelf();
}
shelf.book[i].bookName = bookName.getText();
bookNumber.setText("");
bookName.setText("");
bookNumber.requestFocus();
}
});
I get the error sometimes at:
int i = Integer.parseInt(bookNumber.getText());
I would add some logic to validate that it is a number before attempting to parse it. Since primitive integers cannot be null, a -1
is returned. You can check so see if the processed value is valid as well. Of course, -1
is only an example. If you need -1
to be valid, just make the default Integer.MIN_VALUE
or something.
Catching the error is the prefered way i.e. parseIntSafelyWithCatch()
. You could also use an extraction method i.e. parseIntSafelyWithExtraction()
as an alternative to avoid exception handling.
public class NumberValidator {
public static final String INT_REGEX = "[^-?0-9]+";
public static final String CONTAINS_INT_REGEX = "^.*[-?0-9]+.*$";
public static int parseIntSafelyWithCatch(String value) {
if (value == null || value.isEmpty()) {
return -1;
}
try {
return Integer.parseInt(value.trim());
} catch (NumberFormatException e) {
return -1;
}
}
public static int parseIntSafelyWithExtraction(String value) {
if (value == null || value.isEmpty()) {
return -1;
}
if (value.matches(CONTAINS_INT_REGEX)) {
return Integer.parseInt(value.replaceAll(INT_REGEX, ""));
}
return -1;
}
public static boolean isValidNumber(int value) {
return value != -1;
}
public static void main(String[] args) {
System.out.println(parseIntSafelyWithCatch("")); // -1
System.out.println(parseIntSafelyWithCatch("42")); // 42
System.out.println(parseIntSafelyWithCatch(" 42")); // 42
System.out.println(parseIntSafelyWithCatch(" 42 ")); // 42
System.out.println(parseIntSafelyWithCatch("-42")); // -42
}
}
int i = NumberValidator.parseIntSafelyWithCatch(bookNumber.getText());
boolean isValid = NumberValidator.isValidInteger(i);