编者按:swinghacks不仅仅是视觉上的游戏,就如同本文所阐述的一样。本书的目的是使开发者能够利用java开发出更优秀的桌面应用程序,而本文正是这样的一个例子,不光是利用可视化的jtable,而主要是利用隐藏在这之后的模型来开发。通过j2se所提供的jdbc支持,你可以将一个数据库的表映射到一个swing的表控件模型,然后用jtable将其呈现出来。让我们进入细节吧。
版权声明:任何获得matrix授权的网站,转载时请务必保留以下作者信息和链接
作者:elliotte rusty;henterji
原文:http://www.onjava.com/pub/a/onjava/excerpt/swinghks_hack24/index.html
译文:http://www.matrix.org.cn/resource/article/44/44193_swing+jdbc.html
关键字:swing;jdbc
简单快速的将数据库中的表引入swing之内。
如果你已经用过数据库了,你很可能已经用过为数据库提供的维护和查询表的工具:命令行工具很适合作简单而直接的工作,但是很难完成大量数据的处理工作。在一次查询中写一条返回10或20列的数据就已经很困难了-更糟的是由于换行而使每条记录都有很多行的情况,此时你根本无法区分一条记录在哪一行结束,另一条记录在哪一行开始。
如果能够将数据库中表的内容映射到swing的jtable中是否好一些呢?加上一些jdbc语句,添加到jframe上,顷刻之间就形成了图形界面。
建立连接
如果你同时用到jdbc和swing,只需要一句话你就可以抓住要点:使用数据库表的元数据来建立swing表控件模型。如果你还没用到它们,下面就是你需要了解的背景知识:jdbc提供许多抽象方法来存取数据库。对于一个数据库有效的java代码也应该对其他数据库有效,唯一的不同之处在于jdbc与不同的数据库建立连接时所需要提供的下面的一些字符串也是不同的:
¨ 一个驱动程序类的类名,提供各种不同的java.sql接口的实现。
¨ 一个连接到数据库的url。这就意味着可能会用到socket,尽管这不是一定的。一些小的可嵌入的数据库就像你的应用程序一样可以存活于java虚拟机中。
¨ 一个可选的用户名。
¨ 一个可选的密码。
一旦建立了连接,你就可以发送一些命令(创建、删除、或修改表),或者通过该连接,创建sql语句来对数据库进行查询。你也能通过该连接得到数据库的元数据,例如它所支持的各种特性,某一字符串的最大长度等等。更重要的是,它可以让你知道数据库中都有哪些表,它们都有哪些字段,每个字段的数据类型是什么。
因此,假设连接到了数据库,并且知道该数据库中的一个表的表名,你就可以利用两次查询将表的内容用java表现出来。第一次查询能得到该表的各字段的元数据并且将字段名和字段的类型构建成一个数组。这些能被适当地而且很好地映射到java类中,至少支持你想支持的各种类型。第二次查询得到表中所有的数据。对于每行数据,对应字段它都有相应的值。这些数据可以放入一个二维数组中,该数组存放的是整个表的内容。
通过这两次查询,也就完成了要实现abstracttablemodel类中的抽象方法的所有准备:
¨ getrowcount():是你所创建的内容数组contents的长度。
¨ getcolumncount():如果没有内容则为0,否则为数组contents的第一项(该项也是一个数组,因为内容数组是一个二维数组)的长度。
¨ getvalueat():contents[row][col]的值。
abstracttablemodel已经完全的实现了getcolumnclass()和getcolumnname()两个方法,因此,前者总是返回object.class,后者返回"a","b","c",等等;你也可以利用第一次查询的字段元数据覆盖这两个方法,以更好的实现它们。
例3-12演示jdbctablemodel如何被实现。
例3-12.由数据库连接生成的swing表控件模型
import javax.swing.*;
import javax.swing.table.*;
import java.sql.*;
import java.util.*;
/** an immutable table model built from getting
metadata about a table in a jdbc database
*/
public class jdbctablemodel extends abstracttablemodel {
object[][] contents;
string[] columnnames;
class[] columnclasses;
public jdbctablemodel (connection conn, string tablename)
throws sqlexception {
super();
gettablecontents (conn, tablename);
}
protected void gettablecontents (connection conn,
string tablename)
throws sqlexception {
// get metadata: what columns exist and what
// types (classes) are they?
databasemetadata meta = conn.getmetadata();
system.out.println ("got meta = " + meta);
resultset results =
meta.getcolumns (null, null, tablename, null);
system.out.println ("got column results");
arraylist colnameslist = new arraylist();
arraylist colclasseslist = new arraylist();
while (results.next()) {
colnameslist.add (results.getstring ("column_name"));
system.out.println ("name: " +
results.getstring ("column_name"));
int dbtype = results.getint ("data_type");
switch (dbtype) {
case types.integer:
colclasseslist.add (integer.class); break;
case types.float:
colclasseslist.add (float.class); break;
case types.double:
case types.real:
colclasseslist.add (double.class); break;
case types.date:
case types.time:
case types.timestamp:
colclasseslist.add (java.sql.date.class); break;
default:
colclasseslist.add (string.class); break;
};
system.out.println ("type: " +
results.getint ("data_type"));
}
columnnames = new string [colnameslist.size()];
colnameslist.toarray (columnnames);
columnclasses = new class [colclasseslist.size()];
colclasseslist.toarray (columnclasses);
// get all data from table and put into
// contents array
statement statement =
conn.createstatement ();
results = statement.executequery ("select * from " +
tablename);
arraylist rowlist = new arraylist();
while (results.next()) {
arraylist celllist = new arraylist();
for (int i = 0; i<columnclasses.length; i++) {
object cellvalue = null;
if (columnclasses[i] == string.class)
cellvalue = results.getstring (columnnames[i]);
else if (columnclasses[i] == integer.class)
cellvalue = new integer (
results.getint (columnnames[i]));
else if (columnclasses[i] == float.class)
cellvalue = new float (
results.getint (columnnames[i]));
else if (columnclasses[i] == double.class)
cellvalue = new double (
results.getdouble (columnnames[i]));
else if (columnclasses[i] == java.sql.date.class)
cellvalue = results.getdate (columnnames[i]);
else
system.out.println ("can't assign " +
columnnames[i]);
celllist.add (cellvalue);
}// for
object[] cells = celllist.toarray();
rowlist.add (cells);
} // while
// finally create contents two-dim array
contents = new object[rowlist.size()] [];
for (int i=0; i<contents.length; i++)
contents[i] = (object []) rowlist.get (i);
system.out.println ("created model with " +
contents.length + " rows");
// close stuff
results.close();
statement.close();
}
// abstracttablemodel methods
public int getrowcount() {
return contents.length;
}
public int getcolumncount() {
if (contents.length == 0)
return 0;
else
return contents[0].length;
}
public object getvalueat (int row, int column) {
return contents [row][column];
}
// overrides methods for which abstracttablemodel
// has trivial implementations
public class getcolumnclass (int col) {
return columnclasses [col];
}
public string getcolumnname (int col) {
return columnnames [col];
}
}
import javax.swing.*;
import javax.swing.table.*;
import java.sql.*;
import java.util.*;
import java.io.*;
public class testjdbctable {
public static void main (string[] args) {
try {
/*
driver, url, user, and pass can be passed in as
system properties "jdbctable.driver",
"jdbctable.url", "jdbctable.user", and
"jdbctable.pass", or specified in a file
called "jdbctable.properties" in current
directory
*/
properties testprops = new properties();
string ddriver = system.getproperty ("jdbctable.driver");
string durl = system.getproperty ("jdbctable.url");
string duser = system.getproperty ("jdbctable.user");
string dpass = system.getproperty ("jdbctable.pass");
if (ddriver != null)
testprops.setproperty ("jdbctable.driver", ddriver);
if (durl != null)
testprops.setproperty ("jdbctable.url", durl);
if (duser != null)
testprops.setproperty ("jdbctable.user", duser);
if (dpass != null)
testprops.setproperty ("jdbctable.pass", dpass);
try {
testprops.load (new fileinputstream (
new file ("jdbctable.properties")));
} catch (exception e) {} // ignore fnf, etc.
system.out.println ("test properties:");
testprops.list (system.out);
// now get a connection
// note care to replace nulls with empty strings
class.forname(testprops.getproperty
("jdbctable.driver")).newinstance();
string url = testprops.getproperty ("jdbctable.url");
url = ((url == null) ? "" : url);
string user = testprops.getproperty ("jdbctable.user");
user = ((user == null) ? "" : user);
string pass = testprops.getproperty ("jdbctable.pass");
pass = ((pass == null) ? "" : pass);
connection conn =
drivermanager.getconnection (url, user, pass);
// create db table to use
string tablename = createsampletable(conn);
// get a model for this db table and add to a jtable
tablemodel mod =
new jdbctablemodel (conn, tablename);
jtable jtable = new jtable (mod);
jscrollpane scroller =
new jscrollpane (jtable,
scrollpaneconstants.vertical_scrollbar_as_needed,
scrollpaneconstants.horizontal_scrollbar_as_needed);
jframe frame = new jframe ("jdbctablemodel demo");
frame.getcontentpane().add (scroller);
frame.pack();
frame.setvisible (true);
conn.close();
} catch (exception e) {
e.printstacktrace();
}
}
public static string createsampletable (connection conn)
throws sqlexception {
statement statement = conn.createstatement();
// drop table if it exists
try {
statement.execute ("drop table employees");
} catch (sqlexception sqle) {
sqle.printstacktrace(); // if table !exists
}
statement.execute ("create table employees " +
"(name char(20), title char(30), salary int)");
statement.execute ("insert into employees values " +
"('jill', 'ceo', 200000 )");
statement.execute ("insert into employees values " +
"('bob', 'vp', 195000 )");
statement.execute ("insert into employees values " +
"('omar', 'vp', 190000 )");
statement.execute ("insert into employees values " +
"('amy', 'software engineer', 50000 )");
statement.execute ("insert into employees values " +
"('greg', 'software engineer', 45000 )");
statement.close();
return "employees";
}
}
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器