Essa é para os swingueiros de plantão(swinguers é outra coisa e não sou chegado a isso não… rsrsrs):
Tive problemas há pouco tempo atrás, para montar um JTable com Sub Headers, peguei uma classe bem antiga(acho que de 97-98), e cansei até dar o tratamento que eu queria na JTable.Com para corno, todo castigo é pouco, depois que tinha tudo pronto descobri uma (feita por Steve Webb) bem melhor que a minha, que funciona beleza.(Código completo no anexo).
Fica aqui registrado para quem precisar.
Não sei como não existe algo simples para isso, só grupando as colunas automaticamente.
[]´ção!
Nossa, interessante, baixei, agora só preciso implementar para funcionar.
Já executei e vi o resultado. Não achava que isso era possível hahaha
Brigadão o/
Nem precisa, se quiser testar, rode o GroupableColumnExample.java que vc verá funcionando.
Tem coisas que eu não entendo pq não tem algo assim na API.
Acabei de ter que fazer algo porco(e graannde) só para comparar uma célula de uma coluna com outra, e se uma for menor, pintar de uma cor, se for maior que a outra, de outra.Ter que ficar implementando um TableCellRenderer para colorir, outro para centralizar conteúdo… eu fico velho perdendo esse tempo danado. 
Nossa, muito bom, e funciona com qualquer model.
Acabei de testar com o que eu fiz e sem problema algum.
Perfeito!
Peraí, vc não deu só um setModel(seuTableModel) e funcionou,né? :shock:
Peraí, vc não deu só um setModel(seuTableModel) e funcionou,né? :shock: [/quote]
Não não, dei uma mechida naqueles TableHeadersGroups também.
Vou melhorar meu exemplo e posto aqui depois.
Mas o barato é bom mesmo.
Ah, tá… eu fiz uma pta gambiarra aqui para aceitar meu AbstractTableModel.Tá horroroso o código.
Sério?
Basicamente o que fiz.
ObjectTableModel<Person> model = new ObjectTableModel<Person>(
new AnnotationResolver(Person.class), "name,age,live");
model.add(new Person("Marky",19,true));
model.add(new Person("Doug",20,true));
model.add(new Person("Adams",17,true));
model.add(new Person("Vscs",23,true));
model.add(new Person("Pedro",70,false));
// Setup table
JTable table = new JTable();
table.setColumnModel(new GroupableTableColumnModel());
table.setTableHeader(new GroupableTableHeader(
(GroupableTableColumnModel) table.getColumnModel()));
table.setModel(model);
// Setup Column Groups
GroupableTableColumnModel cm = (GroupableTableColumnModel) table
.getColumnModel();
ColumnGroup g_name = new ColumnGroup("name");
g_name.add(cm.getColumn(1));
ColumnGroup g_token = new ColumnGroup(new GroupableTableCellRenderer(),
"live");
g_name.add(g_token);
g_token.add(cm.getColumn(2));
// Finish off gui
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll);
setSize(800, 200);
Mas não tenho certeza se usei todos recursos, é dificil pensar nesses groups ai.
Peraí o que vc mexeu nesse TableHeader.
Se eu apenas passar o model como vc passou acima eu receberia de cara um ArrayIndexOutOfBoundsException.
Acho que vou ter que customizar esse troço, tem que ficar mais fácil passar um AbstractTableModel, se não todo mundo vai usar o default para carregar os dados nesse troço(e nossa campanha vai por água abaixo… :lol: )
Então, eu tinha tomado um ArrayIndexOutOfBoundsException também, mas é por causa de g_token.add(cm.getColumn(3));
, e o model só tem 3 colunas (0, 1 e 2).
Tem que aprender configurar isso direitinho ou facilitar o modo como faz isso.
Realmente, não podemos nossa campanha ir por agua abaixo.
Na verdade, eu acho que é por causa do GroupableTableColumnModel(que extende DefaultTableColumnModel).Se vc testar, ele já bomba em cm.getColumn(0) pois vc recebe um:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:427)
(meu model de testes tem 9 colunas).Tô lendo a API aqui para ver o que é melhor substituir.
Ué, mas meu código ali em cima funcionou sem problemas.
Sem mexer em nenhuma das outras classes? :shock: (nem o TableHeader, se o fez, posta a mudança aqui)???
import java.awt.Color;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import mark.utils.el.annotation.AnnotationResolver;
import mark.utils.swing.table.ObjectTableModel;
public class GroupableColumnExample extends JFrame {
GroupableColumnExample() {
super("Multi-Width Header Example");
ObjectTableModel<Person> model = new ObjectTableModel<Person>(
new AnnotationResolver(Person.class), "name,age,live");
model.add(new Person("Marky",19,true));
model.add(new Person("Doug",20,true));
model.add(new Person("Adams",17,true));
model.add(new Person("Vscs",23,true));
model.add(new Person("Pedro",70,false));
// Setup table
JTable table = new JTable();
table.setColumnModel(new GroupableTableColumnModel());
table.setTableHeader(new GroupableTableHeader(
(GroupableTableColumnModel) table.getColumnModel()));
table.setModel(model);
// Setup Column Groups
GroupableTableColumnModel cm = (GroupableTableColumnModel) table
.getColumnModel();
ColumnGroup g_name = new ColumnGroup("name");
g_name.add(cm.getColumn(1));
ColumnGroup g_token = new ColumnGroup(new GroupableTableCellRenderer(),
"live");
g_name.add(g_token);
g_token.add(cm.getColumn(2));
// Finish off gui
JScrollPane scroll = new JScrollPane(table);
getContentPane().add(scroll);
setSize(800, 200);
}
public static void main(String[] args) {
GroupableColumnExample frame = new GroupableColumnExample();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
}
}
/**
* Demo renderer just to prove they can be used.
*/
class GroupableTableCellRenderer extends DefaultTableCellRenderer {
/**
*
* @param table
* @param value
* @param selected
* @param focused
* @param row
* @param column
* @return
*/
public Component getTableCellRendererComponent(JTable table, Object value,
boolean selected, boolean focused, int row, int column) {
JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(Color.WHITE);
setBackground(Color.RED);
}
setHorizontalAlignment(SwingConstants.CENTER);
setText(value != null ? value.toString() : " ");
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
}
E o o model Person
import mark.utils.bean.Formatter;
import mark.utils.el.annotation.Resolvable;
public class Person {
@Resolvable(colName = "Name")
private String name;
@Resolvable(colName = "Age", formatter = ObjectFormatter.class)
private int age;
@Resolvable(colName = "Live", formatter = ObjectFormatter.class)
private boolean live;
public Person(String name, int age, boolean live) {
this.name = name;
this.age = age;
this.live = live;
}
public static class ObjectFormatter implements Formatter {
public Object format(Object arg0) {
return arg0;
}
public String getName() {
return "obj";
}
public Object parse(Object arg0) {
return arg0;
}
}
}
Marky.Vasconcelos, como faço para mapear sua ObjectTableModel usando um relacionamento OneToOne?
grato
Wesley Oiveira
PS: Esse topico merecia aquela carta “O topico que renasce” kk
anyway…
O que voce quis dizer com esse relacionamento OneToOne? Se for mostrar atributos dos objetos dentro do objeto do model (exemplo: person.getAddress().getStreet()) o ObjectTableModel já suporta, desde que os dados já estejam no modelo.