Towel release 1.2

58 respostas
Marky.Vasconcelos

Hoje dia 25/05 está sendo liberado o novo release do projeto Towel.

As novidades são:

[list]FieldResolver consegue obter/setar os valores dos atributos através da hierarquia do objeto;[/list]
[list]Não é obrigatório declarar as anotações @Resolvable em todos os atributos;[/list]
[list]Um novo componente foi incluido no pacote com.towel.swing sob o nome de CalendarView, que é um DatePicker para Swing(artigo em breve);[/list]

Para baixar a nova versão, basta acessar a pagina de downloads no github.

Noticia original com mais informações.

Mais uma coisa está acontecendo hoje:

Dia 25/05 é o Towel Day, em homenagem a Douglas Adams.
Abraço a todos, e feliz dia da toalha!

:wink:

58 Respostas

Priuli

Cada vez ficando melhor!!!..

TheKill

Mark, estou tentando visualizar teu CalendarView e DatePicker, mas como eu pego o dia, mes, ano do CalendarView ?

TheKill

A saquei, vc ja ta usando internamente dentro do CalendarView… :slight_smile:

Gostei da implementação, e como ficaria a questão de BUG´s, acesso aos fontes, maneira a implementação

Marky.Vasconcelos

Na verdade, essa classe CalendarView foi meu professor de Java que fez em 1999.

Eu fiz um refactoring monstruoso para voce ter idéia, esse componente recebia 4 inteiros no construtor.

Ele assumia que o parent usava null-layout e se “auto-setava” com setBounds.

Mas realmente, agora que voce falou, esqueci de criar um metodo util “getSelectedDate” nele.

É necessario pegar com o getText e ainda converter =/

TheKill

Sim, eu notei a falta de algo para retornar a data…

Mas ficou legal o componente

Marky.Vasconcelos

Alias, adicionei esse método que tinha esquecido.

J

Muito bom… sempre presente em meus projetos! É uma mão na roda!

Eu inclusive tive que fazer uma modificação (comentar 2 linhas) na classe TableHeaderPopup se não me engano. Fiz isso porque estava dando erro quando usado juntamente o Substance LAF. Há ainda algumas modificações que pretendo fazer no TableFilter em breve para resolver um problema que tive ao ter que acessar o índice do model de acordo com o filtro na JTable. Eu até iria relatar o problema, mas acabei esquecendo.

Mas valeu… o Towel está ficando cada vez melhor! Parabéns.

Adelar

Legal, vou acompanhar o projeto.

Feliz dia da toalha pra vc também Marky :smiley:

TheKill

Ja atualizou o jar do gitHub ?

=)

Mark sempre com suas inovações, parabens ae pelo utilProject

Marky.Vasconcelos

Sim, o 1.2 que está lá já é a versão com o método getSelectedDate.

Assim que voce disse eu fiz a troca rapidamente :stuck_out_tongue:

TheKill

rs,

quase na velocidade da luz hauisdhaiudhiaud
tem que melhorar essa velocidade ein ^^

Congratulations

T

Até quem fim! tava esperando o novo Towel hehehehe xD

CintiaDR

Eu tenho até um projeto semi-fake esquecido que acho que uma toalha cairia bem rs

Diz aí uma coisa, a licença é CC3.0. Tem alguma razão pela qual vc não usou a GPL ou LGPL? Digo isso porque não entendo ela bem.

Marky.Vasconcelos

CintiaDR:
Eu tenho até um projeto semi-fake esquecido que acho que uma toalha cairia bem rs

Diz aí uma coisa, a licença é CC3.0. Tem alguma razão pela qual vc não usou a GPL ou LGPL? Digo isso porque não entendo ela bem.

Good question, também não entendo muito bem de licenças. :oops:

Só sei que a GPL é viral, se liberar assim qualquer projeto que utilize precisa ser GPL, e não faço questão disso.

Só coloquei CC 3.0 por que eu achei meu codigo em um outro projeto com os nomes modificados e com o autor dizendo ser idéia dele. Mas posso mudar para uma mais interessante.

E realmente, toalhas são muito uteis :stuck_out_tongue:

CintiaDR

Eu sempre fico na dúvida dessas coisas.

O que eu ACHO, e posso estar muito errada, que a GPL é sim viral (isto é, qualquer trabalho que derive/link deve ser GPL tb). Pra ser GPL, todas as partes ali dentro tem que ter uma licença compatível.

