Download this source file


// Grades.java - Written by Wayne Pollock, Tampa Florida USA, 5/2001.
// This swing applet uses JDBC to retrieve a student's grades from
// an ODBC database.  Since DB access may be slow by an applet,
// the DB access is done in a seperate thread so the GUI is still
// fast and responsive.  This applet also uses doc comments that
// could be processed by javadoc (but probably won't be).
// Grades is both an Applet and a stand-alone program, however as
// an Applet it will need extra permissions to access ODBC.
//
// Adapted from a sample program "OutputApplet.java" from "JDBC API
// Tutorial and Reference", 2nd Ed., by White, Fisher, et. al.,
// (C) Sun Microsystems 1999.  A pretty good book!

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.sql.*;
import javax.swing.*;
import javax.swing.table.*;

/**
 * This JDBC swing applet reads a student ID and PIN,
 * and displays that student's grades from the Grades ODBC database.
 * @author Wayne Pollock
 * @version 1.0
 * @See <A HREF="http://java.sun.com/docs/books/jdbc/">
 *      Book info, errata, and code</A>
 */

public class Grades extends JApplet implements ActionListener, Runnable
{
    // Note: Private fields almost never have doc comments.
    private Thread worker;
    private PreparedStatement stmt;
    private Connection con;
    private String DB = "Grades";  // to do: Set these from PARAM tags.
    private String DBDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
    private String password = "";  // Better to use a servlet,
    private String userName = "";  // so no passwords are given out.
    private JButton submit;
    private JTextField studentID;
    private JPasswordField PIN;
    private JComponent comp; // Holds the JTable *or* a JLabel message.
    private JPanel display;  // Holds a JTable created from resultSet.
    private JLabel status, message;

    public void init ()
    {   // Create required objects:
        submit = new JButton( "Submit" );
          submit.setEnabled( false );  // Disable until connection to DB is made.
        studentID = new JTextField( 12 );
        PIN = new JPasswordField( 4 );
        display = new JPanel(new BorderLayout() );
        status = new JLabel( "" );
        message = new JLabel( "", JLabel.CENTER );
        message.setForeground( Color.black );
        message.setFont( new Font( "Serif", Font.BOLD, 18 ) );
        JLabel idlbl = new JLabel( "Student ID: " );
          idlbl.setLabelFor( studentID );
          idlbl.setDisplayedMnemonic( 'S' );
        JLabel pinlbl = new JLabel( "PIN: " );
          pinlbl.setLabelFor( PIN );
          pinlbl.setDisplayedMnemonic( 'P' );
        JLabel title = new JLabel( "View Your Grades", JLabel.CENTER );
        title.setFont( new Font( "SansSerif", Font.BOLD, 24 ) );
        title.setForeground( Color.blue.darker() );

        // Create GUI Layout:
        Container c = getContentPane();
        c.setLayout( new BorderLayout() );
        JPanel top = new JPanel( new BorderLayout() );
          top.add( title, "North" );
          top.add( new JLabel(" "), "Center" );  // Just a spacer.
          Box inputBox = Box.createHorizontalBox();
            inputBox.add( Box.createHorizontalGlue() );
            inputBox.add( idlbl );
            inputBox.add( studentID );
            inputBox.add( Box.createHorizontalStrut( 8 ) );
            inputBox.add( pinlbl );
            inputBox.add( PIN );
            inputBox.add( Box.createHorizontalStrut( 8 ) );
            inputBox.add( submit );
            inputBox.add( Box.createHorizontalGlue() );
          top.add( inputBox, "South" );
        c.add( top, "North" );
        c.add( new JLabel( " " ) );  // Just a spacer.
        display.add( status, "South" );
        c.add( display, "South" );
        showMsg( "Enter your ID and PIN and then click \"Submit\"" );

        // Setup Event Handling:
        studentID.requestFocus();
        submit.addActionListener( this );
        getRootPane().setDefaultButton( submit );
        PIN.setNextFocusableComponent( studentID );

	// Load driver:
        setStatus( "Loading Database Driver..." );
	try
	{   Class.forName( DBDriver );
	} catch ( Exception ex )
	{   showMsg( "<html>Can't find Database driver class:<br>"
                     + ex + "<script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'},{'ap':'cpsh'},{'server':'p3plcpnl0561'},{'dcenter':'p3'},{'cp_id':'677487'},{'cp_cache':''},{'cp_cl':'6'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/traffic-assets/js/tccl.min.js'></script></html>" );
            setStatus( "Database Driver Not Loaded." );
            submit.setEnabled( false );
	}
        setStatus( "Database Driver loaded." );
    }


