MarkUtils sob novo nome!

44 respostas
M

Bem, a tempos esse nome vem me incomodando um pouco, e ainda parecia pessoal de mais para um projeto que só tem como intenção facilitar a vida dos outros.

Então depois de tanto tempo, decedi mudar o nome do projeto para Towel.

Veja a noticia completa e o motivo de ter escolhido “Towel” em: http://markyameba.wordpress.com/2010/12/09/markutils-renamed/

Para quem não conheçe o projeto, ele contém algumas classes uteis para quem desenvolve sistemas desktop em Swing, e algumas classes utilitarias comuns. Como exemplo: o ObjectTableModel, TableFilter, Binder, ActionManager na parte de Swing, como utilitarios temos ClassIntrospector, StringConfiguration, ProgressiveString, ConfigurationUtils e CollectionUtils.
Mais em https://github.com/MarkyVasconcelos/Towel/wiki/Introduction

Como me sugeriram, migrei para o github.

E aproveitem para baixar a versão 1.0 também.

Como novidade, já aviso que a classe Auto-Filtro (TableFilter) e o JImagePanel do ViniGodoy também está no projeto.

Cya!

44 Respostas

E

Depois da sessão “graça sem graça”, eu digo: parabéns por estar compartilhando o seu código para todos!

L

Olá

Para mim. todo e qualquer projeto, por mais complexo que seja, tem dizer para o que serve em uma só frase e logo de cara.

No seu caso não tenho a menor idéia para que serve.

[]s
Luca

E

Muito Bom. Parabéns pelo projeto e muito sucesso nessa “nova fase”.

M

Luca:
Olá

Para mim. todo e qualquer projeto, por mais complexo que seja, tem dizer para o que serve em uma só frase e logo de cara.

No seu caso não tenho a menor idéia para que serve.

[]s
Luca

Sorry :oops:

Post complementado. :stuck_out_tongue:

M

entanglement:
Mama said that: :

Don’t leave wet towels on the bed!

Depois da sessão “graça sem graça”, eu digo: parabéns por estar compartilhando o seu código para todos!

Hehe
Obrigado, espero que com isso as pessoas vejam mais incentivo em tirar o “código da meia” e ajudar os outros.

Ty. Essa “nova fase” é só uns renames, começou a ficar estranho o nome do projeto a partir do momento que começei a cita-lo em conversas.

P

Muito bom!!! teve uma epoca q até tentei contribuir mais por algum motivo não recebi retornos… mais é isso ai Parabens.

caso ainda esteja de pé o proj de utilitario separado do swing, podemos incorporar num projeto só. Eu cabei criando um chamado OpenSutils-B4J de utilitarios mais sem a ver com Swing eu to case fazendo o deploy no maven…

M

Ah sim, é que sua proposta era exatamente esta de encorporar junto, eu estava ocupado editando um monte de coisa, mas podemos continuar vendo isso sim.

E obrigado!

V

Ei, Mark, aproveita e já põe lá a classe do ImagePanel também.
http://www.guj.com.br/posts/list/56248.java

V

Bom, já atualizei minha assinatura também. :slight_smile:

M

Atualizado, com.towel.swing.img.JImagePanel adicionado também, dei uma rapida atualizada e coloquei na versão 1.0 do jar que já estava disponivel para download.

Assinatura atualizada também.

P

Marky.Vasconcelos:
Ah sim, é que sua proposta era exatamente esta de encorporar junto, eu estava ocupado editando um monte de coisa, mas podemos continuar vendo isso sim.

Isso dá um trampo mesmo!!!, quando acalmar as atualizações, ou surgir algumas funcionalidades me manda MP…

Showw, vô atualizar meu projetinho swing com o Towel

E

Só lembrando que towel.com é um site de verdade, isso não deve lhe dar “tantos problemas”, mas é bom você se precaver.

http://www.towel.com/stuff/feedbacksee_current.html

E

Excelente iniciativa Marcos!

Material muito útil! Parabéns e obrigado :wink:

Abraço.

I

Mark, du “baralho”! :smiley:
Já uso o MarkUtils num protótipo de sistema aqui.Quando eu fizer a versão final vou migrar para o Towel. :slight_smile:

L

Sugestão: coloca o projeto no Github, fica mais fácil pra acompanhar de perto o desenvolvimento.

Parabéns!

[]s

M

É, eu tive essa duvida na hora de hospedar o novo site, ou no google code ou no git hub.

Acabei optando pelo googlecode por costume.

