> List of tutorials

Table of contents for this tutorial

Base lesson 2: A DataBase-Loader with a GUI (Graphic User Interface)

For this document and all references (links) please obey the hints and regulations concerning copyright, disclaimer and trademarks.

Last revision of this document:
2006-02-13

This is document contains the code for all classes of the lesson.
For easy 'cut and paste' ;-)

Class JS_DBLoad
Class JS_DBLoad__Action_Handler
Class JS_DBLoad__Thread

Class  JS_DBLoad:

package js_base02.application;

import javax.awt.*;
import javax.awt.event.*;
import
javax.swing.*;

/**
*
* @author
kurt@javascout.biz

* @date 2006-02-10
*
* @description
*
Tutorial how to
* - create a GUI using javax.swing components
* - load parameters for DB-connection from a XML-file
* - connect to a database
* - read SQL-commands from a text-file and perform them
*
* @change-log
* when         who               why
* --------------------------------------------------------
*
*/

public class JS_DBLoad extends JFrame implements ActionListener {

    private JPanel pnl_Main=null;
    private JButton btn_Select=null;
    private JButton btn_Start=null;
    private JButton btn_Print=null;
    private JTextField txt_InputFile=null;
    private JScrollPane scroll_Report=null;
    
private JTextrArea txt_Report=null;

