MarkUtils sob novo nome!

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

Parabéns!

[]s
[/quote]

Tem algum ‘GitHub for Dummies’? :lol: [/quote]
http://help.github.com/

:smiley:

[/quote]

Perfeito, vlw :wink:

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

Aproveitem e me sigam.

Good Job !!!

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

:wink:

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

[quote=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![/quote]

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!

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.

[quote=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.[/quote]

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.

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.

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

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)

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.

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…

[quote=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… [/quote]

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

Obrigado por compartilhar.

PS:

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

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

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”

[quote=Marky.Vasconcelos]PS:

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

Não é o Towel do MarkUtils, é o projeto Towel, antigo MarkUtils.[/quote]

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

era para ficar do projeto Towel do Marky Vasconcelos

Corrigido

[quote=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”[/quote]

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…

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

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.

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.