|
|
ImageCanvas.java
ImageCanvas.java class is a canvas containing an image. An update method is provided to draw the image using double buffering, if possible. Listing 10-11 shows the source code for this class.
Listing 10-11: ImageCanvas.java.
//
// 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
{
Graphics bufGr = buf.getGraphics(); // get buffer's graPHIC CONTEXT
bufGr.clearRect(0,0,d.width,d.height); // erase content of buffer
paint(bufGr); // paint into the offscreen buffer
iGraphics.drawImage(buf,0,0,this); // copy the offscreen buffer to the
panel
buf.flush(); // dispose buffer's resources
}
else super.update(iGraphics); // if there's not enough memory for double buffering
let the superclass update as usual
}
/** 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);
d.height -= image.getHeight(this); // then draw the image centered in the
canvas
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));
}
return new Dimension(1,1); // otherwise 1 pixel will do (0 would be too little,
'cause paint would never be called)
}
}
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 10-12 shows the source code for this class.
Listing 10-12: MapCanvas.java.
//
// 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()
{
super("images/world.gif"); // display world map until airports are selected
iconFrom = Airplet.loadImage("images/iconFrom.gif"); // load origin and
destination icons
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);
for(double p = .1 ; p <= 1.0 ; p += .1) // draw a slanted arc as 20 connected lines
{
int xc = (int) (x1 + (double) (x2 - x1) * p); // calculate parametric position
in the line connecting origin with arrival
int yc = (int) (y1 + (double) (y2 - y1) * p);
double pslanted = p; // (p < .75) ? (p * .50 / .75) : (.50 + (p - .75) * .50 / .25);
yc -= (int) (Math.sin(Math.PI * pslanted) * arc); // add variable y value to
form an 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
int w = image.getWidth(this), hofs = (d.width - w) / 2; // origin of the
map in the canvas
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;
int xTo = hofs + mapTo.x - iconTo.getWidth(this) / 2; // calculate origin
and destination icon's position
int yTo = vofs + mapTo.y - iconTo.getHeight(this) / 2;
iGraphics.drawImage(iconFrom,xFrom,yFrom,this); // draw origin and
destination icons
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;
}
// System.out.println("MapCanvas.setAirport - " + airFrom + " " +
mapFrom + " to " + airTo + " " + mapTo);
}
name = "images/" + (name != null ? name : "world") + ".gif"; // use world's map if
there's no better one
setImage(name); // display new image
}
public Dimension preferredSize()
{
return new Dimension(500,300); // size of the maps is fixed
}
}
|