    public JS_DBLoad(){
      super();
      initialize();
    }

 
    
private JButton get_btn_Select {
/* The code of this method auto-creates the element if it is not already defined */
      if (btn_Select == null) {
        try {
          btn_Select = new JButton();
          btn_Select.setName(btn_Select“);
          btn_Select.setToolTipText(Select Input-File containing SQL-commands“);
          btn_Select.setMargin(new Insets(3,3,3,3));
          btn_Select.setVerticalTextPosition(SwingConstants.CENTER);
          btn_Select.setHorizontalTextPosition(SwingConstants.CENTER);
          btn_Select.setText(Select Input-File“);
          btn_Select.addActionListener(this);
          btn_Select.setActionCommand(btn_Select“);
        }
        catch (Throwable Exc) {
          System.out.println(Error while building btn_Select“);
          Exc.printStackTrace();
        }
      }
      return btn_Select;
    }

 
    protected JTextField get_txt_InputFile {
/* The code of this method auto-creates the element if it is not already defined */
      if (txt_InputFile == null) {
        try {
          txt_InputFile = new JTextField();
          txt_InputFile.setName(txt_InputFile);
          txt_InputFile.setToolTipText(“Selected Input-File containing SQL-commands“);
          txt_InputFile.setMargin(new Insets(3,3,3,3));
          txt_InputFile.setEditable(false);
        }
        catch (Throwable Exc) {
          System.out.println(Error while building txt_InputFile“);
          Exc.printStackTrace();
        }
      }
      return txt_InputFile;
    }

 
    private JButton get_btn_Start {
/* The code of this method auto-creates the element if it is not already defined */
      if (btn_Start == null) {
        try {
          btn_Start = new JButton();
          btn_Start.setName(btn_Start);
          btn_Start.setToolTipText(Start SQL-commands against the DataBase“);
          btn_Start.setMargin(new Insets(3,3,3,3));
          btn_Start.setVerticalTextPosition(SwingConstants.CENTER);
          btn_Start.setHorizontalTextPosition(SwingConstants.CENTER);
          btn_Start.setText(Start SQL execution“);
          btn_Start.addActionListener(this);
          btn_Start.setActionCommand(btn_Start);
        }
        catch (Throwable Exc) {
          System.out.println(Error while building btn_Start“);
          Exc.printStackTrace();
        }
      }
      return btn_Start;
    }

 
    protected JTextArea get_txt_Report {
/* The code of this method auto-creates the element if it is not already defined */
      if (txt_Report == null) {
        try {
          txt_Report = new JTextArea();
          txt_Report.setName(txt_Report);
          txt_Report.setToolTipText(“Report“);
          txt_Report.setMargin(new Insets(3,3,3,3));
          txt_Report.setEditable(false);
        }
        catch (Throwable Exc) {
          System.out.println(Error while building txt_Report);
          Exc.printStackTrace();
        }
      }
      return txt_Report;
    }

 
    private JScrollPane get_scroll_Report {
/* The code of this method auto-creates the element if it is not already defined */
      if (txt_Report == null) {
        try {
           scroll_Report = new JScrollPane(get_txt_Report());
          txt_Report.setName(scroll_Report);
          txt_Report.setPreferredSize(new Dimension(600, 600));
 
       }
        catch (Throwable Exc) {
          System.out.println(Error while building scroll_Report“);
          Exc.printStackTrace();
        }
      }
      return scroll_Report;
    }

 
    
private JButton get_btn_Print {
/* The code of this method auto-creates the element if it is not already defined */
      if (btn_Print == null) {
        try {
          btn_Print = new JButton();
          btn_Print.setName(btn_Print);
          btn_Print.setToolTipText(“Print the Report“);
          btn_Print.setMargin(new Insets(3,3,3,3));
          btn_Print.setVerticalTextPosition(SwingConstants.CENTER);
          btn_Print.setHorizontalTextPosition(SwingConstants.CENTER);
          btn_Print.setText(“Print the Report“);
          btn_ Print.addActionListener(this);
          btn_ Print.setActionCommand(btn_Print);
        }
        catch (Throwable Exc) {
          System.out.println(Error while building btn_Print“);
          Exc.printStackTrace();
        }
      }
      return btn_Print;
    }

 
    
private JPanel get_pnl_Main {
/* The code of this method auto-creates the element if it is not already defined */

      if (pnl_Main == null) {
        try {
          pnl_Main = new JPanel();
          pnl_Main.setName(pnl_Main);
          pnl_Main.setLayout(new GridBagLayout());
/* Define GridBagConstraints for the Button to be added */
          GridBagConstraints gbc_btn_Select = new GridBagConstraints();
          gbc_btn_Select.gridx = 0;
          gbc_btn_Select.gridy = 0;
          gbc_btn_Select.fill = GridBagConstraints.HORIZONTAL;
          gbc_btn_Select.weightx = 1;
          gbc_btn_Select.anchor = GridBagConstraints.LINE_END;
/* Add the Button to the Panel; Button-position is controlled by GridBagConstraints */
          get_pnl_Main().add(get_btn_Select(), gbc_btn_Select);
/*
 * Define GridBagConstraints for the TextField to be added */
          GridBagConstraints gbc_txt_InputFile = new GridBagConstraints();
          gbc_txt_InputFile.gridx = 0;
          gbc_txt_InputFile.gridy = 1;
          gbc_txt_InputFile.fill = GridBagConstraints.HORIZONTAL;
          gbc_txt_InputFile.weightx = 3;
          gbc_txt_InputFile.anchor = GridBagConstraints.CENTER;
/* Add the Button to the Panel; Button-position is controlled by GridBagConstraints */
          get_pnl_Main().add(get_txt_InputFile(), gbc_txt_InputFile);
/*
 * Define GridBagConstraints for the Button to be added */
          GridBagConstraints gbc_btn_Start = new GridBagConstraints();
          gbc_btn_Start.gridx = 0;
          gbc_btn_Start.gridy = 2;
          gbc_btn_Start.fill = GridBagConstraints.HORIZONTAL;
          gbc_btn_Start.weightx = 1;
          gbc_btn_Start.anchor = GridBagConstraints.LINE_START;
/* Add the Button to the Panel; Button-position is controlled by GridBagConstraints */
          get_pnl_Main().add(get_btn_Start(), gbc_btn_Start);
/*
 * Define GridBagConstraints for the Scroll-Pane to be added */
          GridBagConstraints gbc_scroll_Report = new GridBagConstraints();
          gbc_scroll_Report.gridx = 0;
          gbc_scroll_Report.gridy = 1;
          gbc_scroll_Report.gridwidth = 3;
          gbc_scroll_Report.
fill = GridBagConstraints.BOTH;
          gbc_scroll_Report.weightx = 10;
          gbc_scroll_Report.weighty = 10;
          gbc_scroll_Report.
anchor = GridBagConstraints.CENTER;
/* Add the Scroll-Pane to the Panel; Pane-position is controlled by GridBagConstraints */
          get_pnl_Main().add(get_scroll_Report(), gbc_scroll_Report);
/*
 * Define GridBagConstraints for the Button to be added */
          GridBagConstraints gbc_btn_Print = new GridBagConstraints();
          gbc_btn_Print.gridx = 2;
          gbc_btn_Print.gridy = 2;
          gbc_btn_Print.fill = GridBagConstraints.HORIZONTAL;
          gbc_btn_Print.weightx = 1;
          gbc_btn_Print.anchor = GridBagConstraints.LINE_START;
/* Add the Button to the Panel; Button-position is controlled by GridBagConstraints */
          get_pnl_Main().add(get_btn_Print(), gbc_btn_Print);
        }
        catch (Throwable Exc) {
          System.out.println(Error while building pnl_Main“);
          Exc.printStackTrace();
        }
      }
      return pnl_Main;
    }

 
    private void initialize() {
      setVisible(true);
      setSize(600, 700);
      setTitle(„JavaScout-Tutorial – Base02 – DBLoad“);
      setContentPane(get_pnl_Main());
    }

 
    
public static void main(String[] args) {
      try
{
        JS_DBLoad aJS_DBLoad = new JS_DBLoad();
        aJS_DBLoad.setVisible
(true);
      }
      catch(Throwable exc) {
        System.out.println(„Exception occured in main() of JS_DBLoad“);
        exc.printStackTrace(System.out);
      }
    }
 