A LGPL, por outro lado, não ‘propaga’, isto é, trabalhos que linkem não precisam ser GPL nem nada.

Ironlynx

Wow!Beleza Marky, só agora que eu vi.Já tô atualizando meu projeto aqui para utilizá-lo! :wink:

Idéias para futuras versões:Um CellFormatter(acho que já citei antes) e um DataGrid, sem abrir mão da internacionalização nos botões do componente.

Priuli

CintiaDR:
Eu sempre fico na dúvida dessas coisas.

O que eu ACHO, e posso estar muito errada, que a GPL é sim viral (isto é, qualquer trabalho que derive/link deve ser GPL tb). Pra ser GPL, todas as partes ali dentro tem que ter uma licença compatível.

A LGPL, por outro lado, não ‘propaga’, isto é, trabalhos que linkem não precisam ser GPL nem nada.

±, um projeto GPL só pode ser modificado se quem modifica também seguir a mesma licença, em outras palavras, quem modifica ñ pode limitar nada da licença original e também deve disponibilizar as modificações da mesma forma que foi obtido do código original. Porem vc pode usar em códigos proprietários deste que não modifique nada, e até vender desde que o código fonte seja entregue junto na venda. Esta licença é mais usada em programas executáveis como destop, web…(mas não é regra)
Já a LGPL é utilizada mais em bibliotecas de códigos, é mais livre que a gpl, e não obriga q a modificação do código original siga a mesma regra da gpl, assim uma modificação pode até ir em sistema fechado proprietário, porem existe restrições do código como por exemplo os nomes dos autores sempre tem que ser mantidos entre varias outras…

Marky.Vasconcelos

Tem como explicar mais um pouco? Eu anoto na TodoList.

Valeu por explicar, acho melhor eu usar LGPL então né?

Priuli

Marky.Vasconcelos:

Valeu por explicar, acho melhor eu usar LGPL então né?

Existe uma porrada de tipos de lincença, mas para o seu proj que tá mais como biblioteca, eu aconselharia a LGPL.

Marky.Vasconcelos

Só pra constar, o artigo de como usar o CalendarView éstá pronto.

@priuli
Vou usar LGPL então.

Ironlynx

Fala Marky!
Eu já tinha postado algo aqui: http://www.guj.com.br/posts/quote/15/1198744.java

O ideal é podermos ter algo a menos para se preocupar.
Imagine uma JTable assim:
Nome tempo1 tempo2 média
Cesar Cielo 20,91 20,89 20,90
Frederick Bousquet 20,94 21,30 21,12
Nathan Adrian 21,55 21,49 21,52

Imagine que ao vc preencher o campo 2, vc quer automaticamente gerar a média FORMATADA do outro lado, seja um double ou um BigDecimal.O problema é:Vc tem que pegar o valor, formatar para a célula, pegar do conteúdo digitado, fazer os cálculos/processamento, pegar o resultado e formatar de novo para a exibição na célula posterior.
Se o programador pudesse passar o tipo de formatação que ele quer a um CellFormatter para exibição e não se preocupar mais com isso a não ser recuperar e trabalhar com esses valores para um dado processamento, seria um trabalho a menos muito interessante.Talvez o Vini possa ter alguma idéia bacana sobre isso.
Já o DataGrid, poderia vir como uma especialização/aprimoramento do SelectTable, permitindo uma paginação/navegação eventual por componentes do BD, pesquisa por datas…

Há, algo que eu tinha esquecido, permitir um setFont no SelectTable, pq em alguns looks and feel(eu uso o Liquid), as letras ficam sem destaques.Se eu puder ao menos deixá-las bold, isso já ajuda para os usuários “cegos”.

No mais, muito bom o projeto.Vou testar algumas das novas features. :thumbup:

Marky.Vasconcelos

@Ironlynx

Ah é, agora lembrei disso do CellRenderer.

Vou pensar em uma solução legal pra isso.

Valeu pela dica.

Talvez eu faça isso para o proximo release, junto com um super refactoring que farei no JTableView com as AggregateFunction para ficarem mais redimensionaveis.

Ironlynx

Não consegui achar onde vc postou a API, por isso posto aqui:
Uma das coisas chatas com o JCalendar, é não possuir um método clear ou reset para restaurar o estado inicial quando necessário(sem ter que reinstanciar o objeto).Se não tiver, seria interessante de por um. :slight_smile:

