Como mesclar celular em DefaultTableModel / JTable?

Eu procurei muito e consegui algumas respostas para este Q. mas muitos deles se referiram a links que dão erro 404. Eu quero fazer uma tabela assim:

Número de células a serem mescladas não é fixo

Existe algum método em java para isso?

MultiSpanCellTableExample demonstra como mesclar células criando uma TableUI personalizada. Parece haver um problema neste exemplo que causa StackOverflowError , pelo menos no Java 6. Para corrigir isso, dentro de AttributiveCellTableModel.setDataVector() substitua:

 setColumnIdentifiers(columnNames); 

com:

 this.columnIdentifiers = columnNames; 

IE:

 public void setDataVector(Vector newData, Vector columnNames) { if (newData == null) throw new IllegalArgumentException( "setDataVector() - Null parameter"); dataVector = new Vector(0); // setColumnIdentifiers(columnNames); this.columnIdentifiers = columnNames; dataVector = newData; cellAtt = new DefaultCellAttribute(dataVector.size(), columnIdentifiers.size()); newRowsAdded(new TableModelEvent(this, 0, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } 

O problema é que setColumnIdentifiers chamadas setDataVector para setDataVector portanto, acionam o StackOverflowError . Depois de corrigido, é assim que o exemplo se parece:

insira a descrição da imagem aqui

Há também uma solução pronta do JIDE , infelizmente não é gratuita. Aqui está, por exemplo, CellSpanTable :

insira a descrição da imagem aqui

MultiCellSpanTableExample é bom, mas tem um pequeno problema que pode se tornar um grande problema se sua tabela tiver muitas colunas. Como você pode ver no exemplo dado pelo tenorsax, aparentemente cada coluna da tabela tem um pixel extra na sua largura. Esses pixels adicionais se summ, tornando cada coluna mais deslocada do que a anterior.

Eu poderia simplesmente consertar isso substituindo a linha:

 cellFrame.width = aColumn.getWidth() + columnMargin; 

com:

 cellFrame.width = aColumn.getWidth() + columnMargin - 1; 

Eu sei que ninguém perguntou, mas espero que isso ajude alguém. 🙂