Accessing a Database Remotely with a Browser

Accessing a Database Remotely with a Browser

Looking for cheap tickets? Choose JDBC Airlines! The JDBC Airlines applet illustrates remote access to a database through a browser user interface. This example runs as an applet within World Wide Web browsers that support Java. It uses JDBC to connect and retrieve flight schedules from a database. No other middleware is involved. The JDBC driver used for this example is a 100 percent Java driver that directly connects to the database server.

Figure 11-4 shows the JDBC Airlines applet, which is from Connect Software, Inc.

click to expand
Figure 11-4: Connect Software’s JDBC Airlines applet.

Thanks to its 100 percent Java drivers, this applet is able to run within any Java-compatible WWW browser. Again, no specific classes must be preinstalled on the client machine. The JDBC driver downloads from the Web server along with the applet classes.

The HTML file

The following is the HTML file for this example; it contains the tag to load the applet as well as parameters that provide connection information to the applet. Such connection information includes the driver to use to connect to the database and the database’s URL.

<html> <head> <title> Airplet, the Airline Applet by Connect Software </title> </head> <body bgcolor="#FFFFFF"> <center> <img src="/books/3/397/1/html/2/images/banner.gif"> <p> <applet code=airplet.Airplet width=500 height=600> <param name=driver value=connect.sybase.SybaseDriver> <param name=connection value=’jdbc:sybase://db.mydomain.com:8192/airline;user=guest;password=guest’> </center> </applet> </html>

A Type 4 driver for Sybase was used in this example. If a Type 4 driver is available for your database, refer to its documentation for the format of the URL and possible restrictions when using it over the Internet. If the driver and database listener doesn’t support HTTP-tuneling, firewalls and Web proxies won’t be supported.

Airplet.java

Airplet.java is the main applet class. Initialization establishes a connection with the database server. As soon as the connection is established, various panels are prepared and displayed. These panels include a panel with name and preset choices for departure and arrival airports, a panel with search and roundtrip buttons, and a panel with maps and routes between airports.

User events are handled when selecting airport choices and clicking search or roundtrip buttons. A search for flights from the origin to the destination is performed. A method is also provided to load map images from the server.

On the Web 

The structure of the database tables plus some sample data is available on this book’s companion Web site at www.hungryminds.com/extras/. Please see the Preface for details on accessing files on the Web site.

Listing 11-7 shows the source code for the main part of the applet, Airplet. java.

Listing 11-7: Airplet.java

