/* * NQPhotoAlbum.java Version 1.0 09/25/2002 * * Copyright (c) 2002 Jim Effinger. All Rights Reserved. * * End User License Agreement: * 1. You may NOT modify or distribute this file or it's compiled class files. * 2. You are granted a non-exclusive license to use this software on any Web site. * 3. THIS SOFTWARE IS MADE AVAILABLE TO YOU WITH NO WARRANTIES. * * Contact: admin@nilqualm.com */ /* If you want to make improvements to this software, then you must change * the class names, method names, and variable names. Also, you must remove * or replace all comments with your own, including my copyright notice and * EULA. In other words, feel free to use this as a learning tool, but don't * modify MY software in any way. */ import java.awt.*; import java.net.*; import java.awt.event.*; import java.applet.*; /** * This class is the applet run by the browser. After initializing the * components and event listeners for the buttons, it's plan is to read * parameters from the html in order to display photos. Not all photos * are loaded into memory at once. Instead, they are loaded into memory * one at a time as the user clicks through them. */ public class NQPhotoAlbum extends Applet { //Applet components private Panel buttonPanel = new Panel(); //defaults to FlowLayout private Panel picturePanel = new Panel(); //defaults to FlowLayout private PhotoCanvas canvas = new PhotoCanvas(); //image observer private Button bck = new Button("Back"); //looping backward private Button fwd = new Button("Next"); //looping forward private Button fit = new Button("Fit Image"); //optimize image on canvas private Label showing = new Label(" Showing:"); //label for status private TextField txt = new TextField("None.", 10); //text for status //Other variables private Image[] photos; private String[] imageNames; private URL url; private int currIdx = -1; //Variables configured by PARAM tags in html private String numPhotosString; private int num_photos; private String image_loc; /** * Standard browsers can call this method * to get information about the applet. */ public String getAppletInfo(){ return new String("by Jim Effinger, version 1.0, Copyright (c) 2002."); } /** * This method is used when the browser creates the Applet. * Constructor-like code goes here. */ public void init() { //This line must come early in order to avoid errors. loadParameters(); photos = new Image[num_photos]; //Add all the GUI components setLayout(new BorderLayout(2,2) ); add(picturePanel, BorderLayout.CENTER); add(buttonPanel, BorderLayout.SOUTH); canvas.setSize( getSize() ); canvas.setBackground( Color.white ); picturePanel.add(canvas); buttonPanel.add(bck); buttonPanel.add(fwd); buttonPanel.add(showing); showing.setBackground( Color.lightGray ); buttonPanel.add(txt); buttonPanel.add(fit); txt.setBackground( Color.lightGray ); txt.setEditable( false ); setBackground( Color.lightGray ); //the applet's color //Add the button listeners bck.addMouseListener( new MouseAdapter(){ public void mouseClicked(MouseEvent e) { showPreviousImage(); } }); fwd.addMouseListener( new MouseAdapter(){ public void mouseClicked(MouseEvent e) { showNextImage(); } }); fit.addMouseListener( new MouseAdapter(){ public void mouseClicked(MouseEvent e) { fitImage(); } }); //This line serves as a Welcome message. canvas.setText("Click the [Next] button to begin."); } /** * This method is used when the browser starts the Applet * either after stopping for some reason, or initially after * the applet is initialized. */ public void start() { //make the canvas fit perfectly in the white region. canvas.setSize( picturePanel.getSize() ); } /** * Stop method is used usually when the browser looses focus. */ public void stop() { } /** * Destroy method is used when the applet is refreshed or when the user * quits the browser session. Don't normally put code here. */ public void destroy() { } /** * This is where the applet draws things on itself. Buttons and * text fields, etc will repaint themselves automatically. In this * software, the PhotoCanvas class is a Canvas component that we * use to "paint" the images. Thus, we may not place any code here. */ public void paint(Graphics g) { } /** * This method gets information from the html file to allow * the user to configure some of the applet behavior: * * NUM_PHOTOS is the number of photos that this applet will display. * IMAGE_LOC is the folder containing the photos (images). * IMAGEx is a place-holder for loading each image by name, where * x is a number from 1 to NUM_PHOTOS. */ private void loadParameters(){ String param; //First get the number of photos to loop through num_photos = 1; numPhotosString = getParameter("NUM_PHOTOS"); if (numPhotosString != null) { try{ num_photos = Integer.parseInt( numPhotosString ); }catch(Exception e){ //defaults to 1 photo } } //Get the name of the subFolder containing the images. image_loc = getParameter("IMAGE_LOC"); if (image_loc == null) image_loc = "."; //defaults to the codeBase folder (where the applet is) //Initialize the array of image file names to load. imageNames = new String[num_photos]; //Then loop through the image name parameters. for (int i=0; i < num_photos; i++ ) { param = new String("IMAGE" + String.valueOf(i+1)); imageNames[i] = new String(getParameter(param)); } } /** * Decrements the image index. */ public void showPreviousImage() { currIdx--; if (currIdx < 0) currIdx = num_photos - 1; displayPhoto(currIdx); } /** * Increments the image index. */ public void showNextImage() { currIdx++; if (currIdx == num_photos) currIdx = 0; displayPhoto(currIdx); } /** * Loads image from Web folder, if necessary, then sets the canvas image. */ private void displayPhoto(int idx){ String path = "getImage not called"; String text = ""; try{ //Only load image into memory if not already done. if (photos[idx] == null){ canvas.setText("Loading image, please wait..."); path = image_loc + "/" + imageNames[idx]; photos[idx] = getImage(getCodeBase(), path ); } //Update PhotoCanvas. canvas.setImage( photos[idx] ); //Update the text field. text = new String( idx + 1 + " of " + num_photos ); txt.setText( text ); }catch(Exception e){ //This only works with the AppletViewer.exe utility e.printStackTrace(); } } /** * This method calculates the image size and the aspect ratio * and compares it to the PhotoCanvas, then streches or compresses * the image so that it fits optimally in the area available. */ public void fitImage(){ float imgH=1, imgW=1, scrH=1, scrW=1; float imgRat=1, scrRat=1; float multiplier=1; int width=100, height=100; Image tempImage; //only perform if there is an image ready. if (currIdx >= 0 && photos[currIdx] != null){ scrH = canvas.getSize().height; scrW = canvas.getSize().width; imgH = photos[currIdx].getHeight(canvas); imgW = photos[currIdx].getWidth(canvas); imgRat = imgW/imgH; scrRat = scrW/scrH; //This will fit to height if (imgRat <= scrRat){ multiplier = scrH/imgH; } else{ //fit to width multiplier = scrW/imgW; } width = (int)(imgW * multiplier); height = (int)(imgH * multiplier); //Generate the better image with smooth scaling. tempImage = photos[currIdx].getScaledInstance( width, height, Image.SCALE_SMOOTH ); //Display the better image. canvas.setImage(tempImage); //replace the old image in the array if not already done. if (width != imgW) photos[currIdx] = tempImage; } } } /* * This class is used to render text or images via setter methods. */ class PhotoCanvas extends Canvas { private String text; private Image image; /** Default constructor. Initializes private variables. */ public PhotoCanvas(){ text = new String(); } /** Displays a string and sets the image to null. */ public void setText(String text) { this.text = text; image = null; repaint(); } /** Displays the image passed in and empties the text. */ public void setImage(Image img){ image = img; text = ""; repaint(); } /** Overrides the paint method for the Canvas object. */ public void paint(Graphics g) { if (text.length() > 0){ //display any text as necessary g.drawString(text, 20,20); } if (image != null){ //keep the image on the canvas g.drawImage(image, 0, 0,this); } } }