View Javadoc
1   /*
2    * Copyright (c) 1997, 2013, 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;
27  
28  import java.awt.geom.AffineTransform;
29  import java.awt.image.BufferedImage;
30  import java.awt.image.ColorModel;
31  import java.awt.image.VolatileImage;
32  import java.awt.image.WritableRaster;
33  
34  import sun.awt.image.SunVolatileImage;
35  
36  /**
37   * The <code>GraphicsConfiguration</code> class describes the
38   * characteristics of a graphics destination such as a printer or monitor.
39   * There can be many <code>GraphicsConfiguration</code> objects associated
40   * with a single graphics device, representing different drawing modes or
41   * capabilities.  The corresponding native structure will vary from platform
42   * to platform.  For example, on X11 windowing systems,
43   * each visual is a different <code>GraphicsConfiguration</code>.
44   * On Microsoft Windows, <code>GraphicsConfiguration</code>s represent
45   * PixelFormats available in the current resolution and color depth.
46   * <p>
47   * In a virtual device multi-screen environment in which the desktop
48   * area could span multiple physical screen devices, the bounds of the
49   * <code>GraphicsConfiguration</code> objects are relative to the
50   * virtual coordinate system.  When setting the location of a
51   * component, use {@link #getBounds() getBounds} to get the bounds of
52   * the desired <code>GraphicsConfiguration</code> and offset the location
53   * with the coordinates of the <code>GraphicsConfiguration</code>,
54   * as the following code sample illustrates:
55   * </p>
56   *
57   * <pre>
58   *      Frame f = new Frame(gc);  // where gc is a GraphicsConfiguration
59   *      Rectangle bounds = gc.getBounds();
60   *      f.setLocation(10 + bounds.x, 10 + bounds.y); </pre>
61   *
62   * <p>
63   * To determine if your environment is a virtual device
64   * environment, call <code>getBounds</code> on all of the
65   * <code>GraphicsConfiguration</code> objects in your system.  If
66   * any of the origins of the returned bounds is not (0,&nbsp;0),
67   * your environment is a virtual device environment.
68   *
69   * <p>
70   * You can also use <code>getBounds</code> to determine the bounds
71   * of the virtual device.  To do this, first call <code>getBounds</code> on all
72   * of the <code>GraphicsConfiguration</code> objects in your
73   * system.  Then calculate the union of all of the bounds returned
74   * from the calls to <code>getBounds</code>.  The union is the
75   * bounds of the virtual device.  The following code sample
76   * calculates the bounds of the virtual device.
77   *
78   * <pre>{@code
79   *      Rectangle virtualBounds = new Rectangle();
80   *      GraphicsEnvironment ge = GraphicsEnvironment.
81   *              getLocalGraphicsEnvironment();
82   *      GraphicsDevice[] gs =
83   *              ge.getScreenDevices();
84   *      for (int j = 0; j < gs.length; j++) {
85   *          GraphicsDevice gd = gs[j];
86   *          GraphicsConfiguration[] gc =
87   *              gd.getConfigurations();
88   *          for (int i=0; i < gc.length; i++) {
89   *              virtualBounds =
90   *                  virtualBounds.union(gc[i].getBounds());
91   *          }
92   *      } }</pre>
93   *
94   * @see Window
95   * @see Frame
96   * @see GraphicsEnvironment
97   * @see GraphicsDevice
98   */
99  /*
100  * REMIND:  What to do about capabilities?
101  * The
102  * capabilities of the device can be determined by enumerating the possible
103  * capabilities and checking if the GraphicsConfiguration
104  * implements the interface for that capability.
105  *
106  */
107 
108 
109 public abstract class GraphicsConfiguration {
110 
111     private static BufferCapabilities defaultBufferCaps;
112     private static ImageCapabilities defaultImageCaps;
113 
114     /**
115      * This is an abstract class that cannot be instantiated directly.
116      * Instances must be obtained from a suitable factory or query method.
117      *
118      * @see GraphicsDevice#getConfigurations
119      * @see GraphicsDevice#getDefaultConfiguration
120      * @see GraphicsDevice#getBestConfiguration
121      * @see Graphics2D#getDeviceConfiguration
122      */
123     protected GraphicsConfiguration() {
124     }
125 
126     /**
127      * Returns the {@link GraphicsDevice} associated with this
128      * <code>GraphicsConfiguration</code>.
129      * @return a <code>GraphicsDevice</code> object that is
130      * associated with this <code>GraphicsConfiguration</code>.
131      */
132     public abstract GraphicsDevice getDevice();
133 
134     /**
135      * Returns a {@link BufferedImage} with a data layout and color model
136      * compatible with this <code>GraphicsConfiguration</code>.  This
137      * method has nothing to do with memory-mapping
138      * a device.  The returned <code>BufferedImage</code> has
139      * a layout and color model that is closest to this native device
140      * configuration and can therefore be optimally blitted to this
141      * device.
142      * @param width the width of the returned <code>BufferedImage</code>
143      * @param height the height of the returned <code>BufferedImage</code>
144      * @return a <code>BufferedImage</code> whose data layout and color
145      * model is compatible with this <code>GraphicsConfiguration</code>.
146      */
147     public BufferedImage createCompatibleImage(int width, int height) {
148         ColorModel model = getColorModel();
149         WritableRaster raster =
150             model.createCompatibleWritableRaster(width, height);
151         return new BufferedImage(model, raster,
152                                  model.isAlphaPremultiplied(), null);
153     }
154 
155     /**
156      * Returns a <code>BufferedImage</code> that supports the specified
157      * transparency and has a data layout and color model
158      * compatible with this <code>GraphicsConfiguration</code>.  This
159      * method has nothing to do with memory-mapping
160      * a device. The returned <code>BufferedImage</code> has a layout and
161      * color model that can be optimally blitted to a device
162      * with this <code>GraphicsConfiguration</code>.
163      * @param width the width of the returned <code>BufferedImage</code>
164      * @param height the height of the returned <code>BufferedImage</code>
165      * @param transparency the specified transparency mode
166      * @return a <code>BufferedImage</code> whose data layout and color
167      * model is compatible with this <code>GraphicsConfiguration</code>
168      * and also supports the specified transparency.
169      * @throws IllegalArgumentException if the transparency is not a valid value
170      * @see Transparency#OPAQUE
171      * @see Transparency#BITMASK
172      * @see Transparency#TRANSLUCENT
173      */
174     public BufferedImage createCompatibleImage(int width, int height,
175                                                int transparency)
176     {
177         if (getColorModel().getTransparency() == transparency) {
178             return createCompatibleImage(width, height);
179         }
180 
181         ColorModel cm = getColorModel(transparency);
182         if (cm == null) {
183             throw new IllegalArgumentException("Unknown transparency: " +
184                                                transparency);
185         }
186         WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
187         return new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
188     }
189 
190 
191     /**
192      * Returns a {@link VolatileImage} with a data layout and color model
193      * compatible with this <code>GraphicsConfiguration</code>.
194      * The returned <code>VolatileImage</code>
195      * may have data that is stored optimally for the underlying graphics
196      * device and may therefore benefit from platform-specific rendering
197      * acceleration.
198      * @param width the width of the returned <code>VolatileImage</code>
199      * @param height the height of the returned <code>VolatileImage</code>
200      * @return a <code>VolatileImage</code> whose data layout and color
201      * model is compatible with this <code>GraphicsConfiguration</code>.
202      * @see Component#createVolatileImage(int, int)
203      * @since 1.4
204      */
205     public VolatileImage createCompatibleVolatileImage(int width, int height) {
206         VolatileImage vi = null;
207         try {
208             vi = createCompatibleVolatileImage(width, height,
209                                                null, Transparency.OPAQUE);
210         } catch (AWTException e) {
211             // shouldn't happen: we're passing in null caps
212             assert false;
213         }
214         return vi;
215     }
216 
217     /**
218      * Returns a {@link VolatileImage} with a data layout and color model
219      * compatible with this <code>GraphicsConfiguration</code>.
220      * The returned <code>VolatileImage</code>
221      * may have data that is stored optimally for the underlying graphics
222      * device and may therefore benefit from platform-specific rendering
223      * acceleration.
224      * @param width the width of the returned <code>VolatileImage</code>
225      * @param height the height of the returned <code>VolatileImage</code>
226      * @param transparency the specified transparency mode
227      * @return a <code>VolatileImage</code> whose data layout and color
228      * model is compatible with this <code>GraphicsConfiguration</code>.
229      * @throws IllegalArgumentException if the transparency is not a valid value
230      * @see Transparency#OPAQUE
231      * @see Transparency#BITMASK
232      * @see Transparency#TRANSLUCENT
233      * @see Component#createVolatileImage(int, int)
234      * @since 1.5
235      */
236     public VolatileImage createCompatibleVolatileImage(int width, int height,
237                                                        int transparency)
238     {
239         VolatileImage vi = null;
240         try {
241             vi = createCompatibleVolatileImage(width, height, null, transparency);
242         } catch (AWTException e) {
243             // shouldn't happen: we're passing in null caps
244             assert false;
245         }
246         return vi;
247     }
248 
249     /**
250      * Returns a {@link VolatileImage} with a data layout and color model
251      * compatible with this <code>GraphicsConfiguration</code>, using
252      * the specified image capabilities.
253      * If the <code>caps</code> parameter is null, it is effectively ignored
254      * and this method will create a VolatileImage without regard to
255      * <code>ImageCapabilities</code> constraints.
256      *
257      * The returned <code>VolatileImage</code> has
258      * a layout and color model that is closest to this native device
259      * configuration and can therefore be optimally blitted to this
260      * device.
261      * @return a <code>VolatileImage</code> whose data layout and color
262      * model is compatible with this <code>GraphicsConfiguration</code>.
263      * @param width the width of the returned <code>VolatileImage</code>
264      * @param height the height of the returned <code>VolatileImage</code>
265      * @param caps the image capabilities
266      * @exception AWTException if the supplied image capabilities could not
267      * be met by this graphics configuration
268      * @since 1.4
269      */
270     public VolatileImage createCompatibleVolatileImage(int width, int height,
271         ImageCapabilities caps) throws AWTException
272     {
273         return createCompatibleVolatileImage(width, height, caps,
274                                              Transparency.OPAQUE);
275     }
276 
277     /**
278      * Returns a {@link VolatileImage} with a data layout and color model
279      * compatible with this <code>GraphicsConfiguration</code>, using
280      * the specified image capabilities and transparency value.
281      * If the <code>caps</code> parameter is null, it is effectively ignored
282      * and this method will create a VolatileImage without regard to
283      * <code>ImageCapabilities</code> constraints.
284      *
285      * The returned <code>VolatileImage</code> has
286      * a layout and color model that is closest to this native device
287      * configuration and can therefore be optimally blitted to this
288      * device.
289      * @param width the width of the returned <code>VolatileImage</code>
290      * @param height the height of the returned <code>VolatileImage</code>
291      * @param caps the image capabilities
292      * @param transparency the specified transparency mode
293      * @return a <code>VolatileImage</code> whose data layout and color
294      * model is compatible with this <code>GraphicsConfiguration</code>.
295      * @see Transparency#OPAQUE
296      * @see Transparency#BITMASK
297      * @see Transparency#TRANSLUCENT
298      * @throws IllegalArgumentException if the transparency is not a valid value
299      * @exception AWTException if the supplied image capabilities could not
300      * be met by this graphics configuration
301      * @see Component#createVolatileImage(int, int)
302      * @since 1.5
303      */
304     public VolatileImage createCompatibleVolatileImage(int width, int height,
305         ImageCapabilities caps, int transparency) throws AWTException
306     {
307         VolatileImage vi =
308             new SunVolatileImage(this, width, height, transparency, caps);
309         if (caps != null && caps.isAccelerated() &&
310             !vi.getCapabilities().isAccelerated())
311         {
312             throw new AWTException("Supplied image capabilities could not " +
313                                    "be met by this graphics configuration.");
314         }
315         return vi;
316     }
317 
318     /**
319      * Returns the {@link ColorModel} associated with this
320      * <code>GraphicsConfiguration</code>.
321      * @return a <code>ColorModel</code> object that is associated with
322      * this <code>GraphicsConfiguration</code>.
323      */
324     public abstract ColorModel getColorModel();
325 
326     /**
327      * Returns the <code>ColorModel</code> associated with this
328      * <code>GraphicsConfiguration</code> that supports the specified
329      * transparency.
330      * @param transparency the specified transparency mode
331      * @return a <code>ColorModel</code> object that is associated with
332      * this <code>GraphicsConfiguration</code> and supports the
333      * specified transparency or null if the transparency is not a valid
334      * value.
335      * @see Transparency#OPAQUE
336      * @see Transparency#BITMASK
337      * @see Transparency#TRANSLUCENT
338      */
339     public abstract ColorModel getColorModel(int transparency);
340 
341     /**
342      * Returns the default {@link AffineTransform} for this
343      * <code>GraphicsConfiguration</code>. This
344      * <code>AffineTransform</code> is typically the Identity transform
345      * for most normal screens.  The default <code>AffineTransform</code>
346      * maps coordinates onto the device such that 72 user space
347      * coordinate units measure approximately 1 inch in device
348      * space.  The normalizing transform can be used to make
349      * this mapping more exact.  Coordinates in the coordinate space
350      * defined by the default <code>AffineTransform</code> for screen and
351      * printer devices have the origin in the upper left-hand corner of
352      * the target region of the device, with X coordinates
353      * increasing to the right and Y coordinates increasing downwards.
354      * For image buffers not associated with a device, such as those not
355      * created by <code>createCompatibleImage</code>,
356      * this <code>AffineTransform</code> is the Identity transform.
357      * @return the default <code>AffineTransform</code> for this
358      * <code>GraphicsConfiguration</code>.
359      */
360     public abstract AffineTransform getDefaultTransform();
361 
362     /**
363      *
364      * Returns a <code>AffineTransform</code> that can be concatenated
365      * with the default <code>AffineTransform</code>
366      * of a <code>GraphicsConfiguration</code> so that 72 units in user
367      * space equals 1 inch in device space.
368      * <p>
369      * For a particular {@link Graphics2D}, g, one
370      * can reset the transformation to create
371      * such a mapping by using the following pseudocode:
372      * <pre>
373      *      GraphicsConfiguration gc = g.getDeviceConfiguration();
374      *
375      *      g.setTransform(gc.getDefaultTransform());
376      *      g.transform(gc.getNormalizingTransform());
377      * </pre>
378      * Note that sometimes this <code>AffineTransform</code> is identity,
379      * such as for printers or metafile output, and that this
380      * <code>AffineTransform</code> is only as accurate as the information
381      * supplied by the underlying system.  For image buffers not
382      * associated with a device, such as those not created by
383      * <code>createCompatibleImage</code>, this
384      * <code>AffineTransform</code> is the Identity transform
385      * since there is no valid distance measurement.
386      * @return an <code>AffineTransform</code> to concatenate to the
387      * default <code>AffineTransform</code> so that 72 units in user
388      * space is mapped to 1 inch in device space.
389      */
390     public abstract AffineTransform getNormalizingTransform();
391 
392     /**
393      * Returns the bounds of the <code>GraphicsConfiguration</code>
394      * in the device coordinates. In a multi-screen environment
395      * with a virtual device, the bounds can have negative X
396      * or Y origins.
397      * @return the bounds of the area covered by this
398      * <code>GraphicsConfiguration</code>.
399      * @since 1.3
400      */
401     public abstract Rectangle getBounds();
402 
403     private static class DefaultBufferCapabilities extends BufferCapabilities {
404         public DefaultBufferCapabilities(ImageCapabilities imageCaps) {
405             super(imageCaps, imageCaps, null);
406         }
407     }
408 
409     /**
410      * Returns the buffering capabilities of this
411      * <code>GraphicsConfiguration</code>.
412      * @return the buffering capabilities of this graphics
413      * configuration object
414      * @since 1.4
415      */
416     public BufferCapabilities getBufferCapabilities() {
417         if (defaultBufferCaps == null) {
418             defaultBufferCaps = new DefaultBufferCapabilities(
419                 getImageCapabilities());
420         }
421         return defaultBufferCaps;
422     }
423 
424     /**
425      * Returns the image capabilities of this
426      * <code>GraphicsConfiguration</code>.
427      * @return the image capabilities of this graphics
428      * configuration object
429      * @since 1.4
430      */
431     public ImageCapabilities getImageCapabilities() {
432         if (defaultImageCaps == null) {
433             defaultImageCaps = new ImageCapabilities(false);
434         }
435         return defaultImageCaps;
436     }
437 
438     /**
439      * Returns whether this {@code GraphicsConfiguration} supports
440      * the {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
441      * PERPIXEL_TRANSLUCENT} kind of translucency.
442      *
443      * @return whether the given GraphicsConfiguration supports
444      *         the translucency effects.
445      *
446      * @see Window#setBackground(Color)
447      *
448      * @since 1.7
449      */
450     public boolean isTranslucencyCapable() {
451         // Overridden in subclasses
452         return false;
453     }
454 }