start example
// // Airplet.java - Connect Software’s Airline Applet, a.k.a. jdbc airlines // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // // Connect Software, Inc. // 81 Lansing Street, Suite #411 // San Francisco, CA 94105 // (415) 710-1544 (phone) - (415) 543-6695 (fax) // // email: info@connectsw.com - www: http://www.connectsw.com package airplet; // airplet’s package import java.applet.*; // import a number of java libraries import java.awt.*; import java.io.*; import java.net.*; import java.util.*; import java.sql.*; // import modified jdbc libraries public class Airplet extends java.applet.Applet // main applet class {     private TextField nameTo = null; // names of departure and arrival airports     private TextField nameFrom = null;     private AirportChoice choiceTo = null;      // preset lists of departure and arrival airports     private AirportChoice choiceFrom = null;     private FlightsPanel panelFlights = null;      // panel containing maps and flight listings     /** Initialize the applet, opens the connection with the database and          add user interface items in the applet. */     synchronized public void init()     {          airplet = this; // static reference to this airplet          setBackground(Color.white); // white background for this applet         LayoutManager columnLayout = new ColumnLayout(5,5);          // all panels go in a single column         setLayout(columnLayout);         showStatus("Connecting...");          // let user know we’re connecting to the database         try             {                 String driver = getParameter("driver");                  // use sql driver specified in ‘driver’ parameter                 if(driver != null) Class.forName(driver).newInstance();                  // register driver with DriverManager                 String url = getParameter("connection"); // get connection’s url                 connection = DriverManager.getConnection(url);                  // establish connection with server             }         catch(Exception sqlEx)             {                 System.out.println("Connection failed because " + sqlEx + "\n");             }         showStatus("Preparing...");         try             {                 // create panel with name and preset choices                  // for departure’s airport                 Panel panelFrom = new Panel();                  ImageCanvas imageFrom = new                      ImageCanvas("images/airFrom.gif"); panelFrom.add(imageFrom);                 nameFrom = new TextField(25); panelFrom.add(nameFrom);                 choiceFrom = new AirportChoice(); panelFrom.add(choiceFrom);                 // create panel with name and preset choices                  // for arrival’s airport                 Panel panelTo = new Panel();                  ImageCanvas imageTo = new ImageCanvas("images/airTo.gif");                  panelTo.add(imageTo);                 nameTo = new TextField(25); panelTo.add(nameTo);                 choiceTo = new AirportChoice(); panelTo.add(choiceTo);                 Panel panelButtons = new Panel();                  // panel with search and roundtrip buttons                 Button button1 = new Button("Search"); panelButtons.add(button1);                 Button button2 = new Button("Roundtrip");                  panelButtons.add(button2);                 panelFlights = new FlightsPanel(); // panel with maps and routes                 add(panelFrom); // add all panels to the applet                 add(panelTo);                 add(panelButtons);                 add(panelFlights);                 showStatus("Connect Software, 1996."); // here we are!             }         catch(SQLException sqlEx) {              showStatus("Sorry, could not initialize, e-mail              support@connectsw.com");          }    }    /** Responds to user selecting an airport in the choice menus or clicking         search or roundtrip. */    public boolean action(Event iEvent,Object iArgument)    {         if(iEvent.target == choiceFrom) // user picked an origin from the choices             {                 Airport air = choiceFrom.getSelectedAirport();                 nameFrom.setText(air.getName());                  // copy origin’s name to origin’s text field                 return true;             }         if(iEvent.target == choiceTo)          // user picked a destination from the choices             {                 Airport air = choiceTo.getSelectedAirport();                 nameTo.setText(air.getName());                  // copy destination’s name to destination’s text field             }         // search for flights from origin to destination         if(iArgument.equals("Search") || iArgument.equals("Roundtrip"))              {                 String airFrom = nameFrom.getText();                 if(airFrom.length() < 1) airFrom = choiceFrom.getSelectedItem();                 String airTo = nameTo.getText();                 if(airTo.length() < 1) airTo = choiceTo.getSelectedItem();                 searchFlights(airFrom,airTo,iArgument.equals("Roundtrip"));                 return true;              }          return super.action(iEvent,iArgument); // event was handled     }     private void searchFlights(String departingFrom,String arrivingTo,     boolean roundTrip)     {          try              {                  Airport airFrom = Airport.getAirport(departingFrom);                   // find out more about departing airport                  Airport airTo = Airport.getAirport(arrivingTo);                   // find out more about arriving airport                  // if both airports were found (and they are different)                  if(airFrom != null && airTo != null)                       {                           // show complete name and code for departure airport                           nameFrom.setText(airFrom.getName());                            choiceFrom.select(airFrom.getCode());                           // show complete name and code for arrival airport                           nameTo.setText(airTo.getName());                            choiceTo.select(airTo.getCode());                           if(roundTrip) // if user requested return trip                               {                                   // show inverse route                                   panelFlights.setAirports(airTo,airFrom);                               }                           // show normal route                           else panelFlights.setAirports(airFrom, airTo);                            layout();                      }              }          catch(SQLException sqlEx) { panelFlights.setText(sqlEx.toString());           }     }     static Statement createStatement() throws SQLException     {          return connection.createStatement();     }     private static Connection connection = null;      // connection to the airline database     /** Loads given image from the network, or file system, and returns it. */     static Image loadImage(String iName)     {          if(images == null) // if there’s no hash table for images yet              {                  images = new Hashtable(); // create an empty hash table              }          // try to get image from the hash table (hash is image’s name)          Image image = (Image) images.get(iName);           if(image == null) // if this image hasn’t been loaded yet              {                  try // catch all loading problems                      {                           // create url of image on Web server or                           // local file system                           URL url = new URL(airplet.getDocumentBase(), iName);                            image = airplet.getImage(url); // try to load image                           airplet.prepareImage(image,airplet);                      }                  catch(Exception e) { }                  if(image != null) // if image was loaded                      {                           // add it to the hash table so next time                            // we don’t have to load it                           images.put(iName,image);                       }              }          return image; // return the image     }     static private Hashtable images = null; // a hash table of loaded images     // a static reference to this applet      // (there’s only one instance of it running at any time)     static private Airplet airplet = null;  }
end example

