Binding BigDecimal

5 Messages Forum Options Options
Permalink
Allan Maio
Binding BigDecimal
Reply Threaded More
Print post
Permalink
Oi Hugo, tudo bem?
Sempre leio seus artigos e seu site, são excelentes!
Seguinte, to com um grande problema na utilização do Jgoodies Binding. É para meu projeto final e tenho que entregar logo.

Tô tentando fazer o binding de um JTextField com um atributo BigDecimal, mas sempre dá uma exceção.

O que tentei fazer foi:

        NumberFormatter numberFormatter = new EmptyNumberFormatter(NumberFormat.getInstance(), 0);
        numberFormatter.setValueClass(BigDecimal.class);
        txtVendas = new JFormattedTextField(numberFormatter);
        Bindings.bind(txtVendas, presentation.getModel(InformacoesFinanceiras.VENDAS));


e antes tentei (mas nesse caso ele não observa as alterações do modelo na tela:

Bindings.bind(txtVendas, new BigDecimalConverter(new PropertyAdapter( presentation.getBean(), InformacoesFinanceiras.VENDAS)));

A classe BigDecimaConverter eu escrevi:

public class BigDecimalConverter extends AbstractConverter {

    public BigDecimalConverter(ValueModel subject) {
        super(subject);
    }

    public Object convertFromSubject(Object object) {
        BigDecimal value = (BigDecimal) object;
        if (value == null) {
            return "";
        }
        return value.toString();
    }

    public void setValue(Object object) {
        if (object != null) {
            BigDecimal tmp = new BigDecimal((String) object);
            subject.setValue (tmp);
        } else {
            subject.setValue(new BigDecimal("0.00"));
        }
    }

}

 

Se puder me dar essa ajuda ficarei muito grato.
Abraços,
--
Allan Maio
Hugo Teixeira
Re: Binding BigDecimal
Reply Threaded More
Print post
Permalink
Olá Allan,

Eu testei o seguinte código:


    NumberFormatter numberFormatter = new EmptyNumberFormatter(NumberFormat.getInstance(), new BigDecimal(0));
    numberFormatter.setValueClass(BigDecimal.class);

    ValueModel bigDecimalModel = new ValueHolder(new BigDecimal(1221));
    bigDecimalModel.addValueChangeListener(new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
            System.out.println("mudou para " + ((BigDecimal) evt.getNewValue()).doubleValue());
        }
    });

    txtVendas = BasicComponentFactory.createFormattedTextField(bigDecimalModel, numberFormatter);
    Bindings.bind(txtVendas, bigDecimalModel);


Repare que eu coloquei um listener no valueModel para saber se ele está escutando as mudanças na tela.
Funcionou sem problemas. ;-)

Grande abraço,
Hugo Teixeira
http://www.componenthouse.com
Allan Maio
Re: Binding BigDecimal
Reply Threaded More
Print post
Permalink
Consegui rodar com o codigo que vc me passou, porém ao tentar linkar com o meu bean de negocio (classe modelo):

        txtVendas = new JTextField();
       
        NumberFormatter numberFormatter = new EmptyNumberFormatter(NumberFormat.getInstance(), new BigDecimal("0"));
        numberFormatter.setValueClass(BigDecimal.class);

        ValueModel bigDecimalModel = new ValueHolder( presentation.getModel(InformacoesFinanceiras.VENDAS));
        bigDecimalModel.addValueChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                System.out.println("mudou para " + ((BigDecimal) evt.getNewValue()).doubleValue());
            }
        });

        txtVendas = BasicComponentFactory.createFormattedTextField(bigDecimalModel, numberFormatter);
        Bindings.bind(txtVendas, bigDecimalModel);


Eu pego a seguinte exception:

Exception in thread "AWT-EventQueue-0" com.jgoodies.binding.beans.PropertyAccessException: Failed to set an adapted Java Bean property.
cause=java.lang.IllegalArgumentException: Cannot format given Object as a Number
bean=javax.swing.JFormattedTextField[,0,0,0x0,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY= 0.0,border=com.birosoft.liquid.borders.LiquidTextFieldBorder@1220fd1,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=javax.swing.plaf.ColorUIResource[r=0,g=0,b=0],disabledTextColor=javax.swing.plaf.ColorUIResource [r=167,g=165,b=163],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=javax.swing.plaf.ColorUIResource[r=3,g=3,b=3],selectionColor=javax.swing.plaf.ColorUIResource[r=169,g=209,b=255],columns=0,columnWidth=0,command=,horizontalAlignment=LEADING]
bean type=javax.swing.JFormattedTextField
value=null
value type=com.jgoodies.binding.beans.BeanAdapter$SimplePropertyAdapter
property name=value
property type=java.lang.Object
property setter=public void javax.swing.JFormattedTextField.setValue(java.lang.Object)

Ele me diz que o objeto não pode ser casteado para número, mas o tipo que está na classe é um BigDecima!
O lugar para linkar seria esse?
ValueModel bigDecimalModel = new ValueHolder(presentation.getModel(InformacoesFinanceiras.VENDAS));

Valeu mesmo Hugo.
Vc tá me quebrando um galhão!
Allan Maio
Re: Binding BigDecimal
Reply Threaded More
Print post
Permalink
Hugo, consequi!!
Foi só fazer:

        txtVendas = new JTextField();
        Bindings.bind(txtVendas, new BigDecimalConverter(presentation.getModel(InformacoesFinanceiras.VENDAS)));


Esta é a classe que converte!

public class BigDecimalConverter extends AbstractConverter {

    public BigDecimalConverter(ValueModel subject) {
        super(subject);
    }

    public Object convertFromSubject(Object object) {
        BigDecimal value = (BigDecimal) object;
        if (value == null) {
            return "";
        }
        return value.toString();
    }

    public void setValue(Object object) {
        if (object != null) {
            BigDecimal tmp = new BigDecimal((String) object);
            subject.setValue(tmp);
        } else {
            subject.setValue(new BigDecimal("0.00"));
        }
    }

}

Valew mesmo! Agora tá uma beleza! hehee
Abraços
Hugo Teixeira
Re: Binding BigDecimal
Reply Threaded More
Print post
Permalink
Oi Allan,

Que bom! Fiquei muito impressionado com a sua solução.
Na verdade, você foi a única pessoa até agora que realmente olhou o código-fonte da API Binding procurando extendê-la. Isso normalmente só acontece com desenvolvedores acima do normal. Isso demonstra muita experiência e outra coisa que acho fundamental para o sucesso de um desenvolvedor: não ter medo de enfrentar o código dos outros.

Eu falo isso porque também sou assim. Se eu estivesse precisando de um desenvolvedor, você teria vaga certa na minha equipe ;-)

Parabéns!

Grande abraço,
Hugo Teixeira.
http://www.componenthouse.com