Не удается отфильтровать и изменить текст в расширении JTextField

#java #swing #jtextfield #documentfilter

Вопрос:

Я пытаюсь применить несколько фильтров документов к своему пользовательскому полю JTextField И изменить его поведение, чтобы все буквы были ПРОПИСНЫМИ.

Я могу сделать то или другое, но я не могу сделать и то, и другое. Вот пользовательский документ, который я назначаю своему пользовательскому полю JTextField.

 class UpperCaseDocument extends PlainDocument {

    private static final long serialVersionUID = 1L;
    private List<DocumentFilterInspector> _documentFilterInspectors;

    public UpperCaseDocument(List<DocumentFilterInspector> documentFilterInspectors) {
        _documentFilterInspectors = documentFilterInspectors;
        
        setDocumentFilter(new DocumentFilter() {

            @Override public void insertString(FilterBypass fb, int offset, String text, AttributeSet attrs) throws BadLocationException {
                for(DocumentFilterInspector dfi : _documentFilterInspectors) {
                    if(!dfi.acceptInsertString(fb, offset, text, attrs)) {
                        return;
                    }
                }
                super.insertString(fb, offset, text, attrs);
            }

            @Override public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException {
                for(DocumentFilterInspector dfi : _documentFilterInspectors) {
                    if(!dfi.acceptRemove(fb, offset, length)) {
                        return;
                    }
                }
                super.remove(fb, offset, length);
            }
            
            @Override public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
                for(DocumentFilterInspector dfi : _documentFilterInspectors) {
                    if(!dfi.acceptReplace(fb, offset, length, text, attrs)) {
                        return;
                    }
                }
                super.replace(fb, offset, length, text, attrs);
            }
        });     
    }
    
    @Override public void insertString(int offs, String str, AttributeSet a)
        throws BadLocationException {

        if (str == null) {
            return;
        }
        char[] upper = str.toCharArray();
        for (int i = 0; i < upper.length; i  ) {
            upper[i] = Character.toUpperCase(upper[i]);
        }
        super.insertString(offs, new String(upper), a);
    }
}
 

DocumentFilterInspector-это интерфейс, который позволяет использовать определенный фильтр, например:

 public class CharacterLimitFilter implements DocumentFilterInspector {

    private int _limit;
    
    public CharacterLimitFilter(int limit) {
        _limit = limit;
    }
    
    @Override public boolean acceptInsertString(
            FilterBypass fb, 
            int offset, 
            String text, 
            AttributeSet attr) {

        return (fb.getDocument().getLength()   text.length()) <= _limit;
    }

    @Override public boolean acceptRemove(
            FilterBypass fb, 
            int offset, 
            int length) {

        return true;
    }

    @Override public boolean acceptReplace(
            FilterBypass fb, 
            int offset, 
            int length, 
            String text, 
            AttributeSet attrs) {

        return (fb.getDocument().getLength()   text.length()) <= _limit;
    }
}
 

Here’s my custom TextField:

 public class TextFieldUI extends JTextField {

    private static final long serialVersionUID = 1L;

    private List<DocumentFilterInspector> _documentFilterInspectors;

    public TextFieldUI() {
        super();
        init();
    }

    public TextFieldUI(int columns) {
        super(columns);
        init();
    }

    private final void init() {
        _documentFilterInspectors = new ArrayList<DocumentFilterInspector>();
        setDocument(new UpperCaseDocument(_documentFilterInspectors));
        setFont(new Font(Font.MONOSPACED, Font.PLAIN, 14));
    }

    public synchronized void addDocumentFilterInspector(DocumentFilterInspector inspector) {
        _documentFilterInspectors.add(inspector);
    }

    public synchronized void removeDocumentFilterInspector(DocumentFilterInspector inspector) {
        _documentFilterInspectors.remove(inspector);
    }
}
 

**************** ОБНОВЛЕНИЕ ****************

БОЛЬШОЕ спасибо камикру. Я использовал его отличный код, и он удивительно работает!!! Ссылка в его комментариях …

 import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
 
/**
 *  The UpperCaseDocumentFilter converts all characters to upper case before
 *  the characters are inserted into the Document.
 */
public class UpperCaseDocumentFilter extends ChainedDocumentFilter {
    /**
     *  Standard constructor for stand alone usage
     */
    public UpperCaseDocumentFilter() {}

    /**
     *  Constructor used when further filtering is required after this
     *  filter has been applied.
     */
    public UpperCaseDocumentFilter(DocumentFilter filter) {
        super(filter);
    }

    public void insertString(FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException {
        if (str != null) {
            String converted = convertString(str);
            super.insertString(fb, offs, converted, a);
        }
    }

    public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a) throws BadLocationException {
        if (str != null) {
            String converted = convertString(str);
            super.replace(fb, offs, length, converted, a);
        }
    }

    /**
     *  Convert each character in the input string to upper case
     *
     *  @param  mixedCase a String of mixed case characters
     *  @return an upper cased String
     */
    private String convertString(String mixedCase) {
        return mixedCase.toUpperCase();
    }
}
 

Комментарии:

1. Возможно, цепочка фильтров документов поможет.

2. Я уже подключаю фильтры, однако мне удалось успешно использовать ваш метод преобразования 🙂 Я продолжаю тестирование и вскоре сообщу об этом

3. Ваш код довольно элегантен. Изначально я хотел отделить «фильтрацию» входных данных от «форматирования» входных данных. Наверное, не стоит такой головной боли. Я думаю, что вместо этого я буду использовать ваш подход. Кстати, почему ты так пишешь в верхнем регистре? Почему бы просто не сделать String.toUpperCase()?

4. Не знаю, почему я использовал такой код в верхнем регистре. Думаю, в то время я не был знаком с этим toUpperCase() методом. Я обновил свой пример кода на своем компьютере, но не на веб-сайте. На веб-сайте теперь есть текущая версия. Спасибо, что указали на это.

5. Я преобразовал весь свой код, чтобы использовать вашу прекрасную библиотеку, большое спасибо. Как я могу принять ваш ответ?