Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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. :)

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();
}
});
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top