JTable
是Java.swing包下的一个类,用于显示和编辑常规二维单元表

构造方法:
//表格title一维数组
String[] columnNames=new String[] {"id","name","hp","damage"};
//表格内容二维数组
String[][]heros=new String[][] {{"1","盖伦","616","100"},
										{"2","提莫","512","102"},
										{"3","奎因","832","200"}};
JTable t=new JTable(heros,columnNames);//默认情况下,表格的标题不会显示出来,除非使用JScrollPane
		
//根据t创建JScrollPane
JScrollPane sp=new JScrollPane(t);
t.getColumnModel().getColumn(0).setPreferredWidth(100);//第一列 列宽

AbstractTableModel:

java提供的AbstractTableModel是一个抽象类,这个类帮我们实现大部份的TableModel方法,除了getRowCount(),getColumnCount(),getValueAt()这三个方法外。因此我们的主要任务就是去实现这三个方法.利用这个抽象类就可以设计出不同格式的表格.

TableModel的设计思想,在Model这种思想的指导下,数据和显示分离开,对于JTable而言,有数据部分也有显示部分。数据部分专门做一个类TableModel用于存放要显示的数据。

接口 DAO:操作数据库内表的接口

public interface DAO {
	public void add(Hero hero);
	public void update(Hero hero);
	public void delete(int id);
	public Hero get(int id);
	public List<Hero> list();
	public List<Hero> list(int start,int count);
}

类HeroDAO:操作指定数据库的类
public class HeroDAO implements DAO{
//把驱动初始化放在构造方法里
public HeroDAO() {
try {
Class.forName(“com.mysql.jdbc.Driver”);
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}

public Connection getConnection() throws SQLException{
	return DriverManager.getConnection("jdbc:mysql://localhost/eclipse-database?characterEncoding&useSSL=false","root","12345678");
}
public int getTotal() {
	int total=0;
	try(Connection c=getConnection();Statement s=c.createStatement();){
		String sql="select count(*) from hero";
		ResultSet rs=s.executeQuery(sql);
		while(rs.next()) {
			total=rs.getInt(1);
		}
	}catch(SQLException e) {
		e.printStackTrace();
	}
	return total;
}
@Override
public void add(Hero hero) {
	// TODO 自动生成的方法存根
	String sql="insert into hero values(null,?,?,?)";
	try(Connection c=getConnection();PreparedStatement ps=c.prepareStatement(sql);){
		ps.setString(1, hero.name);
		ps.setFloat(2, hero.hp);
		ps.setInt(3, hero.damage);
		
		ps.execute();
		
		ResultSet rs=ps.getGeneratedKeys();//获得insert插入后生成的主键id
		if(rs.next()) {
			int id=rs.getInt(1);
			hero.id=id;
		}
	}catch(SQLException e) {
		e.printStackTrace();
	}
}

@Override
public void update(Hero hero) {
	// TODO 自动生成的方法存根
	String sql="update hero set name = ?,hp= ?,damage = ? where id = ?";
	try(Connection c=getConnection();PreparedStatement ps=c.prepareStatement(sql);){
		ps.setString(1, hero.name);
		ps.setFloat(2, hero.hp);
		ps.setInt(3, hero.damage);
		ps.setInt(4, hero.id);
		
		ps.execute();
	}catch(SQLException e) {
		e.printStackTrace();
	}
}

@Override
public void delete(int id) {
	// TODO 自动生成的方法存根
	try(Connection c=getConnection();Statement s=c.createStatement();){
		String sql="delete from hero where id ="+ id;
		s.execute(sql);
	}catch(SQLException e) {
		e.printStackTrace();
	}
}

@Override
public Hero get(int id) {
	// TODO 自动生成的方法存根
	Hero hero=null;
	
	try(Connection c=getConnection();Statement s=c.createStatement();){
		String sql="select * from hero where id =" + id;
		ResultSet rs=s.executeQuery(sql);//executeQuery(sql);是对Statement,execute();是对preparedStatement
		if(rs.next()) {
			hero=new Hero();
			String name=rs.getString(2);
			float hp=rs.getFloat("hp");
			int damage=rs.getInt(4);
			hero.name=name;
			hero.hp=hp;
			hero.damage=damage;
			hero.id=id;
		}
	}catch(SQLException e) {
		e.printStackTrace();
	}
	return hero;
}

@Override
public List<Hero> list() {
	// TODO 自动生成的方法存根
	System.out.println("HeroDao的list方法");
	return list(0,Short.MAX_VALUE);
}

@Override
public List<Hero> list(int start, int count) {
	// TODO 自动生成的方法存根
	List<Hero> heros=new ArrayList<Hero>();
	String sql="select * from hero order by id desc limit ?,?";
	try(Connection c=getConnection();PreparedStatement ps=c.prepareStatement(sql);){
		ps.setInt(1, start);
		ps.setInt(2, count);
		
		ResultSet rs=ps.executeQuery();
		
		while(rs.next()) {
			Hero hero=new Hero();
			int id=rs.getInt(1);
			String name=rs.getString(2);
			float hp=rs.getFloat("hp");
			int damage=rs.getInt(4);
			hero.id=id;
			hero.name=name;
			hero.hp=hp;
			hero.damage=damage;
			heros.add(hero);
		}
	}catch(SQLException e) {
		e.printStackTrace();
	}
	return heros;
}
}

类HeroTableModel显示表格
public class HeroTableModel extends AbstractTableModel{

String[] columnNames=new String[] {"id","name","hp","damage"};
//使用从DAO返回的List作为TableModel的数据
public List<Hero> heros=new HeroDAO().list();


public int getRowCount() {
	return heros.size();
}
public int getColumnCount() {
	return columnNames.length;
}
public String getColumnName(int columnIndex) {
	return columnNames[columnIndex];
}
public boolean isCellEditable(int rowIndex, int columIndex) {
	return false;
}
//先通过heros.get(rowIndex)获取行对应的Hero对象
//然后根据columnIndex返回对应的属性
public Object getValueAt(int rowIndex, int columnIndex) {
	Hero h=heros.get(rowIndex);
	if(0==columnIndex)
		return h.id;
	if(1==columnIndex)
		return h.name;
	if(2==columnIndex)
		return h.hp;
	if(3==columnIndex)
		return h.damage;
	return null;
}
}

只需要修改HeroDao我们显示的数据就会改变,数据与显示分开。

public static void test01() {
JFrame f=new JFrame(“LOL”);
f.setSize(400,300);
f.setLocation(200,200);
f.setLayout(new BorderLayout());
//创建一个TableModel
HeroTableModel htm=new HeroTableModel();

//根据TableModel来创建Table
	JTable t=new JTable(htm);
	
	
	
	//准备一个Panel上放一个Label用于显示哪条被选中了
	JPanel p=new JPanel();
	final JLabel l=new JLabel("暂未选中条目");
	p.add(l);
	
	JScrollPane sp=new JScrollPane(t);
	//****可以获取一个TableSelectionModel,专门用于监听jtable选中项的变化****
	t.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

		//当选择了某一行的时候触发该事件
		public void valueChanged(ListSelectionEvent arg0) {
			//获取哪一行被选中了
			int row =t.getSelectedRow();
			//根据选中的行,到HeroTableModel中获取对应的对象
			Hero h=htm.heros.get(row);
			//更新标签内容
			l.setText("当前选中的英雄是:"+h.name);
		}
		
	});
	f.add(p, BorderLayout.NORTH);
	f.add(sp,BorderLayout.CENTER);
	
	
	f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	f.setVisible(true);
}