Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing

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.

The GraphicsConfiguration class should not be confused with the DisplayMode class (although it's easy to do so). The display mode is something with which most savvy computer users will be familiar. On a system that supports multisync monitors, the DisplayMode class encapsulates the width, height, color-depth, and refresh rate information for a given mode. The GraphicsConfiguration class stores things like square versus rectangular pixels. GraphicsConfiguration could even be used for devices such as printers. The configuration information is highly dependent on the native platform and thus varies widely from system to system. In any given system, both configurations and modes can be found through the available GraphicsDevice 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 Modes

One 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.

Table 3-4. Swing components that throw HeadlessException

Component

Method(s)

JApplet

Constructors

JColorChooser

showDialog( ); setDragEnabled( ); createDialog( ); constructors

JDialog

Constructors

JFileChooser

createDialog( ); showDialog( ); showOpenDialog( ); showSaveDialog( ); setDragenabled( )

JFrame

Constructors

JList

setDragEnabled( )

JOptionPane

All show dialog methods; createDialog( ); getFrameForComponent( ); getWindowForComponent( ); getRootFrame( )

JTable

setDragEnabled( )

JTree

setDragEnabled( )

JWindow

Constructors

SwingUtilities

getSharedOwnerFrame( )

Категории