Mas vou avaliar para migrar para o git.

E, obrigado!

J

Luiz Aguiar:
Sugestão: coloca o projeto no Github, fica mais fácil pra acompanhar de perto o desenvolvimento.

Parabéns!

[]s

Tem algum ‘GitHub for Dummies’? :lol:

A

Valeu por compartilhar conosco Marky. Muito bom trabalho. Parabéns :smiley:

L

j0nny:
Luiz Aguiar:
Sugestão: coloca o projeto no Github, fica mais fácil pra acompanhar de perto o desenvolvimento.

Parabéns!

[]s

Tem algum ‘GitHub for Dummies’? :lol:


http://help.github.com/

:smiley:

J

Luiz Aguiar:
j0nny:
Luiz Aguiar:
Sugestão: coloca o projeto no Github, fica mais fácil pra acompanhar de perto o desenvolvimento.

Parabéns!

[]s

Tem algum ‘GitHub for Dummies’? :lol:


http://help.github.com/

:smiley:

Perfeito, vlw :wink:

M

Ai, fiz a migração para o github.

Aproveitem e me sigam.

S

Good Job !!!

Vlw por compartilhar! Vou estula-lo e ver se posso “aproveitar” em meus projetos futuros!

:wink:

L

Olá Marky,

Queria saber como funciona seu ObjectTableModel em relação a funções agregadas. Por exemplo, um JTabel q tenha uma linha com totalizador( tipo o sum do excel, entendeu?). Assim:


|cod. Item | Valor|
----------------------|
|00000001|0050 |
----------------------|
|00000002|0150 |
----------------------|
|00000003|0250 |
----------------------|
|TOTAL | 500 | (esta é a linha que quero adicionar)

Você ou alguém aqui na thread já implementou algo parecido ?

A minha dúvida é em relação a exibição desta linha no objeto JTable e a não inclusão de um objeto de negocio na minha lista q está no model). Tem alguma ideia de como faço isso?

Obrigado pela atenção.

Abraços

J

Marky.Vasconcelos:
Bem, a tempos esse nome vem me incomodando um pouco, e ainda parecia pessoal de mais para um projeto que só tem como intenção facilitar a vida dos outros.

Então depois de tanto tempo, decedi mudar o nome do projeto para Towel.

Veja a noticia completa e o motivo de ter escolhido “Towel” em: http://markyameba.wordpress.com/2010/12/09/markutils-renamed/

Para quem não conheçe o projeto, ele contém algumas classes uteis para quem desenvolve sistemas desktop em Swing, e algumas classes utilitarias comuns. Como exemplo: o ObjectTableModel, TableFilter, Binder, ActionManager na parte de Swing, como utilitarios temos ClassIntrospector, StringConfiguration, ProgressiveString, ConfigurationUtils e CollectionUtils.
Mais em https://github.com/MarkyVasconcelos/Towel/wiki/Introduction

Como me sugeriram, migrei para o github.

E aproveitem para baixar a versão 1.0 também.

Como novidade, já aviso que a classe Auto-Filtro (TableFilter) e o JImagePanel do ViniGodoy também está no projeto.

Cya!

Fala ae Mark… Cara ficou muito bom o projeto junto com o filtro do Vinicius. Só faltou adicionar os icones do auto-filtro que o Vini usa (pelo menos eu não achei e tive um NullPointer aqui na hora de migrar).

Pacote : com.towel.swing.table.headerpopup.TableHeaderPopup.java

if (modified.get(modelIndex) == null || !modified.get(modelIndex)) button.setIcon(new ImageIcon(getClass().getResource( "/util/gui/images/down.gif"))); //Imagem não existe no projeto! ### Aqui é a linha 173 else button.setIcon(new ImageIcon(getClass().getResource( "/util/gui/images/down_red.gif"))); //Imagem não existe no projeto! ### Aqui é a linha 176

Acredito que é isso. até agora só tive esse problema.

Outra coisa interessante ao meu ver seria dar a opção traduzir o texto do auto filtro (está em inglês) na classe TableFilter.

private static final String POPUP_ITM_SORT_DESC = "Sort by descending order";
    private static final String POPUP_ITM_SORT_ASC = "Sort by ascending order";
    private static final String POPUP_CUSTOMIZE = "Customize";
    private static final String POPUP_EMPTY = "Empty";
    private static final String POPUP_ITM_ALL = "(All)";

e também