    private void actionPerformed(ActionEvent e) {
      
    }

 
}


top.

Class  JS_DBLoad__Action_Handler:

package js_base02.application;

import
java.awt.*;

import java.awt.event.*;

import org.jdom.*;
import org.jdom.input.*;

import java.sql.*;
/**
*
* @author
kurt@javascout.biz
* @date 2006-02-10
*
* @description
*
Tutorial how to
* - create a GUI using javax.swing components
* - load parameters for DB-connection from a XML-file
* - connect to a database
* - read SQL-commands from a text-file and perform them
*
* @change-log
* when who why
* --------------------------------------------------------
*
*/

public class JS_DBLoad__Action_Handler {

    protected static void handleEvent(JS_DBLoad parmCallingFrame, ActionEvent parmActionEvent){
/*
* Extract the action-command (in form of a String) that triggered the Event from the Event */
      String cmd = parmActionEvent.getActionCommand().trim();
/*
* Compare the String with the action-command and call the adjacent method */
      if(cmd.equals(„btn_Select“)) processSelectFile(parmCallingFrame);

      if(cmd.equals(„btn_Start“)) processDBLoad(parmCallingFrame);
      if(cmd.equals(„btn_Print“)) processPrint(parmCallingFrame);
    }

    protected static void processSelectFile(JS_DBLoad parmCallingFrame){
/*
 * Create a File-Dialog to let the user choose the Input-file */
      FileDialog fd = new FileDialog(parmCallingFrame,
                                     „Select input-file containing SQL-commands“,
                                     FileDialog.LOAD);
      fd.setFile(„“);
      fd.setDirectory(„“);
      fd.setVisible(true);
/*
 * Extract the directory and file-name chosen and put it into a String */
      String strDirectoryAndFileName = fd.getDirectory + fd.getFile();
/*
 * Store the chosen directory and file-name in the TextField */
      parmCallingFrame.get_txt_InputFile().setText(strDirectoryAndFileName);

    }

    protected static void processDBLoad(JS_DBLoad parmCallingFrame){
/*
 * Define an array that holds the parameters for the database-access */
      String[] array_DBParms;
/* Call the method that extracts the parameters from the XML-file */
      array_DBParms = processGetDBParms(parmCallingFrame);
/* Perform the connection to the database */
      Connection conToDatabase = null;

      conToDatabase = processConnectToDatabase(parmCallingFrame, array_DBParms, conToDatabase);
      if (conToDatabase != null) {
/* Connection to Database successfully established;
 * run the SQL-commands in a thread that allows to periodically update the results */
        JS_DBLoad__Thread t = new JS_DBLoad__Thread(parmCallingFrame, conToDatabase);
        t.start();
      }

    }

