package com.example.client.utils; import javax.swing.*; import javax.swing.plaf.basic.BasicTableUI; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumnModel; import java.awt.*; /** * 实现表头渲染UI,主要功能时画出表头的单元格 * @author 雷锋 * @Date 2019年5月27日 */ import javax.swing.*; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumnModel; import java.awt.*; import java.awt.event.MouseEvent; public class ComplexTableUI extends BasicTableUI { private Object[][] headerRows; // 表头数据,用于判断合并逻辑 private JTable table; private int singleRowHeight; // 每行的高度 private int headerHeight; // 表头的总高度 public ComplexTableUI(Object[][] headerRows, JTable table) { this.headerRows = headerRows; this.table = table; this.singleRowHeight = table.getRowHeight(); // 获取单行高度 this.headerHeight = singleRowHeight * headerRows.length; // 计算表头总高度 } @Override public void installUI(JComponent c) { super.installUI(c); // 禁用列的拖动,因为合并单元格可能导致布局混乱 table.getTableHeader().setReorderingAllowed(false); } @Override public void paint(Graphics g, JComponent c) { super.paint(g, c); // 绘制默认的表格内容 // 遍历表格主体的每一行和每一列 for (int row = 0; row < table.getRowCount(); row++) { for (int col = 0; col < table.getColumnCount(); col++) { if (isMergedCell(row, col)) { continue; // 跳过被合并的单元格 } // 获取单元格的绘制区域 Rectangle rect = getCellRect(row, col); // 获取单元格内容 Object value = table.getValueAt(row, col); String text = value == null ? "" : value.toString(); // 绘制单元格 paintCell(g, rect, text); } } } /** * 判断单元格是否被合并 */ private boolean isMergedCell(int row, int col) { // 示例:假设合并逻辑基于表格主体数据 Object cellValue = table.getValueAt(row, col); return cellValue == ComplexTable.mergeCellX || cellValue == ComplexTable.mergeCellY; } /** * 获取单元格的绘制区域 */ private Rectangle getCellRect(int row, int col) { // 获取默认单元格区域 Rectangle rect = table.getCellRect(row, col, false); // 调整 y 坐标,考虑表头高度 rect.y += headerHeight; // 如果需要合并单元格,调整区域大小 if (isMergedCell(row, col)) { int mergeRowNum = getMergeRowNum(row, col); int mergeColNum = getMergeColNum(row, col); rect.height = getCellHeight(mergeRowNum); rect.width = getCellWidth(col, mergeColNum); } return rect; } /** * 获取合并的行数 */ private int getMergeRowNum(int row, int col) { int mergeRowNum = 1; for (int nextRow = row + 1; nextRow < table.getRowCount(); nextRow++) { Object nextRowCell = table.getValueAt(nextRow, col); if (nextRowCell == ComplexTable.mergeCellY) { mergeRowNum++; } else { break; } } return mergeRowNum; } /** * 获取合并的列数 */ private int getMergeColNum(int row, int col) { int mergeColNum = 1; for (int nextCol = col + 1; nextCol < table.getColumnCount(); nextCol++) { Object nextCell = table.getValueAt(row, nextCol); if (nextCell == ComplexTable.mergeCellX) { mergeColNum++; } else { break; } } return mergeColNum; } /** * 根据合并行数计算单元格高度 */ private int getCellHeight(int mergeRowNum) { return mergeRowNum * singleRowHeight; } /** * 根据合并列数计算单元格宽度 */ private int getCellWidth(int col, int mergeColNum) { TableColumnModel colModel = table.getColumnModel(); int width = 0; for (int i = 0; i < mergeColNum; i++) { width += colModel.getColumn(col + i).getWidth(); } return width; } /** * 绘制单元格 */ private void paintCell(Graphics g, Rectangle rect, String text) { Component component = getComponent(text); rendererPane.paintComponent(g, component, table, rect.x, rect.y, rect.width, rect.height, true); } /** * 创建用于绘制的组件 */ private JLabel getComponent(String text) { JLabel label = new JLabel(text, JLabel.CENTER); Font font = new Font("宋体", Font.PLAIN, 16); label.setFont(font); label.setBorder(UIManager.getBorder("Table.cellBorder")); return label; } }