SDK 1.4 recognizes a great deal of information about its environment. You can retrieve that information for your own code through the GraphicsEnvironment, GraphicsDevice, and GraphicsConfiguration classes from the java.awt package. While they aren't part of Swing proper, these classes are definitely useful for Swing applications, especially those that take full advantage of their environment. To sum up these classes, a system keeps a local GraphicsEnvironment object that describes the devices on the system with an array of GraphicsDevice objects. Each GraphicsDevice contains (or at least may contain) multiple configurations of device capabilities (such as pixel formats or which visual screen you're on) bundled up in an array of GraphicsConfiguration objects.
If you're curious about the various graphics configurations on your system, try out this little program, GuiScreens.java. It prints information on all devices and configurations. For each configuration, it also pops up a JFrame using that configuration. // GuiScreens.java // import java.awt.*; import javax.swing.*; public class GuiScreens { public static void main(String[] args) { Rectangle virtualBounds = new Rectangle( ); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment( ); GraphicsDevice[] gs = ge.getScreenDevices( ); JFrame frame[][] = new JFrame[gs.length][]; for (int j = 0; j < gs.length; j++) { GraphicsDevice gd = gs[j]; System.out.println("Device " + j + ": " + gd); GraphicsConfiguration[] gc = gd.getConfigurations( ); frame[j] = new JFrame[gc.length]; for (int i=0; i < gc.length; i++) { System.out.println(" Configuration " + i + ": " + gc[i]); System.out.println(" Bounds: " + gc[i].getBounds( )); virtualBounds = virtualBounds.union(gc[i].getBounds( )); frame[j][i] = new JFrame("Config: " + i, gc[i]); frame[j][i].setBounds(50, 50, 400, 100); frame[j][i].setLocation( (int)gc[i].getBounds( ).getX( ) + 50, (int)gc[i].getBounds( ).getY( ) + 50); frame[j][i].getContentPane( ).add(new JTextArea("Config:\n" + gc[i])); frame[j][i].setVisible(true); } System.out.println("Overall bounds: " + virtualBounds); } } } Here's the text output from a Solaris system running CDE with one monitor: Device 0: X11GraphicsDevice[screen=0] Configuration 0: X11GraphicsConfig[dev=X11GraphicsDevice[screen=0],vis=0x22] Bounds: java.awt.Rectangle[x=0,y=0,width=1152,height=900] Configuration 1: X11GraphicsConfig[dev=X11GraphicsDevice[screen=0],vis=0x26] Bounds: java.awt.Rectangle[x=0,y=0,width=1152,height=900] Configuration 2: X11GraphicsConfig[dev=X11GraphicsDevice[screen=0],vis=0x25] Bounds: java.awt.Rectangle[x=0,y=0,width=1152,height=900] Configuration 3: X11GraphicsConfig[dev=X11GraphicsDevice[screen=0],vis=0x24] Bounds: java.awt.Rectangle[x=0,y=0,width=1152,height=900] Configuration 4: X11GraphicsConfig[dev=X11GraphicsDevice[screen=0],vis=0x27] Bounds: java.awt.Rectangle[x=0,y=0,width=1152,height=900] Overall bounds: java.awt.Rectangle[x=0,y=0,width=1152,height=900] And here's the output from an OS X system with two monitors: Device 0: sun.awt.MacGraphicsDevice@4dd8d9 Configuration 0: com.apple.mrj.internal.awt.graphics.MacGraphicsConfig@303297 Bounds: java.awt.Rectangle[x=0,y=0,width=1280,height=1024] Device 1: sun.awt.MacGraphicsDevice@5c08c3 Configuration 0: com.apple.mrj.internal.awt.graphics.MacGraphicsConfig@435a72 Bounds: java.awt.Rectangle[x=1280,y=-52,width=1152,height=870] Overall bounds: java.awt.Rectangle[x=0,y=-52,width=2432,height=1076] 3.3.1 Headless ModesOne other variation on the graphics environment is "headless" operation. This mode of running without any monitor shows up quite often on back-end systems. Java servlets trying to use the AWT, 2D, and Swing classes to draw dynamic graphs for a web page are a classic example of applications that need a graphics environment on a machine that might not have any graphics displays. You can detect such a case with the GraphicsEnvironment.isHeadless( ) call. If an environment is headless, there are certain calls that cannot be made. These calls tend to create onscreen components such as frames or dialogs no good without a head or otherwise attempt to interact with the (nonexistent) local user. Table 3-4 shows the documented Swing components that generate a HeadlessException when called. Since HeadlessException is an unchecked exception (i.e., a descendant of RuntimeException), it is not always documented in the Javadoc for a method or in its throws clause (in the source code). The best practice that has evolved for writing Javadoc for such exceptions requires that the Javadoc mention the exception (with an @throws entry), but that the throws clause in the actual method signature omit it. This leads to a visual indication that it is an unchecked exception. Not all code has adopted this best practice, of course.
|