JTextArea только с числами, но допускает отрицательные значения

У меня есть JTextArea, который должен принимать только числа. Это мой код:

DocumentFilter onlyNumberFilter = new AxisJTextFilter();
    final JTextArea areaTextoXMin = new JTextArea(String.valueOf(xMin));
    ((AbstractDocument)areaTextoXMin.getDocument()).setDocumentFilter(onlyNumberFilter);

Работает нормально для положительных чисел, но не для отрицательных. Как я могу это исправить?

РЕДАКТИРОВАТЬ: Извините, AxisJTextFilter был найден в Интернете, и я забыл об этом. Его код:

import javax.swing.text.*;
import java.util.regex.*;

public class AxisJTextFilter extends DocumentFilter
{
    public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException
    {
        StringBuilder sb = new StringBuilder();
        sb.append(fb.getDocument().getText(0, fb.getDocument().getLength()));
        sb.insert(offset, text);
        if(!containsOnlyNumbers(sb.toString())) return;
        fb.insertString(offset, text, attr);
    }
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attr) throws BadLocationException
    {
        StringBuilder sb = new StringBuilder();
        sb.append(fb.getDocument().getText(0, fb.getDocument().getLength()));
        sb.replace(offset, offset + length, text);
        if(!containsOnlyNumbers(sb.toString())) return;
        fb.replace(offset, length, text, attr);
    }
    public boolean containsOnlyNumbers(String text)
    {
        Pattern pattern = Pattern.compile("\\d*(\\.\\d{0,3})?");
        Matcher matcher = pattern.matcher(text);
        boolean isMatch = matcher.matches();
        return isMatch;
    }
}

person Roman Rdgz    schedule 03.10.2011    source источник
comment
никогда не видел этого, проверьте, где ваш документ фильтрует отрицательные числа   -  person mKorbel    schedule 03.10.2011
comment
просто побочный узел: вы можете сохранить шаблон вместо перекомпиляции при каждом вызове   -  person kleopatra    schedule 03.10.2011
comment
Я бы использовал JTextField для этого.   -  person camickr    schedule 03.10.2011


Ответы (2)


Попробуйте изменить регулярное выражение (метод проверки содержитOnlyNumbers).

Pattern pattern = Pattern.compile("^[\\-\\+]?\\d+(\\.\\d+)?$");

Это примет следующие числа:

  • 1234
  • -1234
  • +1234
  • 1234.1234

Я надеюсь, что это помогает

Уди

person Udi Cohen    schedule 03.10.2011
comment
Работает правильно, но я хотел, как и раньше, только 3 десятичных цифры, поэтому я изменил на Pattern pattern = Pattern.compile(^[\\-\\+]?\\d+(\\.\\d{0,3}+ )?$); Спасибо! - person Roman Rdgz; 03.10.2011
comment
Строка должна быть: ^[\\-\\+]?\\d+(\\.\\d{1,3})?$ - person Udi Cohen; 03.10.2011
comment
@kleopatra, конечно, странно, что я забыл принять это. Извиняюсь! - person Roman Rdgz; 05.10.2011

Это задумано как комментарий к отличному сообщению Уди, но я не могу понять, как это сделать.

Я думаю, что его шаблон (d+) требует как минимум 1 цифру, и это должно быть d? чтобы разрешить 0-N цифр. Потому что, когда пользователь печатает, "-" является допустимым вводом. И десятичная точка, за которой не следуют никакие цифры, всегда допустима, особенно при наборе текста. Только в конце (когда вы теряете фокус и т. Д., YMMV) вы можете либо потребовать хотя бы одну цифру, либо быть любезным и прагматичным и просто рассматривать строку «-» как 0.

И при разработке таких регулярных выражений не забывайте, что пользователь может копировать и вставлять.

person user949300    schedule 04.10.2011
comment
Это хороший комментарий. Упомянутый выше regExp больше подходит для случая, когда текстовое поле теряет фокус. Но было бы неправильно изменить '\d+' на '\d*', потому что '-' не является допустимым вводом. Спасибо за отзыв! - person Udi Cohen; 05.10.2011
comment
Да, строго говоря, у вас должно быть два разных регулярных выражения, одно для того, пока пользователь печатает, а другое для финальной проверки при потере фокуса. Окончательный тест не принимает - или , при вводе должен. Или вы можете использовать более свободный, прагматичный подход, использовать только одно регулярное выражение и рассматривать финал - и как 0. - person user949300; 09.10.2011