DocumentFilter для отрицательных и положительных целых чисел

Я знаю, что это распространенный вопрос, но я пытаюсь создать TextField, который принимает только числа int, и это почти сделано, вот код:

Создать текстовое поле:

nome = new JFormattedTextField();
            nome.setHorizontalAlignment(SwingConstants.CENTER);
            nome.setColumns(2);

            DocumentFilter filtro = new FiltroNumero();
            ((AbstractDocument) nome.getDocument()).setDocumentFilter(filtro);

            panel.add(nome);

Фильтр документов:

public class FiltroNumero extends DocumentFilter{

    public void insertString(DocumentFilter.FilterBypass fb, int offset, int length,
              String text, javax.swing.text.AttributeSet attr)

              throws BadLocationException {
                    fb.insertString(offset, text.replaceAll("[^-0-9]", ""), attr);
         }  
}

При этом TextField будет принимать только числа и «-», но это означает, что «1-» является возможным значением.

Мне нужен способ заставить текстовое поле не принимать минус после первого символа.

Если кто-то может мне помочь, я буду очень рад :)


person Mackson Lima    schedule 23.10.2014    source источник
comment
Вы должны либо проверить, равен ли текст (или содержит -), и что он находится в начале, когда добавляются значения...   -  person MadProgrammer    schedule 23.10.2014
comment
@MadProgrammer либо это, либо разрешить только 0-9 для каждого отдельного символа, я чувствую, что это проверит еще больше проблем, которые возникнут в будущем, тем более что это часть параметров   -  person DreadHeadedDeveloper    schedule 23.10.2014
comment
@DreadHeadedDeveloper Я думал, что вы также можете проверить наличие символа -, удалить его из входящего String и вставить в начало документа, в зависимости от того, существует он или нет ... поэтому нажатие - всегда поместите его в начале (или в конце в зависимости от потребностей)   -  person MadProgrammer    schedule 23.10.2014
comment
@MadProgrammer ах, я исправлен   -  person DreadHeadedDeveloper    schedule 23.10.2014
comment
Рассмотрим также JSpinner с SpinnerNumberModel..   -  person Andrew Thompson    schedule 23.10.2014


Ответы (1)


Вы можете просто получить весь текст из Document (который был до замены), а затем создать новую строку из этого текста документа, добавив аргумент text. Затем просто проверьте полное регулярное выражение, которое соответствует целым числам (отрицательным или положительным). Если он совпадает, то сделайте замену. Что-то типа:

@Override
public void replace(FilterBypass fb, int offs, int length,
        String str, AttributeSet a) throws BadLocationException {

    String text = fb.getDocument().getText(0,
            fb.getDocument().getLength());

    StringBuilder builder = new StringBuilder(text);
    builder.insert(offs, str);
    String newText = builder.toString();

    // check
    System.out.println("text = " + text 
                   + ", offset = " + offs 
                   + ", newText = " + newText);

    if (newText.matches("(-)?\\d*")) {
        super.replace(fb, offs, length, str, a);
    } else {
        Toolkit.getDefaultToolkit().beep();
    }
}

Примечание: вы должны использовать replace, а не insertString, хотя не помешает переопределить оба.

Вот полная демонстрация

import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class FilterDemo {

    public FilterDemo() {
        JFrame frame = new JFrame();
        frame.add(createFilteredField());
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

    }

    private  JTextField createFilteredField() {
        JTextField field = new JTextField(10);
        AbstractDocument document = (AbstractDocument) field.getDocument();
        document.setDocumentFilter(new DocumentFilter() {

            @Override
            public void replace(FilterBypass fb, int offs, int length,
                    String str, AttributeSet a) throws BadLocationException {

                String text = fb.getDocument().getText(0,
                        fb.getDocument().getLength());

                StringBuilder builder = new StringBuilder(text);
                builder.insert(offs, str);
                String newText = builder.toString();

                // check
                System.out.println("text = " + text 
                               + ", offset = " + offs 
                               + ", newText = " + newText);

                if (newText.matches("(-)?\\d*")) {
                    super.replace(fb, offs, length, str, a);
                } else {
                    Toolkit.getDefaultToolkit().beep();
                }
            }


            @Override
            public void insertString(FilterBypass fb, int offs, String str,
                    AttributeSet a) throws BadLocationException {

                String text = fb.getDocument().getText(0,
                        fb.getDocument().getLength());

                StringBuilder builder = new StringBuilder(text);
                builder.insert(offs, str);
                String newText = builder.toString();

                // checks
                System.out.println("text = " + text 
                               + ", offset = " + offs 
                               + ", newText = " + newText);

                if (newText.matches("(-)?\\d*")) {
                    super.insertString(fb, offs, str, a);
                } else {
                    Toolkit.getDefaultToolkit().beep();
                }
            } 
        });
        return field;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new FilterDemo();
            }
        });
    }
}
person Paul Samsotha    schedule 23.10.2014
comment
Большое спасибо! Я пытаюсь понять код, но он работает, так что все в порядке, еще раз спасибо! - person Mackson Lima; 23.10.2014