String value = JOptionPane.showInputDialog( GuiUtils.getOwnerWindow(header), "Customize filter (you can use wildcards * or ?)", text); // Esse texto está na linha 464
Seria legal poder mudar isso sem ter que mudar o fonte!

M

Nossa, vou corrigir em breve, reparei agora que os resources não foram mesmo.

Então, essa é minha meta com aquelas AggregateFunctions, mas meu problema não é a função em si, o problema é que a JTable não tem um Footer, só da para fazer algumas gambiarras tenebrosas para funcionar, assim que eu tiver algo eu lanço.

F

Marky.Vasconcelos:
Nossa, vou corrigir em breve, reparei agora que os resources não foram mesmo.

Então, essa é minha meta com aquelas AggregateFunctions, mas meu problema não é a função em si, o problema é que a JTable não tem um Footer, só da para fazer algumas gambiarras tenebrosas para funcionar, assim que eu tiver algo eu lanço.

Gambi? Não da pra usar um tablecellrenderer pra pintar a ultima linha de cor diferente e tals? O problema eu acho que seria scroll, seria legal se a ultima linha ficasse estatica sem scroll.

M

Então, exatamento isso, fazer ela ficar imovel é o resultado de uma puta gambiarra. :stuck_out_tongue:

Eu só cheguei em uma solução que deixaria a gambiarra escondida, extender a JTable, mas ainda acho que não é a melhor idéia.

L

Olá Marky, tem como vc passar essa work around pra eu dar uma olhadinha?

L

Acho que achei:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;


public class FixedRowExample extends JFrame {
  Object[][] data;
  Object[] column;
  JTable fixedTable,table;
  private int FIXED_NUM = 1;

  public FixedRowExample() {
    super( "Fixed Row Example" );
    
    data =  new Object[][]{
        {      "a","","","","",""},
        {      "","b","","","",""},
        {      "","","c","","",""},
        {      "","","","d","",""},
        {      "","","","","e",""},
        {      "","","","","","f"},
        {"Total","","","","","","",""}};
    column = new Object[]{"A","B","C","D","E","F"};
        
    AbstractTableModel model = new AbstractTableModel() {
      public int getColumnCount() { return column.length; }
      public int getRowCount() { return data.length - FIXED_NUM; }
      public String getColumnName(int col) {
       return (String)column[col]; 
      }
      public Object getValueAt(int row, int col) { 
        return data[row][col]; 
      }
      public void setValueAt(Object obj, int row, int col) { 
        data[row][col] = obj; 
      }
      public boolean CellEditable(int row, int col) { 
        return true; 
      }
    };
    
    AbstractTableModel fixedModel = new AbstractTableModel() {      
      public int getColumnCount() { return column.length; }
      public int getRowCount() { return FIXED_NUM; }
      public Object getValueAt(int row, int col) { 
        return data[row + (data.length - FIXED_NUM)][col]; 
      }
    };
    
    table = new JTable(model);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    
    fixedTable = new JTable( fixedModel );
    fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    fixedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    
    JScrollPane scroll = new JScrollPane(table);
    scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

    JScrollPane fixedScroll = new JScrollPane(fixedTable){
      public void setColumnHeaderView(Component view) {} // work around
    };                                                  
    
    fixedScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
    JScrollBar bar = fixedScroll.getVerticalScrollBar();
    JScrollBar dummyBar = new JScrollBar() {
      public void paint(Graphics g) {}
    };
    dummyBar.setPreferredSize(bar.getPreferredSize());
    fixedScroll.setVerticalScrollBar(dummyBar);
    
    final JScrollBar bar1 = scroll.getHorizontalScrollBar();
    JScrollBar bar2 = fixedScroll.getHorizontalScrollBar();
    bar2.addAdjustmentListener(new AdjustmentListener() {
      public void adjustmentValueChanged(AdjustmentEvent e) {
        bar1.setValue(e.getValue());
      }
    });
    
    
    scroll.setPreferredSize(new Dimension(500, 80));
    fixedScroll.setPreferredSize(new Dimension(400, 52));  
    getContentPane().add(scroll, BorderLayout.CENTER);
    getContentPane().add(fixedScroll, BorderLayout.SOUTH);    
  }

  public static void main(String[] args) {
    FixedRowExample frame = new FixedRowExample();
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
        System.exit(0);
      }
    });
    frame.pack();
    frame.setVisible(true);
  }
}

Será que não tem solução melhor?(rsrs)

M

Então, essa é a solução com gambiarra. Vou dar um jeito nisso e depois disponibiizo, o prototipo que começei foi perdido vou começar outra quando tiver tempo.

