home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / awt / image / TileChangeMulticaster.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  7.3 KB  |  231 lines

  1. /*
  2.  * @(#)TileChangeMulticaster.java    1.3 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt.image;
  16. import java.util.Enumeration;
  17. import java.util.Hashtable;
  18. import java.util.Vector;
  19. import java.awt.Point;
  20.  
  21. /**
  22.   * A convenience class that takes care of the details of implementing
  23.   * the TileChangeListener interface.  A BufferedImage or other
  24.   * implementation of the WritableRenderedImage interface will use
  25.   * this class by constructing a single instance and forwarding calls
  26.   * to the methods addTileChangeListener, removeTileChangeListener,
  27.   * getTileChangeListeners, getWritableTile, releaseWritableTile,
  28.   * getWritableTiles, and hasTileWriters.  Except for
  29.   * getWritableTile and releaseWritableTile, there will rarely be
  30.   * any reason for the WritableRenderedImage to do any additional
  31.   * work.
  32.   *
  33.   */
  34. public class TileChangeMulticaster {
  35.  
  36.  
  37.   /**
  38.    * List of TileListeners.
  39.    */
  40.   private Vector listeners = new Vector();
  41.   
  42.   /**
  43.    * A Hashtable containg key/value pairs of the form
  44.    * TileIndex/Integer.  The TileIndex key indicates the (x, y)
  45.    * position of the tile and the Integer encodes the number of
  46.    * current writers.  When the number of writers drops to zero,
  47.    * the entry is removed from the Hashtable.
  48.    */
  49.   private Hashtable tileWriterCount = new Hashtable();
  50.  
  51.   public TileChangeMulticaster () { }
  52.   
  53.   /** Inform the multicaster of a new listener. */
  54.   public void addTileChangeListener (TileChangeListener tcl) {
  55.     listeners.addElement(tcl);
  56.   }
  57.   
  58.   /** Inform the multicaster that a listener has dropped out. */
  59.   public void removeTileChangeListener (TileChangeListener tcl) {
  60.     listeners.removeElement(tcl);
  61.   }
  62.   
  63.   /** Allow the multicaster to return its list of listeners. */
  64.   public TileChangeListener[] getTileChangeListeners () {
  65.     int length = listeners.size();
  66.     TileChangeListener larray[] = new TileChangeListener[length];
  67.     Object objArray[] = listeners.toArray();
  68.     for (int i = 0; i < length; i++) {
  69.        larray[i] = (TileChangeListener)objArray[i];
  70.     }
  71.     return larray;
  72.   }
  73.  
  74.   /**
  75.     * Multicast the tileGrabbed message.
  76.     *
  77.     * @param source the image that owns the tile being grabbed.
  78.     * @param tileX the X index of the tile.
  79.     * @param tileY the Y index of the tile.
  80.     */
  81.   public void tileGrabbed (WritableRenderedImage source,
  82.                            int tileX, int tileY) {
  83.     Enumeration enum = listeners.elements();
  84.     while (enum.hasMoreElements()) {
  85.       TileChangeListener tcl = (TileChangeListener) enum.nextElement();
  86.       tcl.tileGrabbed(source, tileX, tileY);
  87.     }
  88.   }
  89.  
  90.   /**
  91.     * Multicast the tileReleased message.
  92.     *
  93.     * @param source the image that owns the tile being released.
  94.     * @param tileX the X index of the tile.
  95.     * @param tileY the Y index of the tile.
  96.     */
  97.   public void tileReleased (WritableRenderedImage source,
  98.                             int tileX, int tileY) {
  99.     Enumeration enum = listeners.elements();
  100.     while (enum.hasMoreElements()) {
  101.       TileChangeListener tcl = (TileChangeListener) enum.nextElement();
  102.       tcl.tileReleased(source, tileX, tileY);
  103.     }
  104.   }
  105.  
  106.   
  107.   /**
  108.     * Record a new getWritableTile request to a particular tile
  109.     * of a source image.  
  110.     *
  111.     * @param source the image that owns the tile being grabbed.
  112.     * @param tileX the X index of the tile.
  113.     * @param tileY the Y index of the tile.
  114.    */
  115.   public void addTileWriter (WritableRenderedImage source,
  116.                  int tileX, int tileY) {
  117.     TileIndex index = new TileIndex(tileX, tileY);
  118.     Object count = tileWriterCount.get(index);
  119.  
  120.     if (count != null) { // The tile is in the Hashtable
  121.       int icount = ((Integer) count).intValue(); // Increment the count
  122.       tileWriterCount.put(index, new Integer(icount + 1));
  123.     } else {
  124.       tileWriterCount.put(index, new Integer(1)); // Insert with count = 1
  125.       tileGrabbed(source, tileX, tileY); // Multicast the notification
  126.     }
  127.   }
  128.  
  129.   /**
  130.     * Record a new releaseWritableTile request to a particular tile
  131.     * of a source image. 
  132.     *
  133.     * @param source the image that owns the tile being released.
  134.     * @param tileX the X index of the tile.
  135.     * @param tileY the Y index of the tile.
  136.     */
  137.   public void removeTileWriter (WritableRenderedImage source,
  138.                 int tileX, int tileY) {
  139.     TileIndex index = new TileIndex(tileX, tileY);    
  140.     Object count = tileWriterCount.get(index);
  141.     
  142.     if (count != null) { // The tile is in the Hashtable
  143.       int icount = ((Integer) count).intValue(); // Get the count
  144.       if (icount == 1) { // Only one writer, remove it from the Hashtable
  145.     tileWriterCount.remove(index);
  146.     tileReleased(source, tileX, tileY);
  147.       } else { // Multiple writers exist
  148.     // Decrement the count
  149.     tileWriterCount.put(index, new Integer(icount - 1));
  150.       }    
  151.     } else {
  152.       // The tile had no writers, this should never happen.
  153.     }
  154.   }
  155.  
  156.   /**
  157.    * Returns whether a particular tile has a current writer.
  158.    * @param tileX the X index of the tile.
  159.    * @param tileY the Y index of the tile.
  160.    * @returns true if a writer currently has access to the tile.
  161.    */
  162.   public boolean isTileWritable (int tileX, int tileY) {
  163.     TileIndex index = new TileIndex(tileX, tileY);
  164.     Object count = tileWriterCount.get(index);
  165.     return (count != null); // index has a match in the Hashtable
  166.   }
  167.  
  168.   /**
  169.    * Returns a Vector listing the tiles that are currently writable.
  170.    * @returns a Vector of TileIndex objects indicating which tiles
  171.    * are held by writers.
  172.    */
  173.   public Point[] getWritableTiles () {
  174.     Point tiles[] = new Point[tileWriterCount.size()];
  175.  
  176.     int count = 0;
  177.     Enumeration enum = tileWriterCount.keys();
  178.     while (enum.hasMoreElements()) {
  179.       TileIndex index = (TileIndex) enum.nextElement();
  180.       tiles[count++] = new Point(index.tileX,index.tileY);
  181.     }
  182.  
  183.     return tiles;
  184.   }
  185.   
  186.   /** 
  187.    * Return whether any tile is currently checked out for writing.
  188.    * @returns true if any tile has a current writer.
  189.    */
  190.   public boolean hasTileWriters () {
  191.     return (tileWriterCount.size() != 0); // Hashtable non-empty
  192.   }
  193. }
  194.  
  195.  
  196. /**
  197.  * A pair of integers with hash and equality functions, used by the
  198.  * WritableRenderedImage and TileChangeFilter classes to represent
  199.  * tile indices.  Equality is based on equality of the tileX and
  200.  * tileY values, not object equality.
  201.  *
  202.  * @see WritableRenderedImage
  203.  * @see TileChangeFilter
  204.  */
  205. class TileIndex extends Object {
  206.   int tileX;
  207.   int tileY;
  208.  
  209.   /** Construct a TileIndex from a pair of integers. */
  210.   TileIndex (int tileX, int tileY) {
  211.     this.tileX = tileX;
  212.     this.tileY = tileY;
  213.   }
  214.  
  215.   /** Create a hash code by concatenating the X and Y indices. */
  216.   public int hashCode () {
  217.     return (tileX << 16) | tileY;
  218.   }
  219.  
  220.   /** Compare for equality based on equality of the integer values. */
  221.   public boolean equals (Object obj) {
  222.     if (obj instanceof TileIndex) {
  223.       TileIndex index = (TileIndex) obj;
  224.       return ((tileX == index.tileX) && (tileY == index.tileY));
  225.     } else {
  226.       return false;
  227.     }
  228.   }
  229. }
  230.  
  231.