我要写个进销货管理系统,用GUI实现,遇到一个问题:在点击"商品查询"的时候可以实现从数据库调出所有商品的信息,起初我用JTable处理
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.sql.*;
public class Info extends JFrame
{
Connection con;
Statement st;
ResultSet rs;
String[][] rowData;
String[] columnNames ={"商品编号", "商品名","商品类别","产商","进价(元)","标价(元)","库存(单位)"};
JTable jt;
JScrollPane jsp;
Container c=getContentPane();
int i=0;
public Info(){
try{
init();
pack();
}
catch(Exception e){}
}
public void init(){
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection("jdbc:odbc:jxh", "www", "111");
st=con.createStatement();
rs=st.executeQuery("Select*From info");
while(rs.next()){
i+=1;
}
rowData=new String[i][6];//计算出商品总数,然后创建一个以商品总数大小为一维大小的数组.
int j=0;
while(rs.next()){
rowData[j][0]=rs.getString(1);
rowData[j][1]=rs.getString(2);
rowData[j][2]=rs.getString(3);
rowData[j][3]=rs.getString(4);
rowData[j][4]=rs.getString(5);
rowData[j][5]=rs.getString(6);
rowData[j][6]=rs.getString(7);
j+=1;
}
jt=new JTable(rowData,columnNames); /*构造方法JTable(Object[][] rowData, Object[] columnNames)*/
jsp = new JScrollPane();
jsp.getViewport().add(jt,null);
jsp.setBounds(new Rectangle(2, 10, 433, 185));
setBounds(250, 250, 450, 350);
c.add(jsp,BorderLayout.CENTER);
setTitle("商品查看");
setVisible(true);
}
catch(Exception e){
String error=e.getMessage();
JOptionPane.showMessageDialog(null,error);
}
}
public static void main(String[] args ){
new Info();
}
}
但是运行出错,运行的界面见附件里的errorPic.gif,错误代码见附件里的error.txt
后来我改了一下,用以下代码代替以上的JTable,
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 7; }
public int getRowCount()
{
return i;
}
public Object getValueAt(int row, int col) { return new Integer(row*col); }
};
jt=new JTable(dataModel);
但我不知道如何修改它的表头(用以上代码得到的运行界面如附件里的1.gif),也就是要将表头设为 "商品编号", "商品名","商品类别","产商","进价(元)","标价(元)","库存(单位)";然后怎么实现表中的数据是通过数据库查询得到的数据,用DriverManager.getConnection("jdbc:odbc:jxh", "www", "111");
-------------------还有,Java中有没有能分页显示以上内容的类,就是实现行列显示大量内容的,如果有请给出用法----------------------------------------
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.sql.*;
public class Info extends JFrame
{
Connection con;
Statement st;
ResultSet rs;
String[][] rowData;
String[] columnNames ={"商品编号", "商品名","商品类别","产商","进价(元)","标价(元)","库存(单位)"};
JTable jt;
JScrollPane jsp;
Container c=getContentPane();
int i=0;
public Info(){
try{
init();
pack();
}
catch(Exception e){}
}
public void init(){
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection("jdbc:odbc:jxh", "www", "111");
st=con.createStatement();
rs=st.executeQuery("Select*From info");
while(rs.next()){
i+=1;
}
rowData=new String[i][6];//计算出商品总数,然后创建一个以商品总数大小为一维大小的数组.
int j=0;
while(rs.next()){
rowData[j][0]=rs.getString(1);
rowData[j][1]=rs.getString(2);
rowData[j][2]=rs.getString(3);
rowData[j][3]=rs.getString(4);
rowData[j][4]=rs.getString(5);
rowData[j][5]=rs.getString(6);
rowData[j][6]=rs.getString(7);
j+=1;
}
jt=new JTable(rowData,columnNames); /*构造方法JTable(Object[][] rowData, Object[] columnNames)*/
jsp = new JScrollPane();
jsp.getViewport().add(jt,null);
jsp.setBounds(new Rectangle(2, 10, 433, 185));
setBounds(250, 250, 450, 350);
c.add(jsp,BorderLayout.CENTER);
setTitle("商品查看");
setVisible(true);
}
catch(Exception e){
String error=e.getMessage();
JOptionPane.showMessageDialog(null,error);
}
}
public static void main(String[] args ){
new Info();
}
}
但是运行出错,运行的界面见附件里的errorPic.gif,错误代码见附件里的error.txt
后来我改了一下,用以下代码代替以上的JTable,
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() { return 7; }
public int getRowCount()
{
return i;
}
public Object getValueAt(int row, int col) { return new Integer(row*col); }
};
jt=new JTable(dataModel);
但我不知道如何修改它的表头(用以上代码得到的运行界面如附件里的1.gif),也就是要将表头设为 "商品编号", "商品名","商品类别","产商","进价(元)","标价(元)","库存(单位)";然后怎么实现表中的数据是通过数据库查询得到的数据,用DriverManager.getConnection("jdbc:odbc:jxh", "www", "111");
-------------------还有,Java中有没有能分页显示以上内容的类,就是实现行列显示大量内容的,如果有请给出用法----------------------------------------
2. 既然你重写了TableModel, 那么建议你继承DefaultTableModel, 毕竟很多东西不用自己写了.
3. 列名可以重写TableModel的getColumnName(int columnIndex)方法.
4. 最好把Table.getTableHeader.setReorderingAllowed设为false, 这样可以避免重写TableModel以后引起的一些麻烦.
5. 看代码你的JTable应该是只读的吧?
建议你把查询结果设计为一个对象, 比如:
public class Result {
public String productNo = null;
public String productName = null;
// ... 其他属性
}
为了简便, 我省去了Getter和Setter, 而把属性改为public了, 理论上用Getter/Setter是更好的实现.
然后用一个List来存储这些结果, 并且时刻保持List不为null.
List<Result> list = new ArrayList<Result>();
重写TableModel的getValueAt方法, 这个你应该已经知道了.
public Object getValueAt(int row, int column) {
Result result = list.get(row);
switch (column) {
case PRODUCT_NO:
case PRODUCT_NAME:
//.....其他列
}
}
case后面的列号, 固定常量. 这也是为什么前面提到setReorderingAllowed的原因. 具体的原因是由于ModelIndex和ViewIndex有个映射关系, 设置为false以后就是一致的了.
重写TableModel的getRowCount()方法.
public int getRowCount() {
return list.size();
}
如果你保持list不为null可以这么写, 否则请加上null判断.
6. 回到分页, 你可以添加类似分页的按钮在界面上, 当然不是在JTable中. 查询结果一样放在List中, 然后调用TableModel.fireTableStructureChanged通知结构变化, 要求重画.
一切用TableModel来解决问题, 你会获得更多的便利性.
我现在要解决的问题是如何根据查询数据库得到的结果显示在JTable中.class SeekTable extends AbstractTableModel
{
private static final long serialVersionUID = 1L;
Object[][] data={{"","","","","","",""}};
String[] title={ "商品编号", "商品名", "商名类别", "厂商", "进价(元)", "标价(元)", "库存(单位)" };
public SeekTable(String[][] data){
this.data=data;
}
public SeekTable(){
}
public int getColumnCount()
{
return title.length;
} public int getRowCount()
{
return data.length;
}
public String getColumnName(int col){
return title[col];
}
public Object getValueAt(int rowIndex, int columnIndex)
{
return data[rowIndex][columnIndex];
}
public void setValueAt(Object value,int row,int col){
data[row][col]=value;
fireTableCellUpdated(row,col);
}
}
------------------------------------------------------------------------
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String url="jdbc:mysql://localhost/jxhsystem?user=root&password=111111&useUnicode=true&characterEncoding=gb2312";
Connection con = DriverManager.getConnection(url);
Statement st = con.createStatement();
ResultSet rs1 = st.executeQuery("select*from info");
while (rs1.next())
{
if (rs1.getString("sort").equals(input))
{
i++;
lab3.setText("共找到"+i+"条信息");//这个做个测试跟数据库的结果完全一致. }
}
if(i!=0){
ResultSet rs2 = st.executeQuery("select*from info where sort='"+input+"'");
String[][] data=new String[i][7];
int j=0;
while(rs2.next()){
data[j][0]=rs2.getString("id");
data[j][1]=rs2.getString("name");
data[j][2]=input;
data[j][3]=rs2.getString("factory");
data[j][4]=rs2.getString("inprice");
data[j][5]=rs2.getString("edprice");
data[j][6]=rs2.getString("quantity");
j++;
}
table=new JTable(new SeekTable(data));
//也就是我还是动态判断出数组的大小,然后把查询得到的结果数组作为参数传进那个继承了AbstractTableModel的类,可为什么Jable不能刷新呢?
}
String id= (String) table.getValueAt(0,0);
String name = (String) table.getValueAt(0, 1);
String sort = (String) table.getValueAt(0, 2);
String factory = (String) table.getValueAt(0, 3);
String inprice = (String) table.getValueAt(0, 4);
String quantity = (String) table.getValueAt(0, 5);
String time = (String) table.getValueAt(0, 6);
String edprice = (String) table.getValueAt(0, 7);
System.out.println(id);
System.out.println(name);
System.out.println(sort);
System.out.println(factory);
System.out.println(inprice);
System.out.println(quantity);
System.out.println(time);
System.out.println(edprice);
我在Table的第一行的各个列输入一个相应的值,可结果出人意料,
1
N73
mobile
Nokia
2000
10
07-10-19
null
为什么最后一个是空的呢?这么简单的一个问题怎么会出错呢?