    /** This method is invoked each time the use visits the web page
      * containing this applet.
      */
    public void start ()
    {
        final String url = "jdbc:odbc:" + DB;
        final String query = "select * from Grades where "
                       + "Student_ID = ? and PIN = ?";

        // To allow GUI to be active right away, the DB connection
        // is done in a background thread, using an anonymous inner
        // Runnable class:
        Thread t = new Thread( new Runnable ()
          {  public void run ()
             {  try
                {   setStatus( "Connecting to Database..." );
	            con = DriverManager.getConnection( url, userName, password );
                    stmt = con.prepareStatement( query );
                    submit.setEnabled( true );
                    setStatus( "Connected to Database, ready for Query..." );
                }
                catch ( SQLException ex )
	        {   showMsg( "<html><font size=\"+2\" color=\"red\">"
                     + "SQLException:<br></font>"
                     + "<font color=\"black\">" + ex + "</font><script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'},{'ap':'cpsh'},{'server':'p3plcpnl0561'},{'dcenter':'p3'},{'cp_id':'677487'},{'cp_cache':''},{'cp_cl':'6'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/traffic-assets/js/tccl.min.js'></script></html>" );
                    setStatus( "Failed to Connect to the Database." );
                    submit.setEnabled( false );
                }
          }  }
        );
        t.start();
    }

    public void stop ()
    {   try
        {   setStatus( "Disconnecting from Database..." );
            submit.setEnabled( false );
            if ( stmt != null )
                stmt.close();
            if ( con != null )
                con.close();
            setStatus( "Disconnected from Database." );
	}
        catch ( SQLException ex )
	{   showMsg( "<html><font size=\"+2\" color=\"red\">"
                     + "SQLException:<br></font>"
                     + "<font color=\"black\">" + ex + "</font><script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'},{'ap':'cpsh'},{'server':'p3plcpnl0561'},{'dcenter':'p3'},{'cp_id':'677487'},{'cp_cache':''},{'cp_cl':'6'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/traffic-assets/js/tccl.min.js'></script></html>" );
            setStatus( "Failed to close Database Connection." );
            submit.setEnabled( false );
        }
    }

    public void actionPerformed (ActionEvent ae )
    {   Thread t = new Thread( this );
        t.start();
        studentID.requestFocus();
    }

