public class Inquirer implements
ActionListener, ItemListener
{
private Frame fMain;
private TextField tfDriver;
private TextField tfDatabase;
private TextField tfQuery;
private Label lStatus;
private Connection DBConnection;
private Statement SQLStatement;
private ResultSet rsQuery;
private List[] lQueryColumn;
private Panel pResultSet;
private ScrollPane scroll;
public static void main(String args[]) {
Inquirer inquirer = new Inquirer();
inquirer.init();
}
...
}
|
main methodFields of the Inquiry Class and the main function. This function simply construct an Inquiry Object and initializes it. All the useful code in this class is wrapped in Adapter Classes or in Listener methods and called by user's actions.
|
public Inquirer() {
super();
fMain = new Frame("Inquirer");
WindowAdapter waMain =
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
closeSql();
System.exit(0);
}
}
;
fMain.addWindowListener(waMain);
tfDriver = new TextField(
"sun.jdbc.odbc.JdbcOdbcDriver",80
);
tfDatabase = new TextField("jdbc:odbc:",80);
FocusAdapter faDatabase =
new FocusAdapter() {
public void focusLost(FocusEvent e) {
DBConnect(tfDatabase.getText());
}
}
;
tfDatabase.addFocusListener(faDatabase);
tfDatabase.addActionListener(this);
tfQuery = new TextField("SELECT * FROM",80);
tfQuery.addActionListener(this);
lStatus = new Label(copyright,Label.LEFT);
pResultSet = new Panel();
scroll = new ScrollPane();
scroll.setSize(200,200);
}
|
Inquirer Constructor methodThe Constructor of Inquirer simply initializes all the fields of the Class with default values. It defines also two Adapter Classes
- waMain a class that listens to the Window Closing Event and closes all the connections when such an event is performed
- faDatabase a class that listens to the Database Textfield Losing Focus Event and try to connect the specified database when such an event happens
|
protected void closeSql() {
try {
if(rsQuery != null) rsQuery.close();
if(SQLStatement != null) SQLStatement.close();
if(DBConnection != null) DBConnection.close();
} catch(java.sql.SQLException exc) {
lStatus.setText(exc.toString());
}
}
|
Database ClosecloseSql method closes the Connection, the Statement and the ResultSet Objects.
This method is declared protected because it must be accessible from the adapter method that listens to the window closing event. It's also used by the DBConnect method before the creation of a new connection.
|
public void init() {
fMain.setLayout(new BorderLayout());
Panel pTop = new Panel();
GridBagLayout gbl = new GridBagLayout();
pTop.setLayout(gbl);
GridBagConstraints gbc =
new GridBagConstraints()
;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = 1;
addComponent(
pTop,new Label("Driver",Label.RIGHT),gbl,gbc
);
gbc.gridwidth = GridBagConstraints.REMAINDER;
addComponent(pTop,tfDriver,gbl,gbc);
gbc.gridwidth = 1;
addComponent(
pTop,new Label("Database",Label.RIGHT),gbl,gbc
);
gbc.gridwidth = GridBagConstraints.REMAINDER;
addComponent(pTop,tfDatabase,gbl,gbc);
gbc.gridwidth = 1;
addComponent(
pTop,new Label("Query",Label.RIGHT),gbl,gbc
);
gbc.gridwidth = GridBagConstraints.REMAINDER;
addComponent(pTop,tfQuery,gbl,gbc);
fMain.add(pTop,"North");
fMain.add(lStatus,"South");
scroll.add(pResultSet);
fMain.add(scroll,"Center");
fMain.pack();
fMain.setVisible(true);
}
|
Inquirer init method
The init method builds the Dialog Layout placing the components to their right place.
|
public void itemStateChanged(ItemEvent e) {
for(
int col = 0; col < lQueryColumn.length; col++
) {
if(lQueryColumn[col].equals(e.getSource())) {
int idx =
lQueryColumn[col].getSelectedIndex()
;
for(
int ncol = 0;
ncol < lQueryColumn.length;
ncol++
) {
if(ncol != col) {
lQueryColumn[ncol].select(idx);
}
}
break;
}
}
}
|
ItemListener implementationThe itemStateChanged method implements the ItemListener Interface in the Inquiry Class. No Adapter Class is provided for ItemListeners because there is only one method to implement (this one). This method is called when the user selects an item in a List Object and highlights all the corresponding rows in the other Lists.
|
protected void DBConnect(String dbName) {
try {
closeSql();
Class.forName(tfDriver.getText());
DBConnection =
DriverManager.getConnection(dbName)
;
DatabaseMetaData DBMetadata =
DBConnection.getMetaData()
;
lStatus.setText(
"Connected to "+DBMetadata.getURL()+
" Driver "+DBMetadata.getDriverName()+
" Version "+DBMetadata.getDriverVersion()
);
SQLStatement = DBConnection.createStatement();
} catch(java.lang.Exception exc) {
lStatus.setText(exc.toString());
}
}
|
Database ConnectionDBConnect method connects to the database through the getConnection method. It uses the data filled in the Driver and Database textfields using the getText method. The status of the connection is shown in the status bar. Then a java.sql.statement Object is created.
This method is declared protected because it must be accessible by the adapter method that listens to the textfield losing focus event.
|
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(tfQuery)) {
try {
if(SQLStatement == null) {
lStatus.setText("Database not connected");
return;
}
lStatus.setText(copyright);
|
ActionListener implementationThe actionPerformed method implements the ActionListener Interface in the Inquiry Class. No Adapter Class is provided for ActionListeners since there is only one method to implement (this one). This method is called when the user hits the ENTER key on the Query Textfield submitting the query to the database.
|
rsQuery = SQLStatement.executeQuery(
e.getActionCommand()
);
ResultSetMetaData rsmd =
rsQuery.getMetaData()
;
int nCols = rsmd.getColumnCount();
lQueryColumn = new List[nCols];
pResultSet.removeAll();
GridBagLayout gbl = new GridBagLayout();
pResultSet.setLayout(gbl);
GridBagConstraints gbc =
new GridBagConstraints()
;
gbc.fill = GridBagConstraints.BOTH;
for(int ctCol = 1; ctCol <= nCols; ctCol++) {
if(ctCol != nCols)
gbc.gridwidth = 1
; else
gbc.gridwidth =
GridBagConstraints.REMAINDER
;
addComponent(
pResultSet,new Label(
rsmd.getColumnLabel(ctCol),
Label.CENTER
),gbl,gbc
);
}
for(int ctCol = 0; ctCol < nCols; ctCol++) {
lQueryColumn[ctCol] = new List(10,false);
lQueryColumn[ctCol].addItemListener(this);
if(ctCol != nCols-1)
gbc.gridwidth = 1
; else
gbc.gridwidth =
GridBagConstraints.REMAINDER
;
addComponent(
pResultSet,lQueryColumn[ctCol],gbl,gbc
);
}
fMain.pack();
fMain.invalidate();
fMain.repaint();
while(rsQuery.next()) {
for(int ctCol = 0; ctCol < nCols; ctCol++) {
String str = rsQuery.getString(ctCol+1);
if(str == null) str = "-";
lQueryColumn[ctCol].add(str);
}
}
} catch(java.sql.SQLException exc) {
lStatus.setText(exc.toString());
}
}
}
|
Database QueryThis chunck of code is executed when the actionPerformed method is called by the Query Textfield (tipically when the user hits the ENTER key). The query is read by a getActionCommand on the ActionEvent Object. The resulting Result Set, named rsQuery is asked for its metadata (i.e. number of columns). If the query doesn't give a Result Set an executeUpdate is better than executeQuery and avoids the SQLException. Then two cycles begin:
- a cycle for writing the labels of the columns
- another one to construct a List Object for every column
All these components are added to a ScroolPane and formatted using GridBagLayout and GridBagConstraints Objects. A Listener is associated to every List to catch selection events.
Then the window is packed, repainted and, finally, begins the cycle for filling the Lists with the data in the rows of the columns.
|