import javax.swing.JFrame; // import JFrame class
import javax.swing.JLabel; // import JLabel class
import javax.swing.JPanel; // import JPanel class
import java.awt.Font; // import awt Font class
import javax.swing.border.Border; // import Border interface
import javax.swing.BorderFactory; // import BorderFactory class
import javax.swing.JTextField; // import JTextField class
import javax.swing.JComboBox; // import JComboBox class
import javax.swing.JButton; // import JButton class
import javax.swing.JOptionPane; // import JOptionPane class
import java.sql.*; // import ALL SQL package classes
import java.awt.event.WindowEvent; // import class WindowEvent
import java.awt.event.WindowAdapter; //import abstract class WindowAdapter
import java.util.List; // import List class
import java.util.ArrayList; // import ArrayList class
import java.awt.event.ItemListener; // import int. to listen for item events
import java.awt.event.ItemEvent; // indicates item selcted/deselected
import java.awt.event.ActionListener; // import int. to listen for action events
import java.awt.event.ActionEvent; // indicates action event occurred.
import java.text.DecimalFormat; // import class DecimalFormat
public class RestaurantBillCalculator1 extends JFrame
{
private Connection myConnection = null;
private Statement myStatement = null;
private ResultSet myResultSet = null;
private Font restaurantJLabelFont = new Font("SansSerif", Font.BOLD, 16);
// create a new font for title label
private Font restaurantMenuFont = new Font("SansSerif", Font.BOLD, 12);
// create a new font for menu labels
private List <String> billItems = new ArrayList<String>();
// declare & initialise ArrayList billItems
private final static double TAX_RATE = 0.10; // set generous tax rate
private final JComboBox tableNumberJComboBox = new JComboBox();
private final JTextField waiterNameJTextField = new JTextField();
private JPanel waiterJPanel = new JPanel(); // JPanel for waiter info.
private JPanel menuItemsJPanel = new JPanel(); // JPanel for menu items
private JComboBox beverageJComboBox = new JComboBox();
private JComboBox appetizerJComboBox = new JComboBox();
private JComboBox mainCourseJComboBox = new JComboBox();
private JComboBox dessertJComboBox = new JComboBox();
private final JButton saveTableJButton = new JButton("Save Table");
private Jlabel beverageJlabel = new beverageJLabel ();
private Jlabel appetizerJlabel = new appetizerJLabel ();
private Jlabel mainCourseJlabel = new mainCourseJLabel ();
private Jlabel dessertJlabel = new dessertJLabel ();
private DecimalFormat myFormat = new DecimalFormat( "0.00" );
private Object event;
// decimal formatting object
//** RestaurantBillCaculator constructor, note there is no "no-arg"
RestaurantBillCalculator1(String dbDriver, String dbURL)
{
this.setResizable(false); // user cannot resize JFrame
this.setLayout(null);
/** set layout manager to null for JFrame so components can be
* placed using absolute positioning */
this.addWindowListener(
new WindowAdapter() // anonymous inner class
{
@Override
public void windowClosing( WindowEvent event )
{
frameWindowClosing( event ); //invoke method
}
private void frameWindowClosing(WindowEvent event) {
}
} // end anonymous inner class
); // end addWindowListener
/** Establish database driver & handle exceptions*/
try
{
Class.forName(dbDriver); // call static method of class "Class"
// and pass in URL of Database as argument
}
catch (ClassNotFoundException e) // catch ClassNotFoundException first!
{
JOptionPane.showMessageDialog(null, "Invalid database driver" +
" provided: " + e.getMessage()); // show error message box
System.exit(0);
}
catch (Exception e) // catch general exception
{
System.err.println("Exception: " + e.getMessage()); // print error
}
/** Establish connection to database using URL parameter
* & handle exceptions*/
try
{
myConnection = DriverManager.getConnection(dbURL);
}
catch (SQLException e) // catch SQLException first!
{
JOptionPane.showMessageDialog(null, "Unable to locate " +
"database: " + e.getMessage()); // show error message box
System.exit(0);
}
catch (Exception e) // catch general exception
{
System.err.println("Exception: " + e.getMessage()); // print error
}
/** obtain & display meta info about connection - data about data! */
try
{
DatabaseMetaData meta = myConnection.getMetaData();
// use meta object to obtain metadata about connection
System.out.println("Database product type: "
+ meta.getDatabaseProductName() +
" \nDatabase driver name: " + meta.getDriverName());
// print out connection information
}
catch (SQLException e)
{
System.err.println("Exception: " + e.getMessage()); // print error
}
catch (Exception e) // catch general exception
{
System.err.println("Exception: " + e.getMessage()); // print error
}
JLabel restaurantJLabel = new JLabel("Restaurant"); // JLabel with title
restaurantJLabel.setFont(restaurantJLabelFont); // set JLabel font
restaurantJLabel.setBounds(125, 25, 125, 20); // set x,y,width & height
this.add(restaurantJLabel); // add JLabel
waiterJPanel.setLayout(null); // set no layout manager to JPanel
String waiterTitle = "Waiter information"; // title for border
Border waiterInfoBorder = BorderFactory.
createRaisedBevelBorder(); // create a raised bevel border
waiterInfoBorder = BorderFactory.createTitledBorder
(waiterInfoBorder, waiterTitle, 1,
2, restaurantMenuFont); // create a titled border
waiterJPanel.setBorder(waiterInfoBorder); // set JPanel border
waiterJPanel.setBounds(45, 70, 300, 115); // set x,y, width & height
JLabel tableNumberJLabel = new JLabel("Table number:"); // new JLabel
tableNumberJLabel.setFont(restaurantMenuFont); // set JLabel font
tableNumberJLabel.setBounds(30, 35, 125, 20); // set x,y,width & height
waiterJPanel.add(tableNumberJLabel); // add JLabel to JPanel
tableNumberJComboBox.setBounds(145, 35, 125, 20); // set bounds
tableNumberJComboBox.setFont(restaurantMenuFont); // set font
waiterJPanel.add(tableNumberJComboBox); // add to JPanel
tableNumberJComboBox.addItemListener( new ItemListener()
// add Listener to JComboBox using anonymous inner class
{
public void itemStateChanged( ItemEvent event )//State change method
{
// Determine whether item in box selected
if ( event.getStateChange() == ItemEvent.SELECTED )
tableNumberJComboBoxItemStateChanged(event);
} // end method itemStateChanged
} );// end anonymous inner class
JLabel waiterNameJLabel = new JLabel("Waiter name:"); // new JLabel
waiterNameJLabel.setFont(restaurantMenuFont); // set JLabel font
waiterNameJLabel.setBounds(30, 75, 125, 20); // set x,y,width & height
waiterJPanel.add(waiterNameJLabel); // add JLabel to JPanel
waiterNameJTextField.setBounds(145, 75, 125, 20);
waiterNameJTextField.setFont(restaurantMenuFont); // set font
waiterJPanel.add(waiterNameJTextField);
this.add(waiterJPanel);
this.add(createMenuItemsJPanel()); // add waiterJPanel to current JFrame
/* The following code initializes the first 4 indices of ArrayList
* billItems to null, so that these indices can be set later in the
* application. Indices are used to ensure a user can select only
* ONE item per category.
*/
billItems.add(0, null); // index 0 is reserved for beverage category
billItems.add(1, null); // index 1 is reserved for appetizer category
billItems.add(2, null); // index 2 is reserved for main course category
billItems.add(3, null); // index 3 is reserved for dessert category
}
void tableNumberJComboBoxItemStateChanged(ItemEvent event)
{
try
{
tableNumber = Integer.parseInt(event.getItem().toString());
myStatement = myConnection.createStatement(); // create statement
myResultSet = myStatement.executeQuery( "SELECT * FROM " +
"restaurantTables WHERE tableNumber = "
+ tableNumber + "");
// executeQuery returns values of query
while (myResultSet.next()) // loop through myResultSet
{
waiterNameJTextField.setText(myResultSet.getString("waiterName"));
// set text to waiter name
displayTotal(myResultSet.getDouble("subTotal"));
// pass subtotal to displayTotal method
}
} // end try
catch (SQLException e)
{
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
System.err.println(e.getMessage()); // show error message
}
finally
{
try
{
myResultSet.close();
// close result set
}
catch (SQLException e)
{
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
System.err.println(e.getMessage()); // show error message
}
} // end finally
}
/** This method returns a JPanel object - menuItemsJPanel */
JPanel createMenuItemsJPanel()
{
menuItemsJPanel.setLayout(null); // set no layout manager to JPanel
String menuTitle = "Menu items"; // title for border
Border menuItemsBorder = BorderFactory.
createRaisedBevelBorder(); // create a raised bevel border
menuItemsBorder = BorderFactory.createTitledBorder
(menuItemsBorder, menuTitle, 1,
2, restaurantMenuFont); // create a titled border
menuItemsJPanel.setBorder(menuItemsBorder); // set JPanel border
menuItemsJPanel.setBounds(45, 190, 300, 200); // set x,y, width & height
JLabel beverageJLabel = new JLabel("Beverage:"); // new JLabel
beverageJLabel.setFont(restaurantMenuFont); // set JLabel font
beverageJLabel.setBounds(30, 35, 125, 20); // set x,y,width & height
menuItemsJPanel.add(beverageJLabel); // add JLabel to JPanel
beverageJComboBox.setBounds(145, 35, 125, 20); // set bounds
beverageJComboBox.setFont(restaurantMenuFont); // set font
beverageJComboBox.setEnabled(false); // disable by default
loadCategory("Beverage", beverageJComboBox); // pass cat. & JCBox ref
beverageJComboBox.addItemListener( new ItemListener()
{
public void itemStateChanged( ItemEvent event )//State change method
{
} // end of item state changed
}// end annoynous inner class
);// close add item listener
//add Listener to JComboBox using anonymous inner class;
menuItemsJPanel.add(beverageJComboBox); // add to JPanel
JLabel appetizerJLabel = new JLabel("Appetizer:"); // new JLabel
appetizerJLabel.setFont(restaurantMenuFont); // set JLabel font
appetizerJLabel.setBounds(30, 75, 125, 20); // set x,y,width & height
menuItemsJPanel.add(appetizerJLabel); // add JLabel to JPanel
appetizerJComboBox.setBounds(145, 35, 125, 20); // set bounds
appetizerJComboBox.setFont(restaurantMenuFont); // set font
appetizerJComboBox.setEnabled(false); // disable by default
loadCategory("Appetizer", appetizerJComboBox); // pass cat. & JCBox ref
appetizerJComboBox.addItemListener( new ItemListener()
{
public void itemStateChanged( ItemEvent event )//State change method
{
// Determine whether item in box selected
if ( event.getStateChange() == ItemEvent.SELECTED )
appetizerJComboBoxItemStateChanged(event);
}// end of item state changed
}// end annoynous inner class
);// close add item listener
// add Listener to JComboBox using anonymous inner class
menuItemsJPanel.add(appetizerJComboBox);
JLabel mainCourseJLabel = new JLabel("MainCourse:"); // new JLabel
mainCourseJLabel.setFont(restaurantMenuFont); // set JLabel font
mainCourseJLabel.setBounds(30, 115, 125, 20); // set x,y,width & height
menuItemsJPanel.add(mainCourseJLabel); // add JLabel to JPanel
mainCourseJComboBox.setBounds(145, 115, 125, 20); // set bounds
mainCourseJComboBox.setFont(restaurantMenuFont); // set font
mainCourseJComboBox.setEnabled(false); // disable by default
loadCategory("MainCourse", mainCourseJComboBox); // pass cat. & JCBox ref
dessertJComboBox.addItemListener( new ItemListener()
// add Listener to JComboBox using anonymous inner class
{
public void itemStateChanged( ItemEvent event )//State change method
{
// Determine whether item in box selected
if ( event.getStateChange() == ItemEvent.SELECTED )
dessertJComboBoxItemStateChanged(event);
} // end method itemStateChanged
} );// end anonymous inner class
menuItemsJPanel.add(mainCourseJComboBox); // add to JPanel
JLabel dessertJLabel = new JLabel("Dessert:"); // new JLabel
dessertJLabel.setFont(restaurantMenuFont); // set JLabel font
dessertJLabel.setBounds(30, 155, 125, 20); // set x,y,width & height
menuItemsJPanel.add(dessertJLabel); // add JLabel to JPanel
dessertJComboBox.setBounds(145, 155, 125, 20); // set bounds
dessertJComboBox.setFont(restaurantMenuFont); // set font
dessertJComboBox.setEnabled(false); // disable by default
loadCategory("Dessert", dessertJComboBox); // pass cat. & JCBox ref
dessertJComboBox.addItemListener( new ItemListener()
// add Listener to JComboBox using anonymous inner class
{
public void itemStateChanged( ItemEvent event )//State change method
{
// Determine whether item in box selected
if ( event.getStateChange() == ItemEvent.SELECTED )
dessertJComboBoxItemStateChanged(event);
} // end method itemStateChanged
} );// end anonymous inner class
menuItemsJPanel.add(dessertJComboBox); // add to JPanel
return(menuItemsJPanel); // return menuItemsJPanel
/** method that loads categories into respective JComboBoxs it
* receives a String and a JComboBox reference (which will point to
* the respective JComboBox that invoked the method0 */
}
void loadCategory(String beverage, JComboBox beverageJComboBox)
{
try
{
myStatement = myConnection.createStatement(); // create statement
myResultSet = myStatement.executeQuery( "SELECT name FROM Menu " +
"WHERE category = '" + beverage+ "' ORDER BY NAME" );
// executeQuery returns values of query
while (myResultSet.next()) // loop through myResultSet
{
beverageJComboBox.addItem(myResultSet.getString("name"));
}
} // end try
catch (SQLException e)
{
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
System.err.println(e.getMessage()); // show error message
}
void loadCategory (String appetizer, JComboBox appetizerJComboBox)
{
try
{
myStatement = myConnection.createStatement(); // create statement
myResultSet = myStatement.executeQuery( "SELECT name FROM Menu " +
"WHERE category = '" + appetizer + "' ORDER BY NAME" );
//executeQuery returns values of query
while (myResultSet.next()) // loop through myResultSet
appetizerJComboBox.addItem(myResultSet.getString("name"));
} // end try
catch (SQLException e)
{
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
System.err.println(e.getMessage()); // show error message
}
void loadCategory(String mainCourse , JComboBoxmainCourseJComboBox)
{
try
{
myStatement = myConnection.createStatement(); // create statement
myResultSet = myStatement.executeQuery( "SELECT name FROM Menu " +
"WHERE category = '" + mainCourse + "' ORDER BY NAME" );
// executeQuery returns values of query
while (myResultSet.next()) // loop through myResultSet
{
mainCourseJComboBox.addItem(myResultSet.getString("name"));
}
} // end try
catch (SQLException e)
{
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
System.err.println(e.getMessage()); // show error message
}
void loadCategory(String dessert, JComboBox dessertJComboBox)
{
try
{
myStatement = myConnection.createStatement(); // create statement
myResultSet = myStatement.executeQuery( "SELECT name FROM Menu " +
"WHERE category = '" + dessert+ "' ORDER BY NAME" );
// executeQuery returns values of query
while (myResultSet.next()) // loop through myResultSet
{
dessertJComboBox.addItem(myResultSet.getString("name"));
}
} // end try
catch (SQLException e)
{
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
System.err.println(e.getMessage()); // show error message
}
void beverageJComboBoxItemStateChanged(ItemEvent event)
{
billItems.set(0, event.getItem().toString());
{// add String to index 0 as this category is desserts
{
void appetizerJComboBoxItemStateChanged(ItemEvent event)
{
billItems.set(1, event.getItem().toString());
// add String to index 3 as this category is desserts
}
void mainCourseJComboBoxItemStateChanged(ItemEvent event)
{
billItems.set(2, event.getItem().toString());
// add String to index 3 as this category is desserts
}
void dessertJComboBoxItemStateChanged(ItemEvent event)
{
billItems.set(3, event.getItem().toString());
// add String to index 3 as this category is desserts
}
double calculateSubtotal()
{
double sub = 0.00;
double tax = 0.00;
double total = 0.00;
try
{
myStatement = myConnection.createStatement(); // create statement
for (int i = 0; i <= 3; i++)
{
myResultSet = myStatement.executeQuery(
"SELECT price FROM Menu " +
"WHERE name = '" + billItems.get(i) + "'" );
// executeQuery returns values of query, i.e. prices
while (myResultSet.next()) // loop through myResultSet
{
sub += myResultSet.getDouble("price");
// add value to subTotal
}
}
tax = sub*TAX_RATE; // establish tax amount
taxJTextField.setText(myFormat.format(tax));
// place tax amount in taxJTextField
total = sub + tax; // total up!
totalJTextField.setText(myFormat.format(total));
// place total in totalJTextField
} // end try
catch (SQLException e)
{
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
System.err.println(e.getMessage()); // show error message
}
finally
{
try
{
myResultSet.close();
// close result set
}
catch (SQLException e)
{
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
System.err.println(e.getMessage()); // show error message
}
} // end finally
return sub;
void payBillJButtonActionPerformed()
{
subtotal = 0.0; // reset subTotal
updateTable(); // update table
resetJFrame(); // reset the window
}
void updateTable()
{
try
{
myStatement = myConnection.createStatement(); // create statement
myStatement.executeUpdate("UPDATE restaurantTables " +
"SET subTotal = " + subtotal +
" WHERE tableNumber = " + tableNumber );
} // end try
catch (SQLException e)
{
}
System.err.println(e.getMessage()); // show error message
}
catch (Exception e)
{
}
System.err.println(e.getMessage()); // show error message
}
}
beverageJComboBox.setSelectedIndex(0); // reset JCBox
beverageJComboBox.setEnabled(false); // disable JCBox
appetizerJComboBox.setSelectedIndex(0); // reset JCBox
appetizerJComboBox.setEnabled(false); // disable JCBox
mainCourseJComboBox.setSelectedIndex(0); // reset JCBox
mainCourseJComboBox.setEnabled(false); // disable JCBox
dessertJComboBox.setSelectedIndex(0); // reset JCBox
dessertJComboBox.setEnabled(false); // disable JCBox
/* reset & enable waiterJPanel components*/
tableNumberJComboBox.setSelectedIndex(0); // reset JCBox
tableNumberJComboBox.setEnabled(true); // enable JCBox
waiterNameJTextField.setText(""); // clear text
waiterNameJTextField.setEnabled(true); // enable JTF
}
void displayTotal(double subTotal)
{
subTotalJTextField.setText(myFormat.format(subTotal));
// display subtotal
double tax = subTotal*TAX_RATE; // establish tax amount
taxJTextField.setText(myFormat.format(tax));
// place tax amount in taxJTextField
double total = subTotal + tax; // total up!
totalJTextField.setText(myFormat.format(total));
// place total in totalJTextField
/** enable menuItemsJPanel components*/
beverageJComboBox.setEnabled(true); // enable JCBox
appetizerJComboBox.setEnabled(true); // enable JCBox
mainCourseJComboBox.setEnabled(true); // enable JCBox
dessertJComboBox.setEnabled(true); // enable JCBox
/** disable waiterJPanel components*/
tableNumberJComboBox.setEnabled(false); // disable JCBox
/** enable operation buttons */
saveTableJButton.setEnabled(true);
calculateBillJButton.setEnabled(true);
payBillJButton.setEnabled(true);
}
void saveTableJButtonActionPerformed()
{
subtotal = calculateSubtotal(); // assign return value to subtotal
updateTable(); // update table
resetJFrame(); // reset the window
}
}
void resetJFrame()
{
/* reset arraylist */
billItems.add(0, null); // index 0 is reserved for beverage category
billItems.add(1, null); // index 1 is reserved for appetizer category
billItems.add(2, null); // index 2 is reserved for main course category
billItems.add(3, null); // index 3 is reserved for dessert category
/* reset & disable menuItemsJPanel components*/
beverageJComboBox.setSelectedIndex(0); // reset JCBox index 0 == <none>
beverageJComboBox.setEnabled(false); // disable JCBox
appetizerJComboBox.setSelectedIndex(0); // reset JCBox
appetizerJComboBox.setEnabled(false); // disable JCBox
mainCourseJComboBox.setSelectedIndex(0); // reset JCBox
mainCourseJComboBox.setEnabled(false); // disable JCBox
dessertJComboBox.setSelectedIndex(0); // reset JCBox
dessertJComboBox.setEnabled(false); // disable JCBox
/* reset & enable waiterJPanel components*/
tableNumberJComboBox.setSelectedIndex(-1); // index -1 selects NOTHING
tableNumberJComboBox.setEnabled(true); // enable JCBox
waiterNameJTextField.setText(""); // clear text
waiterNameJTextField.setEnabled(true); // enable JTF
/* clear JTextFields */
subTotalJTextField.setText(""); // clear text
taxJTextField.setText(""); // clear text
totalJTextField.setText(""); // clear text
/* disable JButtons */
saveTableJButton.setEnabled(false); // disable button
calculateBillJButton.setEnabled(false); // disable button
payBillJButton.setEnabled(false); // disable button
/** override close operation in this method so that I can close
* connections & statements when user closes JFrame */
void frameWindowClosing(WindowEvent event)
{
try //try to close myStatement & myConnection
{
myStatement.close();
myConnection.close();
}
catch(Exception e)
{
System.err.println(e.getMessage()); // show error
}
finally
{
System.exit(0); // exit application
}
public static void main(String[] args)
{
String databaseDriver = "sun.jdbc.odbc.JdbcOdbcDriver";
// initialize to use Access DB by default
String databaseURL = "jdbc:odbc:JAVA_ACCESS";
// initialize to use Access DB by default
if (args.length != 0) // check if arguments passed at command line
{
if (args.length < 2) // if there are not exactly two args.
{
System.out.println("Two arguments required " +
"for non-Access Database connection. Attempting " +
"to connect to Access Database instead...");
// display message
}
else if (args.length >= 2) // if there are two args.
{
databaseDriver = args[0]; // databaseDriver = first arg
databaseURL = args[1]; // databaseURL = second arg
}
}
RestaurantBillCalculator1 bill =
new RestaurantBillCalculator1(databaseDriver, databaseURL);
/** new RestaurantBillCalculator instance, pass in null values of
* databaseDriver and databaseURL if args.length is 0.
* I check these values in the constructor for this class to determine
* which DBMS to use */
bill.setTitle("Restaurant Bill Calculator");
// set RestaurantBillCalculator title
bill.setSize(400, 615); // set RestaurantBillCalculator title
bill.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// exit program on RestaurantBillCalculator close
bill.setVisible(true); // show RestaurantBillCalculator
} // end of main
} // end of class RestaurantBillCalculator