Airport.java

Airport.java holds the information regarding an airport. The constructor executes a query returning airport details such as its code, its name, its description, and its geographical coordinates in terms of x and y positions on different maps.

A hash table of airports is also created in Listing 11-8, which shows the source code of Airport.java.

Listing 11-8: Airport.java

start example
// // Airport.java - this object holds information regarding an airport // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; import java.sql.*; // import sql server access classes import java.awt.*; // java’s windowing toolkit and other ui classes import java.util.*; // utility classes /** Information regarding an airport. */ class Airport {     public Airport(String iAirport) throws SQLException     {          iAirport = iAirport.trim(); // remove leading and trailing spaces          // use normal statement to query the Airports table          ResultSet r = null; Statement s = Airplet.createStatement();           if(iAirport.length() == 3) // if this is likely to be an airport code              {                  r = s.executeQuery("select * from airports where code =                   ‘" + iAirport + "‘");                  // move over to the first (and only) row in the result set                  if(r.next() == false)                       {                           r = null;                            // there are no entries with given airport code                      }              }          // search for airports whose name contain given airport          // string (like %string%)          if(r == null)              {                  r = s.executeQuery("select * from airports where name like ‘%" +                   iAirport + "%’");                  // move to first (and probably only) row in result set                  if(r.next() == false)                       {                           // case insensitive name, eg. [mM][iI][lL][aA][nN]                           // instead of Milan                           String nocase = "";                            // scan all characters in the string                           for(int i = 0 ; i < iAirport.length() ; i++)                                {                                   // extract character then convert to                                   // lowercase and uppercase                                   String single = iAirport.substring(i,i+1);                                    String lower = single.toLowerCase(), upper =                                    single.toUpperCase();                                   // if lowercase is different from uppercase                                   // (that is, if this character is alpha)                                   if(lower.equals(upper) == false)                                        {                                            // regular expression for both lower                                            // or uppercase                                            // (for example, [aA])                                            nocase += "[" + lower + upper + "]";                                        }                                   else nocase += single;                               }                           r = s.executeQuery("select * from airports where name                            like ‘%" +                           nocase + "%’");                           // if this one didn’t work either, there’s                           // no such airport                           if(r.next() == false) r = null;                       }              }          if(r != null)              {                  code = r.getString("code"); // airport code, eg. ‘SFO’                  name = r.getString("name"); // airport name,                                              // eg. ‘San Francisco, CA’                  description = r.getString("description"); // description                                                            // of this airport                  StringTokenizer sTokenizer = new StringTokenizer                   (r.getString("maps"),";");                  // scan each token, maps entry looks something like                   // "california(45,60);usa(123,3);world(56,78)"                  while(sTokenizer.hasMoreTokens())                       {                           // create an object containing information regarding                           // this airport on a single map                           MapInfo info = new MapInfo(sTokenizer.nextToken());                            if(maps != null) // if there are other maps already                               {                                   // add this map to the linked list of maps                                   maps.append(info);                                }                           else maps = info; // this is the first map in the list                           // System.out.println(code + " map " + info);                      }              }          else throw new SQLException("Can’t find ‘" + iAirport +           "‘ in the airports database.");     }     // airport code, name and description, eg. ‘SFO’,     // ‘San Francisco, CA’, ‘International Airport, ...’     private String code, name, description;      // linked list of maps available for this airport (and coordinates     // on each map) in preferred order (eg. ‘california’, ‘usa’, ‘world’)     private MapInfo maps;      public String getCode()     {          return code; // return airport code     }     public String getName()     {          return name;     }     public MapInfo getMaps()     {          return maps;     }     /** Returns airport with the given name or code. */     static public Airport getAirport(String iName)     {          try              {                  if(airports = null) // if there’s no hash table for airports                      {                           // create an empty hash table                           airports = new Hashtable();                       }                  // try getting the airport from the hash table                  Airport airport = (Airport) airports.get(iName);                   if(airport = null) // if airport was not found                      {                           // create a new airport from that name                           // (will query the database)                           airport = new Airport(iName);                            // add airport to the hash table (by name)                           airports.put(airport.getName(),airport);                            // add also by code                           airports.put(airport.getCode(),airport); //                      }                  return airport; // return the airport              }          catch(SQLException sqlException) { return null; } // airport could                                                            // not be found     }     // hash table of airports (used to minimize database access)     static private Hashtable airports = null;      public String toString()     {          return "Airport[" + code + "," + name + "]"; // convert object to string     } }
end example

