1. /*
  2. * @(#)GraphicsEnvironment.java 1.62 04/04/13
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.awt.image.BufferedImage;
  9. import java.util.Hashtable;
  10. import java.util.Locale;
  11. import java.util.Map;
  12. import java.io.InputStream;
  13. import sun.java2d.HeadlessGraphicsEnvironment;
  14. import sun.java2d.SunGraphicsEnvironment;
  15. /**
  16. *
  17. * The <code>GraphicsEnvironment</code> class describes the collection
  18. * of {@link GraphicsDevice} objects and {@link java.awt.Font} objects
  19. * available to a Java(tm) application on a particular platform.
  20. * The resources in this <code>GraphicsEnvironment</code> might be local
  21. * or on a remote machine. <code>GraphicsDevice</code> objects can be
  22. * screens, printers or image buffers and are the destination of
  23. * {@link Graphics2D} drawing methods. Each <code>GraphicsDevice</code>
  24. * has a number of {@link GraphicsConfiguration} objects associated with
  25. * it. These objects specify the different configurations in which the
  26. * <code>GraphicsDevice</code> can be used.
  27. * @see GraphicsDevice
  28. * @see GraphicsConfiguration
  29. * @version 1.62, 04/13/04
  30. */
  31. public abstract class GraphicsEnvironment {
  32. private static GraphicsEnvironment localEnv;
  33. /**
  34. * The headless state of the Toolkit and GraphicsEnvironment
  35. */
  36. private static Boolean headless;
  37. /**
  38. * The headless state assumed by default
  39. */
  40. private static Boolean defaultHeadless;
  41. /**
  42. * This is an abstract class and cannot be instantiated directly.
  43. * Instances must be obtained from a suitable factory or query method.
  44. */
  45. protected GraphicsEnvironment() {
  46. }
  47. /**
  48. * Returns the local <code>GraphicsEnvironment</code>.
  49. * @return the local <code>GraphicsEnvironment</code>
  50. */
  51. public static synchronized GraphicsEnvironment getLocalGraphicsEnvironment() {
  52. if (localEnv == null) {
  53. String nm = (String) java.security.AccessController.doPrivileged
  54. (new sun.security.action.GetPropertyAction
  55. ("java.awt.graphicsenv", null));
  56. try {
  57. // long t0 = System.currentTimeMillis();
  58. localEnv =
  59. (GraphicsEnvironment) Class.forName(nm).newInstance();
  60. // long t1 = System.currentTimeMillis();
  61. // System.out.println("GE creation took " + (t1-t0)+ "ms.");
  62. if (isHeadless()) {
  63. localEnv = new HeadlessGraphicsEnvironment(localEnv);
  64. }
  65. } catch (ClassNotFoundException e) {
  66. throw new Error("Could not find class: "+nm);
  67. } catch (InstantiationException e) {
  68. throw new Error("Could not instantiate Graphics Environment: "
  69. + nm);
  70. } catch (IllegalAccessException e) {
  71. throw new Error ("Could not access Graphics Environment: "
  72. + nm);
  73. }
  74. }
  75. return localEnv;
  76. }
  77. /**
  78. * Tests whether or not a display, keyboard, and mouse can be
  79. * supported in this environment. If this method returns true,
  80. * a HeadlessException is thrown from areas of the Toolkit
  81. * and GraphicsEnvironment that are dependent on a display,
  82. * keyboard, or mouse.
  83. * @return <code>true</code> if this environment cannot support
  84. * a display, keyboard, and mouse; <code>false</code>
  85. * otherwise
  86. * @see java.awt.HeadlessException
  87. * @since 1.4
  88. */
  89. public static boolean isHeadless() {
  90. return getHeadlessProperty();
  91. }
  92. /**
  93. * @return warning message if headless state is assumed by default;
  94. * null otherwise
  95. * @since 1.5
  96. */
  97. static String getHeadlessMessage() {
  98. if (headless == null) {
  99. getHeadlessProperty(); // initialize the values
  100. }
  101. return defaultHeadless != Boolean.TRUE ? null :
  102. "\nNo X11 DISPLAY variable was set, " +
  103. "but this program performed an operation which requires it.";
  104. }
  105. /**
  106. * @return the value of the property "java.awt.headless"
  107. * @since 1.4
  108. */
  109. private static boolean getHeadlessProperty() {
  110. if (headless == null) {
  111. java.security.AccessController.doPrivileged(
  112. new java.security.PrivilegedAction() {
  113. public Object run() {
  114. String nm = System.getProperty("java.awt.headless");
  115. if (nm == null) {
  116. /* No need to ask for DISPLAY when run in a browser */
  117. if (System.getProperty("javaplugin.version") != null) {
  118. headless = defaultHeadless = Boolean.FALSE;
  119. } else {
  120. String osName = System.getProperty("os.name");
  121. headless = defaultHeadless =
  122. Boolean.valueOf(("Linux".equals(osName) || "SunOS".equals(osName)) &&
  123. (System.getenv("DISPLAY") == null));
  124. }
  125. } else if (nm.equals("true")) {
  126. headless = Boolean.TRUE;
  127. } else {
  128. headless = Boolean.FALSE;
  129. }
  130. return null;
  131. }
  132. }
  133. );
  134. }
  135. return headless.booleanValue();
  136. }
  137. /**
  138. * Check for headless state and throw HeadlessException if headless
  139. * @since 1.4
  140. */
  141. static void checkHeadless() throws HeadlessException {
  142. if (isHeadless()) {
  143. throw new HeadlessException();
  144. }
  145. }
  146. /**
  147. * Returns whether or not a display, keyboard, and mouse can be
  148. * supported in this graphics environment. If this returns true,
  149. * <code>HeadlessException</code> will be thrown from areas of the
  150. * graphics environment that are dependent on a display, keyboard, or
  151. * mouse.
  152. * @return <code>true</code> if a display, keyboard, and mouse
  153. * can be supported in this environment; <code>false</code>
  154. * otherwise
  155. * @see java.awt.HeadlessException
  156. * @see #isHeadless
  157. * @since 1.4
  158. */
  159. public boolean isHeadlessInstance() {
  160. // By default (local graphics environment), simply check the
  161. // headless property.
  162. return getHeadlessProperty();
  163. }
  164. /**
  165. * Returns an array of all of the screen <code>GraphicsDevice</code>
  166. * objects.
  167. * @return an array containing all the <code>GraphicsDevice</code>
  168. * objects that represent screen devices
  169. * @exception HeadlessException if isHeadless() returns true
  170. * @see #isHeadless()
  171. */
  172. public abstract GraphicsDevice[] getScreenDevices()
  173. throws HeadlessException;
  174. /**
  175. * Returns the default screen <code>GraphicsDevice</code>.
  176. * @return the <code>GraphicsDevice</code> that represents the
  177. * default screen device
  178. * @exception HeadlessException if isHeadless() returns true
  179. * @see #isHeadless()
  180. */
  181. public abstract GraphicsDevice getDefaultScreenDevice()
  182. throws HeadlessException;
  183. /**
  184. * Returns a <code>Graphics2D</code> object for rendering into the
  185. * specified {@link BufferedImage}.
  186. * @param img the specified <code>BufferedImage</code>
  187. * @return a <code>Graphics2D</code> to be used for rendering into
  188. * the specified <code>BufferedImage</code>
  189. */
  190. public abstract Graphics2D createGraphics(BufferedImage img);
  191. /**
  192. * Returns an array containing a one-point size instance of all fonts
  193. * available in this <code>GraphicsEnvironment</code>. Typical usage
  194. * would be to allow a user to select a particular font. Then, the
  195. * application can size the font and set various font attributes by
  196. * calling the <code>deriveFont</code> method on the choosen instance.
  197. * <p>
  198. * This method provides for the application the most precise control
  199. * over which <code>Font</code> instance is used to render text.
  200. * If a font in this <code>GraphicsEnvironment</code> has multiple
  201. * programmable variations, only one
  202. * instance of that <code>Font</code> is returned in the array, and
  203. * other variations must be derived by the application.
  204. * <p>
  205. * If a font in this environment has multiple programmable variations,
  206. * such as Multiple-Master fonts, only one instance of that font is
  207. * returned in the <code>Font</code> array. The other variations
  208. * must be derived by the application.
  209. *
  210. * @return an array of <code>Font</code> objects
  211. * @see #getAvailableFontFamilyNames
  212. * @see java.awt.Font
  213. * @see java.awt.Font#deriveFont
  214. * @see java.awt.Font#getFontName
  215. * @since 1.2
  216. */
  217. public abstract Font[] getAllFonts();
  218. /**
  219. * Returns an array containing the names of all font families in this
  220. * <code>GraphicsEnvironment</code> localized for the default locale,
  221. * as returned by <code>Locale.getDefault()</code>.
  222. * <p>
  223. * Typical usage would be for presentation to a user for selection of
  224. * a particular family name. An application can then specify this name
  225. * when creating a font, in conjunction with a style, such as bold or
  226. * italic, giving the font system flexibility in choosing its own best
  227. * match among multiple fonts in the same font family.
  228. *
  229. * @return an array of <code>String</code> containing font family names
  230. * localized for the default locale, or a suitable alternative
  231. * name if no name exists for this locale.
  232. * @see #getAllFonts
  233. * @see java.awt.Font
  234. * @see java.awt.Font#getFamily
  235. * @since 1.2
  236. */
  237. public abstract String[] getAvailableFontFamilyNames();
  238. /**
  239. * Returns an array containing the names of all font families in this
  240. * <code>GraphicsEnvironment</code> localized for the specified locale.
  241. * <p>
  242. * Typical usage would be for presentation to a user for selection of
  243. * a particular family name. An application can then specify this name
  244. * when creating a font, in conjunction with a style, such as bold or
  245. * italic, giving the font system flexibility in choosing its own best
  246. * match among multiple fonts in the same font family.
  247. *
  248. * @param l a {@link Locale} object that represents a
  249. * particular geographical, political, or cultural region.
  250. * Specifying <code>null</code> is equivalent to
  251. * specifying <code>Locale.getDefault()</code>.
  252. * @return an array of <code>String</code> containing font family names
  253. * localized for the specified <code>Locale</code>, or a
  254. * suitable alternative name if no name exists for the specified locale.
  255. * @see #getAllFonts
  256. * @see java.awt.Font
  257. * @see java.awt.Font#getFamily
  258. * @since 1.2
  259. */
  260. public abstract String[] getAvailableFontFamilyNames(Locale l);
  261. /**
  262. * Indicates a preference for locale-specific fonts in the mapping of
  263. * logical fonts to physical fonts. Calling this method indicates that font
  264. * rendering should primarily use fonts specific to the primary writing
  265. * system (the one indicated by the default encoding and the initial
  266. * default locale). For example, if the primary writing system is
  267. * Japanese, then characters should be rendered using a Japanese font
  268. * if possible, and other fonts should only be used for characters for
  269. * which the Japanese font doesn't have glyphs.
  270. * <p>
  271. * The actual change in font rendering behavior resulting from a call
  272. * to this method is implementation dependent; it may have no effect at
  273. * all, or the requested behavior may already match the default behavior.
  274. * The behavior may differ between font rendering in lightweight
  275. * and peered components. Since calling this method requests a
  276. * different font, clients should expect different metrics, and may need
  277. * to recalculate window sizes and layout. Therefore this method should
  278. * be called before user interface initialisation.
  279. * @since 1.5
  280. */
  281. public void preferLocaleFonts() {
  282. sun.font.FontManager.preferLocaleFonts();
  283. }
  284. /**
  285. * Indicates a preference for proportional over non-proportional (e.g.
  286. * dual-spaced CJK fonts) fonts in the mapping of logical fonts to
  287. * physical fonts. If the default mapping contains fonts for which
  288. * proportional and non-proportional variants exist, then calling
  289. * this method indicates the mapping should use a proportional variant.
  290. * <p>
  291. * The actual change in font rendering behavior resulting from a call to
  292. * this method is implementation dependent; it may have no effect at all.
  293. * The behavior may differ between font rendering in lightweight and
  294. * peered components. Since calling this method requests a
  295. * different font, clients should expect different metrics, and may need
  296. * to recalculate window sizes and layout. Therefore this method should
  297. * be called before user interface initialisation.
  298. * @since 1.5
  299. */
  300. public void preferProportionalFonts() {
  301. sun.font.FontManager.preferProportionalFonts();
  302. }
  303. /**
  304. * Returns the Point where Windows should be centered.
  305. * It is recommended that centered Windows be checked to ensure they fit
  306. * within the available display area using getMaximumWindowBounds().
  307. * @return the point where Windows should be centered
  308. *
  309. * @exception HeadlessException if isHeadless() returns true
  310. * @see #getMaximumWindowBounds
  311. * @since 1.4
  312. */
  313. public Point getCenterPoint() throws HeadlessException {
  314. // Default implementation: return the center of the usable bounds of the
  315. // default screen device.
  316. Rectangle usableBounds =
  317. SunGraphicsEnvironment.getUsableBounds(getDefaultScreenDevice());
  318. return new Point((usableBounds.width / 2) + usableBounds.x,
  319. (usableBounds.height / 2) + usableBounds.y);
  320. }
  321. /**
  322. * Returns the maximum bounds for centered Windows.
  323. * These bounds account for objects in the native windowing system such as
  324. * task bars and menu bars. The returned bounds will reside on a single
  325. * display with one exception: on multi-screen systems where Windows should
  326. * be centered across all displays, this method returns the bounds of the
  327. * entire display area.
  328. * <p>
  329. * To get the usable bounds of a single display, use
  330. * <code>GraphicsConfiguration.getBounds()</code> and
  331. * <code>Toolkit.getScreenInsets()</code>.
  332. * @return the maximum bounds for centered Windows
  333. *
  334. * @exception HeadlessException if isHeadless() returns true
  335. * @see #getCenterPoint
  336. * @see GraphicsConfiguration#getBounds
  337. * @see Toolkit#getScreenInsets
  338. * @since 1.4
  339. */
  340. public Rectangle getMaximumWindowBounds() throws HeadlessException {
  341. // Default implementation: return the usable bounds of the default screen
  342. // device. This is correct for Microsoft Windows and non-Xinerama X11.
  343. return SunGraphicsEnvironment.getUsableBounds(getDefaultScreenDevice());
  344. }
  345. }