import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.Vector;
import javax.swing.table.AbstractTableModel;
import javax.swing.JTable;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import java.awt.BorderLayout;
import javax.swing.ListSelectionModel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
class MyJTable10 extends JFrame
{
MyJTable10(){
super();
setSize(500,400);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vector columnNameV=new Vector();
columnNameV.add("日期");
for(int i=1;i<21;i++){
columnNameV.add("商品"+1);
}
Vector tableValueV=new Vector();
for(int row=1;row<31;row++){
Vector rowV=new Vector();
rowV.add(row);
for(int col=0;col<20;col++){
rowV.add((int)(Math.random()*1000));
}
tableValueV.add(rowV);
}
final MFixedColumnTable panel=new MFixedColumnTable(columnNameV,tableValueV,1);
getContentPane().add(panel,BorderLayout.CENTER);
}
public class MFixedColumnTable extends JPanel
{
private Vector<String> columnNameV;//表格列名数组
private Vector<Vector<Object>> tableValueV;//表格数据数组
private int fixedColumn=1;                   //固定列数量 
private JTable fixedColumnTable;//固定列表格对象
private FixedColumnTableModel fixedColumnTableModel;//固定列表格模型对象
private JTable floatingColumnTable;//移动列表格对象
private FloatingColumnTableModel floatingColumnTableModel;//移动列表格模型对象
public MFixedColumnTable(Vector<String> columnNameV,Vector<Vector<Object>> tableValue,int fixedColumn){
super();
setLayout(new BorderLayout());
this.columnNameV=columnNameV;      //表格列名数组
this.tableValueV=tableValueV;      //表格数据数组
this.fixedColumn=fixedColumn;      //固定列数量
//创建固定列表格
fixedColumnTableModel=new FixedColumnTableModel();//创建固定列表格模型对象
fixedColumnTable=new JTable(fixedColumnTableModel);//创建固定列表格对象
ListSelectionModel fixed=fixedColumnTable.getSelectionModel();//获得选择模型对象
fixed.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);//选择模式为单选
fixed.addListSelectionListener(new MListSelectionListener(true));//添加行被选中的事件监听器
//创建可移动列表格
floatingColumnTableModel=new FloatingColumnTableModel();//创建可移动列表格模型对象
floatingColumnTable=new JTable(floatingColumnTableModel);//创建可移动列表格对象
floatingColumnTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);//关闭表格的自动调整功能
ListSelectionModel floating=floatingColumnTable.getSelectionModel();//获得选择模型对象
floating.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);//选择模式为单选
floating.addListSelectionListener(new MListSelectionListener(false));//添加行被选中的事件监听器
//添加滚动面板
JScrollPane scrollPane=new JScrollPane();     //创建一个滚动面板对象
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,fixedColumnTable.getTableHeader());//将固定列表格头放到滚动面板的左上方
JViewport viewport=new JViewport();//创建一个用来显示基础信息的视口对象
viewport.setView(fixedColumnTable);//将固定列表格添加到视口中
viewport.setPreferredSize(fixedColumnTable.getPreferredSize());//设置市口的首选大小
scrollPane.setRowHeaderView(viewport);//将视口添加到滚动面板的标题视口中
scrollPane.setViewportView(floatingColumnTable);//将可移动列表格添加到默认视口
add(scrollPane,BorderLayout.CENTER);
}
private class FixedColumnTableModel extends AbstractTableModel
{
public int getColumnCount(){   //返回固定列的数量
return fixedColumn;
}
public int getRowCount(){      //返回行数
return tableValueV.size();
}
public Object getValueAt(int rowIndex,int columnIndex){//返回指定单元格的值
return tableValueV.get(rowIndex).get(columnIndex);
}
public String getColumnName(int columnIndex){  //返回指定列的名称
return columnNameV.get(columnIndex);
}
}
private class FloatingColumnTableModel extends AbstractTableModel
{
public int getColumnCount(){   //返回可移动列的数量
return columnNameV.size()-fixedColumn;//需要扣除固定列的数量
}
public int getRowCount(){//返回行数
return tableValueV.size();
}
public Object getValueAt(int rowIndex,int columnIndex){//返回指定单元格的值
return tableValueV.get(rowIndex).get(columnIndex+fixedColumn);//为列索引加上固定列的数量
}
public String getColumnName(int columnIndex){//返回指定列的名称
return columnNameV.get(columnIndex+fixedColumn);//需要为列索引加上固定列的数量
}
}
private class MListSelectionListener implements ListSelectionListener
{
boolean isFixedColumnTable=true;//默认由选中固定列表格的行出发
public MListSelectionListener(boolean isFixedColumnTable){
this.isFixedColumnTable=isFixedColumnTable;
}
public void valueChanged(ListSelectionEvent e){
if(isFixedColumnTable){   //由选中固定列表表格的行触发
int row=fixedColumnTable.getSelectedRow();//获得固定列表格中的选中行
//同时选中右侧可移动列表格中的相应行
floatingColumnTable.setRowSelectionInterval(row,row);
}
else{      //由选中可移动列表格中的行触发
int row=floatingColumnTable.getSelectedRow();//获得可移动列表格中的选中行
//同时选中左侧固定列表格中的相应行
fixedColumnTable.setRowSelectionInterval(row,row);
}
}
}
}
public static void main(String[] args) 
{
MyJTable10 f=new MyJTable10();
f.setVisible(true);
}
}
//为什么编译没错,运行时出现NullPointerException异常,是对象没初始化嘛,是的话,是在哪里?谢谢

解决方案 »

  1.   

    private Vector<Vector<Object>> tableValueV;//表格数据数组
    !!!!!
    !!!!
    你这个没初始化 
    public int getRowCount(){ //返回行数
    return tableValueV.size();
    }
    你这里又在调用
    -------------
    请将数组初始化
      

  2.   

    columnNameV,tableValueV 在构造方法里是设置了值,可是public class MFixedColumnTable extends JPanel
    {}里根本没有引用上面的值,又重新定义的它们private Vector<String> columnNameV;//表格列名数组
    private Vector<Vector<Object>> tableValueV;//表格数据数组
    并且没有赋值,所以会报NullPointerException异常