AirportChoice.java

The AirportChoice.java class queries the database to build a list of airport codes such as SFO, LAX, and JFK. The list is used within the user interface to enable the user to choose the departure and arrival airports. Listing 11-9 shows the source code for AirPortChoice.java.

Listing 11-9: AirportChoice.java

start example
// // AirportChoice.java - user interface widget showing a choice of airports // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; import java.sql.*; // import jdbc and other sql libraries import java.awt.*; // java windowing toolkit /** A choice user interface widget showing a list of available airport codes. */ class AirportChoice extends Choice {     /**      * Initialize the choice user interface widget with a list of airports      * available in the database. The method will query the airports table      * of the database, listing all available airports by code.      */     public AirportChoice() throws SQLException     {          // use sql to select all airport codes from the          // airports table then add them to the widget          // scan all the airports in the table          Statement s = Airplet.createStatement();          for(ResultSet r = s.executeQuery("select code from airports           order by code") ; r.next() ; )              {                  String name = r.getString(1); // name of this airport                  addItem(name); // add airport to the choices              }          s.close(); // close statement     }     /** Returns the Airport corresponding to the entry with the given index. */     public Airport getAirport(int index)     {          return Airport.getAirport(getItem(index)); // return Airport object     }     /** Returns the currently selected Airport. */     public Airport getSelectedAirport()     {          return getAirport(getSelectedIndex());     } } 
end example

ColumnLayout.java

The ColumnLayout.java class arranges a set of components in a single column. The source code for this class is in Listing 11-10.

Listing 11-10: ColumnLayout.java

start example
// // ColumnLayout.java - layout that arranges all components in a column // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo. // package airplet; import java.awt.*; // import java windowing classes /** A layout that arranges all components in a single column. */ public class ColumnLayout implements LayoutManager // just another layout manager {     public ColumnLayout()     {          hgap = vgap = 0; // no gap between components     }     public ColumnLayout(int hgap,int vgap)     {          this.hgap = hgap; this.vgap = vgap; // use this spacing                                              // between components     }     private int hgap, vgap; // horizontal and vertical spacing between components     /** Arrange components contained in iParent in a single column using their          preferred size. */     public void layoutContainer(Container iParent)     {          Insets insets = iParent.insets(); // insets (borders around                                            // the container)          Dimension dimension = iParent.size(); // size of parent container          dimension.width -= insets.left + insets.right; // net width of container          for(int i = 0, v = vgap ; i < iParent.countComponents() ; i++)              {                  // scan each component in the container                  Component component = iParent.getComponent(i);                   // get component’s preferred size and then reshape it                  Dimension size = component.preferredSize();                   component.reshape(insets.left,v,dimension.width - insets.left -                   insets.right,size.height);                  component.repaint(); // redraw the component                  // update vertical origin for next component                  v += size.height + vgap;               }     }     /** Returns the minimum layout size calculated using each component’s          preferred size. */     public Dimension minimumLayoutSize(Container iParent)     {          Dimension dimension = new Dimension(0,0);          for(int i = 0 ; i < iParent.countComponents() ; i++) // scan components              {                  Component component = iParent.getComponent(i);                  // get i-th component’s size                  Dimension size = component.preferredSize();                   dimension.width = Math.max(dimension.width,size.width);                  // update height including this component                  dimension.height += size.height + vgap;               }          Insets insets = iParent.insets(); // add insets (border)          dimension.width += insets.left + insets.right + 2 * hgap;          dimension.height += insets.top + insets.bottom + vgap;          return dimension;     }     /** Preferred size is just like minimum size but can be as wide as the parent          component. */     public Dimension preferredLayoutSize(Container iParent)     {          Dimension dimension = minimumLayoutSize(iParent);          dimension.width = Math.max(iParent.size().width,dimension. width);          return dimension;     }     public void addLayoutComponent(String iName,Component iComponent)     {     }     public void removeLayoutComponent(Component iComponent)     {     } }
end example

Flight.java

Flight.java contains a constructor that initializes the class members (attributes) using flight information. Flight.java extracts the flight number, departure and arrival, flight frequency, and plane identification. Listing 11-11 shows the source code for this class.

