java.lang.NumberFormatException: для входной строки:

При запуске этого кода:

JTextField ansTxt;
...
ansTxt = new JTextField(5);
String aString = ansTxt.getText();
int aInt = Integer.parseInt(aString);

Почему я получаю эту ошибку?

Исключение в потоке "AWT-EventQueue-0" java.lang.NumberFormatException: для входной строки: ""

ОБНОВИТЬ:

JTextField ansTxt;
ansTxt = new JTextField(5);

ansTxt.addKeyListener(new KeyAdapter() {
   public void keyReleased(KeyEvent e) {
    ansTxt = (JTextField) e.getSource();
    String aString = ansTxt.getText().trim();
    int aInt = Integer.parseInt(aString);
   }
}

person Jessy    schedule 13.09.2010    source источник
comment
В чем вопрос? Вы уверены, что в TextField есть анализируемая строка, но она не подхватывается? Или вы хотите знать, как убедиться, что неанализируемые строки обрабатываются правильно?   -  person Thomas Lötzer    schedule 13.09.2010
comment
Я просто не понимаю, почему я получил ошибку.   -  person Jessy    schedule 13.09.2010
comment
Когда возникает ошибка? Вы не набираете, скажем, 5, а затем нажимаете клавишу Backspace?   -  person aioobe    schedule 13.09.2010
comment
Нет, я просто набрал любое число, не нажимая клавишу Backspace... оно автоматически переключилось на другой экран.   -  person Jessy    schedule 13.09.2010
comment
@Jessy Вы проверяли с помощью отладчика, что такое aString, когда вы печатали?   -  person Thomas Lötzer    schedule 13.09.2010
comment
@Thomas Интересно, произошла ли ошибка из-за того, что пробела было 5, и я не набрал все 5 символов, я набрал только 1 символ?   -  person Jessy    schedule 13.09.2010
comment
нет. текстовое поле содержит то, что вы вводите. но честно. вы все равно делаете это неправильно. поймать исключение numberformate и правильно его обработать.   -  person aioobe    schedule 13.09.2010


Ответы (5)


Целочисленный аргумент для JTextField конструктор на самом деле является шириной в количестве столбцов. Из документов:

public JTextField(int columns)

Создает новый пустой TextField с указанным количеством столбцов. Создается модель по умолчанию, и для исходной строки устанавливается значение null.

Построив его с

ansTxt = new JTextField(5);

в основном вы получите пустое текстовое поле (немного шире, чем если бы вы создали его с помощью конструктора без аргументов). Если вы хотите, чтобы он содержал строку «5», вы должны написать

ansTxt = new JTextField("5");
Update: IIRC, you'll get one event for keyDown, one for keyTyped, and one for keyUp. Presumably the text-field has not yet been updated on the keyDown event. Either way I suggest that you encapsulate the Integer.parseInt in a
try { ... } catch (NumberFormatException e) { ... }
block since the user may very well write something else than an integer. -->
person aioobe    schedule 13.09.2010
comment
извините за путаницу.. да, я установил ширину 5... я попросил пользователя ввести любую строку в JTextField, а не конкретно 5... я пробовал trim(), но это не работает . - person Jessy; 13.09.2010
comment
@Jessy В вашем коде в вопросе у пользователя нет возможности что-либо сделать, поскольку JTextField создается и немедленно анализируется. Это ошибка в приведенном выше коде или также в вашем приложении? - person Thomas Lötzer; 13.09.2010
comment
@Jessy Я не уверен, что вы имеете в виду, но это не то, что делает код, который вы разместили. Он создает новое текстовое поле, извлекает содержащийся в нем текст (который по умолчанию является пустой строкой) и пытается преобразовать его в целое число. getText не запрашивает у пользователя текст, он просто извлекает текущий текст из текстового поля - person Michael Mrozek; 13.09.2010
comment
ansTxt = (JTextField) e.getSource(); Строка aString = ansTxt.getText().trim(); int aInt = Integer.parseInt (строка); - person Jessy; 13.09.2010
comment
Вам нужно (обновить вопрос ИЛИ создать новый вопрос) И (дать больше контекста). Откуда e? - person aioobe; 13.09.2010
comment
Я предполагаю, что ваш e генерируется из события, которое запускается до того, как пользователь даже получает возможность ввести (например, событие, которое запускается при фокусе). В любом случае вы должны добавить try { .. } catch (NumberFormatException nfe) { .. } на случай, если пользователь введет что-то еще, кроме целого числа. - person aioobe; 13.09.2010

Вы пытаетесь проанализировать пустую строку как int, что не работает. Какой int должен быть проанализирован как? JTextField должен иметь текст, который можно проанализировать.

ansTxt.addKeyListener(new KeyAdapter() {
    public void keyReleased(KeyEvent e) {
        ansTxt = (JTextField) e.getSource();
        try {
            int aInt = Integer.parseInt(ansTxt.getText());
            //Do whatever you want with the int
        } catch(NumberFormatException nfe) {
            /*
             * handle the case where the textfield 
             * does not contain a number, e.g. show
             * a warning or change the background or 
             * whatever you see fit.
             */
        }
    }
}

Вероятно, также не рекомендуется устанавливать ansTxt внутри KeyAdapter. Я бы посоветовал вам использовать для этого локальную переменную. Это также упрощает перемещение адаптера в «настоящий» класс вместо анонимного.

person Thomas Lötzer    schedule 13.09.2010

Используйте метод trim().

int m=Integer.parseInt(txtfield.getText().trim());  

метод trim() удалит любую строку, прикрепленную к номеру.

person Roodra    schedule 22.02.2011

Ваш KeyAdapter будет запущен до того, как ваш ansText обработает KeyEvent. На самом деле, вы можете e.consume() запретить ansText вообще его обрабатывать. Таким образом, при первом нажатии и отпускании клавиши ansText.getText() по-прежнему будет "". Вот почему вы получаете исключение в первый раз. Двойное нажатие цифровой клавиши должно сработать во второй раз.

person Ishtar    schedule 13.09.2010

Попробуйте ввести в свой проект библиотеку Apache "commons Lang", и для последней строки вы можете сделать

int aInt = 0;
if(StringUtils.isNotBlank(aString) && StringUtils.isNumeric(aString) ){
    aInt = Integer.parseInt(aString);
}

редактировать: не уверен, почему понижение. JtextField примет любую строку. Если текстовое поле прослушивает каждое нажатие клавиши, каждое введенное нечисловое значение (включая пустое) будет генерировать исключение NumberFormatException. Лучше всего проверить, является ли оно числовым, прежде чем что-либо делать с новым значением.

edit2: Согласно комментариям Томаса ниже. Я провел тест, чтобы сравнить способ решения этой проблемы с помощью try/catch и StringUtils. Тест был запущен 5 миллионов раз для каждого. Среднее время попытки/перехвата составило 21 секунду. Среднее время для StringUtils составило 8 секунд. Таким образом, использование StringUtils для большой нагрузки значительно быстрее. Если нагрузка на код небольшая, вы практически не заметите разницы. Тестовый запуск был

try{
   result = Integer.parseInt(num);
}catch(NumberFormatException ex){
   result = -1;
}

vs

if(StringUtils.isNotBlank(num) && StringUtils.isNumeric(num)){
   result = Integer.parseInt(num);
}else{
   result = -1;
}

каждый цикл генерировал новую случайную строку из 10 цифр, чтобы избежать какой-либо оптимизации в циклах оператора if. Это добавило 6-7 секунд накладных расходов.

person Sean    schedule 13.09.2010
comment
Вы предлагаете дополнительную библиотеку, не объясняя, почему ее следует использовать. Почему это лучше, чем просто попытаться разобрать его и обработать исключение? - person Thomas Lötzer; 14.09.2010
comment
@Thomas Есть накладные расходы, чтобы поймать исключение. Также есть накладные расходы при выполнении проверки isNumeric() в StringUtils. Так что дело в ремонтопригодности. Я предпочитаю не перехватывать каждое исключение, которое может быть выброшено, и проверять свои типы перед синтаксическим анализом, чтобы избежать исключения, другие могут этого не делать. Это сводится к предпочтениям. - person Sean; 15.09.2010
comment
Это интерактивный графический интерфейс, реагирующий на нажатия клавиш. Накладные расходы на перехват исключения в вашем тесте составили 0,0000026 секунд на каждое нажатие клавиши. Я не думаю, что пользователь заметит разницу во времени отклика в 0,0026 миллисекунды. - person Thomas Lötzer; 15.09.2010
comment
Да, для небольших приложений разница между любым из наших методов очень мала. Я всегда слышал о накладных расходах при использовании операторов catch, но никогда не знал, насколько они велики. Я использовал эту задачу как упражнение, чтобы выяснить это для себя. Для этого вопроса разница будет очень незначительной, но в более крупном и чувствительном ко времени приложении приведенный выше анализ может помочь. - person Sean; 15.09.2010