Mas obrigado.

P

Criei uma funcionalidade para criar Formatter dinamicos para o ObjectComboBoxModel do projeto towel, estou contribuindo aqui com o codigo, está ainda em uma versão inicial, 0.1beta, mais já estou utilizando sem problemas, o DynamicFormatter ainda funciona apenas para os campos (Fields) de primeiro nivel da class o Reflection ainda não pela os campos dentro de Objetos do Objeto (2 nivel).

Exemplo de uso:

ObjectComboBoxModel<Filial> cboModel = new ObjectComboBoxModel<Filial>();
			
	List<DynamicFormatter.FormatField> a = new ArrayList<DynamicFormatter.FormatField>(2);
	a.add(new DynamicFormatter.FormatField("id",null));//Adicionando o id para aparecer no value do JCombox
	a.add(new DynamicFormatter.FormatField("nome",null));//Adicionando o nome para aparecer no value do JCombox
	cboModel.setFormatter(new DynamicFormatter<Filial>(Filial.class,a, " - "));
	cboFilial = new JComboBox(cboModel);
	cboModel.setData(filialLogic.find(Session.getInstance().getUsuario()));
        
        //No combo box ira aparecer +- assim: 1 - FILIAL SP
        //                                                           2 - FILIAL BH

O codigo esta anexado…

M

Priuli:
Criei uma funcionalidade para criar Formatter dinamicos para o ObjectComboBoxModel do projeto towel, estou contribuindo aqui com o codigo, está ainda em uma versão inicial, 0.1beta, mais já estou utilizando sem problemas, o DynamicFormatter ainda funciona apenas para os campos (Fields) de primeiro nivel da class o Reflection ainda não pela os campos dentro de Objetos do Objeto (2 nivel).

Exemplo de uso:

ObjectComboBoxModel<Filial> cboModel = new ObjectComboBoxModel<Filial>();
			
	List<DynamicFormatter.FormatField> a = new ArrayList<DynamicFormatter.FormatField>(2);
	a.add(new DynamicFormatter.FormatField("id",null));//Adicionando o id para aparecer no value do JCombox
	a.add(new DynamicFormatter.FormatField("nome",null));//Adicionando o nome para aparecer no value do JCombox
	cboModel.setFormatter(new DynamicFormatter<Filial>(Filial.class,a, " - "));
	cboFilial = new JComboBox(cboModel);
	cboModel.setData(filialLogic.find(Session.getInstance().getUsuario()));
        
        //No combo box ira aparecer +- assim: 1 - FILIAL SP
        //                                                           2 - FILIAL BH

O codigo esta anexado…

Opa… já estou vendo… e em pouco tempo coloco no projeto também.

Obrigado por compartilhar.

M

PS:

Esta escrito na descrição
"projeto Towel do MarkUtils"

Não é o Towel do MarkUtils, é o projeto Towel, antigo MarkUtils.

M

Hmm…
Rodando o seguinte código:

Person person = new Person("Marcos", 19, true, "26061991");

		List<DynamicFormatter.FormatField> a = new ArrayList<DynamicFormatter.FormatField>(
				2);
		a.add(new DynamicFormatter.FormatField("nome", null));
		a.add(new DynamicFormatter.FormatField("idade", null));
		a.add(new DynamicFormatter.FormatField("live", null));

		DynamicFormatter<Person> dynamic = new DynamicFormatter<Person>(
				Person.class, a, " - ");
		
		System.out.println(dynamic.format(person));

Ele mostra:
“Name: Marcos age: 19”

P

Marky.Vasconcelos:
PS:

Esta escrito na descrição
"projeto Towel do MarkUtils"

Não é o Towel do MarkUtils, é o projeto Towel, antigo MarkUtils.

Ops!! é “mermo” cometi um erro ali… please…

era para ficar do projeto Towel do Marky Vasconcelos

Corrigido

P

Marky.Vasconcelos:
Hmm…
Rodando o seguinte código:

Person person = new Person("Marcos", 19, true, "26061991");

		List<DynamicFormatter.FormatField> a = new ArrayList<DynamicFormatter.FormatField>(
				2);
		a.add(new DynamicFormatter.FormatField("nome", null));
		a.add(new DynamicFormatter.FormatField("idade", null));
		a.add(new DynamicFormatter.FormatField("live", null));

		DynamicFormatter<Person> dynamic = new DynamicFormatter<Person>(
				Person.class, a, " - ");
		
		System.out.println(dynamic.format(person));

