JTable合并单元格

最近,我为了做一个管理系统,需要用到合并JTable的单元格。查找了很多资料,终于简单的实现了。现在把代码共享出来,希望对大家有用。

本程序主要实现行的合并,列的合并大家可以根据下面的代码修改。

CMap.java  :

package com;

public interface CMap {
 /**
  * @param row
  *            logical cell row
  * @param column
  *            logical cell column
  * @return number of columns spanned a cell
  */
 int span(int row, int column);

 /**
  * @param row
  *            logical cell row
  * @param column
  *            logical cell column
  * @return the index of a visible cell covering a logical cell
  */
 int visibleCell(int row, int column);
}

CTUI.java :

package com;

import javax.swing.table.*;
import javax.swing.plaf.basic.*;
import java.awt.*;
import javax.swing.*;

public class CTUI extends BasicTableUI {
 public void paint(Graphics g, JComponent c) {
  Rectangle r = g.getClipBounds();
//  int firstRow = table.rowAtPoint(new Point(0, r.y));
//  int lastRow = table.rowAtPoint(new Point(0, r.y + r.height));
  int firstCol = table.columnAtPoint( new Point( r.x , 0 ) );
  int lastCol = table.columnAtPoint(new Point( r.x + r.width, 0 ));
  // -1 is a flag that the ending point is outside the table
//  if (lastRow < 0)
//   lastRow = table.getRowCount() - 1;
  if (lastCol < 0)
   lastCol = table.getColumnCount() - 1;
  for (int i = firstCol; i <= lastCol; i++)
   paintCol(i, g);
 } 
 private void paintCol(int col, Graphics g) {
  Rectangle r = g.getClipBounds();
  for (int i = 0; i < table.getRowCount(); i++) {
   Rectangle r1 = table.getCellRect( i, col, true);
   if (r1.intersects(r)) // at least a part is visible
   {
    int sk = ((CTable) table).map.visibleCell( i, col );
    paintCell( sk, col, g, r1);
    // increment the column counter
    i += ((CTable) table).map.span( sk, col ) - 1;
   }
  }
 }

 private void paintCell(int row, int column, Graphics g, Rectangle area) {
  int verticalMargin = table.getRowMargin();
  int horizontalMargin = table.getColumnModel().getColumnMargin();

  Color c = g.getColor();
  g.setColor(table.getGridColor());
  g.drawRect(area.x, area.y, area.width - 1, area.height - 1);
  g.setColor(c);

  area.setBounds(area.x + horizontalMargin / 2, area.y + verticalMargin
    / 2, area.width - horizontalMargin, area.height
    - verticalMargin);

  if (table.isEditing() && table.getEditingRow() == row
    && table.getEditingColumn() == column) {
   Component component = table.getEditorComponent();
   component.setBounds(area);
   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, area.x, area.y,
     area.width, area.height, true);
  }
 }
}

CTable.java :

package com;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;

public class CTable extends JTable {
 public CMap map;

 public CTable(CMap cmp, TableModel tbl) {
  super(tbl);
  map = cmp;
  setUI(new CTUI());
 }

 public Rectangle getCellRect(int row, int column, boolean includeSpacing) {
  // required because getCellRect is used in JTable constructor
  if (map == null)
   return super.getCellRect(row, column, includeSpacing);
  // add widths of all spanned logical cells
  int sk = map.visibleCell(row, column);
  //Rectangle r1 = super.getCellRect(row, sk, includeSpacing);
  Rectangle r1 = super.getCellRect( sk, column, includeSpacing);
  if (map.span( sk, column ) != 1)
   for (int i = 1; i < map.span( sk, column ); i++) {
    //r1.width += getColumnModel().getColumn(sk + i).getWidth();
    r1.height += this.getRowHeight( sk + i );
   }
  return r1;
 }
 public int rowAtPoint(Point p) {
  int x = super.columnAtPoint(p);
  // -1 is returned by columnAtPoint if the point is not in the table
  if (x < 0)
   return x;
  int y = super.rowAtPoint(p);
  return map.visibleCell(y, x);
 }
}

CMap1.java :

/******************************************************************************************

CMap1对CMap地实现

span( ) 表示合并的单元格的列,返回的是合并的格数。

visibleCell() 表示要渲染的格。返回的渲染的开始格的行。

本程序的table是16行10列,合并的单元格是第一列和最后一列(最后一列是第10列)每两个行。

*******************************************************************************************/

package com;

import javax.swing.*;
import javax.swing.table.*;

class CMap1 implements CMap {
 public int span(int row, int column) {
  if( column == 0 || column == 9  )
   return 2;
  return 1;
 }

 public int visibleCell(int row, int column) {
  if( ( ( row >= 0 ) && ( row < 2  ) ) && ( column == 0 || column == 9 ) )
   return 0;
  if( ( ( row >= 2 ) && ( row < 4  ) ) && ( column == 0 || column == 9 ) )
   return 2;
  if( ( ( row >= 4 ) && ( row < 6  ) ) && ( column == 0 || column == 9 ) )
   return 4;
  if( ( ( row >= 6 ) && ( row < 8  ) ) && ( column == 0 || column == 9 ) )
   return 6;
  if( ( ( row >= 8 ) && ( row < 10  ) ) && ( column == 0 || column == 9 ) )
   return 8;
  if( ( ( row >= 10 ) && ( row < 12  ) ) && ( column == 0 || column == 9 ) )
   return 10;
  if( ( ( row >= 12 ) && ( row < 14  ) ) && ( column == 0 || column == 9 ) )
   return 12;
  if( ( ( row >= 14 ) && ( row < 16  ) ) && ( column == 0 || column == 9 ) )
   return 14;

  System.out.println( ">>>row = " + row + "column = " + column );
  return row;
 }
}

下面的程序进行测试。

package com;

import javax.swing.*;
import javax.swing.table.*;

public class CTest {
 public static void main(String args[]) {
  JFrame jf = new JFrame("Table with cell spanning");

  CMap m = new CMap1();
  DefaultTableModel tm = new DefaultTableModel( 16, 10 ){
   public boolean isCellEditable( int indexRow, int indexColumn )
   {
    return false;
   }
  };
  //tm.isCellEditable( 16, 10 );
  tm.setValueAt( "port1", 0, 0);//对一个合并的单元格填一个数据。
  jf.getContentPane().add(new JScrollPane(new CTable(m, tm)));
  jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);
  jf.setSize(500, 500);
  jf.show();
 }
}

 

 

 

你可能感兴趣的:(table,Class,import,interface,Constructor,jcomponent)