问题
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:
Is there any method in java for this?
回答1:
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:
There is also a ready solution from JIDE, unfortunately it is not free. Here is for example CellSpanTable
:
回答2:
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. :)
回答3:
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();
}
});
}
}
来源:https://stackoverflow.com/questions/21856733/how-to-merge-cell-in-defaulttablemodel-jtable