How to merge cell in DefaultTableModel/JTable?
Asked Answered
F

3

13

I searched a lot and got some answers for this Q. but many of them referred to links which give 404 error. I want to make table like this:

No. of cells to be merged is not fixed

Is there any method in java for this?

Fulvi answered 18/2, 2014 at 14:26 Comment(4)
In one of my project, I use that SpanTable. In another I use group header from that SO answer. Try them.Bonaventure
You should check this and/or this.Pendulous
@Qui Exception in thread "main" java.lang.StackOverflowErrorFulvi
@Qui setColumnIdentifiers(columnNames); is causing problemFulvi
E
18

MultiSpanCellTableExample demonstrates how to merge cells by creating a custom TableUI. There seem to be a problem in this example that causes StackOverflowError, at least in Java 6. To fix this, inside AttributiveCellTableModel.setDataVector() replace:

setColumnIdentifiers(columnNames);

with:

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));
}

The problem is that setColumnIdentifiers calls into setDataVector hence triggering the StackOverflowError. Once fixed, this is how the example looks like:

enter image description here

There is also a ready solution from JIDE, unfortunately it is not free. Here is for example CellSpanTable:

enter image description here

Egon answered 24/2, 2014 at 2:23 Comment(1)
I've been using JIDE for years. The API is extremely rich, that is, if you can afford it. I believe they might have a student version. Not sure. Do a google for jidesoft.Whiffletree
D
11

MultiCellSpanTableExample is fine, but it has a little problem that can become a huge problem if your table has too many columns. As you can see in the example given by tenorsax, apparently each table column has an extra pixel in their width. Those additional pixels add up, making each column more displaced than the last.

I could simply fix that by replacing the line:

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

with:

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

I know nobody asked, but I hope this helps someone. :)

Devan answered 26/6, 2016 at 2:8 Comment(1)
thanks! finding the fix before even discovering the problem is the best!Lydon
C
0

Use a custom TableCellRenderer

import java.awt.Color;
import java.awt.Component;

import javax.swing.BorderFactory;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;

public class HeaderRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = 1L;
TableCellRenderer renderer;

public HeaderRenderer(JTable table) {
  renderer = table.getTableHeader().getDefaultRenderer();
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {

super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
switch (col) {
case 0:
  setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, Color.LIGHT_GRAY));
break;
case 1:
  setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, Color.LIGHT_GRAY));
break;
default:
  setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY));
break;
}
  return this;
}
}

from oracle doc

import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class SimpleTableDemo extends JPanel {
private static final long serialVersionUID = 1L;
public SimpleTableDemo() {
super(new GridLayout(1, 0));

String[] columnNames = { "First Name", "Last Name", "Sport", "# of Years", "Vegetarian" };

    Object[][] data = { { "Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false) },{ "John", "Doe", "Rowing", new Integer(3), new Boolean(true) },{ "Sue", "Black", "Knitting", new Integer(2), new Boolean(false) },{ "Jane", "White", "Speed reading", new Integer(20), new Boolean(true) },    { "Joe", "Brown", "Pool", new Integer(10), new Boolean(false) } };

JTable table = new JTable(data, columnNames);
TableCellRenderer myRenderer = new HeaderRenderer(table);
table.getTableHeader().setDefaultRenderer(myRenderer);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);

JScrollPane scrollPane = new JScrollPane(table);

add(scrollPane);
}

private static void createAndShowGUI() {
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);

frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Crossbow answered 13/11, 2018 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.