Jtable单元格合并的问题

这篇博客探讨了在Java Swing中如何实现JTable组件的单元格合并。作者通过取消表格网格线并创建自定义的MergeTableModel,利用数据值相同来决定合并条件。详细步骤包括取消网格线绘制,以及使用Map存储相同数据的单元格坐标。
摘要由CSDN通过智能技术生成

最近有个任务,其中需要实现table网格的单元格合并,想了很久,最后用了一种简单但是感觉不怎么好的方式。

大概思路是这样子的:将网格中相同数据的单元格进行合并。所以这里单元格是否要合并取决于单元格的数据是否一样。

以下是详细的实现步骤:

1 、先取消网格的绘制网格线的功能。

JTable table = new JTable();
table.setModel(tableModel);
table.setShowHorizontalLines(false);
table.setShowVerticalLines(false);

2、定义新的网格模型MergeTableModel继承DefaultTableModel,新增一个map用来存放数据值相同的单元格坐标。

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.swing.table.DefaultTableModel;

import com.griddata.MergeTableData;

public class MergeTableModel extends DefaultTableModel {

        private static final long serialVersionUID = -5431441008936488938L;

        public static final int ROW = 0;
        public static final int COLUMN = 1;

        // 按照单元格的值分组存放被隐藏掉的单元格坐标
        private Map<String, Set<Integer[]>> coverRectIndexMap = new HashMap<String, Set<Integer[]>>();

        public final int columnWidth = 200;

        public MergeTableModel() {
                super();
        }

        public MergeTableModel(Object[] columnNames, int rowCount) {
                super(columnNames, rowCount);
        }

        public MergeTableModel(MergeTableData[][] data, Object[] columnNames) {
                super(data, columnNames);
        }

        public void addCoverRectIndex(String cellValue, int rowIndex, int colIndex) {
                Set<Integer[]> coverSet = this.coverRectIndexMap.get(cellValue);
                if (coverSet == null) {
                        coverSet = new HashSet<Integer[]>();
                        this.coverRectIndexMap.put(cellValue, coverSet);
                        coverSet.add(new Integer[] { rowIndex, colIndex });

                } else {
                        if (isCellCovered(coverSet, rowIndex, colIndex)) {
                                return;
                        } else {
                                coverSet.add(new Integer[] { rowIndex, colIndex });
                        }
                }
        }

        public void removeCoverRectIndex(int rowIndex, int colIndex) {

        }

        // 判断单元格是否被覆盖
        public boolean isCellCovered(String cellValue, int rowIndex, int colIndex) {

                Set<Integer[]> coverSet = this.coverRectIndexMap.get(cellValue);
                if (coverSet == null) {
                        return false;
                }
                return isCellCovered(coverSet, rowIndex, colIndex);
        }

        private boolean isCellCovered(Set<Integer[]> coverSet, int rowIndex, int colIndex) {
                for (Integer[] intArr : coverSet) {
                        if (intArr[0] == rowIndex && intArr[1] == colIndex) {
                                return true;
                        }
                }
                return false;
        }

        /**
         * 获取同一组被覆盖的单元格中最大的行号,如果没有覆盖的单元格则返回-1
         * 
         * @param cellValue
         * @return
         */
        public int getMaxCoverRow(String cellValue) {
                Set<Integer[]> coverSet = this.coverRectIndexMap.get(cellValue);
                if (coverSet == null) {
                        return -1;
                }
                int maxRow = 0;
                for (Integer[] intArr : coverSet) {
                        if (maxRow < intArr[ROW]) {
                                maxRow = intArr[ROW];
                        }
                }
                return maxRow;
        }

        /**
         * 获取同一组被覆盖的单元格中最大的列号,如果没有覆盖的单元格则返回-1
         * 
         * @param cellValue
         * @return
         */
        public int getMaxCoverColumn(String cellValue) {
                Set<Integer[]> coverSet = this.coverRectIndexMap.get(cellValue);
                if (coverSet == null) {
                        return -1;
                }
                int maxCloumn = 0;
                for (Integer[] intArr : coverSet) {
                        if (maxCloumn < intArr[COLUMN]) {
                                maxCloumn = intArr[COLUMN];
                        }
                }
                return maxCloumn;
        }

        /**
         * 判断当前的值是否有隐藏的单元格
         * 
         * @param cellValue
         * @return
         */
        public boolean hasCoverColumns(String cellValue) {
                Set<Integer[]> coverSet = this.coverRectIndexMap.get(cellValue);
                if (coverSet == null || coverSet.size() == 0) {
                        return false;
                }
                return true;
        }

        /**
         * 清除所有数据
         */
        @SuppressWarnings("rawtypes")
        public void removeAllDatas() {
                this.setDataVector(new Vector(), new Vector());
                fireTableDataChanged();
        }
}


3、定义MergeCellRender继承DefaultTableCellRender,重写getTableCellRenderComponent()方法,判断如果当前单元格需要被合并(数据值跟前面的单元格相同),则将当前的单元格控件(JLabel)的text设置为空字符串。然后给这个label设置边框线,注意需要新建一种边框线,因为只需要画一部分的边框线,而不是把整个矩形边框画出来。

MergeCellRender

import java.awt.Component;

import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

import com
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值