home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 October / Chip_1997-10_cd.bin / tema / sybase / powerj / java.z / Component.java < prev    next >
Text File  |  1996-05-03  |  29KB  |  1,146 lines

  1. /*
  2.  * @(#)Component.java    1.66 96/01/18 Arthur van Hoff
  3.  *
  4.  * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19. package java.awt;
  20.  
  21. import java.io.PrintStream;
  22. import java.awt.peer.ComponentPeer;
  23. import java.awt.image.ImageObserver;
  24. import java.awt.image.ImageProducer;
  25. import java.awt.image.ColorModel;
  26.  
  27. /**
  28.  * A generic Abstract Window Toolkit component. 
  29.  *
  30.  * @version     1.66, 01/18/96
  31.  * @author     Arthur van Hoff
  32.  * @author     Sami Shaio
  33.  */
  34. public abstract class Component implements ImageObserver {
  35.     /**
  36.      * The peer of the component. The peer implements the component's
  37.      * behaviour. The peer is set when the Component is added to a 
  38.      * container that also is a peer.
  39.      * @see #getPeer
  40.      * @see #addNotify
  41.      * @see #removeNotify
  42.      */
  43.     ComponentPeer peer;
  44.  
  45.     /**
  46.      * The parent of the object. It may be null for toplevel components.
  47.      * @see #getParent
  48.      */
  49.     Container parent;
  50.  
  51.     /**
  52.      * The x position of the component in the parent's coordinate system.
  53.      * @see #position
  54.      */
  55.     int x;
  56.  
  57.     /**
  58.      * The y position of the component in the parent's coordinate system.
  59.      * @see #position
  60.      */
  61.     int y;
  62.  
  63.     /**
  64.      * The width of the component.
  65.      * @see #size
  66.      */
  67.     int width;
  68.  
  69.     /**
  70.      * The height of the component.
  71.      * @see #size
  72.      */
  73.     int height;
  74.  
  75.     /**
  76.      * The foreground color for this component.
  77.      * @see #getForeground
  78.      * @see #setForeground
  79.      */
  80.     Color    foreground;
  81.  
  82.     /**
  83.      * The background color for this component.
  84.      * @see #getBackground
  85.      * @see #setBackground
  86.      */
  87.     Color    background;
  88.  
  89.     /**
  90.      * The font used by this component.
  91.      * @see #getFont
  92.      * @see #setFont
  93.      */
  94.     Font    font;
  95.  
  96.     /**
  97.      * True when the object is visible. An object that is not
  98.      * visible is not drawn on the screen.
  99.      * @see #isVisible
  100.      * @see #show
  101.      * @see #hide
  102.      */
  103.     boolean visible = true;
  104.  
  105.     /**
  106.      * True when the object is enabled. An object that is not
  107.      * enabled does not interact with the user.
  108.      * @see #isEnabled
  109.      * @see #enable
  110.      * @see #disable
  111.      */
  112.     boolean enabled = true;
  113.  
  114.     /** 
  115.      * True when the object is valid. An invalid object needs to
  116.      * be layed out. This flag is set to false when the object
  117.      * size is changed.
  118.      * @see #isValid
  119.      * @see #validate
  120.      * @see #invalidate
  121.      */
  122.     boolean valid = false;
  123.  
  124.     /**
  125.      * Constructs a new Component. Components should not be subclassed or 
  126.      * instantiated directly.
  127.      */
  128.     Component() {
  129.     }
  130.  
  131.     /**
  132.      * Gets the parent of the component.
  133.      */
  134.     public Container getParent() {
  135.     return parent;
  136.     }
  137.  
  138.     /**
  139.      * Gets the peer of the component.
  140.      */
  141.     public ComponentPeer getPeer() {
  142.     return peer;
  143.     }
  144.  
  145.     /**
  146.      * Gets the toolkit of the component. This toolkit is
  147.      * used to create the peer for this component.  Note that
  148.      * the Frame which contains a Component controls which
  149.      * toolkit is used so if the Component has not yet been
  150.      * added to a Frame or if it is later moved to a different
  151.      * Frame, the toolkit it uses may change.
  152.      */
  153.     public Toolkit getToolkit() {
  154.     ComponentPeer peer = this.peer;
  155.     if (peer != null) {
  156.         return peer.getToolkit();
  157.     }
  158.     Container parent = this.parent;
  159.     if (parent != null) {
  160.         return parent.getToolkit();
  161.     }
  162.     return Toolkit.getDefaultToolkit();
  163.     }
  164.  
  165.     /**
  166.      * Checks if this Component is valid. Components are invalidated when
  167.      * they are first shown on the screen.
  168.      * @see #validate
  169.      * @see #invalidate
  170.      */
  171.     public boolean isValid() {
  172.     return (peer != null) && valid;
  173.     }
  174.  
  175.     /**
  176.      * Checks if this Component is visible. Components are initially visible 
  177.      * (with the exception of top level components such as Frame).
  178.      * @see #show
  179.      * @see #hide
  180.      */
  181.     public boolean isVisible() {
  182.     return visible;
  183.     }
  184.  
  185.     /**
  186.      * Checks if this Component is showing on screen. This means that the 
  187.      * component must be visible, and it must be in a container that is 
  188.      * visible and showing.
  189.      * @see #show
  190.      * @see #hide
  191.      */
  192.     public boolean isShowing() {
  193.     if (visible && (peer != null)) {
  194.         Container parent = this.parent;
  195.         return (parent == null) || parent.isShowing();
  196.     }
  197.     return false;
  198.     }
  199.  
  200.     /**
  201.      * Checks if this Component is enabled. Components are initially enabled.
  202.      * @see #enable
  203.      * @see #disable
  204.      */
  205.     public boolean isEnabled() {
  206.     return enabled;
  207.     }
  208.  
  209.     /** 
  210.      * Returns the current location of this component.
  211.      * The location will be in the parent's coordinate space.
  212.      * @see #move
  213.      */
  214.     public Point location() {
  215.     return new Point(x, y);
  216.     }
  217.  
  218.     /** 
  219.      * Returns the current size of this component.
  220.      * @see #resize
  221.      */
  222.     public Dimension size() {
  223.     return new Dimension(width, height);
  224.     }
  225.  
  226.     /** 
  227.      * Returns the current bounds of this component.
  228.      * @see #reshape
  229.      */
  230.     public Rectangle bounds() {
  231.     return new Rectangle(x, y, width, height);
  232.     }
  233.  
  234.     /**
  235.      * Enables a component.
  236.      * @see #isEnabled
  237.      * @see #disable
  238.      */
  239.     public synchronized void enable() {
  240.     if (!enabled) {
  241.         enabled = true;
  242.         if (peer != null) {
  243.         peer.enable();
  244.         }
  245.     }
  246.     }
  247.  
  248.     /**
  249.      * Conditionally enables a component.
  250.      * @param cond if true, enables component; disables otherwise.
  251.      * @see #enable
  252.      * @see #disable
  253.      */
  254.     public void enable(boolean cond) {
  255.     if (cond) {
  256.         enable();
  257.     } else {
  258.         disable();
  259.     }
  260.     }
  261.  
  262.     /**
  263.      * Disables a component.
  264.      * @see #isEnabled
  265.      * @see #enable
  266.      */
  267.     public synchronized void disable() {
  268.     if (enabled) {
  269.         enabled = false;
  270.         if (peer != null) {
  271.         peer.disable();
  272.         }
  273.     }
  274.     }
  275.  
  276.     /**
  277.      * Shows the component. 
  278.      * @see #isVisible
  279.      * @see #hide
  280.      */
  281.     public synchronized void show() {
  282.     if (!visible) {
  283.         visible = true;
  284.         if (peer != null) {
  285.         peer.show();
  286.         if (parent != null) {
  287.             parent.invalidate();
  288.         }
  289.         }
  290.     }
  291.     }
  292.  
  293.     /**
  294.      * Conditionally shows the component. 
  295.      * @param cond if true, it shows the component; hides otherwise.
  296.      * @see #show
  297.      * @see #hide
  298.      */
  299.     public void show(boolean cond) {
  300.     if (cond) {
  301.         show();
  302.     } else {
  303.         hide();
  304.     }
  305.     }
  306.  
  307.     /**
  308.      * Hides the component.
  309.      * @see #isVisible
  310.      * @see #hide
  311.      */
  312.     public synchronized void hide() {
  313.     if (visible) {
  314.         visible = false;
  315.         if (peer != null) {
  316.         peer.hide();
  317.         if (parent != null) {
  318.             parent.invalidate();
  319.         }
  320.         }
  321.     }
  322.     }
  323.  
  324.     /**
  325.      * Gets the foreground color. If the component does
  326.      * not have a foreground color, the foreground color
  327.      * of its parent is returned.
  328.      * @see #setForeground
  329.      */
  330.     public Color getForeground() {
  331.     Color foreground = this.foreground;
  332.     if (foreground != null) {
  333.         return foreground;
  334.     }
  335.     Container parent = this.parent;
  336.     return (parent != null) ? parent.getForeground() : null;
  337.     }
  338.  
  339.     /** 
  340.      * Sets the foreground color.
  341.      * @param c the Color
  342.      * @see #getForeground
  343.      */
  344.     public synchronized void setForeground(Color c) {
  345.     foreground = c;
  346.     if (peer != null) {
  347.         c = getForeground();
  348.         if (c != null) {
  349.         peer.setForeground(c);
  350.         }
  351.     }
  352.     }
  353.  
  354.     /**
  355.      * Gets the background color. If the component does
  356.      * not have a background color, the background color
  357.      * of its parent is returned.
  358.      * @see #setBackground
  359.      */
  360.     public Color getBackground() {
  361.     Color background = this.background;
  362.     if (background != null) {
  363.         return background;
  364.     }
  365.     Container parent = this.parent;
  366.     return (parent != null) ? parent.getBackground() : null;
  367.     }
  368.  
  369.     /** 
  370.      * Sets the background color.
  371.      * @param c the Color
  372.      * @see #getBackground
  373.      */
  374.     public synchronized void setBackground(Color c) {
  375.     background = c;
  376.     if (peer != null) {
  377.         c = getBackground();
  378.         if (c != null) {
  379.         peer.setBackground(c);
  380.         }
  381.     }
  382.     }
  383.  
  384.     /**
  385.      * Gets the font of the component. If the component does
  386.      * not have a font, the font of its parent is returned.
  387.      * @see #setFont
  388.      */
  389.     public Font getFont() {
  390.     Font font = this.font;
  391.     if (font != null) {
  392.         return font;
  393.     }
  394.     Container parent = this.parent;
  395.     return (parent != null) ? parent.getFont() : null;
  396.     }
  397.  
  398.     /** 
  399.      * Sets the font of the component.
  400.      * @param f the font
  401.      * @see #getFont
  402.      */
  403.     public synchronized void setFont(Font f) {
  404.     font = f;
  405.     if (peer != null) {
  406.         f = getFont();
  407.         if (f != null) {
  408.         peer.setFont(f);
  409.         }
  410.     }
  411.     }
  412.  
  413.     /**
  414.      * Gets the ColorModel used to display the component on the output device.
  415.      * @see ColorModel
  416.      */
  417.     public synchronized ColorModel getColorModel() {
  418.     if (peer == null) {
  419.         return getToolkit().getColorModel();
  420.     } else {
  421.         return peer.getColorModel();
  422.     }
  423.     }
  424.  
  425.     /** 
  426.      * Moves the Component to a new location. The x and y coordinates
  427.      * are in the parent's coordinate space.
  428.      * @param x the x coordinate
  429.      * @param y the y coordinate
  430.      * @see #location
  431.      * @see #reshape
  432.      */
  433.     public void move(int x, int y) {
  434.     reshape(x, y, width, height);
  435.     }
  436.  
  437.     /**
  438.      * Resizes the Component to the specified width and height.
  439.      * @param width the width of the component
  440.      * @param height the height of the component
  441.      * @see #size
  442.      * @see #reshape
  443.      */
  444.     public void resize(int width, int height) {
  445.     reshape(x, y, width, height);
  446.     }
  447.  
  448.     /** 
  449.      * Resizes the Component to the specified dimension.
  450.      * @param d the component dimension
  451.      * @see #size
  452.      * @see #reshape
  453.      */
  454.     public void resize(Dimension d) {
  455.     reshape(x, y, d.width, d.height);
  456.     }
  457.  
  458.     /** 
  459.      * Reshapes the Component to the specified bounding box.
  460.      * @param x the x coordinate
  461.      * @param y the y coordinate
  462.      * @param width the width of the component
  463.      * @param height the height of the component
  464.      * @see #bounds
  465.      * @see #move
  466.      * @see #resize
  467.      */
  468.     public synchronized void reshape(int x, int y, int width, int height) {
  469.     boolean resized = (this.width != width) || (this.height != height);
  470.  
  471.     if (resized || (this.x != x) || (this.y != y)) {
  472.         this.x = x;
  473.         this.y = y;
  474.         this.width = width;
  475.         this.height = height;
  476.         if (peer != null) {
  477.         peer.reshape(x, y, width, height);
  478.         if (resized) {
  479.             invalidate();
  480.         }
  481.         if (parent != null && parent.valid) {
  482.             parent.invalidate();
  483.         }
  484.         }
  485.     }
  486.     }
  487.  
  488.     /** 
  489.      * Returns the preferred size of this component.
  490.      * @see #minimumSize
  491.      * @see LayoutManager
  492.      */
  493.     public Dimension preferredSize() {
  494.     ComponentPeer peer = this.peer;
  495.     return (peer != null) ? peer.preferredSize() : minimumSize();
  496.     }
  497.  
  498.     /**
  499.      * Returns the minimum size of this component.
  500.      * @see #preferredSize
  501.      * @see LayoutManager
  502.      */
  503.     public Dimension minimumSize() {
  504.     ComponentPeer peer = this.peer;
  505.     return (peer != null) ? peer.minimumSize() : size();
  506.     }
  507.  
  508.     /**
  509.      * Lays out the component. This is usually called when the
  510.      * component is validated.
  511.      * @see #validate
  512.      * @see LayoutManager
  513.      */
  514.     public void layout() {
  515.     }
  516.  
  517.     /** 
  518.      * Validates a component.  
  519.      * @see #invalidate
  520.      * @see #layout
  521.      * @see LayoutManager
  522.      */
  523.     public void validate() {
  524.     if ((!valid) && (peer != null)) {
  525.         layout();
  526.         valid = true;
  527.     }
  528.     }
  529.  
  530.     /** 
  531.      * Invalidates the component.  The component and all parents
  532.      * above it are marked as needing to be laid out.
  533.      * @see #validate
  534.      * @see #layout
  535.      * @see LayoutManager
  536.      */
  537.     public void invalidate() {
  538.     valid = false;
  539.     /* For efficiency, propagate invalidate() upwards only if
  540.      * some other component hasn't already done so first.
  541.      */
  542.     if (parent != null && parent.valid) {
  543.         parent.invalidate();
  544.     }
  545.     }
  546.  
  547.     /**
  548.      * Gets a Graphics context for this component. This method will
  549.      * return null if the component is currently not on the screen.
  550.      * @see #paint
  551.      */
  552.     public Graphics getGraphics() {
  553.     ComponentPeer peer = this.peer;
  554.     return (peer != null) ? peer.getGraphics() : null;
  555.     }
  556.  
  557.     /**
  558.      * Gets the font metrics for this component.
  559.      * @param font the font
  560.      * @see #getFont
  561.      */
  562.     public FontMetrics getFontMetrics(Font font) {
  563.     ComponentPeer peer = this.peer;
  564.     return (peer != null)
  565.         ? peer.getFontMetrics(font)
  566.         : getToolkit().getFontMetrics(font);
  567.     }
  568.  
  569.     /** 
  570.      * Paints the component.
  571.      * @param g the specified Graphics window
  572.      * @see #update
  573.      */
  574.     public void paint(Graphics g) {
  575.     }
  576.  
  577.     /** 
  578.      * Updates the component. This method is called in
  579.      * response to a call to repaint. You can assume that
  580.      * the background is not cleared.
  581.      * @param g the specified Graphics window
  582.      * @see #paint
  583.      * @see #repaint
  584.      */
  585.     public void update(Graphics g) {
  586.     g.setColor(getBackground());
  587.     g.fillRect(0, 0, width, height);
  588.     g.setColor(getForeground());
  589.     paint(g);
  590.     }
  591.  
  592.     /**
  593.      * Paints the component and its subcomponents.
  594.      * @param g the specified Graphics window
  595.      * @see #paint
  596.      */
  597.     public void paintAll(Graphics g) {
  598.     ComponentPeer peer = this.peer;
  599.     if (visible && (peer != null)) {
  600.         validate();
  601.         peer.paint(g);
  602.     }
  603.     }
  604.  
  605.     /** 
  606.      * Repaints the component. This will result in a
  607.      * call to update as soon as possible.
  608.      * @see #paint
  609.      */
  610.     public void repaint() {
  611.     repaint(0, 0, 0, width, height);
  612.     }
  613.  
  614.     /** 
  615.      * Repaints the component. This will result in a
  616.      * call to update within <em>tm</em> milliseconds.
  617.      * @param tm maximum time in milliseconds before update
  618.      * @see #paint
  619.      */
  620.     public void repaint(long tm) {
  621.     repaint(tm, 0, 0, width, height);
  622.     }
  623.  
  624.     /** 
  625.      * Repaints part of the component. This will result in a
  626.      * call to update as soon as possible.
  627.      * @param x the x coordinate
  628.      * @param y the y coordinate
  629.      * @param width the width 
  630.      * @param height the height 
  631.      * @see #repaint
  632.      */
  633.     public void repaint(int x, int y, int width, int height) {
  634.     repaint(0, x, y, width, height);
  635.     }
  636.  
  637.     /** 
  638.      * Repaints part of the component. This will result in a
  639.      * call to update width <em>tm</em> millseconds.
  640.      * @param tm maximum time in milliseconds before update
  641.      * @param x the x coordinate
  642.      * @param y the y coordinate
  643.      * @param width the width 
  644.      * @param height the height 
  645.      * @see #repaint
  646.      */
  647.     public void repaint(long tm, int x, int y, int width, int height) {
  648.     ComponentPeer peer = this.peer;
  649.     if ((peer != null) && (width > 0) && (height > 0)) {
  650.         peer.repaint(tm, x, y, width, height);
  651.     }
  652.     }
  653.  
  654.     /**
  655.      * Prints this component. The default implementation of this
  656.      * method calls paint.
  657.      * @param g the specified Graphics window
  658.      * @see #paint
  659.      */
  660.     public void print(Graphics g) {
  661.     paint(g);
  662.     }
  663.  
  664.     /**
  665.      * Prints the component and its subcomponents.
  666.      * @param g the specified Graphics window
  667.      * @see #print
  668.      */
  669.     public void printAll(Graphics g) {
  670.     ComponentPeer peer = this.peer;
  671.     if (visible && (peer != null)) {
  672.         validate();
  673.         peer.print(g);
  674.     }
  675.     }
  676.  
  677.     /**
  678.      * Repaints the component when the image has changed.
  679.      * @return true if image has changed; false otherwise.
  680.      */
  681.     public boolean imageUpdate(Image img, int flags,
  682.                    int x, int y, int w, int h) {
  683.     int rate = -1;
  684.     if ((flags & (FRAMEBITS|ALLBITS)) != 0) {
  685.         rate = 0;
  686.     } else if ((flags & SOMEBITS) != 0) {
  687.         String isInc = System.getProperty("awt.image.incrementaldraw");
  688.         if (isInc == null || isInc.equals("true")) {
  689.         String incRate = System.getProperty("awt.image.redrawrate");
  690.         try {
  691.             rate = (incRate != null) ? Integer.parseInt(incRate) : 100;
  692.             if (rate < 0)
  693.             rate = 0;
  694.         } catch (Exception e) {
  695.             rate = 100;
  696.         }
  697.         }
  698.     }
  699.     if (rate >= 0) {
  700.         repaint(rate, 0, 0, width, height);
  701.     }
  702.     return (flags & (ALLBITS|ABORT)) == 0;
  703.     }
  704.  
  705.     /**
  706.      * Creates an image from the specified image producer.
  707.      * @param producer the image producer
  708.      */
  709.     public Image createImage(ImageProducer producer) {
  710.     ComponentPeer peer = this.peer;
  711.     return (peer != null)
  712.         ? peer.createImage(producer)
  713.         : getToolkit().createImage(producer);
  714.     }
  715.  
  716.     /**
  717.      * Creates an off-screen drawable Image to be used for double buffering.
  718.      * @param width the specified width
  719.      * @param height the specified height
  720.      */
  721.     public Image createImage(int width, int height) {
  722.     ComponentPeer peer = this.peer;
  723.     return (peer != null) ? peer.createImage(width, height) : null;
  724.     }
  725.  
  726.     /**
  727.      * Prepares an image for rendering on this Component.  The image
  728.      * data is downloaded asynchronously in another thread and the
  729.      * appropriate screen representation of the image is generated.
  730.      * @param image the Image to prepare a screen representation for
  731.      * @param observer the ImageObserver object to be notified as the
  732.      *        image is being prepared
  733.      * @return true if the image has already been fully prepared
  734.      * @see ImageObserver
  735.      */
  736.     public boolean prepareImage(Image image, ImageObserver observer) {
  737.         return prepareImage(image, -1, -1, observer);
  738.     }
  739.  
  740.     /**
  741.      * Prepares an image for rendering on this Component at the
  742.      * specified width and height.  The image data is downloaded
  743.      * asynchronously in another thread and an appropriately scaled
  744.      * screen representation of the image is generated.
  745.      * @param image the Image to prepare a screen representation for
  746.      * @param width the width of the desired screen representation
  747.      * @param height the height of the desired screen representation
  748.      * @param observer the ImageObserver object to be notified as the
  749.      *        image is being prepared
  750.      * @return true if the image has already been fully prepared
  751.      * @see ImageObserver
  752.      */
  753.     public boolean prepareImage(Image image, int width, int height,
  754.                 ImageObserver observer) {
  755.     ComponentPeer peer = this.peer;
  756.     return (peer != null)
  757.         ? peer.prepareImage(image, width, height, observer)
  758.         : getToolkit().prepareImage(image, width, height, observer);
  759.     }
  760.  
  761.     /**
  762.      * Returns the status of the construction of a screen representation
  763.      * of the specified image.
  764.      * This method does not cause the image to begin loading. Use the
  765.      * prepareImage method to force the loading of an image.
  766.      * @param image the Image to check the status of
  767.      * @param observer the ImageObserver object to be notified as the
  768.      *        image is being prepared
  769.      * @return the boolean OR of the ImageObserver flags for the
  770.      *         data that is currently available
  771.      * @see ImageObserver
  772.      * @see #prepareImage
  773.      */
  774.     public int checkImage(Image image, ImageObserver observer) {
  775.         return checkImage(image, -1, -1, observer);
  776.     }
  777.  
  778.     /**
  779.      * Returns the status of the construction of a scaled screen
  780.      * representation of the specified image.
  781.      * This method does not cause the image to begin loading, use the
  782.      * prepareImage method to force the loading of an image.
  783.      * @param image the Image to check the status of
  784.      * @param width the width of the scaled version to check the status of
  785.      * @param height the height of the scaled version to check the status of
  786.      * @param observer the ImageObserver object to be notified as the
  787.      *        image is being prepared
  788.      * @return the boolean OR of the ImageObserver flags for the
  789.      *         data that is currently available
  790.      * @see ImageObserver
  791.      * @see #prepareImage
  792.      */
  793.     public int checkImage(Image image, int width, int height,
  794.               ImageObserver observer) {
  795.     ComponentPeer peer = this.peer;
  796.     return (peer != null)
  797.         ? peer.checkImage(image, width, height, observer)
  798.         : getToolkit().checkImage(image, width, height, observer);
  799.     }
  800.  
  801.     /**  
  802.      * Checks whether a specified x,y location is "inside" this
  803.      * Component, where x and y are defined to be relative to the 
  804.      * coordinate system of this component.  
  805.      * @param x the x coordinate 
  806.      * @param y the y coordinate
  807.      * @see #locate
  808.      */
  809.     public synchronized boolean inside(int x, int y) {
  810.     return (x >= 0) && (x <= width) && (y >= 0) && (y <= height);
  811.     }
  812.  
  813.     /** 
  814.      * Returns the component or subcomponent that contains the x,y location.
  815.      * @param x the x coordinate
  816.      * @param y the y coordinate
  817.      * @see #inside
  818.      */
  819.     public Component locate(int x, int y) {
  820.     return inside(x, y) ? this : null;
  821.     }
  822.  
  823.     /**
  824.      * Delivers an event to this component or one of its sub components.
  825.      * @param e the event
  826.      * @see #handleEvent
  827.      * @see #postEvent
  828.      */
  829.     public void deliverEvent(Event e) {
  830.     postEvent(e);
  831.     }
  832.  
  833.     /**
  834.      * Posts an event to this component. This will result in a call
  835.      * to handleEvent. If handleEvent returns false the event is
  836.      * passed on to the parent of this component.
  837.      * @param e the event
  838.      * @see #handleEvent
  839.      * @see #deliverEvent
  840.      */
  841.     public boolean postEvent(Event e) {
  842.     ComponentPeer peer = this.peer;
  843.  
  844.     if (handleEvent(e)) {
  845.         return true;
  846.     }
  847.  
  848.     /* this should be handled by overriding postEvent in
  849.      * Window, however since that breaks compatibility, we'll
  850.      * add this check here for now.
  851.      */
  852.     if (this instanceof Window) {
  853.         Window window = (Window)this;
  854.         if (window.handleTabEvent(e)) {
  855.         return true;
  856.         }
  857.     } else {
  858.         Component parent = this.parent;
  859.         if (parent != null) {
  860.             e.translate(x, y);
  861.             if (parent.postEvent(e)) {
  862.             return true;
  863.             }
  864.         }
  865.     }
  866.     if (peer != null) {
  867.         return peer.handleEvent(e);
  868.     }
  869.     return false;
  870.     }
  871.  
  872.     /**
  873.      * Handles the event. Returns true if the event is handled and
  874.      * should not be passed to the parent of this component. The default
  875.      * event handler calls some helper methods to make life easier
  876.      * on the programmer.
  877.      * @param evt the event
  878.      * @see #mouseEnter
  879.      * @see #mouseExit
  880.      * @see #mouseMove
  881.      * @see #mouseDown
  882.      * @see #mouseDrag
  883.      * @see #mouseUp
  884.      * @see #keyDown
  885.      * @see #action
  886.      */
  887.     public boolean handleEvent(Event evt) {
  888.     switch (evt.id) {
  889.       case Event.MOUSE_ENTER:
  890.         return mouseEnter(evt, evt.x, evt.y);
  891.  
  892.       case Event.MOUSE_EXIT:
  893.         return mouseExit(evt, evt.x, evt.y);
  894.  
  895.       case Event.MOUSE_MOVE:
  896.         return mouseMove(evt, evt.x, evt.y);
  897.  
  898.       case Event.MOUSE_DOWN:
  899.         return mouseDown(evt, evt.x, evt.y);
  900.  
  901.       case Event.MOUSE_DRAG:
  902.         return mouseDrag(evt, evt.x, evt.y);
  903.  
  904.       case Event.MOUSE_UP:
  905.         return mouseUp(evt, evt.x, evt.y);
  906.  
  907.       case Event.KEY_PRESS:
  908.       case Event.KEY_ACTION:
  909.         return keyDown(evt, evt.key);
  910.  
  911.       case Event.KEY_RELEASE:
  912.       case Event.KEY_ACTION_RELEASE:
  913.         return keyUp(evt, evt.key);
  914.         
  915.       case Event.ACTION_EVENT:
  916.         return action(evt, evt.arg);
  917.       case Event.GOT_FOCUS:
  918.         return gotFocus(evt, evt.arg);
  919.       case Event.LOST_FOCUS:
  920.         return lostFocus(evt, evt.arg);
  921.     }
  922.     return false;
  923.     }
  924.  
  925.     /**
  926.      * Called if the mouse is down.
  927.      * @param evt the event 
  928.      * @param x the x coordinate
  929.      * @param y the y coordinate
  930.      * @see #handleEvent
  931.      */
  932.     public boolean mouseDown(Event evt, int x, int y) {
  933.     return false;
  934.     }
  935.  
  936.     /**
  937.      * Called if the mouse is dragged (the mouse button is down).
  938.      * @param evt the event
  939.      * @param x the x coordinate
  940.      * @param y the y coordinate
  941.      * @see #handleEvent
  942.      */
  943.     public boolean mouseDrag(Event evt, int x, int y) {
  944.     return false;
  945.     }
  946.  
  947.     /**
  948.      * Called if the mouse is up.
  949.      * @param evt the event
  950.      * @param x the x coordinate
  951.      * @param y the y coordinate
  952.      * @see #handleEvent
  953.      */
  954.     public boolean mouseUp(Event evt, int x, int y) {
  955.     return false;
  956.     }
  957.  
  958.     /**
  959.      * Called if the mouse moves (the mouse button is up).
  960.      * @param evt the event
  961.      * @param x the x coordinate
  962.      * @param y the y coordinate
  963.      * @see #handleEvent
  964.      */
  965.     public boolean mouseMove(Event evt, int x, int y) {
  966.     return false;
  967.     }
  968.  
  969.     /**
  970.      * Called when the mouse enters the component.
  971.      * @param evt the event
  972.      * @param x the x coordinate
  973.      * @param y the y coordinate
  974.      * @see #handleEvent
  975.      */
  976.     public boolean mouseEnter(Event evt, int x, int y) {
  977.     return false;
  978.     }
  979.  
  980.     /**
  981.      * Called when the mouse exits the component.
  982.      * @param evt the event
  983.      * @param x the x coordinate
  984.      * @param y the y coordinate
  985.      * @see #handleEvent
  986.      */
  987.     public boolean mouseExit(Event evt, int x, int y) {
  988.     return false;
  989.     }
  990.  
  991.     /**
  992.      * Called if a character is pressed.
  993.      * @param evt the event
  994.      * @param key the key that's pressed
  995.      * @see #handleEvent
  996.      */
  997.     public boolean keyDown(Event evt, int key) {
  998.     return false;
  999.     }
  1000.  
  1001.     /**
  1002.      * Called if a character is released.
  1003.      * @param evt the event
  1004.      * @param key the key that's released
  1005.      * @see #handleEvent
  1006.      */
  1007.     public boolean keyUp(Event evt, int key) {
  1008.     return false;
  1009.     }
  1010.  
  1011.     /**
  1012.      * Called if an action occurs in the Component.
  1013.      * @param evt the event
  1014.      * @param what the action that's occuring
  1015.      * @see #handleEvent
  1016.      */
  1017.     public boolean action(Event evt, Object what) {
  1018.     return false;
  1019.     }
  1020.  
  1021.     /** 
  1022.      * Notifies the Component to create a peer.
  1023.      * @see #getPeer
  1024.      * @see #removeNotify
  1025.      */
  1026.     public void addNotify() {
  1027.     valid = false;
  1028.     }
  1029.  
  1030.     /** 
  1031.      * Notifies the Component to destroy the peer.
  1032.      * @see #getPeer
  1033.      * @see #addNotify
  1034.      */
  1035.     public synchronized void removeNotify() {
  1036.     if (peer != null) {
  1037.         peer.dispose();
  1038.         peer = null;
  1039.     }
  1040.     }
  1041.  
  1042.     /** 
  1043.      * Indicates that this component has received the input focus.
  1044.      * @see #requestFocus
  1045.      * @see #lostFocus
  1046.      */
  1047.     public boolean gotFocus(Event evt, Object what) {
  1048.     if (evt.target != this)
  1049.         return false;
  1050.  
  1051.     if (parent != null) {
  1052.         parent.setFocusOwner(this);
  1053.     }
  1054.     return false;
  1055.     }
  1056.  
  1057.     /** 
  1058.      * Indicates that this component has lost the input focus.  
  1059.      * @see #requestFocus
  1060.      * @see #gotFocus
  1061.      */
  1062.     public boolean lostFocus(Event evt, Object what) {
  1063.     return false;
  1064.     }
  1065.  
  1066.     /** 
  1067.      * Requests the input focus. The gotFocus() method will be called
  1068.      * if this method is successful.
  1069.      * @see #gotFocus
  1070.      */
  1071.     public void requestFocus() {
  1072.     ComponentPeer peer = this.peer;
  1073.     if (peer != null) {
  1074.         peer.requestFocus();
  1075.     }
  1076.     }
  1077.  
  1078.     /**
  1079.      * Moves the focus to the next component.
  1080.      * @see #requestFocus
  1081.      * @see #gotFocus
  1082.      */
  1083.      public void nextFocus() {
  1084.     if (parent != null) {
  1085.         parent.nextFocus(this);
  1086.     }
  1087.      }
  1088.  
  1089.     /**
  1090.      * Returns the parameter String of this Component.
  1091.      */
  1092.     protected String paramString() {
  1093.     String str = x + "," + y + "," + width + "x" + height;
  1094.     if (!valid) {
  1095.         str += ",invalid";
  1096.     }
  1097.     if (!visible) {
  1098.         str += ",hidden";
  1099.     }
  1100.     if (!enabled) {
  1101.         str += ",disabled";
  1102.     }
  1103.     return str;
  1104.     }
  1105.  
  1106.     /**
  1107.      * Returns the String representation of this Component's values.
  1108.      */
  1109.     public String toString() {
  1110.     return getClass().getName() + "[" + paramString() + "]";
  1111.     }
  1112.  
  1113.     /**
  1114.      * Prints a listing to a print stream.
  1115.      */
  1116.     public void list() {
  1117.     list(System.out, 0);
  1118.     }
  1119.  
  1120.     /**
  1121.      * Prints a listing to the specified print out stream.
  1122.      * @param out the Stream name
  1123.      */
  1124.     public void list(PrintStream out) {
  1125.     list(out, 0);
  1126.     }
  1127.  
  1128.     /**
  1129.      * Prints out a list, starting at the specified indention, to the specified 
  1130.      * print stream.
  1131.      * @param out the Stream name
  1132.      * @param indent the start of the list 
  1133.      */
  1134.     public void list(PrintStream out, int indent) {
  1135.     for (int i = 0 ; i < indent ; i++) {
  1136.         out.print("  ");
  1137.     }
  1138.     out.println(this);
  1139.     }
  1140.  
  1141.     /* Can this field be tabbed to? */
  1142.     boolean tabbable() {
  1143.         return false;
  1144.     }
  1145. }
  1146.