Listing 11-11: Flight.java

start example
// // Flight.java - holds information regarding a flight // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; import java.sql.*;         // import jdbc and other sql libraries class Flight {     /**      * Initialize flight from the information contained in the current      * row of this result set. The result set is a subset of rows from      * the flights table in the airline database. This method will read      * information on current row (it will not call next).      *      * @param iFlight is a result set whose current row is a flight      */     public Flight(ResultSet iFlight) throws SQLException     {         code = iFlight.getString("code"); // get flight number         from = iFlight.getString("from_city"); to = iFlight.getString("to_city");         departure = iFlight.getTime("departure"); arrival =          iFlight.getTime("arrival");         // flight frequency (eg. which days this flight operates)         frequency = iFlight.getString("frequency");          plane = iFlight.getString("plane"); // airplane used    }    String code, from, to; // the flight code/number and city of                            // departure/arrival, e.g., ‘TWA800’    Time departure, arrival; // departure and arrival time    String frequency; // days when the flight is available,                      // e.g., 123 for Mon, Tue, Wed    String plane; // airplane used, e.g., "Boeing 767"    public String toString()    {         return "Flight[" + code + "," + from + " " + departure + "," + to + " " +          arrival +         "," + frequency + "," + plane + "]";    } }
end example

FlightsPanel.java

The FlightsPanel.java class is a panel containing a graphical map. Which map is displayed depends on the departure and destination airport locations. This panel also displays the routes. Listing 11-12 contains the source code for this class.

Listing 11-12: FlightsPanel.java

start example
// // FlightsPanel.java - a panel showing flight information and routes // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; // airplet package import java.sql.*; // import connect’s jdbc libraries import java.awt.*; // import java windowing library class FlightsPanel extends Panel {     public FlightsPanel()     {          // column layout with 10 pixels between components          LayoutManager layout = new ColumnLayout(0,10);           setLayout(layout); // use this layout for the panel          map = new MapCanvas(); add(map); // add a map to the panel          // label that can display multiple lines of text (draw with subtle          // good looking shadow)          label = new MultilineLabel(Label.CENTER);           setText("Welcome to jdbc airlines!\n \nPlease pick an origin and a           destination\n" +          "then click Search or RoundTrip.");          add(label); // add label to panel     }     /** Converts a time object into a string in the form hh:mm am/pm */     String time2string(Time time)     {          int hour = time.getHours(); // get hours (0..23) and minutes (0..59)          // format the string as hh:mm then append am or pm          int minute = time.getMinutes();           return (hour % 12 < 10 ? "0" : "") + Integer.toString(hour % 12) + ":" +          (minute < 10 ? "0" : "") + Integer.toString(minute) +          (hour < 12 ? " AM" : " PM");     }     void setAirports(Airport iFrom,Airport iTo) throws SQLException     {          String str = null;          try              {                  // show best map for these two airports                  // (and a route between them)                  map.setAirports(iFrom,iTo);                   // if the two airports are not the same                  if(iFrom.getCode().equals(iTo.getCode()) = false)                       {                           // create a vector containing all the                           // flights between the two airports                           FlightsVector flights = new FlightsVector(iFrom,iTo);                            int numFlights = flights.size(); // number of flights                                                             // found                           if(numFlights > 0) // if there are flights                               {                                   str = "Flights from " + iFrom.getName() +                                    " to " + iTo.getName() + "\n \n";                                   // scan flights between these two airports                                   for(int i = 0 ; i < numFlights ; i++)                                        {                                            // retrieve i-th flight                                            Flight flight = (Flight)                                             flights.elementAt(i);                                             str += flight.code + " leaves at " +                                             time2string(flight.departure) + "                                             arrives at " +                                             time2string(flight.arrival) + "                                             (frequency " +                                             flight.frequency + ").\n";                                       }                               }                           else str = "There are no flights between " +                                 iFrom.getName() +                                " and " + iTo.getName() + ".";                      }                  // if there are no flights or airports are the same,                  // show an error message                  else str = "Please pick two different airports, then retry.";               }          // some sql exception was raised, notify the user          catch(SQLException sqlEx)               {                  str = "Sorry, your request didn’t go through,\n" +                  "the server is probably down or busy,\nplease try again later.\n                   \n" + sqlEx;              }          setText(str); // show the string with the flights or the warning          // we may need to redo this panel’s layout          // (the label may have changed its size)          layout();      }     public void setText(String text)     {          label.setText(text);     }     private MapCanvas map = null; // map and route canvas     private MultilineLabel label = null; // label with flights or error message }
end example

