James Elliott
Device 0: X11GraphicsDevice[screen=0]
3.5 The JComponent Class
3.5.6 Position, Size, and Alignment
JComponent
can optimize its repainting time if none of its children overlap; this is because the repaint manager does not have to compute the hidden and visible areas for each child component before rendering them. Some containers, such asJSplitPane
, are designed so that overlap between child components is impossible, so this optimization works nicely. Other containers, such asJLayeredPane
, have support for child components that can overlap.JComponent
contains a property that Swing frequently calls upon to see if it can optimize component drawing:optimizedDrawingEnabled
. InJComponent
, this property is set totrue
by default. If overlap occurs in a subclass ofJComponent
, the subclass should override theisOptimizedDrawingEnabled( )
accessor and returnfalse
. This prevents the repaint manager from using the optimized drawing process when rendering the container's children.JComponent
contains a boolean read-only property (paintingTile
) that indicates whether the component is currently in the process of painting a tile , which is a child component that does not overlap any other children. TheisPaintingTile( )
method returnstrue
until all tiles have been painted.The
visibleRect
property is aRectangle
that indicates the intersection of the component's visible rectangles with the visible rectangles of all of its ancestors. Why the intersection? Remember that you can have a contained object that is clipped by its parent. For example, you can move an internal frame so that a portion of it falls outside the parent window's clipping region. Therefore, the visible portion (the portion that is actually drawn to the screen) consists only of the intersection of the parent's visible portion and the child's visible portion. You typically do not need to access this property.The
validateRoot
property isfalse
by default. If it is set totrue
, it designates this component as the root component in a validation tree. Recall that each time a component in a container is invalidated, its container is invalidated as well, along with all of its children. This causes an invalidation to move all the way up the component hierarchy, stopping only when it reaches a component for whichisValidateRoot( )
returnstrue
. Currently, the only components that set this property totrue
areJRootPane
(which is used by all the Swing top-level components),JScrollPane
, andJTextField
.The
topLevelAncestor
property contains a reference to the top-level window that contains this component, usually aJWindow
orJApplet
. TherootPane
property contains the low-levelJRootPane
for this component;JRootPane
is covered in more detail in Chapter 8.Finally,
JComponent
contains a property calledautoscrolls
, which indicates whether a component is capable of supporting autoscrolling. This property isfalse
by default. If the property istrue
, anAutoscroller
object has been set over this component. TheAutoscroller
object monitors mouse events on the target component. If the mouse is dragged outside the component, the autoscroller forces the target component to scroll itself. Autoscrolling is typically used in containers such asJViewport
.You can set and retrieve a Swing component's current position and size on the screen through the
bounds
property, or more precisely, through thelocation
andsize
properties ofJComponent
. Thelocation
property is defined as aPoint
in the parent's coordinate space where the upper-left corner of the component's bounding box resides. Thesize
property is aDimension
that specifies the current width and height of the component. Thebounds
property is aRectangle
object that gives the same information: it bundles both thelocation
and thesize
properties.Figure 3-6 shows how Swing measures the size and location of a component.
Figure 3-6. Working with the bounds, size, and location properties
Unlike the AWT
Component
class, thegetBounds( )
accessor inJComponent
can take a preinstantiatedRectangle
object:Rectangle myRect = new Rectangle( );
myRect = component.getBounds(myRect);
If a
Rectangle
is supplied, thegetBounds( )
method alters each of the fields in the passed-inRectangle
to reflect the component's current size and position, returning a copy of it. If the reference passed in is anull
, the method instantiates a newRectangle
object, sets its values, and returns it. You can use the former approach to reduce the number of garbage rectangles created and discarded over multiple calls togetBounds( )
, which increases the efficiency of your application.The
setBounds( )
method alters the component's size and position. This method also takes aRectangle
object. If the new settings are different from the previous settings, the component is moved, typically resized, and invalidated. If the component has a parent, it is invalidated as well. Be warned that various layout managers may override any changes you attempt to make to thebounds
property. Invalidating a component with a call tosetBounds( )
may force the layout manager to recompute and reset the bounds of the component in relation to the other components, resolving it to the same size as before.Here is a short example that shows how to retrieve the current position and size of any Swing component:
JFrame frame = new JFrame("Test Frame");
frame.setBounds(20,20,200,200);
frame.setVisible(true);
Rectangle r = new Rectangle( );
r = frame.getBounds(r);
System.out.println("X = " + r.x( ));
System.out.println("Y = " + r.y( ));
System.out.println("Width = " + r.width( ));
System.out.println("Height = " + r.height( ));
There is a shorthand approach for retrieving each of the bounds properties.
JComponent
contains four methods that directly access them:getX( )
,getY( )
,getWidth( )
, andgetHeight( )
. You can use these accessors directly instead of instantiating aRectangle
object on the heap with a call togetBounds( )
. Consequently, you can replace the last six lines with the following four:System.out.println("X = " + frame.getX( ));
System.out.println("Y = " + frame.getY( ));
System.out.println("Width = " + frame.getWidth( ));
System.out.println("Height = " + frame.getHeight( ));
In addition, if it is just the size or location you are concerned with, you can use the
getSize( )
andgetLocation( )
accessors to set or retrieve the size or location. Size is specified as aDimension
while location is given as aPoint
. LikegetBounds( )
, thegetLocation( )
accessor also allows the programmer to pass in a preinstantiatedPoint
object. If one is passed in, the method alters the coordinates of thePoint
instead of instantiating a new object.Point myPoint = new Point( );
myPoint = component.getLocation(myPoint);
You can still use the
setSize( )
andsetLocation( )
methods ofjava.awt.Component
if you prefer to code with those as well. Again, note that when altering the size of the component, the layout manager may override the new value and reset it to its previous value, thus ignoring your new size values.The three well-known AWT sizing properties,
minimumSize
,preferredSize
, andmaximumSize
, are accessible throughJComponent
.minimumSize
indicates the smallest size for the component when it is in a container.preferredSize
contains the size at which the container's layout manager should strive to draw the component.maximumSize
indicates the largest size the component should be when displayed in a container. If none of these properties are set by the user, they are always calculated by the component's UI delegate or directly by the layout manager of the container, in that order. The methodssetMinimumSize( )
,setPreferredSize
, andsetMaximumSize( )
allow you to change these properties without subclassing.Finally,
JComponent
contains two read/write properties that help interested layout managers align the component in a container:alignmentX
andalignmentY
. Both of these properties contain floating-point values between 0.0 and 1.0; the numbers determine the position of the component relative to any siblings. A number closer to 0 indicates that the component should be positioned closer to the left or top side, respectively. A perfect 0.5 indicates that the component should be placed at the center, while a number nearing 1 indicates that the component should be positioned closer to the right or bottom. Currently, the only layout managers that use these properties are theBoxLayout
andOverlayLayout
managers; all AWT 1.1 layout managers ignore these properties and position their children by other means. We discuss these managers further in Chapter 11.
在文檔中
Java™ Swing, 2nd Edition
(頁 96-99)