Marky.Vasconcelos

Anotado :wink:

E como assim não achou a API?

dbadaniel

fala grande Marky !!

Uma duvida bem rapida, eu uso sua lib já faz um tempinho , desde quando tinha outro nome :smiley: !

Agora encontrei um problema com jcombobox , eu tenho uma tela que as vezes eu tenho que atualizar o compo, mas quando eu faço isso o combo é não mostras os item dentro do combo.
Bom uma solução que achei para isso foi tentar um removel all items, mas isso leva a outro problema, uma exception

java.lang.RuntimeException: Cannot use this method with a non-Mutable data model.

aqui um trecho do codigo que uso para atualizar :

role.exec(); //executa query no banco        
combo.setData(role.getRoles());  // retorna o o result para dentro do ObjectComboBoxModel      
jComboBox1.setModel(combo);       
repaint();

alguma dica !!!?

valeu
abraços !

dbadaniel

nada como tomar uma água !!!
acabei de ver que não precisa setar o model novamente !!
apenas carregar o model novamente !!

ou seja o fica é somente isso :

role.exec();        
 combo.setData(role.getRoles());       
 //jComboBox1.setModel(combo);       
 repaint();

valeu !!!

ps : isso apenas comprova como é util o towel !!! :smiley:

Daniel

Marky.Vasconcelos

dbadaniel:
nada como tomar uma água !!!
acabei de ver que não precisa setar o model novamente !!
apenas carregar o model novamente !!

Essa é a idéia mesmo, se precisar mudar todos os dados é só usar o setData.

Sempre tentando ser mais util e mais pratico :wink:

Ironlynx

Devia ter sido mais claro.Não achei os docs, a documentação da API.

Marky.Vasconcelos

Devia ter sido mais claro.Não achei os docs, a documentação da API.

Verdade, preciso de um dominio e logo disponibilizarei os docs.

dbadaniel

Olha o Combo novamente !!!

Marky esse é outro codigo, mas deveria funcionar igual … não achei está errado:

cod carregando o combo ( ok )

consultainss = Lookup.getDefault().lookup(ConsINSS.class);
        comboconsulta = new ObjectComboBoxModel<ConsultasINSS>();
        comboconsulta.setFormatter(new ComboINSS()); // isso é apenas para forma o display do combo.
        consultainss.exec();
        comboconsulta.setData(consultainss.getList());
        jComboBox6.setModel(comboconsulta);

add um novo registro

private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                                         
       NovaConsulta dialog = new NovaConsulta(); 
        
       DialogDescriptor d = new DialogDescriptor(dialog, "Novo Login", true, DialogDescriptor.OK_CANCEL_OPTION,
       DialogDescriptor.OK_OPTION, null);          
        d.setValid(false);
        dialog.setDialogDescriptor(d);
        DialogDisplayer.getDefault().notify(d);         
       
        if(!dialog.getDesc().isEmpty()){
            ConsultasINSS novo = new ConsultasINSS();
            novo.setDescricao(dialog.getDesc());
            int idx = comboconsulta.getSize()-1;
            novo.setConsulta(consultainss.getList().get(idx).getConsulta()+1);
            novo.setData(DateUtil.sysdate());
            consultainss.save(novo);
            consultainss.commit();
            consultainss.exec();
            comboconsulta.setData(consultainss.getList());
            comboconsulta.setSelectedObject(novo);            
            repaint();
        }    
    }

mas quando eu faço esse add , o combo fica em branco.

o que será que pode estar errado ?!

Marky.Vasconcelos

Voce já debugou esse código e viu se getList retorna uma List populada?

Só para constar, voce nao precisa usar o setData uma vez que o combo esteja preenchido.

Use o add com o novo objeto que precisa ser adicionado.

dbadaniel

Sim eu fiz um debug da aplicação, o list do hibernate vem ok e quando eu dou o setData o array do objeto ObjectComboBoxModel também fica ok.

Agora uma coisa estranha que aconteceu , foi que ao dar o add, o combo também fica em branco.

Marky.Vasconcelos

Hmm… vou criar um exemplo pequeno para ver se consigo reproduzir esse erro.

dbadaniel

marky, o mais estranho é que eu tenho outra tela que usa isso também e não está acontecendo isso.