FlightsVector.java

FlightsVector.java is a vector containing all flights between the departure and arrival airports. A query is sent to the database server to get information about flights with the given airport codes for departure and arrival. Listing 11-13 shows the source code for this class.

Listing 11-13: FlightsVector.java

start example
// // FlightsVector.java - a vector containing a bunch of flights // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; import java.sql.*; // import jdbc and other sql libraries import java.util.*; // java utility classes class FlightsVector extends Vector // this is just a vector of Flight objects {     /**      * Initialize this vector with all flights between two given airports.      * The method will select all rows in the flights table having the given      * airport codes in the from_city and to_city fields. An entry in the vector      * will then be created for each flight and each entry will be added to the       * vector.      *      * @param iConnection connection to the database      * @param iFrom the airport we’re leaving from      * @param iTo the airport we’re arriving to      */     public FlightsVector(Airport iFrom,Airport iTo) throws SQLException     {          // executes something like: select * from flights where          // from_city = ‘SFO’ and to_city = ‘JFK’          String sql = "select * from flights where from_city = ‘" +            iFrom.getCode() +           "‘ and to_city = ‘" + iTo.getCode() + "‘ order by departure";          Statement s = Airplet.createStatement(); // create normal sql statement          // scan all flights between given airports          for(ResultSet r = s.executeQuery(sql) ; r.next() ; )               {                  // create a new flight from current row                  Flight flight = new Flight(r);                   addElement(flight); // add this flight to the vector              }          s.close(); // we don’t have to do this                     // (but it could help jdbc optimize access)     } }
end example

ImageCanvas.java

The ImageCanvas.java class is a canvas containing an image. An update method is provided to draw the image using double buffering, if possible. Listing 11-14 shows the source code for this class.

Listing 11-14: ImageCanvas.java

start example
// // ImageCanvas.java - a canvas that shows an image // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; import java.applet.*; import java.awt.*; // java windowing classes /** A canvas used to display an image. */ public class ImageCanvas extends Canvas // shows a canvas containing an image {     /** Initialize canvas showing the image with the given name. */     public ImageCanvas(String name)    {         if(name != null && name.length() > 0) // if a name was specified             {                 setImage(name); // load image             }    }    protected Image image = null; // image shown by this canvas    /** Display image with given name in the canvas. */    public void setImage(String iName)    {         Image newimage = Airplet.loadImage(iName); // load new image         if(image != newimage) // if image changed             {                 image = newimage; repaint(); // refresh the canvas             }    }    /** Update the canvas using double buffering (if enough memory’s        available). */    synchronized public void update(Graphics iGraphics)    {         Dimension d = size();         if(d.width < 1 || d.height < 1) return; // don’t update if empty         Image buf = null;         try // catch memory full and other problem             {                 buf = createImage(d.width,d.height); // create temporary buffer             }         catch(Exception e) { }         if(buf != null) // if buffer was created             {                 // get buffer’s graphic context                 Graphics bufGr = buf.getGraphics();                  bufGr.clearRect(0,0,d.width,d.height); // erase content of buffer                 paint(bufGr); // paint into the offscreen buffer                 // copy the offscreen buffer to the panel                 iGraphics.drawImage(buf,0,0,this);                  buf.flush(); // dispose buffer’s resources             }         // if there’s not enough memory for double buffering,         // let the superclass update as usual         else super.update(iGraphics);      }     /** Draw the image centered in the canvas. */     public void paint(Graphics iGraphics)     {          if(image != null) // if there is an image              {                  Dimension d = size(); // calculate image’s origin                  d.width -= image.getWidth(this);                  // then draw the image centered in the canvas                  d.height -= image.getHeight(this);                   iGraphics.drawImage(image,d.width,d.height,this);              }     }     /** Preferred size for this canvas is the size of the image that it is          showing, if any. */     public Dimension preferredSize()     {          if(image != null) // if an image was selected, return its size              {                  return new Dimension(image.getWidth(this),image.                   getHeight(this));              }          // otherwise 1 pixel will do (0 would be too little,          // ‘cause paint would never be called)          return new Dimension(1,1);      } }
end example

