JTable单元格合并

合并指定的一列或几列中行连续相同的单元格的值。

效果如下

CombineData.java

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

public class CombineData {

public ArrayList combineColumns = new ArrayList();//用于保存需要合并的列号

private String[][] datas;//table的数据,用来计算合并的单元格

private ArrayList> rowPoss;

private ArrayList> rowCounts;

public CombineData() {

}

public CombineData(String[][] datas, int... combineColumns) {

this.datas = datas;

for (int i = 0; i < combineColumns.length; i++) {

if (combineColumns[i] < 0) {

continue;

}

this.combineColumns.add(combineColumns[i]);

}

process();

}

public CombineData(String[][] datas, List combineColumns) {

this.datas = datas;

for (Integer column : combineColumns) {

if (column < 0) {

continue;

}

this.combineColumns.add(column);

}

process();

}

public void initData(String[][] datas, int... combineColumns) {

this.datas = datas;

this.combineColumns.clear();

for (int i = 0; i < combineColumns.length; i++) {

if (combineColumns[i] < 0) {

continue;

}

this.combineColumns.add(combineColumns[i]);

}

process();

}

public void initData(String[][] datas, List combineColumns) {

this.datas = datas;

this.combineColumns.clear();

for (Integer column : combineColumns) {

if (column < 0) {

continue;

}

this.combineColumns.add(column);

}

process();

}

private void process() {

rowPoss = new ArrayList>();

rowCounts = new ArrayList>();

for (Integer integer : combineColumns) {

HashMap rowPos = new HashMap();

HashMap rowCount = new HashMap();

String pre = "";

int count = 0;

int start = 0;

for (int i = 0; i < datas.length; i++) {

String[] data = datas[i];

if (pre.equals(data[integer])) {

count++;

} else {

rowCount.put(start, count);

pre = data[integer];

count = 1;

start = i;

}

rowPos.put(i, start);

}

rowCount.put(start, count);

rowPoss.add(rowPos);

rowCounts.add(rowCount);

}

}

/**

* 返回table中row行column列单元格所跨行数

*/

public int span(int row, int column) {

int index = combineColumns.lastIndexOf(column);

if (index != -1) {

return rowCounts.get(index).get(rowPoss.get(index).get(row));

} else {

return 1;

}

}

/**

* 返回table中row行column列单元格所在的合并单元格的起始行位置

*/

public int visibleCell(int row, int column) {

int index = combineColumns.lastIndexOf(column);

if ((index != -1) && row > -1) {

return rowPoss.get(index).get(row);

} else {

return row;

}

}

}

CombineTable.java

import javax.swing.*;

import java.awt.*;

import javax.swing.table.TableColumn;

import javax.swing.table.TableModel;

public class CombineTable extends JTable {

public CombineData combineData;

public CombineTable(TableModel tableModel) {

super(tableModel);

super.setUI(new CombineTableUI());

}

public CombineTable(CombineData combineData, TableModel tableModel) {

super(tableModel);

this.combineData = combineData;

for (Integer column : combineData.combineColumns) {

TableColumn tableColumn = super.columnModel.getColumn(column);

tableColumn.setCellRenderer(new CombineColumnRender());

}

super.setUI(new CombineTableUI());

}

public void setCombineData(CombineData combineData) {

this.combineData = combineData;

for (Integer column : combineData.combineColumns) {

TableColumn tableColumn = super.columnModel.getColumn(column);

tableColumn.setCellRenderer(new CombineColumnRender());

}

}

@Override

public Rectangle getCellRect(int row, int column, boolean includeSpacing) {

// required because getCellRect is used in JTable constructor

if (combineData == null) {

return super.getCellRect(row, column, includeSpacing);

}

// add widths of all spanned logical cells

int sk = combineData.visibleCell(row, column);

//Rectangle r1 = super.getCellRect(row, sk, includeSpacing);

Rectangle rect1 = super.getCellRect(sk, column, includeSpacing);

if (combineData.span(sk, column) != 1) {

for (int i = 1; i < combineData.span(sk, column); i++) {

//r1.width += getColumnModel().getColumn(sk + i).getWidth();

rect1.height += this.getRowHeight(sk + i);

}

}

return rect1;

}

@Override

public int rowAtPoint(Point p) {

int column = super.columnAtPoint(p);

// -1 is returned by columnAtPoint if the point is not in the table

if (column < 0) {

return column;

}

int row = super.rowAtPoint(p);

return combineData.visibleCell(row, column);

}

@Override

public boolean isCellEditable(int row, int column) {

if (combineData.combineColumns.contains(column)) {

return false;

}

return super.isCellEditable(row, column);

}

@Override

public boolean isCellSelected(int row, int column) {

if (combineData.combineColumns.contains(column)) {

return false;

}

return super.isCellSelected(row, column);

}

}

CombineTableUI.java

import javax.swing.table.*;

import javax.swing.plaf.basic.*;

import java.awt.*;

import javax.swing.*;

