/*
* Copyright 1999-2017 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.support.jconsole.model;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.util.ArrayList;
/**
* 用于显示RowHeader的JTable,只需要将其加入JScrollPane的RowHeaderView即可为JTable生成行标题
*/
public class RowHeaderTable extends JTable {
private static final long serialVersionUID = 1L;
/**
* 为JTable添加RowHeader,
*
* @param refTable 需要添加rowHeader的JTable
* @param columnWidth rowHeader的宽度
*/
public RowHeaderTable(JTable refTable, int columnWidth){
this(null, refTable, columnWidth, 1);
}
public RowHeaderTable(ArrayList<String> title, JTable refTable, int columnWidth){
this(title, refTable, columnWidth, 1);
}
public RowHeaderTable(ArrayList<String> title, JTable refTable, int columnWidth, int rowSpan){
super(new DefaultTableModel(refTable.getRowCount() / rowSpan, 1));
this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);// 不可以调整列宽
this.getColumnModel().getColumn(0).setPreferredWidth(columnWidth);
this.setDefaultRenderer(Object.class, new RowHeaderRenderer(title, refTable, this, rowSpan));// 设置渲染器
this.setPreferredScrollableViewportSize(new Dimension(columnWidth, 0));
}
}
/**
* 用于显示RowHeader的JTable的渲染器,当选择某行时,该行颜色会发生变化
*/
final class RowHeaderRenderer extends JLabel implements TableCellRenderer, ListSelectionListener {
private static final long serialVersionUID = 1L;
private JTable refTable; // 需要添加rowHeader的JTable
private JTable tableShow; // 用于显示rowHeader的JTable
private ArrayList<String> headerList;
private int rowHeightNow;
private int rowSpan;
public RowHeaderRenderer(JTable refTable, JTable tableShow){
this(null, refTable, tableShow, 0);
}
public RowHeaderRenderer(ArrayList<String> headerList, JTable refTable, JTable tableShow, int rowSpan){
this.headerList = headerList;
this.refTable = refTable;
this.tableShow = tableShow;
// 增加监听器,实现当在refTable中选择行时,RowHeader会发生颜色变化
ListSelectionModel listModel = refTable.getSelectionModel();
listModel.addListSelectionListener(this);
rowHeightNow = refTable.getRowCount() * refTable.getRowHeight();
this.rowSpan = rowSpan;
if (rowSpan > 1) {
rowHeightNow = rowSpan * refTable.getRowHeight();
}
}
public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus,
int row, int col) {
int rowCountNow = refTable.getRowCount() / rowSpan;
((DefaultTableModel) table.getModel()).setRowCount(rowCountNow);
JTableHeader header = refTable.getTableHeader();
this.setOpaque(true);
setBorder(UIManager.getBorder("TableHeader.cellBorder"));// 设置为TableHeader的边框类型
setHorizontalAlignment(CENTER);// 让text居中显示
setBackground(header.getBackground());// 设置背景色为TableHeader的背景色
if (isSelect(row)) // 当选取单元格时,在row header上设置成选取颜色
{
setForeground(Color.white);
setBackground(Color.lightGray);
} else {
setForeground(header.getForeground());
}
setFont(header.getFont());
if (row <= rowCountNow) {
showCol(row);
}
return this;
}
private void showCol(int row) {
String text = null;
if (headerList != null && row < headerList.size()) {
text = headerList.get(row);
} else {
text = String.valueOf(row + 1);
}
if (rowSpan > 1) {
setText(text);
this.tableShow.setRowHeight(row, rowHeightNow);
} else {
setText(text);
}
}
public void valueChanged(ListSelectionEvent e) {
this.tableShow.repaint();
}
private boolean isSelect(int row) {
int[] sel = refTable.getSelectedRows();
if (rowSpan <= 1) {
for (int item : sel) {
if (item == row) {
return true;
}
}
} else {
for (int item : sel) {
if (item / rowSpan == row) {
return true;
}
}
}
return false;
}
}