引言
在一个免费的ERP系统的开发过程中,存在这样的需求,需要用JTable的方式定义一个报表模板, 这个模板要能够支持公式,在后台的业务出来中,会根据公式算出实际的值,然后在添回模板中,变成报表。如下图,就是一张负责资产表的报表模板:
而最终生成的数据如下:
在图一,我们可以看到17行是公式是:C3+C4(当然也可以用SUM (C3:C4) ).也就是说,我们的公式需要支持引用其他的单元格。那么在实际的做这个模板的过程中,对于要引用的单元格的行列号,都要能够一目了然;否则,总不至于让人一个一个的去数吧,效率低不说,还很容易出错。至于列号,JTable 本来就有Column Header,自不必多说。现在的关键就是如何实现JTable 的Row Header。如何实现Row Header 呢?那就是用JScrollPane。
JScrollPane介绍:
相信用过JTable和JScrollPane的人都会知道。如果我们把JTable 加到一个JScrollPane中,JTable就会自然后表头(你这不是废话吗?),但是如果我们加大其他的容器中,你就会发现那个表头不见了,比如你想要在一个JPanel 中添加,就只能这样了:
JTable table = new JTable();
JPanel tablePane = new JPanel(new BorderLayout());
tablePane.add(table.getTableHeader(),BorderLayout.NORTH);
tablePane.add(table,BorderLayout.CENTER);
由此,我们可以看出,通过JScrollPane可以自动为JTable 加上列标题。那么他是怎么实现的呢?
先来看看JScrollPane的结构:
可知,JScrollPane具有Column Header 和Row Header的区域,可以通过setColumnHeaderView(Component view) 和setRowHeaderView(Component view)分别为它们添加相应的外观组件。JScrollPane 在添加JTable的时候,会自动setColumnHeaderView(table.getTableHeader()).
想要添加JTable 的Row Header,只需要把一个组件添加到Row Header 区域。那么该用什么样的组件呢? 可以选择JList,也可以用只有一列的JTable.
添加Row Header
首先创建一个只有一列的JTable:
JTable rowHeaderTable = new JTable (){
public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
Component component = super.prepareRenderer(renderer, row, col);
((JLabel)component).setHorizontalAlignment(JLabel.CENTER);
((JLabel)component).setBackground(table.getTableHeader().getBackground());
((JLabel)component).setBorder(UIManager.getBorder("TableHeader.cellBorder"));
((JLabel)component).setText((row +1)+"");
return component;
}
通过prepareRenderer把表格单元的样式设置与column header一样的样式。
然后把这个table加到JScrollPane 的Row Header 区域:
scroll.setRowHeader(rowHeaderTable);