class CombineTableUI extends BasicTableUI {

@Override

public void paint(Graphics g, JComponent c) {

Rectangle r = g.getClipBounds();

rendererPane.removeAll();

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 (lastCol < 0) {

lastCol = table.getColumnCount() - 1;

}

for (int i = firstCol; i <= lastCol; i++) {

paintCol(i, g);

}

paintGrid(g, 0, table.getRowCount() - 1, 0, table.getColumnCount() - 1);

}

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 = ((CombineTable) table).combineData.visibleCell(i, col);

paintCell(sk, col, g, r1);

// increment the column counter

i += ((CombineTable) table).combineData.span(sk, col) - 1;

}

}

}

private void paintCell(int row, int column, Graphics g, Rectangle area) {

int verticalMargin = table.getRowMargin();

int horizontalMargin = table.getColumnModel().getColumnMargin();

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

}

}

private void paintGrid(Graphics g, int rMin, int rMax, int cMin, int cMax) {

g.setColor(table.getGridColor());

Rectangle minCell = table.getCellRect(rMin, cMin, true);

Rectangle maxCell = table.getCellRect(rMax, cMax, true);

Rectangle damagedArea = minCell.union(maxCell);

if (table.getShowHorizontalLines()) {

CombineData cMap = ((CombineTable) table).combineData;

for (int row = rMin; row <= rMax; row++) {

for (int column = cMin; column <= cMax; column++) {

Rectangle cellRect = table.getCellRect(row, column, true);

if (cMap.combineColumns.contains(column)) {

int visibleCell = cMap.visibleCell(row, column);

int span = cMap.span(row, column);

if (span > 1 && row < visibleCell + span - 1) {

} else {

g.drawLine(cellRect.x, cellRect.y + cellRect.height - 1, cellRect.x + cellRect.width - 1, cellRect.y + cellRect.height - 1);

}

} else {

g.drawLine(cellRect.x, cellRect.y + cellRect.height - 1, cellRect.x + cellRect.width - 1, cellRect.y + cellRect.height - 1);

}

}

}

}

if (table.getShowVerticalLines()) {

TableColumnModel cm = table.getColumnModel();

int tableHeight = damagedArea.y + damagedArea.height;

int x;

if (table.getComponentOrientation().isLeftToRight()) {

x = damagedArea.x;

for (int column = cMin; column <= cMax; column++) {

int w = cm.getColumn(column).getWidth();

x += w;

g.drawLine(x - 1, 0, x - 1, tableHeight - 1);

}

} else {

x = damagedArea.x;

for (int column = cMax; column >= cMin; column--) {

int w = cm.getColumn(column).getWidth();

x += w;

g.drawLine(x - 1, 0, x - 1, tableHeight - 1);

}

}

}

}

}

CombineColumnRender.java

import java.awt.Component;

import javax.swing.JTable;

import javax.swing.table.DefaultTableCellRenderer;

/**

* 设置需要合并的列的单元格不能被选中,不能聚焦

* @author hualun-alan

*/

class CombineColumnRender extends DefaultTableCellRenderer {

@Override

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

CombineTable cTable = (CombineTable) table;

if (cTable.combineData.combineColumns.contains(column)) {

hasFocus = false;

}

return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

}

}

Test.java

import java.util.ArrayList;

import javax.swing.*;

import javax.swing.table.*;

public class Test {

public static void main(String args[]) {

JFrame jf = new JFrame("Cell Combine Table");

JTable cTable = getTable1();

jf.getContentPane().add(new JScrollPane(cTable));

jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

jf.setSize(500, 500);

jf.setVisible(true);

}

private static CombineTable getTable1() {

String[][] datas = new String[10][6];

for (int i = 0; i < datas.length; i++) {

String[] data = datas[i];

for (int j = 0; j < data.length; j++) {

data[j] = "";

}

data[0] = String.valueOf((int) (i / 3));

}

ArrayList combineColumns = new ArrayList();

combineColumns.add(0);

CombineData m = new CombineData(datas, combineColumns);

DefaultTableModel tm = new DefaultTableModel(datas, new String[]{"1", "2", "3", "4", "5"});

CombineTable cTable = new CombineTable(m, tm);

TableColumn column = cTable.getColumnModel().getColumn(0);

column.setCellRenderer(new CombineColumnRender());

column.setWidth(50);

column.setMaxWidth(50);

column.setMinWidth(50);

cTable.setCellSelectionEnabled(true);

return cTable;

}

private static CombineTable getTable2() {

String[][] datas = new String[10][6];

for (int i = 0; i < datas.length; i++) {

String[] data = datas[i];

for (int j = 0; j < data.length; j++) {

data[j] = "";

}

data[0] = String.valueOf((int) (i / 4));

data[1] = String.valueOf((int) (i / 2));

}

CombineData m = new CombineData(datas, 0, 1);

DefaultTableModel tm = new DefaultTableModel(datas, new String[]{"1", "2", "3", "4", "5"});

CombineTable cTable = new CombineTable(m, tm);

TableColumnModel columnModel = cTable.getColumnModel();

for (Integer integer : m.combineColumns) {

TableColumn column = columnModel.getColumn(integer);

column.setCellRenderer(new CombineColumnRender());

column.setWidth(50);

column.setMaxWidth(50);

column.setMinWidth(50);

}

cTable.setCellSelectionEnabled(true);

return cTable;

}

}

