home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / RenderingHints.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  21.4 KB  |  651 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)RenderingHints.java    1.12 98/10/05
  3.  *
  4.  * Copyright 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;
  16.  
  17. import java.util.Map;
  18. import java.util.Set;
  19. import java.util.Collection;
  20. import java.util.Collections;
  21. import java.util.HashMap;
  22. import java.util.Iterator;
  23. import sun.awt.SunHints;
  24.  
  25. /**
  26.  * The <code>RenderingHints</code> class contains rendering hints that can
  27.  * be used by the {@link java.awt.Graphics2D} class, and classes that
  28.  * implement {@link java.awt.image.BufferedImageOp} and
  29.  * {@link java.awt.image.Raster}.
  30.  */
  31. public class RenderingHints implements Map, Cloneable {
  32.     /**
  33.      * Defines the base type of all keys used to control various
  34.      * aspects of the rendering and imaging pipelines.  Instances
  35.      * of this class are immutable and unique which means that
  36.      * tests for matches can be made using the == operator instead
  37.      * of the more expensive equals() method.
  38.      */
  39.     public abstract static class Key {
  40.     private static HashMap identitymap = new HashMap(17);
  41.  
  42.     private String getIdentity() {
  43.         return "Instance("+privatekey+") of "+getClass().getName();
  44.     }
  45.  
  46.     private synchronized static void recordIdentity(Key k) {
  47.         Object identity = k.getIdentity();
  48.         if (identitymap.containsKey(identity)) {
  49.         throw new IllegalArgumentException(identity+
  50.                            " already registered");
  51.         }
  52.         identitymap.put(identity, k);
  53.     }
  54.  
  55.     private int privatekey;
  56.  
  57.     /**
  58.      * Construct a key using the indicated private key.  Each
  59.      * subclass of Key maintains its own unique domain of integer
  60.      * keys.  No two objects with the same integer key and of the
  61.      * same specific subclass can be constructed.  An exception
  62.      * will be thrown if an attempt is made to construct another
  63.      * object of a given class with the same integer key as a
  64.      * pre-existing instance of that subclass of Key.
  65.      */
  66.     protected Key(int privatekey) {
  67.         this.privatekey = privatekey;
  68.         recordIdentity(this);
  69.     }
  70.  
  71.     /**
  72.      * Returns true if the specified object is a valid value
  73.      * for this Key.
  74.      */
  75.     public abstract boolean isCompatibleValue(Object val);
  76.  
  77.     /**
  78.      * Returns the private integer key that the subclass
  79.      * instantiated this Key with.
  80.      */
  81.     protected final int intKey() {
  82.         return privatekey;
  83.     }
  84.  
  85.     /**
  86.      * The hash code for all Key objects will be the same as the
  87.      * system identity code of the object as defined by the
  88.      * System.identityHashCode() method.
  89.      */
  90.     public final int hashCode() {
  91.         return System.identityHashCode(this);
  92.     }
  93.  
  94.     /**
  95.      * The equals method for all Key objects will return the same
  96.      * result as the equality operator '=='.
  97.      */
  98.     public final boolean equals(Object o) {
  99.         return this == o;
  100.     }
  101.     }
  102.  
  103.     HashMap hintmap = new HashMap(7);
  104.  
  105.     /**
  106.      * Antialiasing hint key
  107.      */
  108.     public static final Key KEY_ANTIALIASING =
  109.     SunHints.KEY_ANTIALIASING;
  110.  
  111.     /**
  112.      * Antialiasing hint values -- rendering is done with antialiasing
  113.      */
  114.     public static final Object VALUE_ANTIALIAS_ON =
  115.     SunHints.VALUE_ANTIALIAS_ON;
  116.  
  117.     /**
  118.      * Antialiasing hint values -- rendering is done without antialiasing
  119.      */
  120.     public static final Object VALUE_ANTIALIAS_OFF =
  121.     SunHints.VALUE_ANTIALIAS_OFF;
  122.  
  123.     /**
  124.      * Antialiasing hint values -- rendering is done with the platform
  125.      * default antialiasing mode.
  126.      */
  127.     public static final Object VALUE_ANTIALIAS_DEFAULT =
  128.      SunHints.VALUE_ANTIALIAS_DEFAULT;
  129.  
  130.     /**
  131.      * Rendering hint key
  132.      */
  133.     public static final Key KEY_RENDERING =
  134.      SunHints.KEY_RENDERING;
  135.  
  136.     /**
  137.      * Rendering hint values -- Appropriate rendering algorithms are chosen
  138.      * with a preference for output speed.
  139.      */
  140.     public static final Object VALUE_RENDER_SPEED =
  141.      SunHints.VALUE_RENDER_SPEED;
  142.  
  143.     /**
  144.      * Rendering hint values -- Appropriate rendering algorithms are chosen
  145.      * with a preference for output quality.
  146.      */
  147.     public static final Object VALUE_RENDER_QUALITY =
  148.      SunHints.VALUE_RENDER_QUALITY;
  149.  
  150.     /**
  151.      * Rendering hint values -- The platform default rendering algorithms
  152.      * are chosen.
  153.      */
  154.     public static final Object VALUE_RENDER_DEFAULT =
  155.      SunHints.VALUE_RENDER_DEFAULT;
  156.  
  157.  
  158.     /**
  159.      * Dithering hint key
  160.      */
  161.     public static final Key KEY_DITHERING =
  162.      SunHints.KEY_DITHERING;
  163.  
  164.     /**
  165.      * Dithering hint values -- do not dither when rendering
  166.      */
  167.     public static final Object VALUE_DITHER_DISABLE =
  168.      SunHints.VALUE_DITHER_DISABLE;
  169.  
  170.     /**
  171.      * Dithering hint values -- dither when rendering, if needed
  172.      */
  173.     public static final Object VALUE_DITHER_ENABLE =
  174.      SunHints.VALUE_DITHER_ENABLE;
  175.  
  176.     /**
  177.      * Dithering hint values -- use the platform default for dithering
  178.      */
  179.     public static final Object VALUE_DITHER_DEFAULT =
  180.      SunHints.VALUE_DITHER_DEFAULT;
  181.  
  182.     /**
  183.      * Text antialiasing hint key
  184.      */
  185.     public static final Key KEY_TEXT_ANTIALIASING =
  186.      SunHints.KEY_TEXT_ANTIALIASING;
  187.  
  188.     /**
  189.      * Text antialiasing hint value -- text rendering is done with
  190.      * antialiasing
  191.      */
  192.     public static final Object VALUE_TEXT_ANTIALIAS_ON =
  193.      SunHints.VALUE_TEXT_ANTIALIAS_ON;
  194.  
  195.     /**
  196.      * Text antialiasing hint value -- text rendering is done without
  197.      * antialiasing
  198.      */
  199.     public static final Object VALUE_TEXT_ANTIALIAS_OFF =
  200.      SunHints.VALUE_TEXT_ANTIALIAS_OFF;
  201.  
  202.     /**
  203.      * Text antialiasing hint value -- text rendering is done using the
  204.      * platform default text antialiasing mode.
  205.      */
  206.     public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT =
  207.      SunHints.VALUE_TEXT_ANTIALIAS_DEFAULT;
  208.  
  209.     /**
  210.      * Font fractional metrics hint key
  211.      */
  212.     public static final Key KEY_FRACTIONALMETRICS =
  213.      SunHints.KEY_FRACTIONALMETRICS;
  214.  
  215.     /**
  216.      * Font fractional metrics hint values -- fractional metrics disabled
  217.      */
  218.     public static final Object VALUE_FRACTIONALMETRICS_OFF =
  219.      SunHints.VALUE_FRACTIONALMETRICS_OFF;
  220.  
  221.     /**
  222.      * Font fractional metrics hint values -- fractional metrics enabled
  223.      */
  224.     public static final Object VALUE_FRACTIONALMETRICS_ON =
  225.      SunHints.VALUE_FRACTIONALMETRICS_ON;
  226.  
  227.     /**
  228.      * Font fractional metrics hint values -- use the platform default for
  229.      * fractional metrics
  230.      */
  231.     public static final Object VALUE_FRACTIONALMETRICS_DEFAULT =
  232.      SunHints.VALUE_FRACTIONALMETRICS_DEFAULT;
  233.  
  234.  
  235.     /**
  236.      * Interpolation hint key
  237.      */
  238.     public static final Key KEY_INTERPOLATION =
  239.      SunHints.KEY_INTERPOLATION;
  240.  
  241.     /**
  242.      * Interpolation hint value -- INTERPOLATION_NEAREST_NEIGHBOR
  243.      */
  244.     public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR =
  245.      SunHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
  246.  
  247.     /**
  248.      * Interpolation hint value -- INTERPOLATION_BILINEAR
  249.      */
  250.     public static final Object VALUE_INTERPOLATION_BILINEAR =
  251.      SunHints.VALUE_INTERPOLATION_BILINEAR;
  252.  
  253.     /**
  254.      * Interpolation hint value -- INTERPOLATION_BICUBIC
  255.      */
  256.     public static final Object VALUE_INTERPOLATION_BICUBIC =
  257.      SunHints.VALUE_INTERPOLATION_BICUBIC;
  258.  
  259.     /**
  260.      * Alpha interpolation hint key
  261.      */
  262.     public static final Key KEY_ALPHA_INTERPOLATION =
  263.      SunHints.KEY_ALPHA_INTERPOLATION;
  264.  
  265.     /**
  266.      * Alpha interpolation hint value -- ALPHA_INTERPOLATION_SPEED
  267.      */
  268.     public static final Object VALUE_ALPHA_INTERPOLATION_SPEED =
  269.      SunHints.VALUE_ALPHA_INTERPOLATION_SPEED;
  270.  
  271.     /**
  272.      * Alpha interpolation hint value -- ALPHA_INTERPOLATION_QUALITY
  273.      */
  274.     public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY =
  275.      SunHints.VALUE_ALPHA_INTERPOLATION_QUALITY;
  276.  
  277.     /**
  278.      * Alpha interpolation hint value -- ALPHA_INTERPOLATION_DEFAULT
  279.      */
  280.     public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT =
  281.      SunHints.VALUE_ALPHA_INTERPOLATION_DEFAULT;
  282.  
  283.     /**
  284.      * Color rendering hint key
  285.      */
  286.     public static final Key KEY_COLOR_RENDERING =
  287.      SunHints.KEY_COLOR_RENDERING;
  288.  
  289.     /**
  290.      * Color rendering hint value -- COLOR_RENDER_SPEED
  291.      */
  292.     public static final Object VALUE_COLOR_RENDER_SPEED =
  293.      SunHints.VALUE_COLOR_RENDER_SPEED;
  294.  
  295.     /**
  296.      * Color rendering hint value -- COLOR_RENDER_QUALITY
  297.      */
  298.     public static final Object VALUE_COLOR_RENDER_QUALITY =
  299.      SunHints.VALUE_COLOR_RENDER_QUALITY;
  300.  
  301.     /**
  302.      * Color rendering hint value -- COLOR_RENDER_DEFAULT
  303.      */
  304.     public static final Object VALUE_COLOR_RENDER_DEFAULT =
  305.      SunHints.VALUE_COLOR_RENDER_DEFAULT;
  306.  
  307.  
  308.     /**
  309.      * Constructs a new object with keys and values initialized
  310.      * from the specified Map object (which may be null).
  311.      * @param init a map of key/value pairs to initialize the hints
  312.      *        or null if the object should be empty
  313.      */
  314.     public RenderingHints(Map init) {
  315.     if (init != null) {
  316.         hintmap.putAll(init);
  317.     }
  318.     }
  319.  
  320.     /**
  321.      * Constructs a new object with the specified key/value pair.
  322.      * @param key the key of the particular hint property
  323.      * @param value the value of the hint property specified with 
  324.      * <code>key</code>
  325.      */
  326.     public RenderingHints(Key key, Object value) {
  327.     hintmap.put(key, value);
  328.     }
  329.  
  330.     /**
  331.      * Returns the number of key-value mappings in this 
  332.      * <code>RenderingHints</code>.
  333.      *
  334.      * @return the number of key-value mappings in this 
  335.      * <code>RenderingHints</code>.
  336.      */
  337.     public int size() {
  338.     return hintmap.size();
  339.     }
  340.  
  341.     /**
  342.      * Returns <code>true</code> if this 
  343.      * <code>RenderingHints</code> contains no key-value mappings.
  344.      *
  345.      * @return <code>true</code> if this 
  346.      * <code>RenderingHints</code> contains no key-value mappings.
  347.      */
  348.     public boolean isEmpty() {
  349.     return hintmap.isEmpty();
  350.     }
  351.  
  352.     /**
  353.      * Returns <code>true</code> if this <code>RenderingHints</code>
  354.      *  contains a mapping for the specified key.
  355.      *
  356.      * @param key key whose presence in this 
  357.      * <code>RenderingHints</code> is to be tested.
  358.      * @return <code>true</code> if this <code>RenderingHints</code> 
  359.      *         contains a mapping for the specified key.
  360.      * @exception <code>ClassCastException</code> key is not 
  361.      * of type <code>RenderingHints.Key</code>
  362.      * @exception <code>NullPointerException</code>
  363.      *  key is <code>null</code>
  364.      */
  365.     public boolean containsKey(Object key) {
  366.     return hintmap.containsKey((Key) key);
  367.     }
  368.  
  369.     /**
  370.      * Returns true if this RenderingHints maps one or more keys to the
  371.      * specified value.
  372.      * More formally, returns <code>true</code> if and only 
  373.      * if this <code>RenderingHints</code>
  374.      * contains at least one mapping to a value <code>v</code> such that
  375.      * <pre>
  376.      * (value==null ? v==null : value.equals(v))
  377.      * </pre>.
  378.      * This operation will probably require time linear in the
  379.      * <code>RenderingHints</code> size for most implementations 
  380.      * of <code>RenderingHints</code>.
  381.      *
  382.      * @param value value whose presence in this 
  383.      *        <code>RenderingHints</code> is to be tested.
  384.      * @return <code>true</code> if this <code>RenderingHints</code>
  385.      *         maps one or more keys to the specified value.
  386.      */
  387.     public boolean containsValue(Object value) {
  388.     return hintmap.containsValue(value);
  389.     }
  390.  
  391.     /**
  392.      * Returns the value to which the specified key is mapped.
  393.      * @param   key   a rendering hint key
  394.      * @return  the value to which the key is mapped in this object or 
  395.      *          <code>null</code> if the key is not mapped to any value in
  396.      *          this object.
  397.      * @exception <code>ClassCastException</code> key is not of 
  398.      *        type <code>RenderingHints.Key</code>.
  399.      * @see     #put(Object, Object)
  400.      */
  401.     public Object get(Object key) {
  402.     return hintmap.get((Key) key);
  403.     }
  404.  
  405.     /**
  406.      * Maps the specified <code>key</code> to the specified
  407.      * <code>value</code> in this <code>RenderingHints</code> object.
  408.      * Neither the key nor the value can be <code>null</code>.
  409.      * The value can be retrieved by calling the <code>get</code> method
  410.      * with a key that is equal to the original key.
  411.      * @param      key     the rendering hint key.
  412.      * @param      value   the rendering hint value.
  413.      * @return     the previous value of the specified key in this object
  414.      *             or <code>null</code> if it did not have one.
  415.      * @exception  <code>NullPointerException</code>  if the key or value is
  416.      *               <code>null</code>.
  417.      * @exception <code>ClassCastException</code> key is not of 
  418.      *        type <code>RenderingHints.Key</code>.
  419.      * @exception <code>IllegalArgumentException</code> value is not 
  420.      *            appropriate for the specified key.
  421.      * @see     #get(Object)
  422.      */
  423.     public Object put(Object key, Object value) {
  424.     if (!((Key) key).isCompatibleValue(value)) {
  425.         throw new IllegalArgumentException(value+
  426.                            " incompatible with "+
  427.                            key);
  428.     }
  429.         return hintmap.put((Key) key, value);
  430.     }
  431.  
  432.     /**
  433.      * Adds all of the keys and corresponding values from the specified
  434.      * <code>RenderingHints</code> object to this
  435.      * <code>RenderingHints</code> object. Keys that are present in
  436.      * this <code>RenderingHints</code> object, but not in the specified
  437.      * <code>RenderingHints</code> object are not affected.
  438.      * @param hints the set of key/value pairs to be added to this 
  439.      * <code>RenderingHints</code> object
  440.      */
  441.     public void add(RenderingHints hints) {
  442.     hintmap.putAll(hints.hintmap);
  443.     }
  444.  
  445.     /**
  446.      * Clears this <code>RenderingHints</code> object of all key/value
  447.      * pairs.
  448.      */
  449.     public void clear() {
  450.     hintmap.clear();
  451.     }
  452.  
  453.     /**
  454.      * Removes the key and its corresponding value from this
  455.      * <code>RenderingHints</code> object. This method does nothing if the
  456.      * key is not in this <code>RenderingHints</code> object.
  457.      * @param   key   the rendering hints key that needs to be removed
  458.      * @exception <code>ClassCastException</code> key is not of 
  459.      *        type <code>RenderingHints.Key</code>.
  460.      * @return  the value to which the key had previously been mapped in this 
  461.      *        <code>RenderingHints</code> object, or <code>null</code>
  462.      *         if the key did not have a mapping.
  463.      */
  464.     public Object remove(Object key) {
  465.     return hintmap.remove((Key) key);
  466.     }
  467.  
  468.     /**
  469.      * Copies all of the mappings from the specified <code>Map</code>
  470.      * to this <code>RenderingHints</code>.  These mappings replace 
  471.      * any mappings that this <code>RenderingHints</code> had for any 
  472.      * of the keys currently in the specified <code>Map</code>.
  473.      *
  474.      * @param t mappings to be stored in this <code>RenderingHints</code>.
  475.      * @exception <code>ClassCastException</code> class of a key or value 
  476.      *        in the specified <code>Map</code> prevents it from being 
  477.      *        stored in this <code>RenderingHints</code>.
  478.      * @exception <code>IllegalArgumentException</code> some aspect 
  479.      *        of a key or value in the specified <code>Map</code>
  480.      *         prevents it from being stored in
  481.      *           this <code>RenderingHints</code>.
  482.      */
  483.     public void putAll(Map m) {
  484.     if (m instanceof RenderingHints) {
  485.         hintmap.putAll(((RenderingHints) m).hintmap);
  486.     } else {
  487.         // Funnel each key/value pair through our protected put method
  488.         Iterator iter = m.entrySet().iterator();
  489.         while (iter.hasNext()) {
  490.         Map.Entry entry = (Map.Entry) iter.next();
  491.         put(entry.getKey(), entry.getValue());
  492.         }
  493.     }
  494.     }
  495.  
  496.     /**
  497.      * Returns a <code>Set</code> view of the Keys contained in this 
  498.      * <code>RenderingHints</code>.  The Set is backed by the 
  499.      * <code>RenderingHints</code>, so changes to the
  500.      * <code>RenderingHints</code> are reflected in the <code>Set</code>, 
  501.      * and vice-versa.  If the <code>RenderingHints</code> is modified 
  502.      * while an iteration over the <code>Set</code> is in progress, 
  503.      * the results of the iteration are undefined.  The <code>Set</code>
  504.      * supports element removal, which removes the corresponding
  505.      * mapping from the <code>RenderingHints</code>, via the 
  506.      * <code>Iterator.remove</code>, <code>Set.remove</code>,
  507.      * <code>removeAll</code> <code>retainAll</code>, and 
  508.      * <code>clear</code> operations.  It does not support
  509.      * the <code>add</code> or <code>addAll</code> operations.
  510.      *
  511.      * @return a <code>Set</code> view of the keys contained 
  512.      * in this <code>RenderingHints</code>.
  513.      */
  514.     public Set keySet() {
  515.     return hintmap.keySet();
  516.     }
  517.  
  518.     /**
  519.      * Returns a <code>Collection</code> view of the values 
  520.      * contained in this <code>RenderinHints</code>.
  521.      * The <code>Collection</code> is backed by the 
  522.      * <code>RenderingHints</code>, so changes to
  523.      * the <code>RenderingHints</code> are reflected in 
  524.      * the <code>Collection</code>, and vice-versa.
  525.      * If the <code>RenderingHints</code> is modified while 
  526.      * an iteration over the <code>Collection</code> is 
  527.      * in progress, the results of the iteration are undefined.
  528.      * The <code>Collection</code> supports element removal, 
  529.      * which removes the corresponding mapping from the 
  530.      * <code>RenderingHints</code>, via the
  531.      * <code>Iterator.remove</code>, 
  532.      * <code>Collection.remove</code>, <code>removeAll</code>, 
  533.      * <code>retainAll</code> and <code>clear</code> operations.  
  534.      * It does not support the <code>add</code> or 
  535.      * <code>addAll</code> operations.
  536.      *
  537.      * @return a <code>Collection</code> view of the values 
  538.      *        contained in this <code>RenderingHints</code>.
  539.      */
  540.     public Collection values() {
  541.     return hintmap.values();
  542.     }
  543.  
  544.     /**
  545.      * Returns a <code>Set</code> view of the mappings contained 
  546.      * in this <code>RenderingHints</code>.  Each element in the 
  547.      * returned <code>Set</code> is a <code>Map.Entry</code>.  
  548.      * The <code>Set</code> is backed by the <code>RenderingHints</code>, 
  549.      * so changes to the <code>RenderingHints</code> are reflected
  550.      * in the <code>Set</code>, and vice-versa.  If the 
  551.      * <code>RenderingHints</code> is modified while
  552.      * while an iteration over the <code>Set</code> is in progress, 
  553.      * the results of the iteration are undefined.
  554.      * <p>
  555.      * The entrySet returned from a <code>RenderingHints</code> object 
  556.      * is not modifiable.
  557.      *
  558.      * @return a <code>Set</code> view of the mappings contained in 
  559.      * this <code>RenderingHints</code>.
  560.      */
  561.     public Set entrySet() {
  562.     return Collections.unmodifiableMap(hintmap).entrySet();
  563.     }
  564.  
  565.     /**
  566.      * Compares the specified <code>Object</code> with this 
  567.      * <code>RenderingHints</code> for equality.
  568.      * Returns <code>true</code> if the specified object is also a 
  569.      * <code>Map</code> and the two <code>Map</code> objects represent 
  570.      * the same mappings.  More formally, two <code>Map</code> objects 
  571.      * <code>t1</code> and <code>t2</code> represent the same mappings
  572.      * if <code>t1.keySet().equals(t2.keySet())</code> and for every
  573.      * key <code>k</code> in <code>t1.keySet()</code>, 
  574.      * <pre>
  575.      * (t1.get(k)==null ? t2.get(k)==null : t1.get(k).equals(t2.get(k)))
  576.      * </pre>.  
  577.      * This ensures that the <code>equals</code> method works properly across
  578.      * different implementations of the <code>Map</code> interface.
  579.      *
  580.      * @param o <code>Object</code> to be compared for equality with 
  581.      * this <code>RenderingHints</code>.
  582.      * @return <code>true</code> if the specified <code>Object</code> 
  583.      * is equal to this <code>RenderingHints</code>.
  584.      */
  585.     public boolean equals(Object o) {
  586.     if (o instanceof RenderingHints) {
  587.         return hintmap.equals(((RenderingHints) o).hintmap);
  588.     } else if (o instanceof Map) {
  589.         return hintmap.equals(o);
  590.     }
  591.     return false;
  592.     }
  593.  
  594.     /**
  595.      * Returns the hash code value for this <code>RenderingHints</code>.  
  596.      * The hash code of a <code>RenderingHints</code> is defined to be 
  597.      * the sum of the hashCodes of each <code>Entry</code> in the 
  598.      * <code>RenderingHints</code> object's entrySet view.  This ensures that
  599.      * <code>t1.equals(t2)</code> implies that
  600.      * <code>t1.hashCode()==t2.hashCode()</code> for any two <code>Map</code>
  601.      * objects <code>t1</code> and <code>t2</code>, as required by the general
  602.      * contract of <code>Object.hashCode</code>.
  603.      *
  604.      * @return the hash code value for this <code>RenderingHints</code>.
  605.      * @see java.util.Map.Entry#hashCode()
  606.      * @see Object#hashCode()
  607.      * @see Object#equals(Object)
  608.      * @see #equals(Object)
  609.      */
  610.     public int hashCode() {
  611.     return hintmap.hashCode();
  612.     }
  613.  
  614.     /**
  615.      * Creates a clone of this <code>RenderingHints</code> object
  616.      * that has the same contents as this <code>RenderingHints</code>
  617.      * object.
  618.      * @return a clone of this instance.
  619.      */
  620.     public Object clone() {
  621.         RenderingHints rh;
  622.         try {
  623.             rh = (RenderingHints) super.clone();
  624.         if (hintmap != null) {
  625.         rh.hintmap = (HashMap) hintmap.clone();
  626.         }
  627.         } catch (CloneNotSupportedException e) {
  628.         // this shouldn't happen, since we are Cloneable
  629.         throw new InternalError();
  630.     }
  631.  
  632.         return rh;
  633.     }
  634.  
  635.     /**
  636.      * Returns a rather long string representation of the hashmap
  637.      * which contains the mappings of keys to values for this
  638.      * <code>RenderingHints</code> object.
  639.      * @return  a string representation of this object.
  640.      */
  641.     public String toString() {
  642.         if (hintmap == null) {
  643.             return getClass().getName() + "@" +
  644.                 Integer.toHexString(hashCode()) +
  645.                 " (0 hints)";
  646.         }
  647.  
  648.         return hintmap.toString();
  649.     }
  650. }
  651.