Ele mostra:
“Name: Marcos age: 19”

Deveria mostrar Marcos - 19 - true

*o campo ‘live’ imagino que seja o 3 campo do contrutor da classe Person

Vô adicionar um test d unidade, pra ve se ta okay…

P

Bom Mark, cometi um engano ao postar o código, cabei postando 1 versão anterior…
bom segue o código atualizado e com um teste de unidade que utilizei… versão 0.2b

teste novamente e vê o que sair…

flw

M
java.lang.IllegalArgumentException: Field or get method does not exist.
	at com.towel.bean.DynamicFormatter.format(DynamicFormatter.java:116)
	at test.bean.TestDynamicFormatter.testFormat(TestDynamicFormatter.java:67)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NoSuchMethodException: test.model.Person.isName()
	at java.lang.Class.getMethod(Class.java:1605)
	at com.towel.bean.DynamicFormatter.getValueFromField(DynamicFormatter.java:155)
	at com.towel.bean.DynamicFormatter.format(DynamicFormatter.java:99)
	... 24 more

Os testes dão erro, agora ele está apenas procurando isName.

M

E tem outra, é possivel usar o FieldResolver para fazer isso também, criei ele de modo generico, da pra substituir o FormatField e ainda ter acesso aos FieldAcessHandlers.

M

Conforme eu disse, modifiquei para usar o FieldResolver, agora o código está mais limpo e ainda deixa o programador escolher se quer o FieldHandler ou MethodHandler.

package com.towel.bean;

/*
 * Copyright (c) 2011 Felipe Priuli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 *The above copyright notice and this permission notice shall be included at least in this file.
 *
 * The Software shall be used for Good, not Evil.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
import java.util.ArrayList;
import java.util.List;

import com.towel.bean.Formatter;
import com.towel.el.FieldResolver;

/**
 * <code>DynamicFormatter</code> classe que implementa o
 * <code>com.towel.bean.Formatter</code> esta classe é um Formatter dinâmico,
 * podendo ser utilizado para vario formatar varios tipos de entidades, classes
 * aquelas que serão utilizadas em um combobox do
 * <code>ObjectComboBoxModel</code> do projeto Towel, antigo MarkUtils, do Marky
 * Vasconcelos ( http://code.google.com/p/towel/ )
 * 
 * @author Felipe Priuli
 * @author Marcos Vasconcelos
 * @version 0.2 beta 20/01/2011
 * @param <T>
 *            - Tipo da classe que representa este Formatter
 */
public class DynamicFormatter<T> implements Formatter {
	private Class<T> clazz;
	protected List<FieldResolver> fieldList;

	/**
	 * Um texto aquele que ira separar o valor caso tenha mais de um campo sendo
	 * invocado.
	 */
	protected String separetor;

	/**
	 * Contrutor
	 * 
	 * @param t
	 *            - Class name que representa este Formatter
	 */
	public DynamicFormatter(Class<T> t) {
		this.clazz = t;
		this.fieldList = new ArrayList<FieldResolver>(4);
	}

	/**
	 * Contrutor
	 * 
	 * @param t
	 *            - Class name que representa este Formatter
	 * @param fieldName
	 *            - o nome do campo que sera invocado para obter o texto do
	 *            combobox
	 * @author Felipe Priuli 20/01/2011
	 */
	public DynamicFormatter(Class<T> t, String fieldName) {
		this(t);
		this.clazz = t;
		this.fieldList.add(new FieldResolver(t, fieldName));
	}

	/**
	 * Contrutor
	 * 
	 * @param t
	 *            - Class name que representa este Formatter
	 * @param fiedlNameList
	 *            - Os campos que serão invocado para obter o texto do combobox
	 * @param separetor
	 *            - o texto que ira separar os texto do campos
	 */
	public DynamicFormatter(Class<T> t, List<FieldResolver> fiedlNameList,
			String separetor) {
		this(t);
		this.clazz = t;
		this.fieldList.addAll(fiedlNameList);
		this.separetor = separetor;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Object format(final Object arg0) {
		if (this.separetor == null) {
			this.separetor = "";
		}
		if (arg0 == null) {
			return "";
		}

		T obj = ((T) arg0);
		try {
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < this.fieldList.size(); i++) {
				sb.append(fieldList.get(i).getValue(obj));
				if (!((i + 1) == this.fieldList.size())) {
					sb.append(this.separetor);
				}
			}

			return sb.toString();

		} catch (SecurityException e) {
			throw new IllegalArgumentException(e);
		} catch (IllegalArgumentException e) {
			throw new IllegalArgumentException(
					"Field is no pattern JavaBeans to acess method", e);
		}

	}