java jtable 单元格合并_JTable合并单元格相关推荐

  1. java jtable 单元格编辑_JTable中单元格编辑的问题

    我在JTable中使用单元格编辑遇到了一些麻烦 . 首先,我创建了一个函数来处理按下ENTER时的水平滚动,当它到达最后一列时,它再次从下一列的第一个单元格开始 . 这很好但问题是,当我单击一个单元格 ...

  2. java jtable应用源码_JTable的应用(一)

    类层次结构图: java.lang.Object --java.awt.Component --java.awt.Container --javax.swing.JComponent --javax. ...

  3. java读取合并单元格_Java POI常用方法,读取单元格的值,设置单元格格式,合并单元格,获取已合并的单元格,导出至本地等...

    一.设置单元格格式. 设置单元格边框.单元格背景颜色.单元格对齐方式.单元格字体,设置自动换行. /** Description: 设置单元格格式. * @author : ys. * @date : ...

  4. java基于HuTool工具类ExcelWriter合并单元格

    ** java基于HuTool工具类ExcelWriter合并单元格 ** 1.基于HuTool工具类ExcelWriter合并单元格并且使用 jdk1.8 lambda表达式 效果如下: 用姓名和编 ...

  5. java 合并和拆分单元格_如何在Microsoft Word中合并和拆分表和单元格

    java 合并和拆分单元格 You can easily merge and split cells in Microsoft Word to make your tables more intere ...

  6. java 合并和拆分单元格_如何轻松合并和拆分电子书

    java 合并和拆分单元格 Whether you want to merge collections of short stories into a DIY anthology, or you wa ...

  7. 【JAVA基础】在Word中合并单元格时删除重复值

    程序环境: 方法1:手动引入.将​ ​Free Spire.Doc for Java​ ​下载到本地,解压,找到lib文件夹下的Spire.Doc.jar文件.在IDEA中打开如下界面,将本地路径中的 ...

  8. java mergecells_Java 合并/取消合并 Excel 单元格

    合并单元格是指将表格中两个或多个位于同一行或者同一列的单元格合并成一个单元格的操作.本文将介绍如何使用Free Spire.XLS for Java在Excel文档中合并和取消合并单元格. 基本步骤: ...

  9. java操作导出Excel(jxl导出WritableWorkbook)jxl合并单元格,单元格的设置,单元格居中、字体、大小、换行、合并行,列宽、自动换行撑起高度、指定特定字符串样式等

    new WritableCellFormat().setWrap(true);//通过调整宽度和高度自动换行 1.1     需求描述 MS的电子表格(Excel)是Office的重要成员,是保存统计 ...

  10. php拆分excel,PHP_PHPExcel合并与拆分单元格的方法,本文实例讲述了PHPExcel合并与 - phpStudy...

    PHPExcel合并与拆分单元格的方法 本文实例讲述了PHPExcel合并与拆分单元格的方法.分享给大家供大家参考,具体如下: $objPHPExcel; $filepath="c:\tem ...

最新文章

  1. JavaScript实现职责链模式
  2. 2016年第14本:毅力----如何培养自律的习惯(漫画版)
  3. Visual Studio DSL 入门 13---结合T4生成代码
  4. Vs 中关于项目中的某 NuGet 程序包还原失败:找不到“xxx”版本的程序包“xxx”
  5. python——迭代器itertools.cycle
  6. 百度竞价点击器_同等预算,百度竞价托管如何让您的点击量高于您同行?
  7. 一次订单号重复引起的事故,把我坑惨了!
  8. python3小游戏源代码_python3实现弹弹球小游戏
  9. win7修复计算机有密码,win7系统恢复选项密码
  10. C#开发实战1200例(第II卷)目录
  11. Angular实现微博发布功能
  12. 金蝶KIS迷你版标准版年度结账
  13. 小猫钓鱼java代码,【Java个人笔记】练习-小猫钓鱼
  14. 亮剑java web_为什么《亮剑Java Web 项目开发案例导航》第二个项目运行不了?
  15. word保存html格式批注没有了,word批注不见了 怎么显示批注
  16. 怎样进网站空间服务器,怎样进网站空间服务器
  17. 叠加原理--戴维南等效电路--第四篇
  18. 【Linux】基于Mplayer开源多媒体库的音视频播放器
  19. 【云原生 · Kubernetes】Kubernetes基础环境搭建
  20. Phonopy-Spectroscopy计算材料红外和Raman光谱

热门文章

  1. Oracle 繁简体转换(未解决)
  2. 蓝筹股是什么意思?低估值蓝筹股有哪些?拥有蓝筹股的好处?
  3. Xposed框架安装步骤
  4. Shiro记住我(RememberMe)
  5. Android Bluetooth架构
  6. Django发送邮件(附代码)
  7. 搭建私人博客踩过的坑(心酸)
  8. 百度收录批量查询_如何查看网站是否被收录?
  9. 关于json压缩(原始几十个MB大小)传输到安卓性能测试
  10. 路由器 android 打印机,用路由器将普通打印机变成网络打印机