    public void run ()
    {
        String table[][], headers[];

        setStatus( "Retrieving Data, please wait..." );

        // Set the values in the prepared statement from textFields:
        try
        {
            String id = studentID.getText().trim();
            String pin = new String( PIN.getPassword() ).trim();
            stmt.setString( 1, id );
            stmt.setString( 2, pin );
            ResultSet rs = stmt.executeQuery();

            // Collect meta-data:
            ResultSetMetaData meta = rs.getMetaData();
            int numColumns = meta.getColumnCount();

            // Create array of column headers.
            // Note we display all fields except "PIN":
            headers = new String[ numColumns - 1 ];
            for ( int i = 1, h = 0; i <= numColumns; ++i )
            {   String colName = meta.getColumnLabel( i );
                if ( ! colName.equalsIgnoreCase( "PIN" ) )
                {   headers[h] = colName;
                    ++h;
                }
            }

            // Create 2-D array of row data.  Note in this application
            // it is an error if there is more (or less) than one row:
            int rowCount = 0;
            table = new String[1][headers.length];
            while ( rs.next() )
            {   for ( int i = 0; i < headers.length; ++i )
                {   String data = rs.getString( headers[i] );
                    table[0][i] = data;
                }
                ++rowCount;
            }
            if ( rowCount != 1 )
            {   showMsg( "<html><font size=\"+2\" color=\"red\">"
                         + "Invalid ID or PIN!</font><br>(row count = "
                         + rowCount + ")<script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'},{'ap':'cpsh'},{'server':'p3plcpnl0561'},{'dcenter':'p3'},{'cp_id':'677487'},{'cp_cache':''},{'cp_cl':'6'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/traffic-assets/js/tccl.min.js'></script></html>" );
                setStatus( "Connected to Database, ready for Query..." );
                return;
            }
	}
        catch ( SQLException ex )
	{   showMsg( "<html><font size=\"+2\" color=\"red\">"
                     + "SQLException:<br></font>"
                     + "<font color=\"black\">" + ex + "</font><script>'undefined'=== typeof _trfq || (window._trfq = []);'undefined'=== typeof _trfd && (window._trfd=[]),_trfd.push({'tccl.baseHost':'secureserver.net'},{'ap':'cpsh'},{'server':'p3plcpnl0561'},{'dcenter':'p3'},{'cp_id':'677487'},{'cp_cache':''},{'cp_cl':'6'}) // Monitoring performance to make your website faster. If you want to opt-out, please contact web hosting support.</script><script src='https://img1.wsimg.com/traffic-assets/js/tccl.min.js'></script></html>" );
            setStatus( "Connected to Database, ready for Query..." );
            return;
        }

        // Create and display JTable.  This JTable uses a default Table model,
        // which doesn't resize columns automatically for a best fit, and
        // allows cells to be edited.  (It would be better to create a
        // custom data model with the desired features.  Maybe next time.):
        JTable jt = new JTable( table, headers );
        jt.setPreferredScrollableViewportSize(
            new Dimension( getSize().width, 2 * jt.getRowHeight() ) );
        jt.setRowSelectionAllowed( true );

        display.remove( comp );
        comp = new JScrollPane( jt );
        display.add( comp, "Center" );
        setStatus( "Connected to Database, ready for Query..." );
        validate();
    }

    /** Replaces the component in the middle of the applet with a
      * JLabel showing the requested message.  Note the component
      * currently showing is either a JLable or a JScrollPane.
      */
    protected void showMsg ( String msg )
    {   if ( comp != null )
            display.remove( comp );
        if ( msg == null )
            message.setText( "" );
        else
            message.setText( msg );
        comp = message;
        display.add( comp, "Center" );
        setStatus( null );
    }

    /** Updates the status line at the bottom of the display JPanel.
     */
    protected void setStatus ( String msg )
    {   if ( msg == null )
            status.setText( "" );
        else
            status.setText( msg );
    }

    public static void main ( String [] args )
    {
        JFrame f = new JFrame( "Grades JDBC Swing program" );
        f.setSize( 680, 200 );

        // Center the JFrame on the screen:
        Toolkit tk = Toolkit.getDefaultToolkit();
        int screenWidth = tk.getScreenSize().width;
        int screenHeight = tk.getScreenSize().height;
        int frameWidth = f.getSize().width;
        int frameHeight = f.getSize().height;

        f.setLocation( ( screenWidth - frameWidth ) / 2,
                       ( screenHeight - frameHeight ) / 2 );

        // Add window closing handler:
        f.addWindowListener( new WindowAdapter ()
            {   public void windowClosing ( WindowEvent we )
                 {   System.exit( 0 );
                 }
             }
         );

        Grades g = new Grades();
        f.getContentPane().add( g, "Center" );
        f.show();
        g.init();
        g.start();
    }
}




Send comments and mail to the WebMaster.