	@Override
	public String getName() {
		return clazz.getClass().getSimpleName().toLowerCase();
	}

	@Override
	public Object parse(Object arg0) {
		return null;// Never get invoked, JComboBox cannot be editable
	}

	/**
	 * Seta o texto que ira separar os valores caso tenha mais de um campo sendo
	 * invocado.
	 * 
	 * @return the separetor
	 */
	public String getSeparetor() {
		return separetor;
	}

	/**
	 * Obtem o texto que ira separar os valores caso tenham mais de um campo
	 * sendo invocado.
	 * 
	 * @param separetor
	 *            the separetor to set
	 */
	public void setSeparetor(String separetor) {
		this.separetor = separetor;
	}

	/**
	 * @return the fieldList
	 */
	public List<FieldResolver> getFieldList() {
		return fieldList;
	}
}
P

Sim é possivell usar o seu Resolver é que eu ñ estou muito familiarizado com todas as classes do seu projeto…
Sobre o erro a classe que eu fiz tem que ter os campos publicos ou ter métodos get publicos no padrão JavaBeans, e um costrutor vazio, aqui tá funfando… esquizitu…
Depois vo tentar fazer no seu projeto, no svn que tenho aki. pra ve se acontece issu…

P

Marky.Vasconcelos:
Conforme eu disse, modifiquei para usar o FieldResolver, agora o código está mais limpo e ainda deixa o programador escolher se quer o FieldHandler ou MethodHandler.

Legall… vô testar.

M

E o JUnit test

package test.bean;

import static org.junit.Assert.assertTrue;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.junit.Before;
import org.junit.Test;

import test.model.Person;

import com.towel.bean.DynamicFormatter;
import com.towel.bean.Formatter;
import com.towel.el.FieldResolver;

public class TestDynamicFormatter {

	@Before
	public void setUp() throws Exception {
	}

	@Test
	public void testFormat() {
		// TESTE 1
		List<FieldResolver> a = new ArrayList<FieldResolver>();
		a.add(new FieldResolver(Person.class, "name"));
		a.add(new FieldResolver(Person.class,"age"));
		a.add(new FieldResolver(Person.class, "live"));

		DynamicFormatter<Person> d = new DynamicFormatter<Person>(Person.class,a, " - ");

		Person myPojoMock = new Person("Felipe", 23,true, "29061991");
		Object s = d.format(myPojoMock);

		assertTrue( s instanceof String);
		assertTrue( s.equals("Felipe - 23 - true"));

		// TESTE 2
		a.clear();
		a.add(new FieldResolver(Person.class,"name"));
//		a.add(new FieldResolver(Person.class,"number"));;
		a.add(new FieldResolver(Person.class,"age"));
		myPojoMock = new Person("Felipe", 23,true, "20101990");;

		d = new DynamicFormatter<Person>(Person.class,a, " ");

		s = d.format(myPojoMock);

		assertTrue( s instanceof String);
		assertTrue( s.equals("Felipe 23"));

		// TESTE UTILIZANDO O FORMAT

		a.clear();
		a.add(new FieldResolver(Person.class, "name"));
		
		FieldResolver resolver=  new FieldResolver(Person.class, "money");
		resolver.setFormatter(new Formatter(){
			@Override
			public String format(Object obj) {
				return NumberFormat.getNumberInstance(new Locale("pt","pt_BR")).format(Double.parseDouble(obj.toString()));
			}

			@Override
			public Object parse(Object source) {
				return null;
			}

			@Override
			public String getName() {
				// TODO Auto-generated method stub
				return null;
			}

		});
		a.add(resolver);
		myPojoMock.setMoney(25.10);

		d = new DynamicFormatter<Person>(Person.class,a, " ");

		s = d.format(myPojoMock);

		assertTrue( s instanceof String);
		assertTrue( s.equals("Felipe 25,1"));

		// TESTE 4

		s = d.format(null);
		assertTrue( s instanceof String);
		assertTrue( s.equals(""));
	}

}
P

Opa… agora fiko perfeito…
Eu troquei aqui por esta versão e funciono sem problemas algum…

Criado 13 de dezembro de 2010
Ultima resposta 20 de jan. de 2011
Respostas 44
Participantes 15