Máscara + Alinhamento não fucionam juntos

3 respostas
M

Olá amigos do GUJ,

antes de mais nada quero dizer que apesar de ter encontrado diversos tópicos na internet sobre este assunto, nenhum atendeu as minhas necessidades de forma completa, sempre faltando uma ou outra funcionalidade, assim, decidi criar este novo tópico.

É o seguinte, criei um jTextField com máscara para representar o preço de um determinado produto, porém, o cursor deveria digitar da direita para a esquerda, assim como caixa de banco, só que isto não acontece. Posso alinhar o cursor todo a direita, mas sem a máscara, e posso utilizar a máscara, mas o cursor deve ser posicionado corretamente para representar as casas decimais.

Segue abaixo o código:
textPreco = new javax.swing.JTextField();
try{

textPreco = new javax.swing.JFormattedTextField(new MascarasJTextField().iserirMascara("#####.##"));
textPreco.setHorizontalAlignment(textPreco.RIGHT);
textPreco.setDocument(new AlinhaJTextField());
//textPreco.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); 
}catch(Exception e){
JOptionPane.showMessageDialog(null, "Erro ao criar campo de Preço.\nPor favor, contate o desenvolvedor do sistema.", 
"Erro", JOptionPane.ERROR_MESSAGE);

}
Esta classe abaixo eu apliquei mas não surtiu efeito:
public class AlinhaJTextField extends PlainDocument {

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

        String texto = getText(0, getLength());

        if (texto.length() < 7) {

            remove(0, getLength());
            StringBuffer strBuf = new StringBuffer(texto.replaceAll(",", "")
                    + str);

            if (strBuf.length() < 3) {

                strBuf.insert(0, ",");

            } else {

                strBuf.insert(strBuf.length() - 2, ",");
                
            }
            super.insertString(0, strBuf.toString(), atr);
        }
    }
    
}
Classe da máscara:
public class MascarasJTextField {

    public MaskFormatter iserirMascara(String Mascara) {

        MaskFormatter F_Mascara = new MaskFormatter();
        try {
            F_Mascara.setMask(Mascara); //Atribui a mascara
            F_Mascara.setPlaceholderCharacter(' '); //Caracter para preencimento
        } catch (Exception excecao) {
            JOptionPane.showMessageDialog(null, "Problema ao inserir máscara em jTextField.\n" + excecao, "Erro",
                    JOptionPane.ERROR_MESSAGE);
        }
        return F_Mascara;
    }


}

Obs: O método setComponentOrientation funciona do jeito que eu quero, porém contém alguns bugs, como por exemplo, não posso pular para outro componente da gui que automaticamente o conteúdo da jtextfield é deletado sozinho.

3 Respostas

visola

Com certeza o caminho é escrever seu próprio Document. Mas eu criaria um que usasse um buffer cheio de espaços e preenchesse com o conteúdo que fosse adicionado da direita para a esquerda, deixando as casas a esquerda preenchidas com espaços. Isso vai tomar um tempo, não é algo tão simples de se implementar. Se alguém já tiver feito, uma ajuda seria uma boa.

Sobre sua outra solução (usar o setComponentOrientation), você tentou setar o setFocusLostBehaviour ? Ele determina o que acontece quando o componente perde o foco. Nesse caso, poderia usar o PERSIST, como a seguir:

textPreco.setFocusLostBehaviour(JFormattedTextField.PERSIST);

Talvez isso resolva o problema dele apagar o valor quando muda de componente.

M

Não foi possível aplicar o setFocusLostBehaviour pois ele não é utilizado em um jTextField, pelo menos é isto que o netbeans está acusando, por isso ele nem compila.

M

Peguei a classe do Renzo em outro tópico, ela é o que está mais próximo do que eu quero no momento, além de ter inúmeras outras funcionalidades.

Muito obrigado pela ajuda.

/*Classe desenvolvida por Renzo Nuccitelli 
* para fazer validação de valores monetários 
* em Real 
*/  
public class TextFieldMoedaReal extends JTextField implements KeyListener {  
    private StringBuilder lastValidNumber;  
      
      
    /** 
     * Aceita um BigDecimal com escala 2.  
     * Outras escalas não são serão aceitas 
     *  
     * @param BigDecimal 
     */  
       
    public void setNumber(BigDecimal decimal){  
        System.out.println("escala: "+decimal.scale());  
        if(decimal.scale()==2){  
            lastValidNumber=new StringBuilder(decimal.unscaledValue().toString());  
            super.setText(getRealFormat());  
        }  
    }  
    /**Retorna um BigDecimal com o valor encontrando no campo 
     * e com escala igual a 2 
     *  
     * @return BigDecimal 
     */  
    public BigDecimal getNumber(){  
        BigDecimal number;  
        if(lastValidNumber.length()==0)  
            number=new BigDecimal("0");  
        else  
            number=new BigDecimal(lastValidNumber.toString());  
        number.setScale(2);  
        return number.divide(new BigDecimal(100));  
    }  
      
    /**Aceita valor em centavos.  
     * O valor não deve possuir ponto ou vírgula 
     *  
     * @param String 
     */  
    public void setText(String number){  
        if(isNumber(number))  
            lastValidNumber=new StringBuilder(number);  
        super.setText(getRealFormat());  
          
    }  
      
    private boolean isNumber(String number){  
        for(char c: number.toCharArray()){  
            if(!Character.isDigit(c))  
                return false;  
        }  
        return true;  
    }  
    public TextFieldMoedaReal() {  
        super();  
        this.setCaretPosition(this.getText().length());  
        this.addKeyListener(this);  
        lastValidNumber=new StringBuilder();  
        super.setText(getRealFormat());  
    }  
      
    @Override  
    public void keyPressed(KeyEvent e) {  
          
    }  
  
    @Override  
    public void keyReleased(KeyEvent e) {  
        if(Character.isDigit(e.getKeyChar())){  
            lastValidNumber.append(e.getKeyChar());  
        }  
        else if(e.getKeyCode()==KeyEvent.VK_BACK_SPACE){  
            if(lastValidNumber.length()>0){  
                lastValidNumber.deleteCharAt(lastValidNumber.length()-1);  
            }  
        }  
  
        this.setText(getRealFormat());  
          
    }  
  
    @Override  
    public void keyTyped(KeyEvent e) {  
          
    }  
      
    private String getRealFormat(){  
        if(lastValidNumber.length()==0)  
            return "0,00";  
        else if(lastValidNumber.length()==1)  
            return "0,0"+lastValidNumber;  
        else if(lastValidNumber.length()==2)  
            return "0,"+lastValidNumber;  
        else  
            return buildPrefixSeparateWithDots()+lastValidNumber.substring(lastValidNumber.length()-2);  
    }  
      
    private String buildPrefixSeparateWithDots(){  
        StringBuilder builder=new StringBuilder();  
        for(int index=0;index<lastValidNumber.length()-2;++index){  
            builder.append(lastValidNumber.charAt(index));  
            if((lastValidNumber.length()-index)%3==0&&lastValidNumber.length()-index>5)  
                builder.append(".");  
        }  
        builder.append(',');  
        return builder.toString();  
    }  
      
}
Criado 31 de janeiro de 2011
Ultima resposta 1 de fev. de 2011
Respostas 3
Participantes 2