    protected static String[] processGetDBParm(JS_DBLoad parmCallingFrame){
/* Define the return-value holding the parameters */
      String[] array_DBParms = new String[4];
/* Get the selected input-file to derive the directory in the next step */
      String strDirectory = parmCallingFrame.get_txt_InputFile().getText();
/* Get the (system-specific) character that separates directories and files */
      String strDirectorySeparator = System.getProperty(file.separator“);
/* Get the position of the last DirectorySeparator, the one were the file-name is therafter */
      int intLastDirectorySeparator = strDirectory.lastIndexOf(strDirectorySeparator);
/* If there is not separator, e.g. no input-file selected
   write an error message to the text-area and return an empty array */
      if (intLastDirectorySeparator < 1) {
        parmCallingFrame.get_txt_Report().append(Invalid selection: “ + strDirectory + \n“);
        return new String[0];

      }
/* Build the String with the complete directory and file-name and display it in the text-area /
      String strDBParmDirectoryAndFile = strDirectory.substring(0, intLastDirectorySeparator + 1) + DBParms.xml“;
      parmCallingFrame.get_txt_Report().append(DB-Parameters will be read from file: “ + strDBParmDirectoryAndFile\n“);
/*
 * Open the file with methods provided by the org.jdom.input package */
      try
{
           SAXBuilder parser = new SAXBuilder();
           Document document = parser.build(strDBParmDirectoryAndFile);
           Element XML_RootElement = document.getRootElement();
      }
      catch(JDOMException e) {
           parmCallingFrame.get_txt_Report().append(„'Not well formed exception' opening: „ + strDBParmDirectoryAndFile + „\n“);
        return new String[0];
      }

      catch(Exception e) {
           parmCallingFrame.get_txt_Report().append(„'Unknown error' opening: „ + strDBParmDirectoryAndFile + „\n“);
        return new String[0];
      }

/*
 * File could be opened and contains a 'well-formed' XML-structure */
      parmCallingFrame.get_txt_Report().append(„XML-Root-Element found in: „ + strDBParmDirectoryAndFile + „\n“);
      parmCallingFrame.get_txt_Report().append(„XML-Root-Element name: „ + XML_RootElement.getName() + „\n“);
/*
 * The methods of package org.jdom.* are used to extract the elements by parameter-name
 * and get the values of them */
      Element elementSingleParm;
/* Get the value for the name of the JAR file with the Database-Driver */
      elementSingleParm = XML_RootElement.getChild(DataBaseDriverName„);
      if (elementSingleParm == null) {
        parmCallingFrame.get_txt_Report().append(„Element 'DataBaseDriverName' not found \n“);
        return new String[0];

      }
      array_DBParms[0] = elementSingleParm.getText();
      parmCallingFrame.get_txt_Report().append(DataBaseDriverName: „ + array_DBParms[0] + „\n“);
/*
 * Get the value for the name of the Database */
      elementSingleParm = XML_RootElement.getChild(DataBaseName„);
      if (elementSingleParm == null) {
        parmCallingFrame.get_txt_Report().append(„Element 'DataBaseName' not found \n“);
        return new String[0];
      }
      array_DBParms[1] = elementSingleParm.getText();
      parmCallingFrame.get_txt_Report().append(„DataBaseName: „ + array_DBParms[1] + „\n“);
/*
 * Get the value for the user-ID with access rights to the database */
      elementSingleParm = XML_RootElement.getChild(DataBaseUserID„);
      if (elementSingleParm == null) {
        parmCallingFrame.get_txt_Report().append(„Element 'DataBaseUserID' not found \n“);
        return new String[0];
      }
      array_DBParms[2] = elementSingleParm.getText();
      parmCallingFrame.get_txt_Report().append(DataBaseUserID: „ + array_DBParms[2] + „\n“);
/*
 * Get the value for the password of the user-ID with access rights to the database */
      elementSingleParm = XML_RootElement.getChild(DataBasePassword„);
      if (elementSingleParm == null) {
        parmCallingFrame.get_txt_Report().append(„Element 'DataBasePassword' not found \n“);
        return new String[0];
      }
      array_DBParms[3] = elementSingleParm.getText();
      
parmCallingFrame.get_txt_Report().append(DataBasePassword exists \n“);
/*
 * Return the array with the parameters */
      return array_DBParms;
    }

    
protected static Connection processConnectToDatabase(JS_DBLoad parmCallingFrame, String[] parm_array_DBParms){
      Connection ConToDatabase
/*
 * Connection is coded within the try/catch frame to catch exceptions */
      try {
/* Create the class 'DriverManager'.
 * This class is specific for each database-system and defined by parameter */
        Class.forName(parm_array_DBParms[0]);
/* Driver-Manager was successfully created; report on GUI */
        parmCallingFrame.get_txt_Report().append(DriverManager created for: „ + parm_array_DBParms[0] + „\n“);
/* Use DriverManager to establish the connection to the database.
 * The database is specified by parameter. */
        ConToDatabase =
          DriverManager.getConnection(parm_array_DBParms[1], parm_array_DBParms[2], parm_array_DBParms[3]);
/* Connection to database establishes; report on GUI */
        parmCallingFrame.get_txt_Report().append(„Connection to database successful \n“);
/* Set 'AutoCommit'; this prevents losing changed on data to due a forgotten 'commit'.
 * This is fine for the tutorial - but should not be used on real-work-applications
* as a controlled 'commit' or 'rollback' is not possible */
        ConToDatabase.setAutoCommit(true);
      }
      catch(Exception exc) {
/* An error occured within the try-block; report and set Connection to 'null' */
        parmCallingFrame.get_txt_Report().append(Error while connecting to database: „ + exc.toString() „\n“);
        ConToDatabase = null;
      }
      return ConToDatabase
    }
   
   
    protected static void processPrint(JS_DBLoad parmCallingFrame){
/*
 * Content of the TextArea on the GUI as a text-stream */
      String strTextAreaContent = parmCallingFrame.get_txt_Report().getText();
/* Position of the 'NewLine' character after the first line within the text-stream */
      int
intNewLinePosition;
/* First line within the stream (Text till the 'NewLine' character.
 * This line will be printed */
      String strLineToBePrinted;
/*
 * Variables used for printing the text */
/* Page- and Line-Counter to start a new page and print the page-number on top of the sheet /
      int intPageCount = 1;
      int intLineCount = 1;
/* Printer-specific variables */
      Frame f = new Frame();
      PrintJob pJob = f.getToolkit().getPrintJob(f, JS_DBLoad - Printer Selection“, null);
      Graphics g = pJob.getGraphics();
/*
 * Print the header with the page-number */
        g.setColor(Color.black);
        g.setFont(new Font(Arial“, Font.PLAIN , 12));
        g.drawString(page - “ + Integer.toString(intPageCount) + -“, 300, 200);
/*
 * Loop to split up the text-stream into single lines;
 * Extra code for the first line - to catch the case that the text-stream is empty;
 * then a while-loop for the following lines */
      intNewLinePosition = strTextAreaContent.indexOf(„\n“);
      while (intNewLinePosition >= 0) {
/* Text before the 'NewLine' character is split-off */
        strLineToBePrinted = strTextAreaContent.substring(0, intNewLinePosition);
/* Text after the 'NewLine' character is kept /
        strTextAreaContent = strTextAreaContent.substring(intNewLinePosition + 1);
/* Print the single line in another font; vertical position calculated by the LineCount */
/* Standard color */
        g.setColor(Color.black);
/* color for the SQL-commands read from the input-file */
        if (strLineToBePrinted.compareTo(“input-line:“) >= 0) g.setColor(Color.blue);
/* color if the SQL-command was executed */
        if (strLineToBePrinted.compareTo(“SQL-command executed“) >= 0) g.setColor(Color.green);
/* color if the SQL-command was in error */
        if (strLineToBePrinted.compareTo(SQL-command error) >= 0) g.setColor(Color.red);
        g.setFont(new Font(Courier“, Font.PLAIN , 9));
        g.drawString(strLineToBePrinted, 20, 30 + intLineCount*12);
/* Increase the LineCount */
        intLineCount++;
/* See if the lines overflow page and create new page if necessary */
        if (intLineCount > 50) {
          intLineCount = 1;
          intPageCount++;
/* Dispose the graphic and open a new one; this causes a new page in the PrintJob */
          g.dispose();
          g = pJob.getGraphics();
/* Print the headline with the page-number (in another font) */
          g.setColor(Color.black);
          g.setFont(new Font(Arial“, Font.PLAIN , 12));
          g.drawString(page - “ + Integer.toString(intPageCount) + -“, 300, 200);
        }

/* Position of the next 'NewLine' character */
        intNewLinePosition = strTextAreaContent.indexOf(„\n“);
      }

/* End the printing - this starts the printing on paper */
      g.dispose();
      pJob.end();
    }
 
}

 