MapCanvas.java

MapCanvas.java contains the methods used to display the most appropriate map for the departure and arrival selections. A route is drawn between the two airports. Listing 11-15 shows the source code for this class.

Listing 11-15: MapCanvas.java

start example
// // MapCanvas.java - a view that shows a map with airports and a route // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; import java.awt.*; // import java windowing toolkit import java.io.*; // I/O streams, exceptions, etc. import java.applet.*; // applet class /** A canvas that shows a map and a flight’s route. */ class MapCanvas extends ImageCanvas // map class extends canvas (drawable view) {     public MapCanvas()     {          // display world map until airports are selected          super("images/world.gif");           // load origin and destination icons          iconFrom = Airplet.loadImage("images/iconFrom.gif");           iconTo = Airplet.loadImage("images/iconTo.gif");     }     private Airport airFrom = null; // arrival and departure airports     private Airport airTo = null;     private MapInfo mapFrom = null;      // information regarding the airports on the map     private MapInfo mapTo = null;     private Image iconFrom = null;      // icons for arrival and departure points on the map     private Image iconTo = null;     /** Draw a route going from x1,y1 to x2,y2 */     private void drawRoute(Graphics iGraphics,int x1,int y1,int x2,int y2)     {          int xp = x1;          int yp = y1;          double arc = Math.min(Math.abs(x1 - x2) * .20 +           Math.abs(y1 - y2) * .20,30.0);          // draw a slanted arc as 20 connected lines          for(double p = .1 ; p <= 1.0 ; p += .1)               {                  // calculate parametric position in the line                  // connecting origin with arrival                  int xc = (int) (x1 + (double) (x2 - x1) * p);                   int yc = (int) (y1 + (double) (y2 - y1) * p);                  double pslanted = p; // (p < .75) ? (p * .50 / .75) : (.50 +                   (p - .75) * .50 / .25);                  // add variable y value to form an arc                  yc -= (int) (Math.sin(Math.PI * pslanted) * arc);                   iGraphics.drawLine(xp,yp,xc,yc); // draw current segment                  xp = xc; // current position becomes previous position                  yp = yc;              }     }     /** Draw the map of the region containing both airports and a route. */     public void paint(Graphics iGraphics)     {          super.paint(iGraphics); // draws the map          if(mapFrom != null && mapTo != null)              {                  Dimension d = size(); // size of this canvas                  // origin of the map in the canvas                  int w = image.getWidth(this), hofs = (d.width - w) / 2;                   int h = image.getHeight(this), vofs = (d.height - h) / 2;                  iGraphics.setColor(Color.lightGray);                  drawRoute(iGraphics,hofs + mapFrom.x + 1,vofs + mapFrom.y +                    1,hofs +                   mapTo.x + 1,vofs + mapTo.y + 1);                  iGraphics.setColor(Color.black);                  drawRoute(iGraphics,hofs + mapFrom.x,vofs + mapFrom.y,hofs +                   mapTo.x,vofs + mapTo.y);                  int xFrom = hofs + mapFrom.x - iconFrom.getWidth(this) / 2;                  int yFrom = vofs + mapFrom.y - iconFrom.getHeight(this) / 2;                  // calculate origin and destination icon’s position                  int xTo = hofs + mapTo.x - iconTo.getWidth(this) / 2;                   int yTo = vofs + mapTo.y - iconTo.getHeight(this) / 2;                  // draw origin and destination icons                  iGraphics.drawImage(iconFrom,xFrom,yFrom,this);                   iGraphics.drawImage(iconTo,xTo,yTo,this);              }     }     /** Sets departure and arrival airports, selecting and displaying the most          appropriate map. */     void setAirports(Airport iFrom,Airport iTo)     {          String name = null;          airFrom = iFrom; airTo = iTo; // set departure and arrival airports          if(airFrom != null && airTo != null)           // if departure and arrival airports were specified              {                  for(mapFrom = airFrom.getMaps() ; name == null && mapFrom !=                   null ; )                      {                           for(mapTo = airTo.getMaps() ; name == null && mapTo !=                            null ; )                               {                                   if(mapFrom.name.equals(mapTo.name))                                       {                                            name = mapFrom.name;                                       }                                   else mapTo = mapTo.next;                               }                           if(name == null) mapFrom = mapFrom.next;                      }              }          // use world’s map if there’s no better one          name = "images/" + (name != null ? name : "world") + ".gif";           setImage(name); // display new image     }     public Dimension preferredSize()     {          return new Dimension(500,300); // size of the maps is fixed     } }
end example

