📄 rowindextable.java
字号:
package com.zcsoft.swing;
import javax.swing.table.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.event.*;
import java.awt.event.*;
/**
* 首列前面标有行号的表格。
*
* @version 2.1
*/
public class RowIndexTable extends AutoAdaptColumnWidthTable
{
private JTable hdrTable;
/** 参照javax.swing.JTable */
public RowIndexTable(TableModel tm)
{
super(tm);
}
/**
* 处理表格模型激发的表格模型事件
* 如果设置了首列被固定,则重新固定
*/
public void tableChanged(TableModelEvent e)
{
super.tableChanged(e);
//表格行增加/减少时,重新设定索引列宽度
if (e != null && e.getType() != TableModelEvent.UPDATE)
{
this.setHeaderWidth();
}
}
/**
* 设置头部表格宽度:(行数有效为个数+4)* 当前绘制字体下单个字符的绘制宽度
*/
private void setHeaderWidth()
{
if(hdrTable != null)
{
int width = (Integer.toString(this.getRowCount()).length() + 4)*this.getFontMetrics(this.getTableHeader().getFont()).charWidth('0');
TableColumnModel tcm = hdrTable.getColumnModel();
TableColumn col = tcm.getColumn(0);
if (col.getWidth() != width)
{
col.setWidth(width);
col.setPreferredWidth(width);
hdrTable.setPreferredScrollableViewportSize(new java.awt.Dimension(
col.getWidth() + tcm.getColumnMargin()/2, 0));
}
}
}
/**
* 重新实现超类方法。使得固定列不再是该表格的首列
*/
public void setFirstColumnLocked(boolean b)
{
JScrollPane scrollPane=(JScrollPane)SwingUtilities.getAncestorOfClass(JScrollPane.class,this);
if(scrollPane==null)
{
throw new IllegalStateException("No JScrollPane containes the table");
}
if(b)
{
if( this.hdrTable == null)
this.hdrTable = new HeaderTable(this);
if(this.getColumnCount() >0 )
{
this.setHeaderWidth();
scrollPane.setRowHeaderView(hdrTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,
hdrTable.getTableHeader());
}
}
else if(scrollPane.getRowHeader() != null)
{
scrollPane.setRowHeaderView(null);
this.hdrTable = null;
}
}
/**
* 头部表格
* 重新实现setModel(TableModel),setColumnModel(TableColumnModel),
* setSelectionModel(ListSelectioModel),processEvent(AWTEvent e),
* isCellEditable(int, int)和getColumnClass(int), getCellRenderer(int, int)方法
*/
public static class HeaderTable extends JTable
{
/**
* 主表格
*/
private JTable parent;
public HeaderTable(JTable parent)
{
super(parent.getModel(), new DefaultTableColumnModel(), parent.getSelectionModel());
//设置自己的表格列模型特性
TableColumn firstColumn = new TableColumn(0);
firstColumn.setResizable(false);
firstColumn.setCellRenderer(RowIndexCellRenderer.getInstance());
this.getColumnModel().addColumn(firstColumn);
this.parent = parent;
this.setCellSelectionEnabled(false);
this.setRowSelectionAllowed(true);
this.setColumnSelectionAllowed(false);
this.setRequestFocusEnabled(false);
// this.setGridColor(UIManager.getColor("controlHighlight"));
}
public boolean isFocusCycleRoot()
{
return false;
}
protected boolean isFocusTranverable()
{
return false;
}
protected void processKeyEvent(KeyEvent e)
{
this.parent.dispatchEvent(e);
}
/**
* 直接返回
*/
public Class getColumnClass(int i)
{
return Object.class;
}
/**
* 重新实现超类方法
* 当变更表头可视区域时,同时变更主表格可是区域。这样就能避免
* 表头选择行同主表选择行错位的情况发生
* @since 2.1
*/
public void scrollRectToVisible(Rectangle aRect)
{
super.scrollRectToVisible(aRect);
parent.scrollRectToVisible(aRect);
}
/**
* 不返回任何数据,只在绘制是才绘制行号
*/
public Object getValueAt(int row, int column)
{
return null;
}
/**
* 不允许编辑
*/
public boolean isCellEditable(int row, int column)
{
return false;
}
/**
* 同步头部表格和主表格的数据模型
*/
public TableModel getModel()
{
return parent!=null?parent.getModel():super.getModel();
}
/**
* 同步头部表格和主表格的行选择模型
*/
public ListSelectionModel getSelectionModel()
{
return parent!=null?parent.getSelectionModel():super.getSelectionModel();
}
/**
* 头部表格行高随主表格行高变化而等同变化
*/
public int getRowHeight()
{
return parent!=null?parent.getRowHeight():super.getRowHeight();
}
public int getRowHeight(int row)
{
return parent!=null?parent.getRowHeight():super.getRowHeight(row);
}
public int getRowMargin(int margin)
{
return parent!=null?parent.getRowMargin():super.getRowMargin();
}
}
/**
* If this <code>JTable</code> is the <code>viewportView</code> of
* an enclosing <code>JScrollPane</code>
* ,when the table is added to the viewport, 就开始设定行号列
*
*/
public static class RowIndexCellRenderer extends DefaultTableCellRenderer
{
private static final javax.swing.border.Border selectedBorder =
BorderFactory.createEmptyBorder(0, 0, 1, 1);
static TableCellRenderer single;
private RowIndexCellRenderer()
{
this.setHorizontalAlignment(JLabel.CENTER);
}
/**
* 获取唯一的实例
* @since 2.1
*/
public static TableCellRenderer getInstance()
{
return single != null?single:(single = new RowIndexCellRenderer());
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
if (table != null)
{
JTableHeader header = table.getTableHeader();
if (header != null && !isSelected)
{
setForeground(header.getForeground());
setBackground(header.getBackground());
}
else
{
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
}
setFont(table.getFont());
}
setText(Integer.toString(row+1));
setBorder(isSelected?selectedBorder:UIManager.getBorder("TableHeader.cellBorder"));
return this;
}
}
/**
* 在父类实现的基础上,自动设定表头表格
* @see #setFirstColumnLocked(boolean)
* @since
*/
protected void configureEnclosingScrollPane()
{
super.configureEnclosingScrollPane();
Container p = getParent();
if (p instanceof JViewport)
{
if (p.getParent() instanceof JScrollPane)
{
this.setFirstColumnLocked(true);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -