/*
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
/**
* @version 1.0 11/22/98
*/public class AttributiveCellTableModel extends DefaultTableModel { protected CellAttribute cellAtt;
public AttributiveCellTableModel() {
this((Vector)null, 0);
}
public AttributiveCellTableModel(int numRows, int numColumns) {
Vector names = new Vector(numColumns);
names.setSize(numColumns);
setColumnIdentifiers(names);
dataVector = new Vector();
setNumRows(numRows);
cellAtt = new DefaultCellAttribute(numRows,numColumns);
}
public AttributiveCellTableModel(Vector columnNames, int numRows) {
setColumnIdentifiers(columnNames);
dataVector = new Vector();
setNumRows(numRows);
cellAtt = new DefaultCellAttribute(numRows,columnNames.size());
}
public AttributiveCellTableModel(Object[] columnNames, int numRows) {
this(convertToVector(columnNames), numRows);
}
public AttributiveCellTableModel(Vector data, Vector columnNames) {
setDataVector(data, columnNames);
}
public AttributiveCellTableModel(Object[][] data, Object[] columnNames) {
setDataVector(data, columnNames);
}
public void setDataVector(Vector newData, Vector columnNames) {
if (newData == null)
throw new IllegalArgumentException("setDataVector() - Null parameter");
dataVector = new Vector(0);
setColumnIdentifiers(columnNames);
dataVector = newData;
//
cellAtt = new DefaultCellAttribute(dataVector.size(),
columnIdentifiers.size());
newRowsAdded(new TableModelEvent(this, 0, getRowCount()-1,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
} public void addColumn(Object columnName, Vector columnData) {
if (columnName == null)
throw new IllegalArgumentException("addColumn() - null parameter");
columnIdentifiers.addElement(columnName);
int index = 0;
Enumeration enumeration = dataVector.elements();
while (enumeration.hasMoreElements()) {
Object value;
if ((columnData != null) && (index < columnData.size()))
value = columnData.elementAt(index);
else
value = null;
((Vector)enumeration.nextElement()).addElement(value);
index++;
} //
cellAtt.addColumn(); fireTableStructureChanged();
} public void addRow(Vector rowData) {
Vector newData = null;
if (rowData == null) {
newData = new Vector(getColumnCount());
}
else {
rowData.setSize(getColumnCount());
}
dataVector.addElement(newData); //
cellAtt.addRow(); newRowsAdded(new TableModelEvent(this, getRowCount()-1, getRowCount()-1,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
} public void insertRow(int row, Vector rowData) {
if (rowData == null) {
rowData = new Vector(getColumnCount());
}
else {
rowData.setSize(getColumnCount());
} dataVector.insertElementAt(rowData, row); //
cellAtt.insertRow(row); newRowsAdded(new TableModelEvent(this, row, row,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
} public CellAttribute getCellAttribute() {
return cellAtt;
} public void setCellAttribute(CellAttribute newCellAtt) {
int numColumns = getColumnCount();
int numRows = getRowCount();
if ((newCellAtt.getSize().width != numColumns) ||
(newCellAtt.getSize().height != numRows)) {
newCellAtt.setSize(new Dimension(numRows, numColumns));
}
cellAtt = newCellAtt;
fireTableDataChanged();
} /*
public void changeCellAttribute(int row, int column, Object command) {
cellAtt.changeAttribute(row, column, command);
} public void changeCellAttribute(int[] rows, int[] columns, Object command) {
cellAtt.changeAttribute(rows, columns, command);
}
*/
}
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
/**
* @version 1.0 11/22/98
*/public class AttributiveCellTableModel extends DefaultTableModel { protected CellAttribute cellAtt;
public AttributiveCellTableModel() {
this((Vector)null, 0);
}
public AttributiveCellTableModel(int numRows, int numColumns) {
Vector names = new Vector(numColumns);
names.setSize(numColumns);
setColumnIdentifiers(names);
dataVector = new Vector();
setNumRows(numRows);
cellAtt = new DefaultCellAttribute(numRows,numColumns);
}
public AttributiveCellTableModel(Vector columnNames, int numRows) {
setColumnIdentifiers(columnNames);
dataVector = new Vector();
setNumRows(numRows);
cellAtt = new DefaultCellAttribute(numRows,columnNames.size());
}
public AttributiveCellTableModel(Object[] columnNames, int numRows) {
this(convertToVector(columnNames), numRows);
}
public AttributiveCellTableModel(Vector data, Vector columnNames) {
setDataVector(data, columnNames);
}
public AttributiveCellTableModel(Object[][] data, Object[] columnNames) {
setDataVector(data, columnNames);
}
public void setDataVector(Vector newData, Vector columnNames) {
if (newData == null)
throw new IllegalArgumentException("setDataVector() - Null parameter");
dataVector = new Vector(0);
setColumnIdentifiers(columnNames);
dataVector = newData;
//
cellAtt = new DefaultCellAttribute(dataVector.size(),
columnIdentifiers.size());
newRowsAdded(new TableModelEvent(this, 0, getRowCount()-1,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
} public void addColumn(Object columnName, Vector columnData) {
if (columnName == null)
throw new IllegalArgumentException("addColumn() - null parameter");
columnIdentifiers.addElement(columnName);
int index = 0;
Enumeration enumeration = dataVector.elements();
while (enumeration.hasMoreElements()) {
Object value;
if ((columnData != null) && (index < columnData.size()))
value = columnData.elementAt(index);
else
value = null;
((Vector)enumeration.nextElement()).addElement(value);
index++;
} //
cellAtt.addColumn(); fireTableStructureChanged();
} public void addRow(Vector rowData) {
Vector newData = null;
if (rowData == null) {
newData = new Vector(getColumnCount());
}
else {
rowData.setSize(getColumnCount());
}
dataVector.addElement(newData); //
cellAtt.addRow(); newRowsAdded(new TableModelEvent(this, getRowCount()-1, getRowCount()-1,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
} public void insertRow(int row, Vector rowData) {
if (rowData == null) {
rowData = new Vector(getColumnCount());
}
else {
rowData.setSize(getColumnCount());
} dataVector.insertElementAt(rowData, row); //
cellAtt.insertRow(row); newRowsAdded(new TableModelEvent(this, row, row,
TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
} public CellAttribute getCellAttribute() {
return cellAtt;
} public void setCellAttribute(CellAttribute newCellAtt) {
int numColumns = getColumnCount();
int numRows = getRowCount();
if ((newCellAtt.getSize().width != numColumns) ||
(newCellAtt.getSize().height != numRows)) {
newCellAtt.setSize(new Dimension(numRows, numColumns));
}
cellAtt = newCellAtt;
fireTableDataChanged();
} /*
public void changeCellAttribute(int row, int column, Object command) {
cellAtt.changeAttribute(row, column, command);
} public void changeCellAttribute(int[] rows, int[] columns, Object command) {
cellAtt.changeAttribute(rows, columns, command);
}
*/
}
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;import java.awt.*;
/**
* @version 1.0 11/22/98
*/public class DefaultCellAttribute
// implements CellAttribute ,CellSpan {
implements CellAttribute ,CellSpan ,ColoredCell ,CellFont { //
// !!!! CAUTION !!!!!
// these values must be synchronized to Table data
//
protected int rowSize;
protected int columnSize;
protected int[][][] span; // CellSpan
protected Color[][] foreground; // ColoredCell
protected Color[][] background; //
protected Font[][] font; // CellFont
public DefaultCellAttribute() {
this(1,1);
}
public DefaultCellAttribute(int numRows, int numColumns) {
setSize(new Dimension(numColumns, numRows));
} protected void initValue() {
for(int i=0; i<span.length;i++) {
for(int j=0; j<span[i].length; j++) {
span[i][j][CellSpan.COLUMN] = 1;
span[i][j][CellSpan.ROW] = 1;
}
}
}
//
// CellSpan
//
public int[] getSpan(int row, int column) {
if (isOutOfBounds(row, column)) {
int[] ret_code = {1,1};
return ret_code;
}
return span[row][column];
} public void setSpan(int[] span, int row, int column) {
if (isOutOfBounds(row, column)) return;
this.span[row][column] = span;
}
public boolean isVisible(int row, int column) {
if (isOutOfBounds(row, column)) return false;
if ((span[row][column][CellSpan.COLUMN] < 1)
||(span[row][column][CellSpan.ROW] < 1)) return false;
return true;
} public void combine(int[] rows, int[] columns) {
if (isOutOfBounds(rows, columns)) return;
int rowSpan = rows.length;
int columnSpan = columns.length;
int startRow = rows[0];
int startColumn = columns[0];
for (int i=0;i<rowSpan;i++) {
for (int j=0;j<columnSpan;j++) {
if ((span[startRow +i][startColumn +j][CellSpan.COLUMN] != 1)
||(span[startRow +i][startColumn +j][CellSpan.ROW] != 1)) {
//System.out.println("can't combine");
return ;
}
}
}
for (int i=0,ii=0;i<rowSpan;i++,ii--) {
for (int j=0,jj=0;j<columnSpan;j++,jj--) {
span[startRow +i][startColumn +j][CellSpan.COLUMN] = jj;
span[startRow +i][startColumn +j][CellSpan.ROW] = ii;
//System.out.println("r " +ii +" c " +jj);
}
}
span[startRow][startColumn][CellSpan.COLUMN] = columnSpan;
span[startRow][startColumn][CellSpan.ROW] = rowSpan;
} public void split(int row, int column) {
if (isOutOfBounds(row, column)) return;
int columnSpan = span[row][column][CellSpan.COLUMN];
int rowSpan = span[row][column][CellSpan.ROW];
for (int i=0;i<rowSpan;i++) {
for (int j=0;j<columnSpan;j++) {
span[row +i][column +j][CellSpan.COLUMN] = 1;
span[row +i][column +j][CellSpan.ROW] = 1;
}
}
}
//
// ColoredCell
//
public Color getForeground(int row, int column) {
if (isOutOfBounds(row, column)) return null;
return foreground[row][column];
}
public void setForeground(Color color, int row, int column) {
if (isOutOfBounds(row, column)) return;
foreground[row][column] = color;
}
public void setForeground(Color color, int[] rows, int[] columns) {
if (isOutOfBounds(rows, columns)) return;
setValues(foreground, color, rows, columns);
}
public Color getBackground(int row, int column) {
if (isOutOfBounds(row, column)) return null;
return background[row][column];
}
public void setBackground(Color color, int row, int column) {
if (isOutOfBounds(row, column)) return;
background[row][column] = color;
}
public void setBackground(Color color, int[] rows, int[] columns) {
if (isOutOfBounds(rows, columns)) return;
setValues(background, color, rows, columns);
}
//
//
// CellFont
//
public Font getFont(int row, int column) {
if (isOutOfBounds(row, column)) return null;
return font[row][column];
}
public void setFont(Font font, int row, int column) {
if (isOutOfBounds(row, column)) return;
this.font[row][column] = font;
}
public void setFont(Font font, int[] rows, int[] columns) {
if (isOutOfBounds(rows, columns)) return;
setValues(this.font, font, rows, columns);
}
//
//
// CellAttribute
//
public void addColumn() {
int[][][] oldSpan = span;
int numRows = oldSpan.length;
int numColumns = oldSpan[0].length;
span = new int[numRows][numColumns + 1][2];
System.arraycopy(oldSpan,0,span,0,numRows);
for (int i=0;i<numRows;i++) {
span[i][numColumns][CellSpan.COLUMN] = 1;
span[i][numColumns][CellSpan.ROW] = 1;
}
} public void addRow() {
int[][][] oldSpan = span;
int numRows = oldSpan.length;
int numColumns = oldSpan[0].length;
span = new int[numRows + 1][numColumns][2];
System.arraycopy(oldSpan,0,span,0,numRows);
for (int i=0;i<numColumns;i++) {
span[numRows][i][CellSpan.COLUMN] = 1;
span[numRows][i][CellSpan.ROW] = 1;
}
} public void insertRow(int row) {
int[][][] oldSpan = span;
int numRows = oldSpan.length;
int numColumns = oldSpan[0].length;
span = new int[numRows + 1][numColumns][2];
if (0 < row) {
System.arraycopy(oldSpan,0,span,0,row-1);
}
System.arraycopy(oldSpan,0,span,row,numRows - row);
for (int i=0;i<numColumns;i++) {
span[row][i][CellSpan.COLUMN] = 1;
span[row][i][CellSpan.ROW] = 1;
}
} public Dimension getSize() {
return new Dimension(rowSize, columnSize);
} public void setSize(Dimension size) {
columnSize = size.width;
rowSize = size.height;
span = new int[rowSize][columnSize][2]; // 2: COLUMN,ROW
foreground = new Color[rowSize][columnSize];
background = new Color[rowSize][columnSize];
font = new Font[rowSize][columnSize];
initValue();
} /*
public void changeAttribute(int row, int column, Object command) {
} public void changeAttribute(int[] rows, int[] columns, Object command) {
}
*/
protected boolean isOutOfBounds(int row, int column) {
if ((row < 0)||(rowSize <= row)
||(column < 0)||(columnSize <= column)) {
return true;
}
return false;
} protected boolean isOutOfBounds(int[] rows, int[] columns) {
for (int i=0;i<rows.length;i++) {
if ((rows[i] < 0)||(rowSize <= rows[i])) return true;
}
for (int i=0;i<columns.length;i++) {
if ((columns[i] < 0)||(columnSize <= columns[i])) return true;
}
return false;
} protected void setValues(Object[][] target, Object value,
int[] rows, int[] columns) {
for (int i=0;i<rows.length;i++) {
int row = rows[i];
for (int j=0;j<columns.length;j++) {
int column = columns[j];
target[row][column] = value;
}
}
}
}
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;import java.awt.*;/**
* @version 1.0 11/22/98
*/public interface CellAttribute { public void addColumn(); public void addRow(); public void insertRow(int row); public Dimension getSize(); public void setSize(Dimension size);
}
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;import java.awt.*;
/**
* @version 1.0 11/22/98
*/public interface ColoredCell {
public Color getForeground(int row, int column);
public void setForeground(Color color, int row, int column);
public void setForeground(Color color, int[] rows, int[] columns); public Color getBackground(int row, int column);
public void setBackground(Color color, int row, int column);
public void setBackground(Color color, int[] rows, int[] columns);
}
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;import java.awt.*;
/**
* @version 1.0 11/22/98
*/public interface CellFont {
public Font getFont(int row, int column);
public void setFont(Font font, int row, int column);
public void setFont(Font font, int[] rows, int[] columns);
}
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;
/**
* @version 1.0 11/22/98
*/public interface CellSpan {
public final int ROW = 0;
public final int COLUMN = 1;
public int[] getSpan(int row, int column);
public void setSpan(int[] span, int row, int column);
public boolean isVisible(int row, int column);
public void combine(int[] rows, int[] columns);
public void split(int row, int column);}
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.*;
import javax.swing.event.*;
/**
* @version 1.0 11/26/98
*/public class MultiSpanCellTable extends JTable { public MultiSpanCellTable(TableModel model) {
super(model);
setUI(new MultiSpanCellTableUI());
getTableHeader().setReorderingAllowed(false);
setCellSelectionEnabled(true);
setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
}
public Rectangle getCellRect(int row, int column, boolean includeSpacing) {
Rectangle sRect = super.getCellRect(row,column,includeSpacing);
if ((row <0) || (column<0) ||
(getRowCount() <= row) || (getColumnCount() <= column)) {
return sRect;
}
CellSpan cellAtt = (CellSpan)((AttributiveCellTableModel)getModel()).getCellAttribute();
if (! cellAtt.isVisible(row,column)) {
int temp_row = row;
int temp_column = column;
row += cellAtt.getSpan(temp_row,temp_column)[CellSpan.ROW];
column += cellAtt.getSpan(temp_row,temp_column)[CellSpan.COLUMN];
}
int[] n = cellAtt.getSpan(row,column); int index = 0;
int columnMargin = getColumnModel().getColumnMargin();
Rectangle cellFrame = new Rectangle();
int aCellHeight = rowHeight + rowMargin;
cellFrame.y = row * aCellHeight;
cellFrame.height = n[CellSpan.ROW] * aCellHeight;
Enumeration enumeration = getColumnModel().getColumns();
while (enumeration.hasMoreElements()) {
TableColumn aColumn = (TableColumn)enumeration.nextElement();
cellFrame.width = aColumn.getWidth() + columnMargin;
if (index == column) break;
cellFrame.x += cellFrame.width;
index++;
}
for (int i=0;i< n[CellSpan.COLUMN]-1;i++) {
TableColumn aColumn = (TableColumn)enumeration.nextElement();
cellFrame.width += aColumn.getWidth() + columnMargin;
}
if (!includeSpacing) {
Dimension spacing = getIntercellSpacing();
cellFrame.setBounds(cellFrame.x + spacing.width/2,
cellFrame.y + spacing.height/2,
cellFrame.width - spacing.width,
cellFrame.height - spacing.height);
}
return cellFrame;
}
private int[] rowColumnAtPoint(Point point) {
int[] retValue = {-1,-1};
int row = point.y / (rowHeight + rowMargin);
if ((row <0)||(getRowCount() <= row)) return retValue;
int column = getColumnModel().getColumnIndexAtX(point.x); CellSpan cellAtt = (CellSpan)((AttributiveCellTableModel)getModel()).getCellAttribute(); if (cellAtt.isVisible(row,column)) {
retValue[CellSpan.COLUMN] = column;
retValue[CellSpan.ROW ] = row;
return retValue;
}
retValue[CellSpan.COLUMN] = column + cellAtt.getSpan(row,column)[CellSpan.COLUMN];
retValue[CellSpan.ROW ] = row + cellAtt.getSpan(row,column)[CellSpan.ROW];
return retValue;
}
public int rowAtPoint(Point point) {
return rowColumnAtPoint(point)[CellSpan.ROW];
}
public int columnAtPoint(Point point) {
return rowColumnAtPoint(point)[CellSpan.COLUMN];
}
public void columnSelectionChanged(ListSelectionEvent e) {
repaint();
} public void valueChanged(ListSelectionEvent e) {
int firstIndex = e.getFirstIndex();
int lastIndex = e.getLastIndex();
if (firstIndex == -1 && lastIndex == -1) { // Selection cleared.
repaint();
}
Rectangle dirtyRegion = getCellRect(firstIndex, 0, false);
int numCoumns = getColumnCount();
int index = firstIndex;
for (int i=0;i<numCoumns;i++) {
dirtyRegion.add(getCellRect(index, i, false));
}
index = lastIndex;
for (int i=0;i<numCoumns;i++) {
dirtyRegion.add(getCellRect(index, i, false));
}
repaint(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width, dirtyRegion.height);
}
}
* (swing1.1beta3)
*
*/package jp.gr.java_conf.tame.swing.table;import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.*;
/**
* @version 1.0 11/26/98
*/public class MultiSpanCellTableUI extends BasicTableUI { public void paint(Graphics g, JComponent c) {
Rectangle oldClipBounds = g.getClipBounds();
Rectangle clipBounds = new Rectangle(oldClipBounds);
int tableWidth = table.getColumnModel().getTotalColumnWidth();
clipBounds.width = Math.min(clipBounds.width, tableWidth);
g.setClip(clipBounds); int firstIndex = table.rowAtPoint(new Point(0, clipBounds.y));
int lastIndex = table.getRowCount()-1; Rectangle rowRect = new Rectangle(0,0,
tableWidth, table.getRowHeight() + table.getRowMargin());
rowRect.y = firstIndex*rowRect.height; for (int index = firstIndex; index <= lastIndex; index++) {
if (rowRect.intersects(clipBounds)) {
//System.out.println(); // debug
//System.out.print("" + index +": "); // row
paintRow(g, index);
}
rowRect.y += rowRect.height;
}
g.setClip(oldClipBounds);
} private void paintRow(Graphics g, int row) {
Rectangle rect = g.getClipBounds();
boolean drawn = false;
AttributiveCellTableModel tableModel = (AttributiveCellTableModel)table.getModel();
CellSpan cellAtt = (CellSpan)tableModel.getCellAttribute();
int numColumns = table.getColumnCount(); for (int column = 0; column < numColumns; column++) {
Rectangle cellRect = table.getCellRect(row,column,true);
int cellRow,cellColumn;
if (cellAtt.isVisible(row,column)) {
cellRow = row;
cellColumn = column;
// System.out.print(" "+column+" "); // debug
} else {
cellRow = row + cellAtt.getSpan(row,column)[CellSpan.ROW];
cellColumn = column + cellAtt.getSpan(row,column)[CellSpan.COLUMN];
// System.out.print(" ("+column+")"); // debug
}
if (cellRect.intersects(rect)) {
drawn = true;
paintCell(g, cellRect, cellRow, cellColumn);
} else {
if (drawn) break;
}
} } private void paintCell(Graphics g, Rectangle cellRect, int row, int column) {
int spacingHeight = table.getRowMargin();
int spacingWidth = table.getColumnModel().getColumnMargin(); Color c = g.getColor();
g.setColor(table.getGridColor());
g.drawRect(cellRect.x,cellRect.y,cellRect.width-1,cellRect.height-1);
g.setColor(c); cellRect.setBounds(cellRect.x + spacingWidth/2, cellRect.y + spacingHeight/2,
cellRect.width - spacingWidth, cellRect.height - spacingHeight); if (table.isEditing() && table.getEditingRow()==row &&
table.getEditingColumn()==column) {
Component component = table.getEditorComponent();
component.setBounds(cellRect);
component.validate();
}
else {
TableCellRenderer renderer = table.getCellRenderer(row, column);
Component component = table.prepareRenderer(renderer, row, column); if (component.getParent() == null) {
rendererPane.add(component);
}
rendererPane.paintComponent(g, component, table, cellRect.x, cellRect.y,
cellRect.width, cellRect.height, true);
}
}
}
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.Vector;public class GroupableHeaderExample
extends JFrame {
Vector tableData = new Vector();
Vector columnNames = new Vector();
DefaultTableModel dm = new DefaultTableModel();
JTable table = null;
GroupableHeaderExample() {
columnNames.add("SNo");
columnNames.add("1");
columnNames.add("2");
columnNames.add("Native");
columnNames.add("2");
columnNames.add("3");
dm.setDataVector(new Vector(), columnNames);
dm.addRow(new Vector());
table = new JTable(dm) {
protected JTableHeader createDefaultTableHeader() {
return new GroupableTableHeader(columnModel);
}
};
JScrollPane scroll = new JScrollPane(table);
JButton button = new JButton("add");
JButton button2 = new JButton("data");
getContentPane().add(scroll);
getContentPane().add(button);
getContentPane().add(button2);
getContentPane().setLayout(new FlowLayout());
setSize(800, 600);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
GroupableHeaderExample.this.dm.addColumn("aa");
updateHeader();
}
});
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Vector dataVct=new Vector();
dm.addRow(dataVct);
dm.setValueAt("dataaaa",1,1);
}
});
} public void updateHeader() {
TableColumnModel cm = table.getColumnModel();
ColumnGroup g_name = new ColumnGroup("Name");
g_name.add(cm.getColumn(1));
g_name.add(cm.getColumn(2));
GroupableTableHeader header = (GroupableTableHeader) table.getTableHeader();
header.addColumnGroup(g_name);
} public static void main(String[] args) {
GroupableHeaderExample frame = new GroupableHeaderExample();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;public class ColumnGroup {
protected TableCellRenderer renderer;
protected Vector v;
protected String text;
protected int margin=0; public ColumnGroup(String text) {
this(null,text);
} public ColumnGroup(TableCellRenderer renderer,String text) {
if (renderer == null) {
this.renderer = new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
setHorizontalAlignment(JLabel.CENTER);
setText((value == null) ? "" : value.toString());
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
};
} else {
this.renderer = renderer;
}
this.text = text;
v = new Vector();
} public void add(Object obj) {
if (obj == null) { return; }
v.addElement(obj);
} public Vector getColumnGroups(TableColumn c, Vector g) {
g.addElement(this);
if (v.contains(c)) return g;
Enumeration enum = v.elements();
while (enum.hasMoreElements()) {
Object obj = enum.nextElement();
if (obj instanceof ColumnGroup) {
Vector groups =
(Vector)((ColumnGroup)obj).getColumnGroups(c,(Vector)g.clone());
if (groups != null) return groups;
}
}
return null;
}
public TableCellRenderer getHeaderRenderer() {
return renderer;
}
public void setHeaderRenderer(TableCellRenderer renderer) {
if (renderer != null) {
this.renderer = renderer;
}
}
public Object getHeaderValue() {
return text;
}
public Dimension getSize(JTable table) {
Component comp = renderer.getTableCellRendererComponent(
table, getHeaderValue(), false, false,-1, -1);
int height = comp.getPreferredSize().height;
int width = 0;
Enumeration enum = v.elements();
while (enum.hasMoreElements()) {
Object obj = enum.nextElement();
if (obj instanceof TableColumn) {
TableColumn aColumn = (TableColumn)obj;
width += aColumn.getWidth();
width += margin;
} else {
width += ((ColumnGroup)obj).getSize(table).width;
}
}
return new Dimension(width, height);
} public void setColumnMargin(int margin) {
this.margin = margin;
Enumeration enum = v.elements();
while (enum.hasMoreElements()) {
Object obj = enum.nextElement();
if (obj instanceof ColumnGroup) {
((ColumnGroup)obj).setColumnMargin(margin);
}
}
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.*;public class GroupableTableHeader extends JTableHeader {
protected Vector columnGroups = null;
public GroupableTableHeader(TableColumnModel model) {
super(model);
setUI(new GroupableTableHeaderUI());
setReorderingAllowed(false);
}
public void setReorderingAllowed(boolean b) {
reorderingAllowed = false;
}
public void addColumnGroup(ColumnGroup g) {
if (columnGroups == null) {
columnGroups = new Vector();
}
columnGroups.addElement(g);
} public Enumeration getColumnGroups(TableColumn col) {
if (columnGroups == null) return null;
Enumeration enum = columnGroups.elements();
while (enum.hasMoreElements()) {
ColumnGroup cGroup = (ColumnGroup)enum.nextElement();
Vector v_ret = (Vector)cGroup.getColumnGroups(col,new Vector());
if (v_ret != null) {
return v_ret.elements();
}
}
return null;
}
public void setColumnMargin() {
if (columnGroups == null) return;
int columnMargin = getColumnModel().getColumnMargin();
Enumeration enum = columnGroups.elements();
while (enum.hasMoreElements()) {
ColumnGroup cGroup = (ColumnGroup)enum.nextElement();
cGroup.setColumnMargin(columnMargin);
}
} private class GroupableTableHeaderUI extends BasicTableHeaderUI { public void paint(Graphics g, JComponent c) {
Rectangle clipBounds = g.getClipBounds();
if (header.getColumnModel() == null) return;
int column = 0;
Dimension size = header.getSize();
Rectangle cellRect = new Rectangle(0, 0, size.width, size.height);
Hashtable h = new Hashtable();
Enumeration enumeration = header.getColumnModel().getColumns();
while (enumeration.hasMoreElements()) {
cellRect.height = size.height;
cellRect.y = 0;
TableColumn aColumn = (TableColumn)enumeration.nextElement();
Enumeration cGroups = ((GroupableTableHeader)header).getColumnGroups(aColumn);
if (cGroups != null) {
int groupHeight = 0;
while (cGroups.hasMoreElements()) {
ColumnGroup cGroup = (ColumnGroup)cGroups.nextElement();
Rectangle groupRect = (Rectangle)h.get(cGroup);
if (groupRect == null) {
groupRect = new Rectangle(cellRect);
Dimension d = cGroup.getSize(header.getTable());
groupRect.width = d.width;
groupRect.height = d.height;
h.put(cGroup, groupRect);
}
paintCell(g, groupRect, cGroup);
groupHeight += groupRect.height;
cellRect.height = size.height - groupHeight;
cellRect.y = groupHeight;
}
}
cellRect.width = aColumn.getWidth();// + columnMargin;
if (cellRect.intersects(clipBounds)) {
paintCell(g, cellRect, column);
}
cellRect.x += cellRect.width;
column++;
}
} private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) {
TableColumn aColumn = header.getColumnModel().getColumn(columnIndex);
TableCellRenderer renderer = aColumn.getHeaderRenderer();
Component component = renderer.getTableCellRendererComponent(
header.getTable(), aColumn.getHeaderValue(),false, false, -1, columnIndex);
rendererPane.add(component);
rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
cellRect.width, cellRect.height, true);
} private void paintCell(Graphics g, Rectangle cellRect,ColumnGroup cGroup) {
TableCellRenderer renderer = cGroup.getHeaderRenderer();
Component component = renderer.getTableCellRendererComponent(
header.getTable(), cGroup.getHeaderValue(),false, false, -1, -1);
rendererPane.add(component);
rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
cellRect.width, cellRect.height, true);
} private int getHeaderHeight() {
int height = 0;
TableColumnModel columnModel = header.getColumnModel();
for(int column = 0; column < columnModel.getColumnCount(); column++) {
TableColumn aColumn = columnModel.getColumn(column);
TableCellRenderer renderer = aColumn.getHeaderRenderer();
if (renderer == null) {
renderer = new DefaultTableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
setHorizontalAlignment(JLabel.CENTER);
setText((value == null) ? "" : value.toString());
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
};
aColumn.setHeaderRenderer(renderer);
}
Component comp = renderer.getTableCellRendererComponent(
header.getTable(), aColumn.getHeaderValue(), false, false,-1, column);
int cHeight = comp.getPreferredSize().height;
Enumeration enum = ((GroupableTableHeader)header).getColumnGroups(aColumn);
if (enum != null) {
while (enum.hasMoreElements()) {
ColumnGroup cGroup = (ColumnGroup)enum.nextElement();
cHeight += cGroup.getSize(header.getTable()).height;
}
}
height = Math.max(height, cHeight);
}
return height;
} private Dimension createHeaderSize(long width) {
TableColumnModel columnModel = header.getColumnModel();
width += columnModel.getColumnMargin() * columnModel.getColumnCount();
if (width > Integer.MAX_VALUE) {
width = Integer.MAX_VALUE;
}
return new Dimension((int)width, getHeaderHeight());
} public Dimension getPreferredSize(JComponent c) {
long width = 0;
Enumeration enumeration = header.getColumnModel().getColumns();
while (enumeration.hasMoreElements()) {
TableColumn aColumn = (TableColumn)enumeration.nextElement();
width = width + aColumn.getPreferredWidth();
}
return createHeaderSize(width);
}
}
}
public void setDataVector(Vector newData, Vector columnNames) {
if (newData == null)
throw new IllegalArgumentException("setDataVector() - Null parameter");
dataVector = (newData != null) ? newData : new Vector(0);
columnIdentifiers = (columnNames != null) ? columnNames : new Vector(0);
cellAtt = new DefaultCellAttribute(dataVector.size(), columnIdentifiers.size());
newRowsAdded(new TableModelEvent(this, 0, getRowCount()-1,TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
}现在又有新的问题了,程序运行后,行和前面的行头对不齐,这个怎么解决啊??