Telas de seleção padronizadas.

Olá. Outro problema comum em desenvolvimento Swing é o fato das telas de consultas. Na maioria das vezes temos que criar muitas telas que fazem praticamente a mesma coisa. Então decedi implementar uma tela tão genérica quando o TableModel que descrevi no post anterior.

Primeiro: baixar o código fonte do projeto na página Towel Project desse blog.

Vou usar a classe Person como exemplo novamente.

import com.towel.el.annotation.Resolvable;
public class Person {
	@Resolvable(colName = "Name)
	private String name;
	@Resolvable(colName = "Age", formatter = IntFormatter.class)
	private int age;
	private Person parent;
	public Person(String name, int age) {
		this(name, age, null);
	}
	public Person(String name, int age, String bd, Person parent) {
		this.name = name;
		this.age = age;
		this.parent = parent;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Person getParent() {
		return parent;
	}
	public void setParent(Person parent) {
		this.parent = parent;
	}
	public static class IntFormatter implements Formatter {
	@Override
	public String format(Object obj) {
		return Integer.toString((Integer) obj);
	}
	@Override
	public String getName() {
		return "int";
	}
	@Override
	public Object parse(String s) {
		return Integer.parseInt(s);
	}
}
}

Se voce não sabe pra que serve a anotação @Resolvable sugiro ver no meu post anterior sobre o ObjectTableModel.

Agora para nossa tela de seleção.

Precisamos apenas do seguinte código para ter uma tela para seleção.

	FieldResolver[] cols = new AnnotationResolver(Person.class)
		.resolve("name:Nome,age:Idade,parent.name:Pai");
	SelectTable st =new SelectTable(cols,getData());
	st.addObjectSelectListener(new ObjectSelectListener() {
		@Override
		public void notifyObjectSelected(SelectEvent selectevent) {
				Person p = (Person) selectevent.getObject();
				System.out.println(p.getName());
				System.out.println(p.getAge());
			}
	});
	st.showSelectTable();

Com esse código temos uma tela como a seguinte.
Exemplo SelectTable

Algumas vantagens dessa tabela:

  • Paginação e navegação pelos resultados evitando scrolls.
  • Ordenação da pagina clicando nos nomes das colunas.
  • Busca “on-the-fly” pelo atributo da coluna clicada.
  • Botão search filtra o resultado.

Após um duplo clique em um resultado ou então selecionar pelo botão um SelectEvent sera disparado ao Listener que foi adicionado para a tela.
No caso ele só vai imprimir o nome e a idade da pessoa. Mas em uma aplicação real o uso poderia ser muito mais eficiente.

Para alterar o nome dos botões existem os métodos
setSearchButtonText
setSelectButtonText
setCloseButtonText

Que alteram o nome dos botoes search, select e close respectivamente.

Para alterar o titulo da janela ao invés de mostrarmos a tabela com st.showSelectTable podemos passar uma String como parametro que será o nome da janela.

Também existem casos que nosso resultado não está em forma de List.
Na verdade o construtor que recebe um List como argumento apenas encapsula em uma implentação de com.towel.collections.paginator.Paginator feita para Lists.

Mas voce pode implementar o seu próprio e receber dados de qualquer forma.

Caso precisem receber uma lista como resultado é necessario passar outro argumento para o construtor.

SelectTable st = new SelectTable(cols,
				new ListPaginator(getData(), 20), SelectTable.LIST);

Note também o uso do ListPaginator também que dividi a lista em varias com no maximo 20 resultados em cada.

E nese caso é possivel fazer um cast do selectevent.getObject() para List.

As vezes nossa intenção não é abrir uma nova janela. Para isso existe o método getContent da SelectTable que retorna um JPanel com todo o conteudo para ser adicionado onde necessario.