Hoje eu fiz um upgrade para versão 1.2, mas sem sucesso.

até tirei o formatter para ver se tinha alguma diferença, porém acontece do mesmo jeito…

bom se precisar de alguma informação a mais , estou a disposição !

abcs

dbadaniel

Marky, Bom dia !!

Olha depois e revisar tudo e ter certeza que não tinha nada muito diferente de uma tela que funciona para essa sem funcionar eu apaguei dei um clear geral do projeto, apaguei alguns jars na mão e mandei gerar tudo novamente.

Eis que tudo funciona agora !!

Mesmo assim muito grato pelo atenção e disponibilidade !

abraços
Daniel

Marky.Vasconcelos

Nossa, ainda bem que agora funciona.

Pode contar comigo se tiver duvidas :wink:

C

Salve galera do projeto Towel estou usando a lib que por sinal é uma mão na roda, parabéns.
Estou com um detalhe que não consegui resolver, quando utilizo o tablefilter em um jtable nos frames que usam windows lookandfeel as bordas do tableheader somem, alguem já viu isso? nada que impeça a utilização somente questão de estética mesmo.

Ironlynx

Também tive uns probleminhas com uso de L&F no Towell(uso o liquid), no meu caso, ao usar a selecttable, meus labels ficam sem negrito, e eu não consigo deixá-los em negrito.Mas não dei muita bola pq não prejudica o uso geral do sistema.

J

callgas:
Salve galera do projeto Towel estou usando a lib que por sinal é uma mão na roda, parabéns.
Estou com um detalhe que não consegui resolver, quando utilizo o tablefilter em um jtable nos frames que usam windows lookandfeel as bordas do tableheader somem, alguem já viu isso? nada que impeça a utilização somente questão de estética mesmo.

Também aconteceu comigo. Aqui uso o Substance e pra poder usar tive que comentar as linhas 186 e 187 do TableHeaderPopup se não me engano para usar com o Substance porque ocorria um erro e nem chegava a exibir a view que continha a JTable.

C

Eu alterei tambem, mas não comentei, substitui a linha 188

panel.setBorder(label.getBorder()); por

panel.setBorder(border);

no meu caso funcionou bem no windows lookand feel, não testei com o substance

Marky.Vasconcelos

Coloquei um novo jar para download com uma pequena atualização.

O amigo Paulo Henrique enviou um path para que seja possivel setar o texto que fica “Today” no CalendarView.

Para usar é simples:

CalendarView view = new CalendarView();
		view.setTodayString("Hoje");

E basta adicionar a view no lugar que continuara funcionando.

Ironlynx

Já baixando!

Marky, tive pensando numa solução para o CellFormatter e pensei:pq não aproveitar as próprias anotações(Resolvable) do towell?
Pensei em algo do tipo:

@Resolvable(colName = "Time", formatter = BigDecimalFormatter.class colWidth=40 cellFormatter ="00,00;00,000" )
    private BigDecimal time;
@Resolvable(colName = "Date", formatter = DateFormatter.class colWidth=30 cellFormatter ="dd/MM/yyyy" )
    private Date data;

Aí, o importante seria ter métodos do tipo:
MinhaCélula.getFormattedText//pegar o texto puro como formatado tipo 9,991
minhaCélula.getValue //pega os valores de verdade, tipo 9.991
para o usuário fazer as operações necessárias.

Repare que no campo time eu permiti dois valores para o cellFormatter.Isso pode servir para garantir um mínimo(tipo pelo menos 2 casas decimais, máximo 3).

Marky.Vasconcelos

@Ironlynx

Verdade, acho que poderia aproveitar sim.

Mas dai no caso, para que serviria o Formatter se existir os parametros para o cellFormatter?

E não sei como eu conseguiria formatar qualquer coisa, por exemplo no seu codigo, como eu iria formatar um BigDecimal nesse padrao sem deixar hard coded?

Ironlynx

Deixa uma opção de formatação genérica, e outra só para a célula da JTable.O cellFormatter deve ser uma formatação de E/S, para tirar o peso do programador principalmente quando precisar fazer oiperação entre as células.

Por debaixo dos panos, não tenho dúvidas de que ficará hardcoded para o Towell, mas penso que ficará transparente ao programador,não?
Eu penso mais nos beneficios da coisa, e sempre quando eu preciso de uma operação entre as células da JTable, sai + ou - uma gambiarra.Seria uma boa o vini dar uma opnião sobre o assunto, ele sempre tem uma idéia bacana nesses casos.

