WinJar #2 - JTextField / Double / Float com Simbolo da Moeda

Classe para digitação de campo com Valor. Fica opcional informar o tipo de moeda …

Melhorias são bem vindas …

package gen;

import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
 * Gera Objeto tipo JTextField porem com casas decimais (Double/Float)
 * @author vonquelbe.caldeira
 */
public class GeraFieldD extends javax.swing.JTextField {

    private int tamanho;
    private int decimal;
    private String moeda;
/**
 * Gera Objeto tipo JTextField porem com casas decimais (Double/Float)
 * É possivel colocar um Simbolo do valor. Ver construtores.
 * @param x Posição X
 * @param y Posição Y
 * @param w Largura
 * @param h Altura
 * @param tamanho Quantidade de digitos - Total
 * @param decimal Quantidade de casas decimais
 * @param moeda Simbolo da Moeda - R$ / $ / € / ¥ ...
 * @param dica Dica do Campo
 */ public GeraFieldD(int x, int y, int w, int h, int tamanho, int decimal, String moeda, String dica) {
        this.setBounds(x, y, w, h);
        this.setBackground(new java.awt.Color(255, 255, 255));
        this.setToolTipText(dica);
        this.setHorizontalAlignment(JTextField.RIGHT);
        this.tamanho = tamanho;
        this.decimal = decimal;
        if (tamanho <= decimal){
            this.tamanho = tamanho+decimal;
        }
        this.moeda = (moeda==null||moeda=="") ? "" : moeda.replace(" ", "")+" ";
        this.setText(this.moeda);
        this.setCaretPosition(this.moeda.length()); // Posiciona o cursor do lado direito
    }
    public GeraFieldD(int x, int y, int w, int h, int tamanho, int decimal, String dica) {
        this(x, y, w, h, tamanho, decimal, null, dica);
    }
    public GeraFieldD(int x, int y, int w, int h, int tamanho, int decimal) {
        this(x, y, w, h, tamanho, decimal, null, "");
    }
    
 // método interno que define qual Document o JTextField usará
    @Override
    protected Document createDefaultModel() {
        return new Valor();
    }
 // Classe Interna
    class Valor extends PlainDocument {
        @Override
        public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
            if (str != null) {
                try {
                    if (offs<moeda.length()  && str!=moeda){
                       return;
                    }
                    String newStr = (this.getText(0, getLength()) + str).replace(",", ".").replace(moeda, "");
                    double f = Double.parseDouble(newStr); //Se der erro na conversão cai na exceção
                    
                    if (newStr.length() <= tamanho+1){
                        if (newStr.length() > (tamanho-decimal)&&(!newStr.contains("."))){
                            return;
                        }
                        if (newStr.length() > newStr.indexOf(".")+decimal+1&&(newStr.contains("."))){
                            return;
                        }
                        super.insertString(offs, str.replace('.', ','), a);
                    }                    
                } catch (Exception e) {
                    if (str==moeda){
                        super.insertString(offs, str.replace('.', ','), a);
                    }
                }                
            }
        }
        @Override // Trata o Delete
	public void remove(int offs, int len) throws BadLocationException {
            try { // Não exclui o tipo de Moeda
                if (getLength()<=moeda.length() || offs<moeda.length()){
                    return;
                }
                super.remove(offs, 1);
            } catch (Exception e) {
            }
	}
    }
}