MapInfo.java

The MapInfo.java class extracts the x,y coordinates from the flight’s string for a particular graphic map. Listing 11-16 shows its source code.

Listing 11-16: MapInfo.java

start example
// // MapInfo.java - informations regarding airport’s position on a map // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; // airplet’s package import java.util.*; // utility classes /** Information about an airport’s position on a map. */ class MapInfo {     /** Initialize from a ‘map(x,y)’ string. */     MapInfo(String map)     {          // name is encoded as name(x,y) so use ( and comma as separators          StringTokenizer sTokenizer = new StringTokenizer(map,"(,)");           // name of this map (eg. ‘usa’, ‘europe’, ‘world’)          name = sTokenizer.nextToken().toLowerCase();           // coordinate of the airport in this map          x = Integer.parseInt(sTokenizer.nextToken());           y = Integer.parseInt(sTokenizer.nextToken());     }     String name; // name of the map     int x,y; // coordinates of the airport on this map     MapInfo next = null; // next map (this is a linked list)     void append(MapInfo item)     {          // appends item at the end of the linked list          if(next != null) next.append(item); else next = item;      }     public String toString()     {          return "MapInfo[" + name + "," + x + "," + y + "]";           // returns MapInfo[name,x,y]     } }
end example

MultilineLabel.java

MultilineLabel.java is simply a label that can display multiple lines of text. It also provides text shadow for the drawn string. Listing 11-17 shows the source code for this class.

Listing 11-17: MultilineLabel.java

start example
// // MultilineLabel.java - a label that can draw several lines of text // // Copyright (C) 1996 by Connect Software. All rights reserved. // // Written by Gionata Mettifogo, Peter Ham. // package airplet; import java.awt.*; import java.util.*; public class MultilineLabel extends java.awt.Canvas {     public MultilineLabel(int alignment)     {          align = alignment;     }     private String text; private int align;      // text and alignment (see constants in Label)     public void setText(String text)     {          this.text = text;     }     /** Draw the multiline label aligned as specified during object’s          construction. */     public void paint(Graphics iGraphics)     {          // get information on the font’s sizes          FontMetrics fm = iGraphics.getFontMetrics();           // separate different lines          StringTokenizer tokens = new StringTokenizer(text,"\n");           // line height and label’s width          int w = size().width, h = fm.getHeight();           // scan all lines in the label          for(int y = h ; tokens.hasMoreTokens() ; y += h)               {                  String line = tokens.nextToken(); // retrieve line                  int x = 0;                  // if line is centered or right aligned                  if(align == Label.CENTER || align == Label.RIGHT)                       {                           // calculate spacing on left side                           x = w - fm.stringWidth(line);                           if(align == Label.CENTER) x /= 2;                      }                 shadowString(iGraphics,line,x,y); // draw the line             }    }    public Dimension preferredSize()    {         // get information on the font’s sizes         FontMetrics fm = getGraphics().getFontMetrics();          // separate different lines         StringTokenizer tokens = new StringTokenizer(text,"\n");          Dimension dimension = new Dimension(0,fm.getHeight() *           tokens.countTokens() +           fm.getMaxDescent() + 1);         while(tokens.hasMoreTokens()) // scan lines             {                 String line = tokens.nextToken(); // retrieve line                 // width is the length of the longest line                 dimension.width = Math.max(fm.stringWidth(line),dimension.width);              }         return dimension;    }    /**     * Draws the given string at the given position using a     * subtle 1 pixel gray shadow. Light comes from the upper     * left corner (where the Apple used to be).     */    public void shadowString(Graphics iGraphics,String iString,int x,int y)    {         Color color = iGraphics.getColor();         iGraphics.setColor(Color.lightGray);         iGraphics.drawString(iString,x+1,y+1);         iGraphics.setColor(color);         iGraphics.drawString(iString,x,y);    } }
end example



JDBC 3. 0. JAVA Database Connectivity
JDBC 3: Java Database Connectivity
ISBN: 0764548751
EAN: 2147483647
Year: 2002
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net