View Javadoc
1   /*
2    * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.awt.image;
27  
28  import java.awt.Image;
29  import java.awt.image.ImageFilter;
30  import java.awt.image.ImageConsumer;
31  import java.awt.image.ImageProducer;
32  import java.util.Hashtable;
33  import java.awt.image.ColorModel;
34  
35  /**
36   * This class is an implementation of the ImageProducer interface which
37   * takes an existing image and a filter object and uses them to produce
38   * image data for a new filtered version of the original image.
39   * Here is an example which filters an image by swapping the red and
40   * blue compents:
41   * <pre>
42   *
43   *      Image src = getImage("doc:///demo/images/duke/T1.gif");
44   *      ImageFilter colorfilter = new RedBlueSwapFilter();
45   *      Image img = createImage(new FilteredImageSource(src.getSource(),
46   *                                                      colorfilter));
47   *
48   * </pre>
49   *
50   * @see ImageProducer
51   *
52   * @author      Jim Graham
53   */
54  public class FilteredImageSource implements ImageProducer {
55      ImageProducer src;
56      ImageFilter filter;
57  
58      /**
59       * Constructs an ImageProducer object from an existing ImageProducer
60       * and a filter object.
61       * @param orig the specified <code>ImageProducer</code>
62       * @param imgf the specified <code>ImageFilter</code>
63       * @see ImageFilter
64       * @see java.awt.Component#createImage
65       */
66      public FilteredImageSource(ImageProducer orig, ImageFilter imgf) {
67          src = orig;
68          filter = imgf;
69      }
70  
71      private Hashtable proxies;
72  
73      /**
74       * Adds the specified <code>ImageConsumer</code>
75       * to the list of consumers interested in data for the filtered image.
76       * An instance of the original <code>ImageFilter</code>
77       * is created
78       * (using the filter's <code>getFilterInstance</code> method)
79       * to manipulate the image data
80       * for the specified <code>ImageConsumer</code>.
81       * The newly created filter instance
82       * is then passed to the <code>addConsumer</code> method
83       * of the original <code>ImageProducer</code>.
84       *
85       * <p>
86       * This method is public as a side effect
87       * of this class implementing
88       * the <code>ImageProducer</code> interface.
89       * It should not be called from user code,
90       * and its behavior if called from user code is unspecified.
91       *
92       * @param ic  the consumer for the filtered image
93       * @see ImageConsumer
94       */
95      public synchronized void addConsumer(ImageConsumer ic) {
96          if (proxies == null) {
97              proxies = new Hashtable();
98          }
99          if (!proxies.containsKey(ic)) {
100             ImageFilter imgf = filter.getFilterInstance(ic);
101             proxies.put(ic, imgf);
102             src.addConsumer(imgf);
103         }
104     }
105 
106     /**
107      * Determines whether an ImageConsumer is on the list of consumers
108      * currently interested in data for this image.
109      *
110      * <p>
111      * This method is public as a side effect
112      * of this class implementing
113      * the <code>ImageProducer</code> interface.
114      * It should not be called from user code,
115      * and its behavior if called from user code is unspecified.
116      *
117      * @param ic the specified <code>ImageConsumer</code>
118      * @return true if the ImageConsumer is on the list; false otherwise
119      * @see ImageConsumer
120      */
121     public synchronized boolean isConsumer(ImageConsumer ic) {
122         return (proxies != null && proxies.containsKey(ic));
123     }
124 
125     /**
126      * Removes an ImageConsumer from the list of consumers interested in
127      * data for this image.
128      *
129      * <p>
130      * This method is public as a side effect
131      * of this class implementing
132      * the <code>ImageProducer</code> interface.
133      * It should not be called from user code,
134      * and its behavior if called from user code is unspecified.
135      *
136      * @see ImageConsumer
137      */
138     public synchronized void removeConsumer(ImageConsumer ic) {
139         if (proxies != null) {
140             ImageFilter imgf = (ImageFilter) proxies.get(ic);
141             if (imgf != null) {
142                 src.removeConsumer(imgf);
143                 proxies.remove(ic);
144                 if (proxies.isEmpty()) {
145                     proxies = null;
146                 }
147             }
148         }
149     }
150 
151     /**
152      * Starts production of the filtered image.
153      * If the specified <code>ImageConsumer</code>
154      * isn't already a consumer of the filtered image,
155      * an instance of the original <code>ImageFilter</code>
156      * is created
157      * (using the filter's <code>getFilterInstance</code> method)
158      * to manipulate the image data
159      * for the <code>ImageConsumer</code>.
160      * The filter instance for the <code>ImageConsumer</code>
161      * is then passed to the <code>startProduction</code> method
162      * of the original <code>ImageProducer</code>.
163      *
164      * <p>
165      * This method is public as a side effect
166      * of this class implementing
167      * the <code>ImageProducer</code> interface.
168      * It should not be called from user code,
169      * and its behavior if called from user code is unspecified.
170      *
171      * @param ic  the consumer for the filtered image
172      * @see ImageConsumer
173      */
174     public void startProduction(ImageConsumer ic) {
175         if (proxies == null) {
176             proxies = new Hashtable();
177         }
178         ImageFilter imgf = (ImageFilter) proxies.get(ic);
179         if (imgf == null) {
180             imgf = filter.getFilterInstance(ic);
181             proxies.put(ic, imgf);
182         }
183         src.startProduction(imgf);
184     }
185 
186     /**
187      * Requests that a given ImageConsumer have the image data delivered
188      * one more time in top-down, left-right order.  The request is
189      * handed to the ImageFilter for further processing, since the
190      * ability to preserve the pixel ordering depends on the filter.
191      *
192      * <p>
193      * This method is public as a side effect
194      * of this class implementing
195      * the <code>ImageProducer</code> interface.
196      * It should not be called from user code,
197      * and its behavior if called from user code is unspecified.
198      *
199      * @see ImageConsumer
200      */
201     public void requestTopDownLeftRightResend(ImageConsumer ic) {
202         if (proxies != null) {
203             ImageFilter imgf = (ImageFilter) proxies.get(ic);
204             if (imgf != null) {
205                 imgf.resendTopDownLeftRight(src);
206             }
207         }
208     }
209 }