Marky.Vasconcelos

Realmente, para o programador ficaria transparente.

Acho que nao vai ter como fugir de deixar algumas coisas direto no codigo.

J

Mark.
O método abaixo do ObjectTableModel não funciona corretamente:

public void remove(int idx[]) {
		for (int i : idx)
			remove(i);
	}

Dessa maneira tenho sempre que inverter o array para poder dar certo.

Uma sugestão seria:

public void remove(int idx[]) { for (int i = idx.length - 1; i >= 0; i--) remove(i); }

Marky.Vasconcelos

@joyle

Bem lembrado, obrigado, vou atualizar.

J

Mark, enviei um pull com essa pequena alteração pra ti lá no git.

Marky.Vasconcelos

Beleza, vou lembrar como pego o pull denovo :stuck_out_tongue:

Marky.Vasconcelos

Nossa, da para fazer merge automatico pelo site.

Ta lá já, valeu.

J

Marky.Vasconcelos:
Nossa, da para fazer merge automatico pelo site.

Ta lá já, valeu.


Mark, só agora percebi que faltou passar o array no argumento de “remove()”. Já enviei o pull com a correção também.
O método correto ficou assim:

/**
	 * Removes all the values in the specified rows.
	 *
	 * @param idx
	 *            the rows to be removed
	 */
	public void remove(int idx[]) {
		for (int i = idx.length - 1; i >= 0; i--) {
			remove(idx[i]);
		}
	}

Desculpe pela falta de atenção. :wink:

Marky.Vasconcelos

Eu já vi e já atualizei.

vinnysoft

Boa Noite Marky!

Esta é a primeira vez que irei testar o projeto Towel. Leio muitas coisas boas sobre ele, parabéns!

Gostaria de saber se ele está em algum repositório Maven. Se sim, vc tem a dependência?

Obrigado!

Até +!

Marky.Vasconcelos

Ele está somente no github.

vinnysoft

Boa Tarde.

Seu framework está muito bom, Marky! Consegui utilizar bem o ObjectTableModel (foi o atrativo inicial! kkk).

Agora tenho algumas dúvidas:

  1. Para utilizá-lo, eu precisei informar as colunas que eu queria na criação do ObjectTableModel. Testei as três formas:
  • usando FieldResolver e as colunas;
  • usando AnnotationResolver e as colunas;
  • usando a Classe.class e as colunas.

Agora é obrigatório sempre informar as colunas que quero gerar? Isto deixa um pouco inflexível, pois se eu usar o ObjectTableModel em 5 janelas, e criar um novo atributo na minha classe, terei que informar em todas as 5 janelas a minha nova coluna.

  1. Existe alguma forma de eu anotar somente a classe que quero gerar o ObjectTableModel e já são criadas as colunas de todos os atributos da classe? Tipo da forma que o hibernate / JPA fazem quando anoto @Entity na classe.

Você têm alguma idéia quanto a primeira pergunta?

Obrigado!

Marky.Vasconcelos

É, a idéia seria sempre descrever as colunas quando for criar o model.

Principalmente por que voce pode quere exibir coisas diferentes em lugares diferentes.

Se voce adicionar uma coluna nova, e quiser exibi-la, voce vai precisar declarar em todos os ObjectTableModels que voce criou para essa classe.

vinnysoft

Entendi Marky!

Mas gostaria de deixar a sugestão (se possível…rs): criar um outro construtor:

ObjectTableModel  modelo = new ObjectTableModel(MinhaClasse.class); //sem informar as colunas...

E por default ele criaria o modelo com as colunas/nome das colunas = todos os atributos, evitando o problema que eu levantei no post anterior.

Se fosse necessário mapear somente alguns atributos/colunas, ai eu utilizaria o outro construtor:

ObjectTableModel  modelo = new ObjectTableModel(MinhaClasse.class, "coluna1,coluna2");

De qualquer forma o Towel é ótimo, está de parabéns!

Até +!

Marky.Vasconcelos

Obrigado, vou levar isso em consideração para futuros releases.

Obrigado pela ideia!

:wink:

Criado 25 de maio de 2011
Ultima resposta 11 de nov. de 2011
Respostas 58
Participantes 11