top.

Class  JS_DBLoad__Thread:

package js_base02.application;

import java.io.*;
import java.sql.*;

/**
 
*
 * @author
kurt@javascout.biz
 * @date 2006-02-28
 *
 * @description
 *
Thread to read the input-file and
 * execute the SQL-commands against the database.
 *
 * A Thread is used to display the SQL-command and
 * the response of the database immediately
 
*
 * @change-log
 * when         who               why
 * --------------------------------------------------------
 *
 */

public class
JS_DBLoad__Thread extends Thread {
/**
 * A variable to hold the reference to the Class with the GUI.
 * This reference allows to update the text-area periodically.
 * The variable is neccessary as the parameter is not available during the lifetime of the method 'run'
 * as the parameter is 'final' for performance-reasons */
    
JS_DBLoad frmCallingFrame;
    Connection ConToDatabase;
/**
 * Constructor of the class; 'final' is better for performace as it 'defines' that a change
 * of the value of the parameter has not to be considered. */
    
    public JS_DBLoad__Thread(final JS_DBLoad parmCallingFrame, final Connection parmConToDatabase) {
/* Save the reference to the class with the GUI. */
      frmCallingFrame = parmCallingFrame;
      ConToDatabase = parmConToDatabase;
    }

/*
 * The method 'run' is started automatically after the construction of the class 'Thread'. */
    public void
run() {
      try {
        try {
          String strLineRead;
/* Get the name of the file to be read from the field of the GUI. */
          String strInputFileName = frmCallingFrame.get_txt_InputFile().getText();
/* Open the file using methods from the package 'java.io.*'. */
          LineNumberReader InputStream = new LineNumberReader(new FileReader(strInputFileName));
/* Read the first line of the file. */
          strLineRead = InputStream.readLine();
/* Check if at least 1 line is in the file; if not report an error. */
          if (strLineRead == null) {
            frmCallingFrame.get_txt_Report().append(Input file contains no data ! \n“)
          }
/* Use a while-loop to display the content of the line, process it and read the next line. */
          while (strLineRead != null) {
            frmCallingFrame.get_txt_Report().append(Input-line: „ strLineRead \n“);
            processDBOperation( strLineRead );
            strLineRead = InputStream.readLine();
          }
        }
        catch (Exception IOExc) {
/* Error when reading data from the input-file; display the information */
        frmCallingFrame.get_txt_Report().append(„IOException in Thread: „ + IOExc .toString() + 
\n“); 
        }
/* Close the connection to the database */
        try
{
          conToDatabase.close();
        }
        catch(Exception exc) {
           parmCallingFrame.get_txt_Report().append(„Exception while closing database: „ + exc.toString() „\n“);
        }
/* Stop the thread */
        this.destroy();
      }
      catch (Exception e) {
/* Unplanned end; display the information */
        frmCallingFrame.get_txt_Report().append(Exception in Thread: „ + e.toString() + 
\n“); 
      }
    }

    

    private static void processDBOperation(String parmstrSQLCommand){
/*
 * Try/catch-logic to process errors */
      try {
/* first, commands with a 'comment' are skipped */
        int intCommentPosition = parmstrSQLCommand.indexOf(„//“);
        if ((intCommentPosition >= 0) && (intCommentPosition <= 1)) return;

/* Command is not a comment, run it against the database */
        Statement SQLStatement = ConToDatabase.prepareStatement(parmstrSQLCommand);
        SQLStatement.executeUpdate(parmstrSQLCommand);
/* Command successful; report it onto the GUI */
        frmCallingFrame.get_txt_Report().append(SQL-command executed\n“); 
      }
      catch (SQLException SQLExc) {
/* SQL-command was not successful; display reason */
        frmCallingFrame.get_txt_Report().append(SQL-command error: „ + SQLExc.toString() + 
\n“); 
      }
    }

}

top.