home *** CD-ROM | disk | FTP | other *** search
/ Java Developer's Companion / Java Developer's Companion.iso / documentation / tutorial / ui / overview / example / Converter.java < prev    next >
Encoding:
Java Source  |  1997-07-13  |  8.8 KB  |  279 lines

  1. /*
  2.  * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software
  5.  * and its documentation for NON-COMMERCIAL purposes and without
  6.  * fee is hereby granted provided that this copyright notice
  7.  * appears in all copies. Please refer to the file "copyright.html"
  8.  * for further important copyright and licensing information.
  9.  *
  10.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  11.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  14.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  15.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  16.  */
  17. import java.awt.*;
  18. import java.util.*;
  19. import java.applet.Applet;
  20.  
  21. public class Converter extends Applet {
  22.     ConversionPanel metricPanel, usaPanel;
  23.     Unit[] metricDistances = new Unit[3];
  24.     Unit[] usaDistances = new Unit[4];
  25.  
  26.     /** 
  27.      * Create the ConversionPanels (one for metric, another for U.S.).
  28.      * I used "U.S." because although Imperial and U.S. distance
  29.      * measurements are the same, this program could be extended to
  30.      * include volume measurements, which aren't the same.
  31.      */
  32.     public void init() {
  33.         //Use a GridLayout with 2 rows, as many columns as necessary,
  34.         //and 5 pixels of padding around all edges of each cell.
  35.         setLayout(new GridLayout(2,0,5,5));
  36.  
  37.         //Create Unit objects for metric distances, and then 
  38.         //instantiate a ConversionPanel with these Units.
  39.         metricDistances[0] = new Unit("Centimeters", 0.01);
  40.         metricDistances[1] = new Unit("Meters", 1.0);
  41.         metricDistances[2] = new Unit("Kilometers", 1000.0);
  42.         metricPanel = new ConversionPanel(this, "Metric System",
  43.                                             metricDistances);
  44.  
  45.         //Create Unit objects for U.S. distances, and then 
  46.         //instantiate a ConversionPanel with these Units.
  47.         usaDistances[0] = new Unit("Inches", 0.0254);
  48.         usaDistances[1] = new Unit("Feet", 0.305);
  49.         usaDistances[2] = new Unit("Yards", 0.914);
  50.         usaDistances[3] = new Unit("Miles", 1613.0);
  51.         usaPanel = new ConversionPanel(this, "U.S. System", usaDistances);
  52.  
  53.         //Add both ConversionPanels to the Converter.
  54.         add(metricPanel);
  55.         add(usaPanel);
  56.  
  57.         //Calling the validate method here can help applets.
  58.         //It's unnecessary when this program runs as an application.
  59.         validate();
  60.     }
  61.  
  62.     /**
  63.      * Does the conversion from metric to U.S., or vice versa, and
  64.      * updates the appropriate ConversionPanel. 
  65.      */
  66.     void convert(ConversionPanel from) {
  67.         ConversionPanel to;
  68.  
  69.         if (from == metricPanel)
  70.             to = usaPanel;
  71.         else
  72.             to = metricPanel;
  73.         double multiplier = from.getMultiplier() / to.getMultiplier();
  74.         to.setValue(from.getValue() * multiplier);
  75.     }
  76.  
  77.     /** Draws a box around this panel. */
  78.     public void paint(Graphics g) {
  79.         Dimension d = size();
  80.         g.drawRect(0,0, d.width - 1, d.height - 1);
  81.     }
  82.         
  83.     /**
  84.      * Puts a little breathing space between
  85.      * the panel and its contents, which lets us draw a box
  86.      * in the paint() method.
  87.      */
  88.     public Insets insets() {
  89.         return new Insets(5,5,5,5);
  90.     }
  91.  
  92.     /** Executed only when this program runs as an application. */
  93.     public static void main(String[] args) {
  94.         //Create a new window.
  95.         MainFrame f = new MainFrame("Converter Applet/Application");
  96.  
  97.         //Create a Converter instance.
  98.         Converter converter = new Converter();
  99.  
  100.         //Initialize the Converter instance.
  101.         converter.init();
  102.  
  103.         //Add the Converter to the window and display the window.
  104.         f.add("Center", converter);
  105.         f.pack();        //Resizes the window to its natural size.
  106.         f.show();
  107.     }
  108. }
  109.  
  110.  
  111. class ConversionPanel extends Panel {
  112.     TextField textField;
  113.     Scrollbar slider;
  114.     Choice unitChooser;
  115.     int min = 0;
  116.     int max = 10000;
  117.     Converter controller;
  118.     Unit[] units;
  119.  
  120.     ConversionPanel(Converter myController, String myTitle, Unit[] myUnits) {
  121.         //Initialize this ConversionPanel to use a GridBagLayout.
  122.         GridBagConstraints c = new GridBagConstraints();
  123.         GridBagLayout gridbag = new GridBagLayout();
  124.         setLayout(gridbag);
  125.  
  126.         //Save arguments in instance variables.
  127.         controller = myController;
  128.         units = myUnits;
  129.  
  130.         //Set up default layout constraints.
  131.         c.fill = GridBagConstraints.HORIZONTAL;
  132.  
  133.         //Add the label.  It displays this panel's title, centered.
  134.         Label label = new Label(myTitle, Label.CENTER); 
  135.         c.gridwidth = GridBagConstraints.REMAINDER; //It ends a row.
  136.         gridbag.setConstraints(label, c);
  137.         add(label);
  138.  
  139.         //Add the text field.  It initially displays "0" and needs
  140.         //to be at least 10 columns wide.
  141.         textField = new TextField("0", 10); 
  142.         c.weightx = 1.0;  //This component should use all available horizontal space...
  143.         c.gridwidth = 1; //The default value.
  144.         gridbag.setConstraints(textField, c);
  145.         add(textField);
  146.  
  147.         //Add the pop-up list (Choice).
  148.         unitChooser = new Choice(); 
  149.         for (int i = 0; i < units.length; i++) { //Populate it.
  150.             unitChooser.addItem(units[i].description);
  151.         }
  152.         c.weightx = 0.0; //The default value.
  153.         c.gridwidth = GridBagConstraints.REMAINDER; //End a row.
  154.         gridbag.setConstraints(unitChooser, c);
  155.         add(unitChooser);
  156.  
  157.         //Add the slider.  It's horizontal, its initial value is 0,
  158.         //a click increments the value by 100 pixels, and it has the
  159.         //minimum and maximum values specified by the instance variables
  160.         //min and max.
  161.         slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 100, min, max);
  162.         c.gridwidth = 1; //The default value.
  163.         gridbag.setConstraints(slider, c);
  164.         add(slider);
  165.     }
  166.  
  167.     /** 
  168.      * Returns the multiplier (units/meter) for the currently
  169.      * selected unit of measurement.
  170.      */
  171.     double getMultiplier() {
  172.         int i = unitChooser.getSelectedIndex();
  173.         return (units[i].multiplier);
  174.     }
  175.  
  176.     /** Draws a box around this panel. */
  177.     public void paint(Graphics g) {
  178.         Dimension d = size();
  179.         g.drawRect(0,0, d.width - 1, d.height - 1);
  180.     }
  181.         
  182.     /**
  183.      * Puts a little breathing space between
  184.      * the panel and its contents, which lets us draw a box
  185.      * in the paint() method.
  186.      * We add more pixels to the right, to work around a
  187.      * Choice bug.
  188.      */
  189.     public Insets insets() {
  190.         return new Insets(5,5,5,8);
  191.     }
  192.  
  193.     /**
  194.      * Gets the current value in the text field.
  195.      * That's guaranteed to be the same as the value
  196.      * in the scroller (subject to rounding, of course).
  197.      */
  198.     double getValue() {
  199.         double f;
  200.         try {
  201.             f = Double.valueOf(textField.getText()).doubleValue(); 
  202.         } catch (java.lang.NumberFormatException e) {
  203.             f = 0.0;
  204.         }
  205.         return f;
  206.     }
  207.  
  208.     /** Respond to user actions on controls. */
  209.     public boolean action(Event e, Object arg) {
  210.         if (e.target instanceof TextField) {
  211.             setSliderValue(getValue());
  212.             controller.convert(this);
  213.             return true;
  214.         }
  215.         if (e.target instanceof Choice) {
  216.             controller.convert(this);
  217.             return true;
  218.         } 
  219.         return false;
  220.     }
  221.  
  222.     /** Respond to the slider. */
  223.     public boolean handleEvent(Event e) {
  224.         if (e.target instanceof Scrollbar) {
  225.             textField.setText(String.valueOf(slider.getValue()));
  226.             controller.convert(this);
  227.         } 
  228.         return super.handleEvent(e);
  229.     }
  230.  
  231.     /** Set the values in the slider and text field. */
  232.     void setValue(double f) {
  233.         setSliderValue(f);
  234.         textField.setText(String.valueOf(f));
  235.     }
  236.  
  237.     /** Set the slider value. */
  238.     void setSliderValue(double f) {
  239.         int sliderValue = (int)f;
  240.  
  241.         if (sliderValue > max)
  242.                sliderValue = max;
  243.         if (sliderValue < min)
  244.             sliderValue = min;
  245.         slider.setValue(sliderValue);
  246.     }
  247. }
  248.  
  249.  
  250. class Unit {
  251.     String description;
  252.     double multiplier;
  253.  
  254.     Unit(String description, double multiplier) {
  255.         super();
  256.         this.description = description;
  257.         this.multiplier = multiplier;
  258.     }
  259.  
  260.     public String toString() {
  261.         String s = "Meters/" + description + " = " + multiplier;
  262.         return s;
  263.     }
  264. }
  265.  
  266. /** Provides a window if this program is run as an application. */
  267. class MainFrame extends Frame {
  268.     MainFrame(String title) {
  269.     super(title);
  270.     } 
  271.  
  272.     public boolean handleEvent(Event e) {
  273.     if (e.id == Event.WINDOW_DESTROY) {
  274.         System.exit(0);
  275.     }
  276.     return super.handleEvent(e);
  277.     }
  278. }
  279.