Problemas ao usar regex no DocumentFilter para JTextField

Estou usando umDocumentFilter com umJTextField que é usado para inserir a quantidade de tempo que um funcionário trabalhou. o filtro é garantir que o limite de entrada tenha apenas 4 caracteres e permitir apenas números. Uma casa decimal pode ou não ser usada, mas deve ser permitida a inserção apenas uma vez; depois que a casa decimal é inserida, deve haver apenas mais um número. O significado 9.5 ou 10.5 deve ser aceito e 8,45 não.

Até agora, sou capaz de obter cerca da metade da funcionalidade total desejada. Não é possível digitar mais de 4 caracteres e apenas dígitos são permitidos. O último é realizado usando oreplaceAll("[^0-9.]", "") método.

Passei muito tempo assistindo a tutoriais, lendo a documentação e perguntas relacionadas, comoesta, esta, e especialmenteesta, mas parece que não é possível obter uma regex com desempenho completo. Uma coisa em particular que não consigo descobrir é por que exatamente uma regex de[^0-9] permitirá apenas dígitos com êxito, mas^\\d a menos que seja incluído como uma classe de caracteres, como[\\d]

Meu código de filtro está abaixo:

import java.awt.Toolkit;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class TimeWorkedFilter extends DocumentFilter {

    private int maxCharacters;    

    public TimeWorkedFilter(int maxChars) {
        maxCharacters = maxChars;
    }
//"[^0-9.]
    public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
            throws BadLocationException {

        if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
            super.insertString(fb, offs, str.replaceAll("[^0-9.]", ""), a);
        else
            Toolkit.getDefaultToolkit().beep();
    }

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

        if ((fb.getDocument().getLength() + str.length()
                - length) <= maxCharacters)
            super.replace(fb, offs, length, str.replaceAll("[^0-9.]", ""), a);
        else
            Toolkit.getDefaultToolkit().beep();
    }
}

questionAnswers(1)

yourAnswerToTheQuestion