Java 1.1 Unleashed
- 44 -
|
Field | Description |
item_nbr | Integer field containing item identifier |
item_desc | Text field containing item description |
qty_per_pkg | Integer field containing the number of items contained in each package sold |
wholesale_cost | Numeric field containing the wholesale cost of the item |
retail_cost | Numeric field containing the retail cost of the item |
company_id | Integer identifier of the company that makes the item |
color | Optional color of the item |
size | Optional size of the item |
company_item_identifier | Not used in this example |
private Button updateButton; private TextField itemNbr; private TextField itemDesc; private TextField itemQty; private TextField itemWholesale; private TextField itemRetail; private TextField itemCompany; private TextField itemColor; private TextField itemSize; private TextField textResult;
The fields are defined as private only because they are not available to any other class; however, they could just as easily have been defined as public.
Next, the components must be created and laid out. The init() method of the sample class looks similar to Listing 44.3 if we limit our AWT layout classes to the BorderLayout and FlowLayout classes. This code can also be found on the accompanying CD-ROM.
// set background // create layout // and place applet components public void init() { // set background color and font setBackground(new Color(255,255,255)); setFont(new Font("Helvetica", Font.PLAIN, 12)); // create borderlayout setLayout(new BorderLayout(5,5)); // create upperpanel Panel upperpanel = new Panel(); upperpanel.setLayout(new BorderLayout()); // create top panel of upper panel Panel uppertoppanel = new Panel(); uppertoppanel.setLayout(new FlowLayout(1,5,5)); uppertoppanel.add(new Label("Item Nbr:")); itemNbr = new TextField("",5); uppertoppanel.add(itemNbr); uppertoppanel.add(new Label("Item Desc:")); itemDesc = new TextField("", 25); uppertoppanel.add(itemDesc); upperpanel.add("North", uppertoppanel); // create bottom panel of upper panel Panel upperbotpanel = new Panel(); upperbotpanel.setLayout(new FlowLayout(1,5,5)); upperbotpanel.add(new Label("Item Qty:")); itemQty = new TextField("",3); upperbotpanel.add(itemQty); upperbotpanel.add(new Label("Item Wholesale Cost:")); itemWholesale = new TextField("", 7); upperbotpanel.add(itemWholesale); upperpanel.add("South", upperbotpanel); // add to main borderlayout add("North", upperpanel); // create middlepanel Panel middlepanel = new Panel(); middlepanel.setLayout(new BorderLayout()); // create top panel of middle panel Panel middletoppanel = new Panel(); middletoppanel.setLayout(new FlowLayout(1,5,5)); middletoppanel.add(new Label("Item Retail:")); itemRetail = new TextField("",7); middletoppanel.add(itemRetail); middletoppanel.add(new Label("Item Company:")); itemCompany = new TextField("", 3); middletoppanel.add(itemCompany); middlepanel.add("North", middletoppanel); // create bottom panel of middle panel Panel middlebotpanel = new Panel(); middlebotpanel.setLayout(new FlowLayout(1,5,5)); middlebotpanel.add(new Label("Item Color:")); itemColor = new TextField("",8); middlebotpanel.add(itemColor); middlebotpanel.add(new Label("Item Size:")); itemSize = new TextField("", 8); middlebotpanel.add(itemSize); middlepanel.add("South", middlebotpanel); add("Center", middlepanel); // add bottom layer Panel botpanel = new Panel(); botpanel.setLayout(new FlowLayout(1,5,5)); updateButton = new Button(" Update "); updateButton.addActionListener(this); botpanel.add(updateButton); textResult = new TextField("", 25); botpanel.add(textResult); add("South", botpanel);
}
The BorderLayout container class allows you to insert components using the geographical place names "North", "South", "East", "West", and "Center". Alternatively, the FlowLayout container class allows you to add components that are placed one after another in a linear manner. Both layout managers are relatively simple to use. In Listing 44.3, notice the use of the panel object. The panel object allows you to implement a different layout container, which is then inserted into another layout container, and so on. This capability allows developers to use a variety of layouts to display components.
Once the layout is created, you create the event handler for the update button:
// handleEvent // // Overriding handleEvent allows us to // capture the search button push // // call super.handleEvent to allow other // events to be processed correctly public void actionPerformed(ActionEvent event) { if (event.getSource() == updateButton) { processRequest(); } }
Finally, the code to process the database update is created, as shown in Listing 44.4. This file can also be found on the accompanying CD-ROM.
// processRequest // // This method will load the database driver, // connect to the database, create the retrieval statement // and output the results. private synchronized void processRequest() { String stringResult = ""; String result; String stringNbr, stringDesc, stringQty, stringWholesale, stringRetail, stringCompany, stringColor, stringSize; try { //connect to ODBC database Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String url = "jdbc:odbc:Zoo"; // connect Connection con = DriverManager.getConnection(url,"dba", "sql"); textResult.setText("Connected..."); // create Statement object Statement stmt = con.createStatement(); // get insert values stringNbr = itemNbr.getText(); stringDesc = itemDesc.getText(); stringQty = itemQty.getText(); stringWholesale = itemWholesale.getText(); stringRetail = itemRetail.getText(); stringCompany = itemCompany.getText(); stringColor = itemColor.getText(); stringSize = itemSize.getText(); String updatestring = "INSERT INTO RETAIL_ITEM(item_nbr, item_desc, qty_per_pkg, " + "wholesale_cost, retail_cost, company_id, color, size) " + "VALUES(" + stringNbr + ",'" + stringDesc + "'," + stringQty + "," + stringWholesale + "," + stringRetail + "," + stringCompany + ",'" + stringColor + "','" + stringSize + "')"; // run query textResult.setText("Working..."); int ct = stmt.executeUpdate(updatestring); textResult.setText("completed"); // close statement stmt.close(); } // catch all exceptions and print out exception message catch (Exception e) { textResult.setText(e.getMessage()); }
}
As you can see from this example, the values are accessed from the AWT components and then used to create an update string. Once the update string is created and executed, the results of the update are output to the results field. Notice that the code also outputs text strings that inform the user of the progress of the update. This notification is essential, especially for longer transactions. If you don't have such a notification scheme, your user will wonder whether an error has occurred.
The example just shown is simpler than you would find in a real-world business application. The example does no checking to make sure that mandatory fields are filled in and does no checking to see whether the user entered appropriate values. Also, a production-quality applet would probably use a drop-down list for the company identifier field and would pull in values from the database and load them to the list when the applet is initialized.
If you run this sample applet using the applet viewer, you should see something similar to Figure 44.2 when the applet loads. In the figure, behind the applet is the DOS window containing the class activity of the applet. If you type some values, the applet looks similar to Figure 44.3.
Figure 44.2.
The sample2 applet after being loaded.
After you enter the values and click the Update button, the applet runs. In Figure 44.4, note that the result field shows the value completed. This notification means that the record was successfully entered into the database.
Now that you have added data to the database, you may find it handy to review the data for accuracy. The next section creates a simple query-based applet to do just that.
Figure 44.3.
The sample2 applet after data has been typed into AWT components.
Figure 44.4.
The sample2 applet after the record insert is completed.
Once you have successfully created an applet that enters data into a database, you will want to create an applet that enables one or more people to view the data.
Creating an applet to display data is no different than creating one to update a database. AWT components that must be accessed by both the init() method and the database-processing method are usually defined as members of the Applet class. In the next example, the retail_item table from the preceding example is used as the basis for a query. The user can view all the records of the table or can choose to view retail items of a certain color, size, or both. Based on these criteria, two components must be created to access the two query values of color and size. Additional components are a button that runs the query and a text field that displays the results. Following is the definition of the members for the new applet:
Choice colorChoice; Choice sizeChoice; Button searchButton; TextArea resultsTextArea;
For this applet, I decided to use drop-down list boxes (also called choice components) for the two query values. This arrangement assists users by providing a list of valid query values. The init() method uses a combination of BorderLayout, FlowLayout, and GridBagLayout container layout classes (see Listing 44.5 and the accompanying CD-ROM). I used the GridBagLayout class because it allows the developer to define a component that takes up the remainder of the space allocated to the applet (both vertically and horizontally).
// init() // // method will instantiate the applet // // the applet objects will be created and placed // in this method // public void init() { Panel layout_area; Panel search_area; Panel result_area; // set background to white setBackground(new Color(255,255,255)); // create border layout as default setLayout(new BorderLayout()); layout_area = new Panel(); layout_area.setLayout(new BorderLayout()); // add layout_area to top of background panel add("North",layout_area); // add top label to layout setFont(new Font("Helvetica",Font.BOLD,12)); layout_area.add("North",new Label("Enter value(s) to search on:")); setFont(new Font("Helvetica",Font.PLAIN,12)); // create gridlayout search panel // add to background layout { search_area = new Panel(); search_area.setLayout(new FlowLayout(1,5,5)); layout_area.add("Center",search_area); // create color Choice object // add to layout with label // create Choice object colorChoice // add colors to Choice object colorChoice = new Choice(); search_area.add(colorChoice); colorChoice.addItem(""); colorChoice.addItem("Red"); colorChoice.addItem("Orange"); colorChoice.addItem("Navy"); colorChoice.addItem("Green"); colorChoice.addItem("Yellow"); colorChoice.addItem("White"); colorChoice.addItem("Black"); colorChoice.addItem("Blue"); colorChoice.addItem("Purple"); search_area.add(new Label("Color:")); // create Choice object sizeChoice // add sizes to Choice object sizeChoice = new Choice(); search_area.add(sizeChoice); sizeChoice.addItem(""); sizeChoice.addItem("T"); sizeChoice.addItem("J"); sizeChoice.addItem("S"); sizeChoice.addItem("M"); sizeChoice.addItem("L"); search_area.add(new Label("Size:")); search_area.add(new Label(" ")); searchButton = new Button(" Search "); searchButton.addActionListener(this); search_area.add(searchButton); } // create another panel for the result set // make the type of layout GridBagLayout { result_area = new Panel(); // add results label setFont(new Font("Helvetica",Font.BOLD,12)); add("Center", new Label("Results:")); setFont(new Font("Courier",Font.PLAIN,12)); add("South",result_area); GridBagLayout gridbag = new GridBagLayout(); result_area.setLayout(gridbag); GridBagConstraints Constraints = new GridBagConstraints(); Constraints.weightx=1.0; Constraints.weighty=1.0; Constraints.anchor=GridBagConstraints.CENTER; Constraints.fill = GridBagConstraints.BOTH; Constraints.gridwidth = GridBagConstraints.REMAINDER; // create results text area resultsTextArea = new TextArea(15,60); // add with constraints to layout gridbag.setConstraints(resultsTextArea,Constraints); result_area.add(resultsTextArea); resultsTextArea.setEditable(false); }
}
After each Choice component is created, data values are added to it using the addItem() method. When the user clicks the down arrow for the component, a list box opens, displaying the values that have been added to it. The user can then click any one of these options to make it the selected item for that component.
USING DIFFERENT FONTS
As you can see in the preceding code samples, you can use different fonts and sizes in the same applet. You may find it effective to use a larger font for buttons and labels and a smaller font for the displayed result. Listing 44.6 shows the rest of the query applet, which includes the event handler, the database connection method, and a method that gets the query values and builds a where clause for the query. You can also find this code on the CD-ROM that accompanies this book.
// check to see if event was search button being // pressed; // if so // connect to database // create query // send statement // process results // else // disregard // public void actionPerformed(ActionEvent event) { if (event.getSource() == searchButton) { processRequest(); } } // process_request // // connect to database // build where clause // retrieve data // output results public void processRequest() { String whereString = ""; String stringSelect = ""; String tempString = ""; String stringResult = ""; try { resultsTextArea.setText("working..."); //connect to database Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String url = "jdbc:odbc:Zoo"; // connect con = DriverManager.getConnection(url, "dba", "sql"); // create Statement stmt = con.createStatement(); whereString = buildWhere(); // execute statement stringSelect = "Select retail_item.item_nbr," + "retail_item.item_desc,retail_item.qty_per_pkg," + "retail_item.color," + "retail_item.size,retail_item.retail_cost " + "from retail_item" + whereString; rs = stmt.executeQuery(stringSelect); resultsTextArea.setText("Processing Results..."); while (rs.next()) { // get item number tempString = rs.getString(1) + "\t"; stringResult+=tempString; // get description tempString=rs.getString(2) + "\t"; stringResult+=tempString; // get qty tempString = rs.getString(3) + "\t"; stringResult+=tempString; // get color tempString = rs.getString(4) + "\t"; if (rs.wasNull()) { tempString = "\t\t"; } stringResult+=tempString; // get size tempString= rs.getString(5) + "\t"; if (rs.wasNull()) { tempString = "\t\t"; } stringResult+=tempString; // get retail cost tempString="$" + rs.getString(6) + "\n"; stringResult+=tempString; } if (stringResult == "") { stringResult = "No Data Found for Query \n" + stringSelect; } resultsTextArea.setText(stringResult); stmt.close(); rs.close(); } catch (Exception e) { resultsTextArea.setText(e.getMessage()); } } // buildWhere // // check Choice components // if an item is selected and is not // the one at position 0, access the selected item // // if choice is category, access the category code // return generated where clause public String buildWhere() { String colorString = null; String sizeString = null; String whereString = null; int colorInt = colorChoice.getSelectedIndex(); if (colorInt > 0) { colorString = colorChoice.getSelectedItem(); } int sizeInt = sizeChoice.getSelectedIndex(); if (sizeInt > 0) { sizeString = sizeChoice.getSelectedItem(); } if (colorString != null) { whereString = " Where "; whereString = whereString + " retail_item.color = '" + colorString + "'"; } if (sizeString != null) { if (whereString == null) { whereString = " Where "; } else { whereString = whereString + " and "; } whereString = whereString + " retail_item.size = '" + sizeString + "'"; } if (whereString == null) { whereString = ""; } return whereString;
}
The applet checks to see whether the user selected a color and size value and uses these to modify the query string. The results are parsed with a tab character (/t) appended to add some white space between the fields. The results are then displayed in the TextArea result field.
Also consider the processRequest() method; it uses the JDBC wasNull() method to check the code to see whether a value is returned from some fields. This function is called after the get method to see whether the returned result is null. You should make this check on any field defined as optional (that is, any field for which null values are allowed) in the database. Fig-ure 44.5 shows the newly loaded applet in the applet viewer.
Figure 44.5.
The sample3 applet after loading.
TIP: Use the result field to display the query string if no data is found. In this way, you can determine whether no data was found because there was none to match the query, or because the query did not contain all the components you assumed it would contain.
If you select all the Black retail items and run the applet, you see results similar to those shown in Figure 44.6. If you select all the Black retail items of size L (large), you see a smaller subset of records, as shown in Figure 44.7.
Figure 44.6.
The sample3 applet with all Black retail items selected.
Figure 44.7.
The sample3 applet with all Black Large retail
items selected.
This chapter introduced the techniques of using the JDBC with applets. Not all JDBC technology is accessible by an applet, although these restrictions and limitations have improved with the new security features of the JDK 1.1.
You use the JDBC from an applet no differently than you use the JDBC from an application--except that you must use the AWT component classes to provide a way to access and display data. Although this chapter did not explain the AWT, it did demonstrate how to display query results and access data for a database update.
©Copyright, Macmillan Computer Publishing. All rights reserved.