Excel表格有一种功能,就是在你双击表头的分隔线时,会根据表格中内容自动调整列宽,使该列的数据可以完全显示出来。Swing的JTable里如何实现这个功能呢?
如果你看过Swing hacker里,应该见过里面根据列中内容自动调整列宽的方法。这个方法可以拿过来借用一下,那么剩下的就是如何监听到表格头分隔线上的双击事件了。
API里没有这方面的信息,通过观察表格的行为可以发现,当鼠标处于两列之间的分隔线上时,鼠标会变成左右调整的形状,那么我们就可以在鼠标监听里,通过当前的表头鼠标的样式来判断是否在两列之间的分割线上点击了鼠标。
/**
* 添加列表自动调整的监听器,当双击表头不同列间的分隔线时,
* 自动将分隔线左侧的列宽进行调整,使其内容可完全显示
*/
private void addColumnResizeListener() {
tableHeader = jTable1.getTableHeader();
tableHeader.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
// 当光标处于两个列表间的分隔线上时,表头的光标呈东西调整的样式,通过
// 鼠标的样式和点击次数来判断是否需要进行列宽调整
int cursorType = tableHeader.getCursor().getType();
if (cursorType == Cursor.E_RESIZE_CURSOR || cursorType == Cursor.W_RESIZE_CURSOR) {
if (e.getClickCount() == 2) {
// 获取光标点击位置的列号,这里将X的坐标减去3个像素,是为了保证取到的点始终是分隔线前的列号
int col = jTable1.getTableHeader().getColumnModel().getColumnIndexAtX(e.getX() - 3);
adjustColumnPreferredWidths(jTable1, col);
}
}
}
});
}
通过上面的方法就可以得到表格的列分隔线处的双击事件啦,下面就剩下调整列宽的事情了,将Swing Hacker里的代码稍作修改一下:
/**
* 根据给定的列号调整表格的列宽,此算法取自Swing hacker,不多说啦
* @param table
* @param col
*/
public static void adjustColumnPreferredWidths(JTable table, int col) {
// strategy - get max width for cells in column and
// make that the preferred width
TableColumnModel columnModel = table.getColumnModel();
int maxwidth = 0;
for (int row = 0; row < table.getRowCount(); row++) {
TableCellRenderer rend =
table.getCellRenderer(row, col);
Object value = table.getValueAt(row, col);
Component comp =
rend.getTableCellRendererComponent(table,
value,
false,
false,
row,
col);
maxwidth = Math.max(comp.getPreferredSize().width, maxwidth);
} // for row
TableColumn column = columnModel.getColumn(col);
column.setPreferredWidth(maxwidth + 3);
}
通过上面的方法就可以完成Excel表格的类似的功能了。看看附图中的效果