diff options
author | Eric Blake <ebb9@byu.net> | 2002-05-06 02:43:17 +0000 |
---|---|---|
committer | Eric Blake <ebb9@byu.net> | 2002-05-06 02:43:17 +0000 |
commit | fb0219dcce2e53020800c655562b5f7351b0579b (patch) | |
tree | 9f82123162f4b28fe313e1777997035fb852cabf /java | |
parent | d76bb31a7c2246eea1f5f1b9624b8ddf1d841b88 (diff) | |
download | classpath-fb0219dcce2e53020800c655562b5f7351b0579b.tar.gz |
2002-05-05 Eric Blake <ebb9@email.byu.edu>
* java/applet/Applet.java (getAccessibleState): Update.
* java/awt/AWTEvent.java (INPUT_ENABLED_EVENT_MASK): New flag.
* java/awt/AWTKeyStroke.java (keyCode): Make more visible.
* java/awt/AlphaComposite.java: New file (needs documentation).
* java/awt/AttributeValue.java: New file.
* java/awt/BasicStroke.java: New file (needs docs).
* java/awt/BufferCapabilities.java: New file (needs docs).
* java/awt/Button.java (getActionListeners, getListeners): Use new
features of AWTEventMulticater.
* java/awt/Component.java: Partial update to 1.4.
* java/awt/ComponentOrientation.java: Update to 1.4.
* java/awt/Container.java (getContainerListeners, getListeners):
Use new features of AWTEventMulticaster.
* java/awt/ContainerOrderFocusTraversalPolicy.java: New
file (stubbed, needs docs).
* java/awt/DefaultFocusTraversalPolicy.java: New file (stubbed).
* java/awt/DefaultKeyboardFocusManager.java: New file (stubbed).
* java/awt/FocusTraversalPolicy.java: New file (needs docs).
* java/awt/GradientPaint.java: New file (stubbed).
* java/awt/GraphicsConfiguration.java: Update to 1.4.
* java/awt/ImageCapabilities.java: New file (stubbed).
* java/awt/Insets.java: Update to 1.4.
* java/awt/JobAttributes.java: New file (needs docs).
* java/awt/KeyboardFocusManager.java: New file (partially
stubbed).
* java/awt/Makefile.am (EXTRA_DIST): Account for new files.
* java/awt/MenuItem.java (getActionListeners, getListeners): Use
new features of AWTEventMulticaster.
* java/awt/PageAttributes.java: New file (needs docs).
* java/awt/PaintContext.java (paint): Remove redundant keyword.
* java/awt/PrintJob.java: Update to 1.4.
* java/awt/RenderingHints.java: Partial update to 1.4 (needs docs).
* java/awt/Robot.java: New file (stubbed).
* java/awt/TexturePaint.java: New file (stubbed).
* java/awt/Window.java (getWindowListeners, getListeners): Use new
features of AWTEventMulticaster.
* java/awt/geom/Arc2D.java: Implement and document.
* java/awt/geom/Rectangle2D.java: Fix doc typo.
Diffstat (limited to 'java')
31 files changed, 7170 insertions, 1451 deletions
diff --git a/java/applet/Applet.java b/java/applet/Applet.java index d97009778..5990c6392 100644 --- a/java/applet/Applet.java +++ b/java/applet/Applet.java @@ -491,16 +491,16 @@ public class Applet extends Panel /** * Get the state set of this accessible object. In addition to the default - * states of a Component, the applet is also active. + * states of a Component, the applet can also be active. * * @return the role of the object * @see AccessibleState */ public AccessibleStateSet getAccessibleStateSet() { - // XXX Make sure that this is correct. AccessibleStateSet s = super.getAccessibleStateSet(); - s.add(AccessibleState.ACTIVE); + if (isActive()) + s.add(AccessibleState.ACTIVE); return s; } } // class AccessibleApplet diff --git a/java/awt/AWTEvent.java b/java/awt/AWTEvent.java index e74338959..41cdad53f 100644 --- a/java/awt/AWTEvent.java +++ b/java/awt/AWTEvent.java @@ -129,6 +129,11 @@ public abstract class AWTEvent extends EventObject public static final long INPUT_METHOD_EVENT_MASK = 0x00800; /** + * Mask if input methods are enabled. Package visible only. + */ + static final long INPUT_ENABLED_EVENT_MASK = 0x01000; + + /** * Mask for paint events. * @since 1.3 */ diff --git a/java/awt/AWTKeyStroke.java b/java/awt/AWTKeyStroke.java index 75abc2cd5..9848d43ef 100644 --- a/java/awt/AWTKeyStroke.java +++ b/java/awt/AWTKeyStroke.java @@ -150,11 +150,12 @@ public class AWTKeyStroke implements Serializable private char keyChar; /** - * The virtual key code, or VK_UNDEFINED for key typed. + * The virtual key code, or VK_UNDEFINED for key typed. Package visible for + * use by Component. * * @serial the keyCode */ - private int keyCode; + int keyCode; /** * The modifiers in effect. To match Sun, this stores the old style masks diff --git a/java/awt/AlphaComposite.java b/java/awt/AlphaComposite.java new file mode 100644 index 000000000..a99ee23c1 --- /dev/null +++ b/java/awt/AlphaComposite.java @@ -0,0 +1,142 @@ +/* AlphaComposite.java -- provides a context for performing alpha compositing + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.awt.image.ColorModel; +import java.util.LinkedHashMap; + +/** + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Composite + * @see CompositeContext + * @since 1.3 + * @status updated to 1.4 except for createContext, needs documentation + */ +public final class AlphaComposite implements Composite +{ + /** Map Long to AlphaComposites. See getInstance for details. */ + private static final LinkedHashMap cache = new LinkedHashMap(11, 0.75f, true) + { + /** The largest the alpha composite cache can grow. */ + private static final int MAX_CACHE_SIZE = 2048; + + /** Prune stale entries. */ + protected boolean removeEldestEntry(Entry eldest) + { + return size() > MAX_CACHE_SIZE; + } + }; + public static final int CLEAR = 1; + public static final int SRC = 2; + public static final int DST = 9; + public static final int SRC_OVER = 3; + public static final int DST_OVER = 4; + public static final int SRC_IN = 5; + public static final int DST_IN = 6; + public static final int SRC_OUT = 7; + public static final int DST_OUT = 8; + public static final int SRC_ATOP = 10; + public static final int DST_ATOP = 11; + public static final int XOR = 12; + public static final AlphaComposite Clear = getInstance(CLEAR); + public static final AlphaComposite Src = getInstance(SRC); + public static final AlphaComposite Dst = getInstance(DST); + public static final AlphaComposite SrcOver = getInstance(SRC_OVER); + public static final AlphaComposite DstOver = getInstance(DST_OVER); + public static final AlphaComposite SrcIn = getInstance(SRC_IN); + public static final AlphaComposite DstIn = getInstance(DST_IN); + public static final AlphaComposite SrcOut = getInstance(SRC_OUT); + public static final AlphaComposite DstOut = getInstance(DST_OUT); + public static final AlphaComposite SrcAtop = getInstance(SRC_ATOP); + public static final AlphaComposite DstAtop = getInstance(DST_ATOP); + public static final AlphaComposite Xor = getInstance(XOR); + private final int rule; + private final float alpha; + private AlphaComposite(int rule, float alpha) + { + this.rule = rule; + this.alpha = alpha; + } + public static AlphaComposite getInstance(int rule) + { + return getInstance(rule, 1); + } + public static AlphaComposite getInstance(int rule, float alpha) + { + if (rule < CLEAR || rule > XOR || ! (alpha >= 0 && alpha <= 1)) + throw new IllegalArgumentException(); + // This long is guaranteed unique for all valid alpha composites. + Long l = new Long(rule + Double.doubleToLongBits(alpha)); + AlphaComposite a = (AlphaComposite) cache.get(l); + if (a == null) + { + a = new AlphaComposite(rule, alpha); + cache.put(l, a); + } + return a; + } + public CompositeContext createContext(ColorModel srcColorModel, + ColorModel dstColorModel, + RenderingHints hints) + { + // XXX Implement. Sun uses undocumented implementation class + // sun.java2d.SunCompositeContext. + throw new Error("not implemented"); + } + public float getAlpha() + { + return alpha; + } + public int getRule() + { + return rule; + } + public int hashCode() + { + return 31 * Float.floatToIntBits(alpha) + rule; + } + public boolean equals(Object o) + { + if (! (o instanceof AlphaComposite)) + return false; + AlphaComposite a = (AlphaComposite) o; + return rule == a.rule && alpha == a.alpha; + } +} // class AlphaComposite diff --git a/java/awt/AttributeValue.java b/java/awt/AttributeValue.java new file mode 100644 index 000000000..f692c012f --- /dev/null +++ b/java/awt/AttributeValue.java @@ -0,0 +1,98 @@ +/* AttributeValue.java -- parent of type-safe enums of attributes + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +/** + * This class is undocumented by Sun, but it is the parent of several other + * classes, all of which are type-safe enumerations. This takes care of + * <code>equals</code>, <code>toString</code>, and <code>hashCode</code>, so + * that you don't have to (although hashCode is commonly overridden). + * + * @author Eric Blake <ebb9@email.byu.edu> + */ +class AttributeValue +{ + /** The value of the enumeration. Package visible for speed. */ + final int value; + + /** The list of enumeration names for the given subclass. */ + private final String[] names; + + /** + * Construct a type-safe enumeration element. For example,<br> + * <pre> + * class Foo extends AttributeValue + * { + * private static final String[] names = { "one", "two" } + * public static final Foo ONE = new Foo(0); + * public static final Foo TWO = new Foo(1); + * private Foo(int value) { super(value, names); } + * } + * </pre> + * + * @param value the position of this enumeration element, consecutive from 0 + * @param names the constant list of enumeration names for the subclass + */ + AttributeValue(int value, String[] names) + { + this.value = value; + this.names = names; + } + + /** + * Returns the hashcode of this element. This is the index of the element + * in the enumeration. Note that equals defaults to the == relation. + * + * @return the hashcode + */ + public int hashCode() + { + return value; + } + + /** + * Returns the name of this enumeration element. + * + * @return the element name + */ + public String toString() + { + return names[value]; + } +} // class AttributeValue diff --git a/java/awt/BasicStroke.java b/java/awt/BasicStroke.java new file mode 100644 index 000000000..c3290336c --- /dev/null +++ b/java/awt/BasicStroke.java @@ -0,0 +1,144 @@ +/* BasicStroke.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.util.Arrays; + +/** + * STUB CLASS ONLY + */ +public class BasicStroke implements Stroke +{ + public static final int JOIN_MITER = 0; + public static final int JOIN_ROUND = 1; + public static final int JOIN_BEVEL = 2; + public static final int CAP_BUTT = 0; + public static final int CAP_ROUND = 1; + public static final int CAP_SQUARE = 2; + + private final float width; + private final int cap; + private final int join; + private final float limit; + private final float[] dash; + private final float phase; + + public BasicStroke(float width, int cap, int join, float miterlimit, + float[] dash, float dashPhase) + { + if (width < 0 || miterlimit < 1 || cap < CAP_BUTT || cap > CAP_SQUARE + || join < JOIN_MITER || join > JOIN_BEVEL) + throw new IllegalArgumentException(); + this.width = width; + this.cap = cap; + this.join = join; + limit = miterlimit; + this.dash = dash == null ? null : (float[]) dash.clone(); + phase = dashPhase; + } + + public BasicStroke(float width, int cap, int join, float miterlimit) + { + this(width, cap, join, miterlimit, null, 0); + } + + public BasicStroke(float width, int cap, int join) + { + this(width, cap, join, 10, null, 0); + } + + public BasicStroke(float width) + { + this(width, CAP_SQUARE, JOIN_MITER, 10, null, 0); + } + + public BasicStroke() + { + this(1, CAP_SQUARE, JOIN_MITER, 10, null, 0); + } + + public Shape createStrokedShape(Shape s) + { + throw new Error("not implemented"); + } + + public float getLineWidth() + { + return width; + } + + public int getEndCap() + { + return cap; + } + + public int getLineJoin() + { + return join; + } + + public float getMiterLimit() + { + return limit; + } + + public float[] getDashArray() + { + return dash; + } + + public float getDashPhase() + { + return phase; + } + + public int hashCode() + { + throw new Error("not implemented"); + } + + public boolean equals(Object o) + { + if (! (o instanceof BasicStroke)) + return false; + BasicStroke s = (BasicStroke) o; + return width == s.width && cap == s.cap && join == s.join + && limit == s.limit && Arrays.equals(dash, s.dash) && phase == s.phase; + } +} // class BasicStroke diff --git a/java/awt/BufferCapabilities.java b/java/awt/BufferCapabilities.java new file mode 100644 index 000000000..389594b76 --- /dev/null +++ b/java/awt/BufferCapabilities.java @@ -0,0 +1,121 @@ +/* BufferCapabilities.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +/** + * Needs documentation... + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see BufferStrategy#getCapabilities() + * @see GraphicsConfiguration#getCapabilities() + * @since 1.4 + * @status updated to 1.4, lacks documentation + */ +public class BufferCapabilities implements Cloneable +{ + public static final class FlipContents extends AttributeValue + { + private static final String[] NAMES + = { "undefined", "background", "prior", "copied" }; + public static final FlipContents UNDEFINED = new FlipContents(0); + public static final FlipContents BACKGROUND = new FlipContents(1); + public static final FlipContents PRIOR = new FlipContents(2); + public static final FlipContents COPIED = new FlipContents(3); + private FlipContents(int value) + { + super(value, NAMES); + } + } // class FlipContents + + private final ImageCapabilities front; + private final ImageCapabilities back; + private final FlipContents flip; + + public BufferCapabilities(ImageCapabilities front, ImageCapabilities back, + FlipContents flip) + { + this.front = front; + this.back = back; + this.flip = flip; + if (front == null || back == null) + throw new IllegalArgumentException(); + } + + public ImageCapabilities getFrontBufferCapabilities() + { + return front; + } + + public ImageCapabilities getBackBufferCapabilities() + { + return back; + } + + public boolean isPageFlipping() + { + return flip != null; + } + + public FlipContents getFlipContents() + { + return flip; + } + + public boolean isFullScreenRequired() + { + return true; + } + + public boolean isMultiBufferAvailable() + { + return false; + } + + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } + } +} // class BufferCapabilities diff --git a/java/awt/Button.java b/java/awt/Button.java index 139890f73..ed954ddcf 100644 --- a/java/awt/Button.java +++ b/java/awt/Button.java @@ -42,6 +42,7 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.peer.ButtonPeer; import java.awt.peer.ComponentPeer; +import java.lang.reflect.Array; import java.util.EventListener; /** @@ -200,13 +201,24 @@ removeActionListener(ActionListener listener) action_listeners = AWTEventMulticaster.remove(action_listeners, listener); } -public EventListener[] -getListeners(Class listenerType) -{ - if (listenerType == ActionListener.class) - return getListenersImpl(listenerType, action_listeners); - return super.getListeners(listenerType); -} + public synchronized ActionListener[] getActionListeners() + { + return (ActionListener[]) + AWTEventMulticaster.getListeners(action_listeners, + ActionListener.class); + } + +/** Returns all registered EventListers of the given listenerType. + * listenerType must be a subclass of EventListener, or a + * ClassClassException is thrown. + * @since 1.3 + */ + public EventListener[] getListeners(Class listenerType) + { + if (listenerType == ActionListener.class) + return getActionListeners(); + return (EventListener[]) Array.newInstance(listenerType, 0); + } /*************************************************************************/ diff --git a/java/awt/Component.java b/java/awt/Component.java index 2e5e17627..2108287ae 100644 --- a/java/awt/Component.java +++ b/java/awt/Component.java @@ -1,5 +1,5 @@ /* Component.java -- a graphics component - Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation + Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -35,8 +35,10 @@ this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ + package java.awt; +import java.awt.dnd.DropTarget; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.FocusEvent; @@ -51,32 +53,82 @@ import java.awt.event.InputMethodListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelListener; +import java.awt.event.MouseWheelEvent; import java.awt.event.PaintEvent; +import java.awt.im.InputContext; +import java.awt.im.InputMethodRequests; +import java.awt.image.BufferStrategy; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; +import java.awt.image.VolatileImage; import java.awt.peer.ComponentPeer; import java.awt.peer.LightweightPeer; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.io.ObjectInputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.Serializable; import java.lang.reflect.Array; +import java.util.Collections; import java.util.EventListener; +import java.util.HashSet; +import java.util.Iterator; import java.util.Locale; -import java.util.ResourceBundle; +import java.util.Set; import java.util.Vector; import javax.accessibility.Accessible; import javax.accessibility.AccessibleComponent; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleRole; +import javax.accessibility.AccessibleState; import javax.accessibility.AccessibleStateSet; /** - * The root of all evil. + * The root of all evil. All graphical representations are subclasses of this + * giant class, which is designed for screen display and user interaction. + * This class can be extended directly to build a lightweight component (one + * not associated with a native window); lightweight components must reside + * inside a heavyweight window. + * + * <p>This class is Serializable, which has some big implications. A user can + * save the state of all graphical components in one VM, and reload them in + * another. Note that this class will only save Serializable listeners, and + * ignore the rest, without causing any serialization exceptions. However, by + * making a listener serializable, and adding it to another element, you link + * in that entire element to the state of this component. To get around this, + * use the idiom shown in the example below - make listeners non-serializable + * in inner classes, rather than using this object itself as the listener, if + * external objects do not need to save the state of this object. + * + * <p><pre> + * import java.awt.*; + * import java.awt.event.*; + * import java.io.Serializable; + * class MyApp implements Serializable + * { + * BigObjectThatShouldNotBeSerializedWithAButton bigOne; + * // Serializing aButton will not suck in an instance of MyApp, with its + * // accompanying field bigOne. + * Button aButton = new Button(); + * class MyActionListener implements ActionListener + * { + * public void actionPerformed(ActionEvent e) + * { + * System.out.println("Hello There"); + * } + * } + * MyApp() + * { + * aButton.addActionListener(new MyActionListener()); + * } + * } * - * Status: Incomplete. The event dispatch mechanism is implemented. All + * <p>Status: Incomplete. The event dispatch mechanism is implemented. All * other methods defined in the J2SE 1.3 API javadoc exist, but are mostly * incomplete or only stubs; except for methods relating to the Drag and * Drop, Input Method, and Accessibility frameworks: These methods are @@ -90,94 +142,426 @@ import javax.accessibility.AccessibleStateSet; public abstract class Component implements ImageObserver, MenuContainer, Serializable { + // Word to the wise - this file is huge. Search for '\f' (^L) for logical + // sectioning by fields, public API, private API, and nested classes. + + + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -7644114512714619750L; + /** * Constant returned by the <code>getAlignmentY</code> method to indicate - * that the component wishes to be aligned to the bottom relative to + * that the component wishes to be aligned to the top relative to * other components. + * + * @see #getAlignmentY() */ - public static final float BOTTOM_ALIGNMENT = (float)1.0; + public static final float TOP_ALIGNMENT = 0; /** - * Constant returned by the <code>getAlignmentY</code> and + * Constant returned by the <code>getAlignmentY</code> and * <code>getAlignmentX</code> methods to indicate * that the component wishes to be aligned to the center relative to * other components. + * + * @see #getAlignmentX() + * @see #getAlignmentY() */ - public static final float CENTER_ALIGNMENT = (float)0.5; + public static final float CENTER_ALIGNMENT = 0.5f; /** * Constant returned by the <code>getAlignmentY</code> method to indicate - * that the component wishes to be aligned to the top relative to + * that the component wishes to be aligned to the bottom relative to * other components. + * + * @see #getAlignmentY() */ - public static final float TOP_ALIGNMENT = (float)0.0; + public static final float BOTTOM_ALIGNMENT = 1; /** * Constant returned by the <code>getAlignmentX</code> method to indicate * that the component wishes to be aligned to the right relative to * other components. + * + * @see #getAlignmentX() */ - public static final float RIGHT_ALIGNMENT = (float)1.0; + public static final float RIGHT_ALIGNMENT = 1; /** * Constant returned by the <code>getAlignmentX</code> method to indicate * that the component wishes to be aligned to the left relative to * other components. + * + * @see #getAlignmentX() */ - public static final float LEFT_ALIGNMENT = (float)0.0; + public static final float LEFT_ALIGNMENT = 0; - /* Make the treelock a String so that it can easily be identified - in debug dumps. We clone the String in order to avoid a conflict in - the unlikely event that some other package uses exactly the same string - as a lock object. */ - static Object treeLock = new String("AWT_TREE_LOCK"); + /** + * Make the treelock a String so that it can easily be identified + * in debug dumps. We clone the String in order to avoid a conflict in + * the unlikely event that some other package uses exactly the same string + * as a lock object. + */ + static final Object treeLock = new String("AWT_TREE_LOCK"); - /* Serialized fields from the serialization spec. */ - // FIXME: Default values? + // Serialized fields from the serialization spec. + + /** + * The x position of the component in the parent's coordinate system. + * + * @see #getLocation() + * @serial the x position + */ int x; + + /** + * The y position of the component in the parent's coordinate system. + * + * @see #getLocation() + * @serial the y position + */ int y; + + /** + * The component width. + * + * @see #getSize() + * @serial the width + */ int width; + + /** + * The component height. + * + * @see #getSize() + * @serial the height + */ int height; + + /** + * The foreground color for the component. This may be null. + * + * @see #getForeground() + * @see #setForeground(Color) + * @serial the foreground color + */ Color foreground; + + /** + * The background color for the component. This may be null. + * + * @see #getBackground() + * @see #setBackground(Color) + * @serial the background color + */ Color background; + + /** + * The default font used in the component. This may be null. + * + * @see #getFont() + * @see #setFont(Font) + * @serial the font + */ Font font; + + /** + * The font in use by the peer, or null if there is no peer. + * + * @serial the peer's font + */ Font peerFont; + + /** + * The cursor displayed when the pointer is over this component. This may + * be null. + * + * @see #getCursor() + * @see #setCursor(Cursor) + */ Cursor cursor; + + /** + * The locale for the component. + * + * @see #getLocale() + * @see #setLocale(Locale) + */ Locale locale; - boolean visible = true; // default (except for Window) + + /** + * True if the object should ignore repaint events (usually because it is + * not showing). + * + * @see #getIgnoreRepaint() + * @see #setIgnoreRepaint(boolean) + * @serial true to ignore repaints + * @since 1.4 + */ + boolean ignoreRepaint; + + /** + * True when the object is visible (although it is only showing if all + * ancestors are likewise visible). For component, this defaults to true. + * + * @see #isVisible() + * @see #setVisible(boolean) + * @serial true if visible + */ + boolean visible = true; + + /** + * True if the object is enabled, meaning it can interact with the user. + * For component, this defaults to true. + * + * @see #isEnabled() + * @see #setEnabled(boolean) + * @serial true if enabled + */ boolean enabled = true; + + /** + * True if the object is valid. This is set to false any time a size + * adjustment means the component need to be layed out again. + * + * @see #isValid() + * @see #validate() + * @see #invalidate() + * @serial true if layout is valid + */ boolean valid; - boolean hasFocus; - //DropTarget dropTarget; + + /** + * The DropTarget for drag-and-drop operations. + * + * @see #getDropTarget() + * @see #setDropTarget(DropTarget) + * @serial the drop target, or null + * @since 1.2 + */ + DropTarget dropTarget; + + /** + * The list of popup menus for this component. + * + * @see #add(PopupMenu) + * @serial the list of popups + */ Vector popups; + + /** + * The component's name. May be null, in which case a default name is + * generated on the first use. + * + * @see #getName() + * @see #setName(String) + * @serial the name + */ String name; + + /** + * True once the user has set the name. Note that the user may set the name + * to null. + * + * @see #name + * @see #getName() + * @see #setName(String) + * @serial true if the name has been explicitly set + */ boolean nameExplicitlySet; + + /** + * Indicates if the object can be focused. Defaults to true for components. + * + * @see #isFocusable() + * @see #setFocusable(boolean) + * @since 1.4 + */ + boolean focusable = true; + + /** + * Tracks whether this component uses default focus traversal, or has a + * different policy. + * + * @see #isFocusTraversableOverridden() + * @since 1.4 + */ + int isFocusTraversableOverridden; + + /** + * The focus traversal keys, if not inherited from the parent or default + * keyboard manager. These sets will contain only AWTKeyStrokes that + * represent press and release events to use as focus control. + * + * @see #getFocusTraversalKeys(int) + * @see #setFocusTraversalKeys(int, Set) + * @since 1.4 + */ + Set[] focusTraversalKeys; + + /** + * True if focus traversal keys are enabled. This defaults to true for + * Component. If this is true, keystrokes in focusTraversalKeys are trapped + * and processed automatically rather than being passed on to the component. + * + * @see #getFocusTraversalKeysEnabled() + * @see #setFocusTraversalKeysEnabled(boolean) + * @since 1.4 + */ + boolean focusTraversalKeysEnabled = true; + + /** + * Cached information on the minimum size. Should have been transient. + * + * @serial ignore + */ Dimension minSize; + + /** + * Cached information on the preferred size. Should have been transient. + * + * @serial ignore + */ Dimension prefSize; - boolean newEventsOnly; - long eventMask = AWTEvent.PAINT_EVENT_MASK; + + /** + * Set to true if an event is to be handled by this component, false if + * it is to be passed up the hierarcy. + * + * @see #dispatchEvent(AWTEvent) + * @serial true to process event locally + */ + boolean newEventsOnly; + + /** + * Set by subclasses to enable event handling of particular events, and + * left alone when modifying listeners. For component, this defaults to + * enabling only input methods. + * + * @see #enableInputMethods(boolean) + * @see AWTEvent + * @serial the mask of events to process + */ + long eventMask = AWTEvent.INPUT_ENABLED_EVENT_MASK; + + /** + * Describes all registered PropertyChangeListeners. + * + * @see #addPropertyChangeListener(PropertyChangeListener) + * @see #removePropertyChangeListener(PropertyChangeListener) + * @see #firePropertyChange(String, Object, Object) + * @serial the property change listeners + * @since 1.2 + */ PropertyChangeSupport changeSupport; + + /** + * True if the component has been packed (layed out). + * + * @serial true if this is packed + */ boolean isPacked; - int componentSerializedDataVersion; - /* AccessibleContext accessibleContext; */ - /* Anything else is non-serializable, and should be declared "transient". */ - transient Container parent; - transient ComponentPeer peer; + /** + * The serialization version for this class. Currently at version 4. + * + * XXX How do we handle prior versions? + * + * @serial the serialization version + */ + int componentSerializedDataVersion = 4; + + /** + * The accessible context associated with this component. This is only set + * by subclasses. + * + * @see #getAccessibleContext() + * @serial the accessibility context + * @since 1.2 + */ + AccessibleContext accessibleContext; + + + // Guess what - listeners are special cased in serialization. See + // readObject and writeObject. + /** Component listener chain. */ transient ComponentListener componentListener; + + /** Focus listener chain. */ transient FocusListener focusListener; + + /** Key listener chain. */ transient KeyListener keyListener; + + /** Mouse listener chain. */ transient MouseListener mouseListener; + + /** Mouse motion listener chain. */ transient MouseMotionListener mouseMotionListener; + + /** + * Mouse wheel listener chain. + * + * @since 1.4 + */ + transient MouseWheelListener mouseWheelListener; + + /** + * Input method listener chain. + * + * @since 1.2 + */ transient InputMethodListener inputMethodListener; + + /** + * Hierarcy listener chain. + * + * @since 1.3 + */ transient HierarchyListener hierarchyListener; + + /** + * Hierarcy bounds listener chain. + * + * @since 1.3 + */ transient HierarchyBoundsListener hierarchyBoundsListener; + // Anything else is non-serializable, and should be declared "transient". + + /** The parent. */ + transient Container parent; + + /** The associated native peer. */ + transient ComponentPeer peer; + + /** The preferred component orientation. */ transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN; /** - * Default constructor for subclasses. + * The associated graphics configuration. + * + * @since 1.4 + */ + transient GraphicsConfiguration graphicsConfig; + + /** + * The buffer strategy for repainting. + * + * @since 1.4 + */ + transient BufferStrategy bufferStrategy; + + + // Public and protected API. + + /** + * Default constructor for subclasses. When Component is extended directly, + * it forms a lightweight component that must be hosted in an opaque native + * container higher in the tree. */ protected Component() { @@ -186,11 +570,13 @@ public abstract class Component /** * Returns the name of this component. * - * @return The name of this component. + * @return the name of this component + * @see #setName(String) + * @since 1.1 */ public String getName() { - if (name == null && !nameExplicitlySet) + if (name == null && ! nameExplicitlySet) name = generateName(); return name; } @@ -198,44 +584,33 @@ public abstract class Component /** * Sets the name of this component to the specified name. * - * @param name The new name of this component. + * @param name the new name of this component + * @see #getName() + * @since 1.1 */ public void setName(String name) { nameExplicitlySet = true; this.name = name; } - - /** Subclasses should override this to return unique component names like - * "menuitem0". - */ - String generateName() - { - // Component is abstract. - return null; - } /** * Returns the parent of this component. - * - * @return The parent of this component. + * + * @return the parent of this component */ public Container getParent() { - return parent; - } - - // Sets the peer for this component. - final void setPeer (ComponentPeer peer) - { - this.peer = peer; + return parent; } /** - * Returns the native windowing system peer for this component. + * Returns the native windowing system peer for this component. Only the + * platform specific implementation code should call this method. * - * @return The peer for this component. - * @deprecated + * @return the peer for this component + * @deprecated user programs should not directly manipulate peers; use + * {@link #isDisplayable()} instead */ // Classpath's Gtk peers rely on this. public ComponentPeer getPeer() @@ -243,64 +618,56 @@ public abstract class Component return peer; } - // FIXME: java.awt.dnd classes not yet implemented - /* + /** + * Set the associated drag-and-drop target, which receives events when this + * is enabled. + * + * @param dt the new drop target + * @see #isEnabled() + */ public void setDropTarget(DropTarget dt) { this.dropTarget = dt; } - + + /** + * Gets the associated drag-and-drop target, if there is one. + * + * @return the drop target + */ public DropTarget getDropTarget() { return dropTarget; } - */ - - /** @since 1.3 */ + + /** + * Returns the graphics configuration of this component, if there is one. + * If it has not been set, it is inherited from the parent. + * + * @return the graphics configuration, or null + * @since 1.3 + */ public GraphicsConfiguration getGraphicsConfiguration() { return getGraphicsConfigurationImpl(); } - /** Implementation method that allows classes such as Canvas and - Window to override the graphics configuration without violating - the published API. */ - GraphicsConfiguration getGraphicsConfigurationImpl() - { - if (peer != null) - { - GraphicsConfiguration config = peer.getGraphicsConfiguration(); - if (config != null) - return config; - } - - if (parent != null) - return parent.getGraphicsConfiguration(); - - return null; - } - /** * Returns the object used for synchronization locks on this component * when performing tree and layout functions. * - * @return The synchronization lock for this component. + * @return the synchronization lock for this component */ public final Object getTreeLock() { return treeLock; } - // The sync lock object for this component. - final void setTreeLock(Object tree_lock) - { - this.treeLock = tree_lock; - } - /** - * Returns the toolkit in use for this component. + * Returns the toolkit in use for this component. The toolkit is associated + * with the frame this component belongs to. * - * @return The toolkit for this component. + * @return the toolkit for this component */ public Toolkit getToolkit() { @@ -311,23 +678,36 @@ public abstract class Component return tk; } if (parent != null) - return parent.getToolkit (); - return Toolkit.getDefaultToolkit (); + return parent.getToolkit(); + return Toolkit.getDefaultToolkit(); } /** - * Tests whether or not this component is valid. A invalid component needs + * Tests whether or not this component is valid. A invalid component needs * to have its layout redone. * - * @return <code>true</code> if this component is valid, <code>false</code> - * otherwise. + * @return true if this component is valid + * @see #validate() + * @see #invalidate() */ public boolean isValid() { return valid; } - - /** @since 1.2 */ + + /** + * Tests if the component is displayable. It must be connected to a native + * screen resource, and all its ancestors must be displayable. A containment + * hierarchy is made displayable when a window is packed or made visible. + * + * @return true if the component is displayable + * @see Container#add(Component) + * @see Container#remove(Component) + * @see Window#pack() + * @see Window#show() + * @see Window#dispose() + * @since 1.2 + */ public boolean isDisplayable() { if (parent != null) @@ -336,10 +716,11 @@ public abstract class Component } /** - * Tests whether or not this component is visible. + * Tests whether or not this component is visible. Except for top-level + * frames, components are initially visible. * - * @return <code>true</code> if the component is visible, - * <code>false</code> otherwise. + * @return true if the component is visible + * @see #setVisible(boolean) */ public boolean isVisible() { @@ -348,25 +729,26 @@ public abstract class Component /** * Tests whether or not this component is actually being shown on - * the screen. This will be true if and only if it this component is + * the screen. This will be true if and only if it this component is * visible and its parent components are all visible. * - * @return <code>true</code> if the component is showing on the screen, - * <code>false</code> otherwise. + * @return true if the component is showing on the screen + * @see #setVisible(boolean) */ public boolean isShowing() { if (! visible || peer == null) return false; - return parent == null ? true : parent.isShowing (); + return parent == null ? true : parent.isShowing(); } /** - * Tests whether or not this component is enabled. + * Tests whether or not this component is enabled. Components are enabled + * by default, and must be enabled to receive user input or generate events. * - * @return <code>true</code> if the component is enabled, - * <code>false</code> otherwise. + * @return true if the component is enabled + * @see #setEnabled(boolean) */ public boolean isEnabled() { @@ -374,12 +756,14 @@ public abstract class Component } /** - * Enables or disables this component. + * Enables or disables this component. The component must be enabled to + * receive events (except that lightweight components always receive mouse + * events). * - * @param enabled <code>true</code> to enable this component, - * <code>false</code> to disable it. - * - * @deprecated Deprecated in favor of <code>setEnabled()</code>. + * @param enabled true to enable this component + * @see #isEnabled() + * @see #isLightweight() + * @since 1.1 */ public void setEnabled(boolean b) { @@ -391,7 +775,7 @@ public abstract class Component /** * Enables this component. * - * @deprecated Deprecated in favor of <code>setEnabled()</code>. + * @deprecated use {@link #setEnabled(boolean)} instead */ public void enable() { @@ -401,10 +785,8 @@ public abstract class Component /** * Enables or disables this component. * - * @param enabled <code>true</code> to enable this component, - * <code>false</code> to disable it. - * - * @deprecated Deprecated in favor of <code>setEnabled()</code>. + * @param enabled true to enable this component + * @deprecated use {@link #setEnabled(boolean)} instead */ public void enable(boolean b) { @@ -414,206 +796,268 @@ public abstract class Component /** * Disables this component. * - * @deprecated Deprecated in favor of <code>setEnabled()</code>. + * @deprecated use {@link #setEnabled(boolean)} instead */ public void disable() { setEnabled(false); } + /** + * Checks if this image is painted to an offscreen image buffer that is + * later copied to screen (double buffering reduces flicker). This version + * returns false, so subclasses must override it if they provide double + * buffering. + * + * @return true if this is double buffered; defaults to false + */ public boolean isDoubleBuffered() { return false; } - /** @since 1.2 */ + /** + * Enables or disables input method support for this component. By default, + * components have this enabled. Input methods are given the opportunity + * to process key events before this component and its listeners. + * + * @param enable true to enable input method processing + * @see #processKeyEvent(KeyEvent) + * @since 1.2 + */ public void enableInputMethods(boolean enable) { - // FIXME + // XXX Implement. + throw new Error("not implemented"); } /** - * Makes this component visible or invisible. + * Makes this component visible or invisible. Note that it wtill might + * not show the component, if a parent is invisible. * - * @param visible <code>true</code> to make this component visible, - * </code>false</code> to make it invisible. - * @specnote Inspection by subclassing shows that Sun's implementation - * calls show(boolean) which then calls show() or hide(). It is - * the show() method that is overriden in subclasses like Window. - * We do the same to preserve compatibility for subclasses. + * @param visible true to make this component visible + * @see #isVisible() + * @since 1.1 */ public void setVisible(boolean b) { + // Inspection by subclassing shows that Sun's implementation calls + // show(boolean) which then calls show() or hide(). It is the show() + // method that is overriden in subclasses like Window. if (peer != null) - peer.setVisible (b); + peer.setVisible(b); this.visible = b; } /** * Makes this component visible on the screen. * - * @deprecated Deprecated in favor of <code>setVisible()</code>. + * @deprecated use {@link #setVisible(boolean)} instead */ public void show() { - setVisible (true); + setVisible(true); } /** * Makes this component visible or invisible. * - * @param visible <code>true</code> to make this component visible, - * </code>false</code> to make it invisible. - * - * @deprecated Deprecated in favor of <code>setVisible()</code>. + * @param visible true to make this component visible + * @deprecated use {@link #setVisible(boolean)} instead */ public void show(boolean b) { - setVisible (b); + setVisible(b); } /** * Hides this component so that it is no longer shown on the screen. * - * @deprecated Deprecated in favor of <code>setVisible()</code>. + * @deprecated use {@link #setVisible(boolean)} instead */ public void hide() { - setVisible (false); + setVisible(false); } /** - * Returns this component's foreground color. + * Returns this component's foreground color. If not set, this is inherited + * from the parent. * - * @return This component's foreground color. + * @return this component's foreground color, or null + * @see #setForeground(Color) */ public Color getForeground() { if (foreground != null) return foreground; - if (parent != null) - return parent.getForeground(); - return null; + return parent == null ? null : parent.getForeground(); } /** - * Sets this component's foreground color to the specified color. + * Sets this component's foreground color to the specified color. This is a + * bound property. * - * @param foreground_color The new foreground color. + * @param c the new foreground color + * @see #getForeground() */ public void setForeground(Color c) { + firePropertyChange("foreground", foreground, c); if (peer != null) peer.setForeground(c); - this.foreground = c; + foreground = c; + } + + /** + * Tests if the foreground was explicitly set, or just inherited from the + * parent. + * + * @return true if the foreground has been set + * @since 1.4 + */ + public boolean isForegroundSet() + { + return foreground != null; } /** - * Returns this component's background color. + * Returns this component's background color. If not set, this is inherited + * from the parent. * - * @return the background color of the component. null may be - * returned instead of the actual background color, if this - * method is called before the component is added to the - * component hierarchy. + * @return the background color of the component, or null + * @see #setBackground(Color) */ public Color getBackground() { if (background != null) return background; - if (parent != null) - return parent.getBackground(); - return null; + return parent == null ? null : parent.getBackground(); } /** - * Sets this component's background color to the specified color. + * Sets this component's background color to the specified color. The parts + * of the component affected by the background color may by system dependent. + * This is a bound property. * - * @param background_color The new background color + * @param c the new background color + * @see #getBackground() */ public void setBackground(Color c) { + firePropertyChange("background", background, c); if (peer != null) peer.setBackground(c); - this.background = c; + background = c; } /** - * Returns the font in use for this component. + * Tests if the background was explicitly set, or just inherited from the + * parent. * - * @return The font for this component. + * @return true if the background has been set + * @since 1.4 + */ + public boolean isBackgroundSet() + { + return background != null; + } + + /** + * Returns the font in use for this component. If not set, this is inherited + * from the parent. + * + * @return the font for this component + * @see #setFont(Font) */ public Font getFont() { if (font != null) return font; - if (parent != null) - return parent.getFont(); - return null; + return parent == null ? null : parent.getFont(); } /** - * Sets the font for this component to the specified font. + * Sets the font for this component to the specified font. This is a bound + * property. * - * @param font The new font for this component. + * @param font the new font for this component + * @see #getFont() */ public void setFont(Font f) { + firePropertyChange("font", font, f); if (peer != null) peer.setFont(f); - this.font = f; + font = f; } /** - * Returns the locale for this component. If this component does not - * have a locale, the locale of the parent component is returned. If the - * component has no parent, the system default locale is returned. + * Tests if the font was explicitly set, or just inherited from the parent. * - * @return The locale for this component. + * @return true if the font has been set + * @since 1.4 */ - public Locale getLocale() throws IllegalComponentStateException + public boolean isFontSet() + { + return font != null; + } + + /** + * Returns the locale for this component. If this component does not + * have a locale, the locale of the parent component is returned. + * + * @return the locale for this component + * @throws IllegalComponentStateException if it has no locale or parent + * @see setLocale(Locale) + * @since 1.1 + */ + public Locale getLocale() { if (locale != null) return locale; if (parent == null) throw new IllegalComponentStateException - ("Component has no parent: Can not determine Locale"); + ("Component has no parent: can't determine Locale"); return parent.getLocale(); } /** - * Sets the locale for this component to the specified locale. + * Sets the locale for this component to the specified locale. This is a + * bound property. * - * @param locale The new locale for this component. + * @param locale the new locale for this component */ - public void setLocale(Locale l) + public void setLocale(Locale l) { - this.locale = l; - - /* new writing/layout direction perhaps, or make more/less - room for localized text labels */ + firePropertyChange("locale", locale, l); + locale = l; + // New writing/layout direction or more/less room for localized labels. invalidate(); } /** * Returns the color model of the device this componet is displayed on. * - * @return This object's color model. + * @return this object's color model + * @see Toolkit#getColorModel() */ public ColorModel getColorModel() { GraphicsConfiguration config = getGraphicsConfiguration(); - - if (config != null) - return config.getColorModel(); - - return getToolkit().getColorModel(); + return config != null ? config.getColorModel() + : getToolkit().getColorModel(); } /** * Returns the location of this component's top left corner relative to - * its parent component. + * its parent component. This may be outdated, so for synchronous behavior, + * you should use a component listner. * - * @return The location of this component. + * @return the location of this component + * @see #setLocation(int, int) + * @see #getLocationOnScreen() + * @since 1.1 */ public Point getLocation() { @@ -624,25 +1068,23 @@ public abstract class Component * Returns the location of this component's top left corner in screen * coordinates. * - * @return The location of this component in screen coordinates. + * @return the location of this component in screen coordinates + * @throws IllegalComponentStateException if the component is not showing */ public Point getLocationOnScreen() { - if (! isShowing ()) - throw new IllegalComponentStateException ("component not showing"); - + if (! isShowing()) + throw new IllegalComponentStateException("component not showing"); // We know peer != null here. - return peer.getLocationOnScreen (); + return peer.getLocationOnScreen(); } /** * Returns the location of this component's top left corner relative to * its parent component. * - * @return The location of this component. - * - * @deprecated This method is deprecated in favor of - * <code>getLocation()</code>. + * @return the location of this component + * @deprecated use {@link #getLocation()} instead */ public Point location() { @@ -650,19 +1092,20 @@ public abstract class Component } /** - * Moves this component to the specified location. The coordinates are - * the new upper left corner of this component. + * Moves this component to the specified location, relative to the parent's + * coordinates. The coordinates are the new upper left corner of this + * component. * - * @param x The new X coordinate of this component. - * @param y The new Y coordinate of this component. + * @param x the new X coordinate of this component + * @param y the new Y coordinate of this component + * @see #getLocation() + * @see #setBounds(int, int, int, int) */ - public void setLocation (int x, int y) + public void setLocation(int x, int y) { - if ((this.x == x) && (this.y == y)) + if (this.x == x && this.y == y) return; - invalidate(); - this.x = x; this.y = y; if (peer != null) @@ -670,24 +1113,29 @@ public abstract class Component } /** - * Moves this component to the specified location. The coordinates are - * the new upper left corner of this component. + * Moves this component to the specified location, relative to the parent's + * coordinates. The coordinates are the new upper left corner of this + * component. * - * @param x The new X coordinate of this component. - * @param y The new Y coordinate of this component. - * - * @deprecated Deprecated in favor for <code>setLocation</code>. + * @param x the new X coordinate of this component + * @param y the new Y coordinate of this component + * @deprecated use {@link #setLocation(int, int)} instead */ public void move(int x, int y) { - setLocation(x,y); + setLocation(x, y); } /** - * Moves this component to the specified location. The coordinates are - * the new upper left corner of this component. + * Moves this component to the specified location, relative to the parent's + * coordinates. The coordinates are the new upper left corner of this + * component. * - * @param p New coordinates for this component. + * @param p new coordinates for this component + * @throws NullPointerException if p is null + * @see #getLocation() + * @see #setBounds(int, int, int, int) + * @since 1.1 */ public void setLocation(Point p) { @@ -697,7 +1145,9 @@ public abstract class Component /** * Returns the size of this object. * - * @return The size of this object. + * @return the size of this object + * @see #setSize(int, int) + * @since 1.1 */ public Dimension getSize() { @@ -707,9 +1157,8 @@ public abstract class Component /** * Returns the size of this object. * - * @return The size of this object. - * - * @deprecated This method is deprecated in favor of <code>getSize</code>. + * @return the size of this object + * @deprecated use {@link #getSize()} instead */ public Dimension size() { @@ -718,17 +1167,17 @@ public abstract class Component /** * Sets the size of this component to the specified width and height. - * - * @param width The new width of this component. - * @param height The new height of this component. + * + * @param width the new width of this component + * @param height the new height of this component + * @see #getSize() + * @see #setBounds(int, int, int, int) */ public void setSize(int width, int height) { - if ((this.width == width) && (this.height == height)) + if (this.width == width && this.height == height) return; - invalidate(); - this.width = width; this.height = height; if (peer != null) @@ -737,11 +1186,10 @@ public abstract class Component /** * Sets the size of this component to the specified value. - * - * @param width The new width of the component. - * @param height The new height of the component. * - * @deprecated This method is deprecated in favor of <code>setSize</code>. + * @param width the new width of the component + * @param height the new height of the component + * @deprecated use {@link #setSize(int, int)} instead */ public void resize(int width, int height) { @@ -750,8 +1198,12 @@ public abstract class Component /** * Sets the size of this component to the specified value. - * - * @param dim The new size of this component. + * + * @param d the new size of this component + * @throws NullPointerException if d is null + * @see #setSize(int, int) + * @see #setBounds(int, int, int, int) + * @since 1.1 */ public void setSize(Dimension d) { @@ -760,10 +1212,10 @@ public abstract class Component /** * Sets the size of this component to the specified value. - * - * @param dim The new size of this component. * - * @deprecated This method is deprecated in favor of <code>setSize</code>. + * @param d the new size of this component + * @throws NullPointerException if d is null + * @deprecated use {@link #setSize(Dimension)} instead */ public void resize(Dimension d) { @@ -771,25 +1223,27 @@ public abstract class Component } /** - * Returns a bounding rectangle for this component. Note that the + * Returns a bounding rectangle for this component. Note that the * returned rectange is relative to this component's parent, not to * the screen. * - * @return The bounding rectangle for this component. + * @return the bounding rectangle for this component + * @see #setBounds(int, int, int, int) + * @see #getLocation() + * @see #getSize() */ public Rectangle getBounds() { - return new Rectangle (x, y, width, height); + return new Rectangle(x, y, width, height); } /** - * Returns a bounding rectangle for this component. Note that the + * Returns a bounding rectangle for this component. Note that the * returned rectange is relative to this component's parent, not to * the screen. * - * @return The bounding rectangle for this component. - * - * @deprecated Deprecated in favor of <code>getBounds()</code>. + * @return the bounding rectangle for this component + * @deprecated use {@link #getBounds()} instead */ public Rectangle bounds() { @@ -797,46 +1251,42 @@ public abstract class Component } /** - * Sets the bounding rectangle for this component to the specified - * values. Note that these coordinates are relative to the parent, - * not to the screen. + * Sets the bounding rectangle for this component to the specified values. + * Note that these coordinates are relative to the parent, not to the screen. * - * @param x The X coordinate of the upper left corner of the rectangle. - * @param y The Y coordinate of the upper left corner of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. + * @param x the X coordinate of the upper left corner of the rectangle + * @param y the Y coordinate of the upper left corner of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @see #getBounds() + * @see #setLocation(int, int) + * @see #setLocation(Point) + * @see #setSize(int, int) + * @see #setSize(Dimension) + * @since 1.1 */ public void setBounds(int x, int y, int w, int h) { - if (this.x == x - && this.y == y - && this.width == w - && this.height == h) + if (this.x == x && this.y == y && width == w && height == h) return; - invalidate(); - this.x = x; this.y = y; - this.width = w; - this.height = h; - + width = w; + height = h; if (peer != null) peer.setBounds(x, y, w, h); } /** - * Sets the bounding rectangle for this component to the specified - * values. Note that these coordinates are relative to the parent, - * not to the screen. + * Sets the bounding rectangle for this component to the specified values. + * Note that these coordinates are relative to the parent, not to the screen. * - * @param x The X coordinate of the upper left corner of the rectangle. - * @param y The Y coordinate of the upper left corner of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - * - * @deprecated This method is deprecated in favor of - * <code>setBounds(int, int, int, int)</code>. + * @param x the X coordinate of the upper left corner of the rectangle + * @param y the Y coordinate of the upper left corner of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @deprecated use {@link #setBounds(int, int, int, int)} instead */ public void reshape(int x, int y, int width, int height) { @@ -845,100 +1295,169 @@ public abstract class Component /** * Sets the bounding rectangle for this component to the specified - * rectangle. Note that these coordinates are relative to the parent, - * not to the screen. + * rectangle. Note that these coordinates are relative to the parent, not + * to the screen. * - * @param bounding_rectangle The new bounding rectangle. + * @param r the new bounding rectangle + * @throws NullPointerException if r is null + * @see #getBounds() + * @see #setLocation(Point) + * @see #setSize(Dimension) + * @since 1.1 */ public void setBounds(Rectangle r) - { + { setBounds(r.x, r.y, r.width, r.height); } - - /** @since 1.2 */ + + /** + * Gets the x coordinate of the upper left corner. This is more efficient + * than getBounds().x or getLocation().x. + * + * @return the current x coordinate + * @since 1.2 + */ public int getX() { return x; } - - /** @since 1.2 */ + + /** + * Gets the y coordinate of the upper left corner. This is more efficient + * than getBounds().y or getLocation().y. + * + * @return the current y coordinate + * @since 1.2 + */ public int getY() { return y; } - - /** @since 1.2 */ + + /** + * Gets the width of the component. This is more efficient than + * getBounds().width or getSize().width. + * + * @return the current width + * @since 1.2 + */ public int getWidth() { return width; } - - /** @since 1.2 */ + + /** + * Gets the height of the component. This is more efficient than + * getBounds().height or getSize().height. + * + * @return the current width + * @since 1.2 + */ public int getHeight() { return height; } - + + /** + * Returns the bounds of this component. This allows reuse of an existing + * rectangle, if r is non-null. + * + * @param r the rectangle to use, or null + * @return the bounds + */ public Rectangle getBounds(Rectangle r) { - r.x = this.x; - r.y = this.y; - r.width = this.width; - r.height = this.height; + if (r == null) + r = new Rectangle(); + r.x = x; + r.y = y; + r.width = width; + r.height = height; return r; } - + + /** + * Returns the size of this component. This allows reuse of an existing + * dimension, if d is non-null. + * + * @param d the dimension to use, or null + * @return the size + */ public Dimension getSize(Dimension d) { - d.width = this.width; - d.height = this.height; + if (d == null) + d = new Dimension(); + d.width = width; + d.height = height; return d; } - + + /** + * Returns the location of this component. This allows reuse of an existing + * point, if p is non-null. + * + * @param p the point to use, or null + * @return the location + */ public Point getLocation(Point p) { + if (p == null) + p = new Point(); p.x = x; p.y = y; return p; } - - /** @since 1.2 */ + + /** + * Tests if this component is opaque. All "heavyweight" (natively-drawn) + * components are opaque. A component is opaque if it draws all pixels in + * the bounds; a lightweight component is partially transparent if it lets + * pixels underneath show through. Subclasses that guarantee that all pixels + * will be drawn should override this. + * + * @return true if this is opaque + * @see #isLightweight() + * @since 1.2 + */ public boolean isOpaque() { - return !isLightweight(); + return ! isLightweight(); } - - /** - * Return whether the component is lightweight. - * - * @return true if component has a peer and and the peer is lightweight. + + /** + * Return whether the component is lightweight. That means the component has + * no native peer, but is displayable. This applies to subclasses of + * Component not in this package, such as javax.swing. * + * @return true if the component has a lightweight peer + * @see #isDisplayable() * @since 1.2 - */ + */ public boolean isLightweight() { - return (peer != null) && (peer instanceof LightweightPeer); + return peer instanceof LightweightPeer; } /** * Returns the component's preferred size. * - * @return The component's preferred size. + * @return the component's preferred size + * @see #getMinimumSize() + * @see LayoutManager */ public Dimension getPreferredSize() { - if (peer == null) - return new Dimension(width, height); - else - return peer.getPreferredSize(); + if (prefSize == null) + prefSize = (peer != null ? peer.getPreferredSize() + : new Dimension(width, height)); + return prefSize; } /** * Returns the component's preferred size. * - * @return The component's preferred size. - * - * @deprecated Deprecated in favor of <code>getPreferredSize()</code>. + * @return the component's preferred size + * @deprecated use {@link #getPreferredSize()} instead */ public Dimension preferredSize() { @@ -948,22 +1467,23 @@ public abstract class Component /** * Returns the component's minimum size. * - * @return The component's minimum size. + * @return the component's minimum size + * @see #getPreferredSize() + * @see LayoutManager */ public Dimension getMinimumSize() { - if (peer == null) - return new Dimension(width, height); - else - return peer.getMinimumSize(); + if (minSize == null) + minSize = (peer != null ? peer.getMinimumSize() + : new Dimension(width, height)); + return minSize; } /** * Returns the component's minimum size. * - * @return The component's minimum size. - * - * @deprecated Deprecated in favor of <code>getMinimumSize()</code> + * @return the component's minimum size + * @deprecated use {@link #getMinimumSize()} instead */ public Dimension minimumSize() { @@ -973,7 +1493,10 @@ public abstract class Component /** * Returns the component's maximum size. * - * @return The component's maximum size. + * @return the component's maximum size + * @see #getMinimumSize() + * @see #getPreferredSize() + * @see LayoutManager */ public Dimension getMaximumSize() { @@ -981,10 +1504,11 @@ public abstract class Component } /** - * Returns the preferred horizontal alignment of this component. The - * value returned will be one of the constants defined in this class. + * Returns the preferred horizontal alignment of this component. The value + * returned will be between {@link #LEFT_ALIGNMENT} and + * {@link #RIGHT_ALIGNMENT}, inclusive. * - * @return The preferred horizontal alignment of this component. + * @return the preferred horizontal alignment of this component */ public float getAlignmentX() { @@ -992,10 +1516,11 @@ public abstract class Component } /** - * Returns the preferred vertical alignment of this component. The - * value returned will be one of the constants defined in this class. + * Returns the preferred vertical alignment of this component. The value + * returned will be between {@link #TOP_ALIGNMENT} and + * {@link #BOTTOM_ALIGNMENT}, inclusive. * - * @return The preferred vertical alignment of this component. + * @return the preferred vertical alignment of this component */ public float getAlignmentY() { @@ -1003,8 +1528,11 @@ public abstract class Component } /** - * Calls the layout manager to re-layout the component. This is called + * Calls the layout manager to re-layout the component. This is called * during validation of a container in most cases. + * + * @see #validate() + * @see LayoutManager */ public void doLayout() { @@ -1012,10 +1540,10 @@ public abstract class Component } /** - * Calls the layout manager to re-layout the component. This is called + * Calls the layout manager to re-layout the component. This is called * during validation of a container in most cases. * - * @deprecated This method is deprecated in favor of <code>doLayout()</code>. + * @deprecated use {@link #doLayout()} instead */ public void layout() { @@ -1023,7 +1551,13 @@ public abstract class Component } /** - * Called to ensure that the layout for this component is valid. + * Called to ensure that the layout for this component is valid. This is + * usually called on containers. + * + * @see #invalidate() + * @see #doLayout() + * @see LayoutManager + * @see Container#validate() */ public void validate() { @@ -1031,22 +1565,25 @@ public abstract class Component } /** - * Invalidates this component and all of its parent components. This will - * cause them to have their layout redone. + * Invalidates this component and all of its parent components. This will + * cause them to have their layout redone. This is called frequently, so + * make it fast. */ public void invalidate() { valid = false; - - if ((parent != null) && parent.valid) - parent.invalidate (); + prefSize = null; + minSize = null; + if (parent != null && parent.valid) + parent.invalidate(); } /** - * Returns a graphics object for this component. Returns <code>null</code> + * Returns a graphics object for this component. Returns <code>null</code> * if this component is not currently displayed on the screen. * - * @return A graphics object for this component. + * @return a graphics object for this component + * @see #paint(Graphics) */ public Graphics getGraphics() { @@ -1055,7 +1592,6 @@ public abstract class Component Graphics gfx = peer.getGraphics(); if (gfx != null) return gfx; - // create graphics for lightweight: Container parent = getParent(); if (parent != null) @@ -1073,57 +1609,89 @@ public abstract class Component /** * Returns the font metrics for the specified font in this component. * - * @param font The font to retrieve metrics for. - * - * @return The font metrics for the specified font. + * @param font the font to retrieve metrics for + * @return the font metrics for the specified font + * @throws NullPointerException if font is null + * @see #getFont() + * @see Toolkit#getFontMetrics(Font) */ public FontMetrics getFontMetrics(Font font) { - if (peer == null) - return getToolkit().getFontMetrics(font); - return peer.getFontMetrics (font); + return peer == null ? getToolkit().getFontMetrics(font) + : peer.getFontMetrics(font); } /** - * Sets the cursor for this component to the specified cursor. + * Sets the cursor for this component to the specified cursor. The cursor + * is displayed when the point is contained by the component, and the + * component is visible, displayable, and enabled. This is inherited by + * subcomponents unless they set their own cursor. * - * @param cursor The new cursor for this component. + * @param cursor the new cursor for this component + * @see #isEnabled() + * @see #isShowing() + * @see #getCursor() + * @see #contains(int, int) + * @see Toolkit#createCustomCursor(Image, Point, String) */ public void setCursor(Cursor cursor) { this.cursor = cursor; if (peer != null) - peer.setCursor (cursor); + peer.setCursor(cursor); } /** - * Returns the cursor for this component. + * Returns the cursor for this component. If not set, this is inherited + * from the parent, or from Cursor.getDefaultCursor(). * - * @return The cursor for this component. + * @return the cursor for this component */ public Cursor getCursor() { - return this.cursor; + if (cursor != null) + return cursor; + return parent != null ? parent.getCursor() : Cursor.getDefaultCursor(); + } + + /** + * Tests if the cursor was explicitly set, or just inherited from the parent. + * + * @return true if the cursor has been set + * @since 1.4 + */ + public boolean isCursorSet() + { + return cursor != null; } /** - * Paints this component on the screen. The clipping region in the - * graphics context will indicate the region that requires painting. + * Paints this component on the screen. The clipping region in the graphics + * context will indicate the region that requires painting. This is called + * whenever the component first shows, or needs to be repaired because + * something was temporarily drawn on top. It is not necessary for + * subclasses to call <code>super.paint(g)</code>. Components with no area + * are not painted. * - * @param graphics The graphics context for this paint job. + * @param g the graphics context for this paint job + * @see #update(Graphics) */ public void paint(Graphics g) { } /** - * Updates this component. This method fills the component - * with the background color, then sets the foreground color of the - * specified graphics context to the foreground color of this component - * and calls the <code>paint()</code> method. - * // FIXME: What are the coords relative to? + * Updates this component. This is called in response to + * <code>repaint</code>. This method fills the component with the + * background color, then sets the foreground color of the specified + * graphics context to the foreground color of this component and calls + * the <code>paint()</code> method. The coordinates of the graphics are + * relative to this component. Subclasses should call either + * <code>super.update(g)</code> or <code>paint(g)</code>. * - * @param graphics The graphics context for this update. + * @param graphics the graphics context for this update + * @see #paint(Graphics) + * @see #repaint() */ public void update(Graphics g) { @@ -1133,92 +1701,93 @@ public abstract class Component /** * Paints this entire component, including any sub-components. * - * @param graphics The graphics context for this paint job. + * @param graphics the graphics context for this paint job + * @see #paint(Graphics) */ public void paintAll(Graphics g) - { - if (!visible) + { + if (! visible) return; - if (peer != null) peer.paint(g); paint(g); } /** - * Repaint this entire component. The <code>update()</code> method + * Repaint this entire component. The <code>update()</code> method * on this component will be called as soon as possible. - * // FIXME: What are the coords relative to? + * + * @see #update(Graphics) + * @see #repaint(long, int, int, int, int) */ public void repaint() { - repaint(0, 0, 0, getWidth(), getHeight()); + repaint(0, 0, 0, width, height); } /** - * Repaint this entire component. The <code>update()</code> method - * on this component will be called in approximate the specified number - * of milliseconds. - * // FIXME: What are the coords relative to? + * Repaint this entire component. The <code>update()</code> method on this + * component will be called in approximate the specified number of + * milliseconds. * - * @param tm The number of milliseconds before this component should - * be repainted. + * @param tm milliseconds before this component should be repainted + * @see #paint(Graphics) + * @see #repaint(long, int, int, int, int) */ public void repaint(long tm) { - repaint(tm, 0, 0, getWidth(), getHeight()); + repaint(tm, 0, 0, width, height); } /** - * Repaints the specified rectangular region within this component. - * This <code>update</code> method on this component will be called as - * soon as possible. - * // FIXME: What are the coords relative to? + * Repaints the specified rectangular region within this component. The + * <code>update</code> method on this component will be called as soon as + * possible. The coordinates are relative to this component. * - * @param x The X coordinate of the upper left of the region to repaint - * @param y The Y coordinate of the upper left of the region to repaint - * @param width The width of the region to repaint. - * @param height The height of the region to repaint. + * @param x the X coordinate of the upper left of the region to repaint + * @param y the Y coordinate of the upper left of the region to repaint + * @param w the width of the region to repaint + * @param h the height of the region to repaint + * @see #update(Graphics) + * @see #repaint(long, int, int, int, int) */ - public void repaint(int x, int y, int width, int height) + public void repaint(int x, int y, int w, int h) { - repaint(0, x, y, width, height); + repaint(0, x, y, w, h); } /** - * Repaints the specified rectangular region within this component. - * This <code>update</code> method on this component will be called in - * approximately the specified number of milliseconds. - * // FIXME: What are the coords relative to? + * Repaints the specified rectangular region within this component. The + * <code>update</code> method on this component will be called in + * approximately the specified number of milliseconds. The coordinates + * are relative to this component. * - * @param tm The number of milliseconds before this component should - * be repainted. - * @param x The X coordinate of the upper left of the region to repaint - * @param y The Y coordinate of the upper left of the region to repaint - * @param width The width of the region to repaint. - * @param height The height of the region to repaint. + * @param tm milliseconds before this component should be repainted + * @param x the X coordinate of the upper left of the region to repaint + * @param y the Y coordinate of the upper left of the region to repaint + * @param w the width of the region to repaint + * @param h the height of the region to repaint + * @see #update(Graphics) */ public void repaint(long tm, int x, int y, int width, int height) - { + { // Handle lightweight repainting by forwarding to native parent - if (isLightweight() && (parent != null)) + if (isLightweight() && parent != null) { if (parent != null) - parent.repaint(tm, x+getX(), y+getY(), width, height); - return; + parent.repaint(tm, x + getX(), y + getY(), width, height); } - - if (peer != null) + else if (peer != null) peer.repaint(tm, x, y, width, height); } /** - * Prints this component. This method is - * provided so that printing can be done in a different manner from - * painting. However, the implementation in this class simply calls - * the <code>paint()</code> method. + * Prints this component. This method is provided so that printing can be + * done in a different manner from painting. However, the implementation + * in this class simply calls the <code>paint()</code> method. * - * @param graphics The graphics context of the print device. + * @param graphics the graphics context of the print device + * @see #paint(Graphics) */ public void print(Graphics g) { @@ -1226,12 +1795,13 @@ public abstract class Component } /** - * Prints this component, including all sub-components. This method is + * Prints this component, including all sub-components. This method is * provided so that printing can be done in a different manner from - * painting. However, the implementation in this class simply calls - * the <code>paintAll()</code> method. + * painting. However, the implementation in this class simply calls the + * <code>paintAll()</code> method. * - * @param graphics The graphics context of the print device. + * @param graphics the graphics context of the print device + * @see #paintAll(Graphics) */ public void printAll(Graphics g) { @@ -1239,65 +1809,115 @@ public abstract class Component } /** - * Called when an image has changed so that this component is - * repainted. + * Called when an image has changed so that this component is repainted. + * This incrementally draws an image as more bits are available, when + * possible. Incremental drawing is enabled if the system property + * <code>awt.image.incrementalDraw</code> is not present or is true, in which + * case the redraw rate is set to 100ms or the value of the system property + * <code>awt.image.redrawrate</code>. * - * @param image The image that has been updated. - * @param flags Flags as specified in <code>ImageObserver</code>. - * @param x The X coordinate - * @param y The Y coordinate - * @param width The width - * @param height The height + * <p>The coordinate system used depends on the particular flags. * - * @return <code>true</code> if the image has been fully loaded, - * <code>false</code> otherwise. + * @param image the image that has been updated + * @param flags tlags as specified in <code>ImageObserver</code> + * @param x the X coordinate + * @param y the Y coordinate + * @param w the width + * @param h the height + * @return true if the image has been fully loaded + * @see ImageObserver + * @see Graphics#drawImage(Image, int, int, Color, ImageObserver) + * @see Graphics#drawImage(Image, int, int, ImageObserver) + * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver) + * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver) + * @see ImageObserver#update(Image, int, int, int, int, int) */ - public boolean imageUpdate (Image img, int infoflags, int x, int y, - int w, int h) + public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) { - // FIXME - return false; + // XXX Implement. + throw new Error("not implemented"); } /** * Creates an image from the specified producer. * - * @param producer The image procedure to create the image from. - * - * @return The resulting image. + * @param producer the image procedure to create the image from + * @return the resulting image */ public Image createImage(ImageProducer producer) { + // XXX What if peer or producer is null? return peer.createImage(producer); } /** * Creates an image with the specified width and height for use in - * double buffering. - * - * @param width The width of the image. - * @param height The height of the image. + * double buffering. Headless environments do not support images. * - * @return The requested image. + * @param width the width of the image + * @param height the height of the image + * @return the requested image, or null if it is not supported */ public Image createImage(int width, int height) { - return getGraphicsConfiguration().createCompatibleImage(width, height); + if (GraphicsEnvironment.isHeadless()) + return null; + GraphicsConfiguration config = getGraphicsConfiguration(); + return config == null ? null : config.createCompatibleImage(width, height); } /** - * Prepares the specified image for rendering on this component. + * Creates an image with the specified width and height for use in + * double buffering. Headless environments do not support images. * - * @param image The image to prepare for rendering. - * @param observer The image observer to notify of the status of the - * image preparation. + * @param width the width of the image + * @param height the height of the image + * @return the requested image, or null if it is not supported + * @since 1.4 + */ + public VolatileImage createVolatileImage(int width, int height) + { + if (GraphicsEnvironment.isHeadless()) + return null; + GraphicsConfiguration config = getGraphicsConfiguration(); + return config == null ? null + : config.createCompatibleVolatileImage(width, height); + } + + /** + * Creates an image with the specified width and height for use in + * double buffering. Headless environments do not support images. The image + * will support the specified capabilities. * - * @return <code>true</code> if the image is already fully prepared - * for rendering, <code>false</code> otherwise. + * @param width the width of the image + * @param height the height of the image + * @param caps the requested capabilities + * @return the requested image, or null if it is not supported + * @throws AWTException if a buffer with the capabilities cannot be created + * @since 1.4 + */ + public VolatileImage createVolatileImage(int width, int height, + ImageCapabilities caps) + throws AWTException + { + if (GraphicsEnvironment.isHeadless()) + return null; + GraphicsConfiguration config = getGraphicsConfiguration(); + return config == null ? null + : config.createCompatibleVolatileImage(width, height, caps); + } + + /** + * Prepares the specified image for rendering on this component. + * + * @param image the image to prepare for rendering + * @param observer the observer to notify of image preparation status + * @return true if the image is already fully prepared + * @throws NullPointerException if image is null */ public boolean prepareImage(Image image, ImageObserver observer) { - return prepareImage(image, image.getWidth(observer), + return prepareImage(image, image.getWidth(observer), image.getHeight(observer), observer); } @@ -1305,14 +1925,11 @@ public abstract class Component * Prepares the specified image for rendering on this component at the * specified scaled width and height * - * @param image The image to prepare for rendering. - * @param width The scaled width of the image. - * @param height The scaled height of the image. - * @param observer The image observer to notify of the status of the - * image preparation. - * - * @return <code>true</code> if the image is already fully prepared - * for rendering, <code>false</code> otherwise. + * @param image the image to prepare for rendering + * @param width the scaled width of the image + * @param height the scaled height of the image + * @param observer the observer to notify of image preparation status + * @return true if the image is already fully prepared */ public boolean prepareImage(Image image, int width, int height, ImageObserver observer) @@ -1324,15 +1941,16 @@ public abstract class Component * Returns the status of the loading of the specified image. The value * returned will be those flags defined in <code>ImageObserver</code>. * - * @param image The image to check on. - * @param observer The observer to be notified as the image loading - * progresses. - * - * @return The image observer flags indicating the status of the load. + * @param image the image to check on + * @param observer the observer to notify of image loading progress + * @return the image observer flags indicating the status of the load + * @see #prepareImage(Image, int, int, ImageObserver) + * @see #Toolkit#checkImage(Image, int, int, ImageObserver) + * @throws NullPointerException if image is null */ public int checkImage(Image image, ImageObserver observer) { - return checkImage(image, image.getWidth(observer), + return checkImage(image, image.getWidth(observer), image.getHeight(observer), observer); } @@ -1340,62 +1958,88 @@ public abstract class Component * Returns the status of the loading of the specified image. The value * returned will be those flags defined in <code>ImageObserver</code>. * - * @param image The image to check on. - * @param width The scaled image width. - * @param height The scaled image height. - * @param observer The observer to be notified as the image loading - * progresses. - * - * @return The image observer flags indicating the status of the load. + * @param image the image to check on + * @param width the scaled image width + * @param height the scaled image height + * @param observer the observer to notify of image loading progress + * @return the image observer flags indicating the status of the load + * @see #prepareImage(Image, int, int, ImageObserver) + * @see #Toolkit#checkImage(Image, int, int, ImageObserver) */ - public int checkImage (Image image, int width, int height, - ImageObserver observer) + public int checkImage(Image image, int width, int height, + ImageObserver observer) { if (peer != null) - return peer.checkImage (image, width, height, observer); - return getToolkit ().checkImage (image, width, height, observer); + return peer.checkImage(image, width, height, observer); + return getToolkit().checkImage(image, width, height, observer); } /** - * Tests whether or not the specified point is contained within this - * component. Coordinates are relative to this component. + * Sets whether paint messages delivered by the operating system should be + * ignored. This does not affect messages from AWT, except for those + * triggered by OS messages. Setting this to true can allow faster + * performance in full-screen mode or page-flipping. * - * @param x The X coordinate of the point to test. - * @param y The Y coordinate of the point to test. + * @param ignoreRepaint the new setting for ignoring repaint events + * @see #getIgnoreRepaint() + * @see BufferStrategy + * @see GraphicsDevice.setFullScreenWindow(Window) + * @since 1.4 + */ + public void setIgnoreRepaint(boolean ignoreRepaint) + { + this.ignoreRepaint = ignoreRepaint; + } + + /** + * Test whether paint events from the operating system are ignored. * - * @return <code>true</code> if the point is within this component, - * <code>false</code> otherwise. + * @return the status of ignoring paint events + * @see #setIgnoreRepaint(boolean) + * @since 1.4 */ - public boolean contains (int x, int y) + public boolean getIgnoreRepaint() { - return (x >= 0) && (y >= 0) && (x < width) && (y < height); + return ignoreRepaint; } /** * Tests whether or not the specified point is contained within this - * component. Coordinates are relative to this component. - * - * @param x The X coordinate of the point to test. - * @param y The Y coordinate of the point to test. + * component. Coordinates are relative to this component. * - * @return <code>true</code> if the point is within this component, - * <code>false</code> otherwise. + * @param x the X coordinate of the point to test + * @param y the Y coordinate of the point to test + * @return true if the point is within this component + * @see #getComponentAt(int, int) + */ + public boolean contains(int x, int y) + { + return x >= 0 && y >= 0 && x < width && y < height; + } + + /** + * Tests whether or not the specified point is contained within this + * component. Coordinates are relative to this component. * - * @deprecated Deprecated in favor of <code>contains(int, int)</code>. + * @param x the X coordinate of the point to test + * @param y the Y coordinate of the point to test + * @return true if the point is within this component + * @deprecated use {@link #contains(int, int)} instead */ public boolean inside(int x, int y) { - return contains(x,y); + return contains(x, y); } /** * Tests whether or not the specified point is contained within this - * component. Coordinates are relative to this component. - * - * @param point The point to test. + * component. Coordinates are relative to this component. * - * @return <code>true</code> if the point is within this component, - * <code>false</code> otherwise. + * @param p the point to test + * @return true if the point is within this component + * @throws NullPointerException if p is null + * @see #getComponentAt(Point) + * @since 1.1 */ public boolean contains(Point p) { @@ -1403,36 +2047,29 @@ public abstract class Component } /** - * Returns the component occupying the position (x,y). This will either + * Returns the component occupying the position (x,y). This will either * be this component, an immediate child component, or <code>null</code> * if neither of the first two occupies the specified location. * - * @param x The X coordinate to search for components at. - * @param y The Y coordinate to search for components at. - * - * @return The component at the specified location, for <code>null</code> - * if there is none. + * @param x the X coordinate to search for components at + * @param y the Y coordinate to search for components at + * @return the component at the specified location, or null + * @see #contains(int, int) */ public Component getComponentAt(int x, int y) { - if (contains(x,y)) - return this; - return null; + return contains(x, y) ? this : null; } /** - * Returns the component occupying the position (x,y). This will either + * Returns the component occupying the position (x,y). This will either * be this component, an immediate child component, or <code>null</code> * if neither of the first two occupies the specified location. * - * @param x The X coordinate to search for components at. - * @param y The Y coordinate to search for components at. - * - * @return The component at the specified location, for <code>null</code> - * if there is none. - * - * @deprecated The method is deprecated in favor of - * <code>getComponentAt()</code>. + * @param x the X coordinate to search for components at + * @param y the Y coordinate to search for components at + * @return the component at the specified location, or null + * @deprecated use {@link #getComponentAt(int, int)} instead */ public Component locate(int x, int y) { @@ -1440,14 +2077,15 @@ public abstract class Component } /** - * Returns the component occupying the specified point This will either + * Returns the component occupying the position (x,y). This will either * be this component, an immediate child component, or <code>null</code> * if neither of the first two occupies the specified location. * - * @param point The point to search for components at. - * - * @return The component at the specified location, for <code>null</code> - * if there is none. + * @param p the point to search for components at + * @return the component at the specified location, or null + * @throws NullPointerException if p is null + * @see #contains(Point) + * @since 1.1 */ public Component getComponentAt(Point p) { @@ -1457,91 +2095,55 @@ public abstract class Component /** * AWT 1.0 event dispatcher. * - * @deprecated Deprecated in favor of <code>dispatchEvent()</code>. + * @param e the event to dispatch + * @deprecated use {@link #dispatchEvent(AWTEvent)} instead */ public void deliverEvent(Event e) { + // XXX Add backward compatibility handling. } - /** Forward AWT events to processEvent() if: - * - Events have been enabled for this type of event via enableEvents(), - * OR: - * - There is at least one registered listener for this type of event - * - * @param event The event to dispatch - * - * @specnote This method is final, but we need to be able to - * override it in order to handle other event types in our - * subclasses. The solution is to define a second, non-final - * method - dispatchEventImpl() - to actually do the work. - * Investigations with Thread.dumpStack() on the dispatch thread - * in JDK 1.3 show Sun's implementation is doing the same - * thing. - */ + /** + * Forwards AWT events to processEvent() if:<ul> + * <li>Events have been enabled for this type of event via + * <code>enableEvents()</code></li>, + * <li>There is at least one registered listener for this type of event</li> + * </ul> + * + * @param e the event to dispatch + */ public final void dispatchEvent(AWTEvent e) { + // Some subclasses in the AWT package need to override this behavior, + // hence the use of dispatchEventImpl(). dispatchEventImpl(e); - - /* Give the peer a chance to handle the event. */ - if (peer != null) + if (peer != null && ! e.consumed) peer.handleEvent(e); } - void dispatchEventImpl(AWTEvent e) - { - // Make use of event id's in order to avoid multiple instanceof tests. - if (e.id <= ComponentEvent.COMPONENT_LAST - && e.id >= ComponentEvent.COMPONENT_FIRST - && (componentListener != null - || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)) - processEvent(e); - else if (e.id <= KeyEvent.KEY_LAST - && e.id >= KeyEvent.KEY_FIRST - && (keyListener != null - || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0)) - processEvent(e); - else if (e.id <= MouseEvent.MOUSE_LAST - && e.id >= MouseEvent.MOUSE_FIRST - && (mouseListener != null - || mouseMotionListener != null - || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) - processEvent(e); - else if (e.id <= FocusEvent.FOCUS_LAST - && e.id >= FocusEvent.FOCUS_FIRST - && (focusListener != null - || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0)) - processEvent(e); - else if (e.id <= InputMethodEvent.INPUT_METHOD_LAST - && e.id >= InputMethodEvent.INPUT_METHOD_FIRST - && (inputMethodListener != null - || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0)) - processEvent(e); - else if (e.id <= HierarchyEvent.HIERARCHY_LAST - && e.id >= HierarchyEvent.HIERARCHY_FIRST - && (hierarchyListener != null - || hierarchyBoundsListener != null - || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) - processEvent(e); - else if (e.id <= PaintEvent.PAINT_LAST - && e.id >= PaintEvent.PAINT_FIRST - && (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0) - processEvent(e); - } - /** * AWT 1.0 event dispatcher. * - * @deprecated Deprecated in favor of <code>dispatchEvent()</code>. + * @param e the event to dispatch + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #dispatchEvent(AWTEvent)} instead */ public boolean postEvent(Event e) { + // XXX Add backward compatibility handling. return false; } /** - * Adds the specified listener to this component. + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. * - * @param listener The new listener to add. + * @param listener the new listener to add + * @see ComponentEvent + * @see #removeComponentListener(ComponentListener) + * @see #getComponentListeners() + * @since 1.1 */ public synchronized void addComponentListener(ComponentListener l) { @@ -1551,9 +2153,14 @@ public abstract class Component } /** - * Removes the specified listener from the component. + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. * - * @param listener The listener to remove. + * @param listener the listener to remove + * @see ComponentEvent + * @see #addComponentListener(ComponentListener) + * @see #getComponentListeners() + * @since 1.1 */ public synchronized void removeComponentListener(ComponentListener l) { @@ -1561,74 +2168,194 @@ public abstract class Component } /** - * Adds the specified listener to this component. + * Returns an array of all specified listeners registered on this component. + * + * @return an array of listeners + * @see #addComponentListener(ComponentListener) + * @see #removeComponentListener(ComponentListener) + * @since 1.4 + */ + public synchronized ComponentListener[] getComponentListeners() + { + return (ComponentListener[]) + AWTEventMulticaster.getListeners(componentListener, + ComponentListener.class); + } + + /** + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. * - * @param listener The new listener to add. + * @param listener the new listener to add + * @see FocusEvent + * @see #removeFocusListener(FocusListener) + * @see #getFocusListeners() + * @since 1.1 */ public synchronized void addFocusListener(FocusListener l) { focusListener = AWTEventMulticaster.add(focusListener, l); if (focusListener != null) - enableEvents(AWTEvent.FOCUS_EVENT_MASK); + enableEvents(AWTEvent.FOCUS_EVENT_MASK); } /** - * Removes the specified listener from the component. + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. * - * @param listener The listener to remove. + * @param listener the listener to remove + * @see FocusEvent + * @see #addFocusListener(FocusListener) + * @see #getFocusListeners() + * @since 1.1 */ public synchronized void removeFocusListener(FocusListener l) { focusListener = AWTEventMulticaster.remove(focusListener, l); } - - /** @since 1.3 */ + + /** + * Returns an array of all specified listeners registered on this component. + * + * @return an array of listeners + * @see #addFocusListener(FocusListener) + * @see #removeFocusListener(FocusListener) + * @since 1.4 + */ + public synchronized FocusListener[] getFocusListeners() + { + return (FocusListener[]) + AWTEventMulticaster.getListeners(focusListener, FocusListener.class); + } + + /** + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. + * + * @param listener the new listener to add + * @see HierarchyEvent + * @see #removeHierarchyListener(HierarchyListener) + * @see #getHierarchyListeners() + * @since 1.3 + */ public synchronized void addHierarchyListener(HierarchyListener l) { hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l); if (hierarchyListener != null) - enableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + enableEvents(AWTEvent.HIERARCHY_EVENT_MASK); } - - /** @since 1.3 */ + + /** + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. + * + * @param listener the listener to remove + * @see HierarchyEvent + * @see #addHierarchyListener(HierarchyListener) + * @see #getHierarchyListeners() + * @since 1.3 + */ public synchronized void removeHierarchyListener(HierarchyListener l) { hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, l); } - /** @since 1.3 */ - public synchronized void addHierarchyBoundsListener(HierarchyBoundsListener l) + /** + * Returns an array of all specified listeners registered on this component. + * + * @return an array of listeners + * @see #addHierarchyListener(HierarchyListener) + * @see #removeHierarchyListener(HierarchyListener) + * @since 1.4 + */ + public synchronized HierarchyListener[] getHierarchyListeners() + { + return (HierarchyListener[]) + AWTEventMulticaster.getListeners(hierarchyListener, + HierarchyListener.class); + } + + /** + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. + * + * @param listener the new listener to add + * @see HierarchyEvent + * @see #removeHierarchyBoundsListener(HierarchyBoundsListener) + * @see #getHierarchyBoundsListeners() + * @since 1.3 + */ + public synchronized void + addHierarchyBoundsListener(HierarchyBoundsListener l) { - hierarchyBoundsListener = + hierarchyBoundsListener = AWTEventMulticaster.add(hierarchyBoundsListener, l); if (hierarchyBoundsListener != null) - enableEvents(AWTEvent.HIERARCHY_EVENT_MASK); + enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); } - /** @since 1.3 */ - public synchronized void + /** + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. + * + * @param listener the listener to remove + * @see HierarchyEvent + * @see #addHierarchyBoundsListener(HierarchyBoundsListener) + * @see #getHierarchyBoundsListeners() + * @since 1.3 + */ + public synchronized void removeHierarchyBoundsListener(HierarchyBoundsListener l) { - hierarchyBoundsListener = + hierarchyBoundsListener = AWTEventMulticaster.remove(hierarchyBoundsListener, l); } /** - * Adds the specified listener to this component. + * Returns an array of all specified listeners registered on this component. * - * @param listener The new listener to add. + * @return an array of listeners + * @see #addHierarchyBoundsListener(HierarchyBoundsListener) + * @see #removeHierarchyBoundsListener(HierarchyBoundsListener) + * @since 1.4 + */ + public synchronized HierarchyBoundsListener[] getHierarchyBoundsListeners() + { + return (HierarchyBoundsListener[]) + AWTEventMulticaster.getListeners(hierarchyBoundsListener, + HierarchyBoundsListener.class); + } + + /** + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. + * + * @param listener the new listener to add + * @see KeyEvent + * @see #removeKeyListener(KeyListener) + * @see #getKeyListeners() + * @since 1.1 */ public synchronized void addKeyListener(KeyListener l) { keyListener = AWTEventMulticaster.add(keyListener, l); if (keyListener != null) - enableEvents(AWTEvent.KEY_EVENT_MASK); + enableEvents(AWTEvent.KEY_EVENT_MASK); } /** - * Removes the specified listener from the component. + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. * - * @param listener The listener to remove. + * @param listener the listener to remove + * @see KeyEvent + * @see #addKeyListener(KeyListener) + * @see #getKeyListeners() + * @since 1.1 */ public synchronized void removeKeyListener(KeyListener l) { @@ -1636,158 +2363,318 @@ public abstract class Component } /** - * Adds the specified listener to this component. + * Returns an array of all specified listeners registered on this component. * - * @param listener The new listener to add. + * @return an array of listeners + * @see #addKeyListener(KeyListener) + * @see #removeKeyListener(KeyListener) + * @since 1.4 + */ + public synchronized KeyListener[] getKeyListeners() + { + return (KeyListener[]) + AWTEventMulticaster.getListeners(keyListener, KeyListener.class); + } + + /** + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. + * + * @param listener the new listener to add + * @see MouseEvent + * @see #removeMouseListener(MouseListener) + * @see #getMouseListeners() + * @since 1.1 */ public synchronized void addMouseListener(MouseListener l) { mouseListener = AWTEventMulticaster.add(mouseListener, l); if (mouseListener != null) - enableEvents(AWTEvent.MOUSE_EVENT_MASK); + enableEvents(AWTEvent.MOUSE_EVENT_MASK); } /** - * Removes the specified listener from the component. + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. * - * @param listener The listener to remove. + * @param listener the listener to remove + * @see MouseEvent + * @see #addMouseListener(MouseListener) + * @see #getMouseListeners() + * @since 1.1 */ public synchronized void removeMouseListener(MouseListener l) { - mouseListener = AWTEventMulticaster.remove(mouseListener, l); + mouseListener = AWTEventMulticaster.remove(mouseListener, l); } /** - * Adds the specified listener to this component. + * Returns an array of all specified listeners registered on this component. * - * @param listener The new listener to add. + * @return an array of listeners + * @see #addMouseListener(MouseListener) + * @see #removeMouseListener(MouseListener) + * @since 1.4 + */ + public synchronized MouseListener[] getMouseListeners() + { + return (MouseListener[]) + AWTEventMulticaster.getListeners(mouseListener, MouseListener.class); + } + + /** + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. + * + * @param listener the new listener to add + * @see MouseEvent + * @see #removeMouseMotionListener(MouseMotionListener) + * @see #getMouseMotionListeners() + * @since 1.1 */ public synchronized void addMouseMotionListener(MouseMotionListener l) { mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, l); if (mouseMotionListener != null) - enableEvents(AWTEvent.MOUSE_EVENT_MASK); + enableEvents(AWTEvent.MOUSE_EVENT_MASK); } /** - * Removes the specified listener from the component. + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. * - * @param listener The listener to remove. + * @param listener the listener to remove + * @see MouseEvent + * @see #addMouseMotionListener(MouseMotionListener) + * @see #getMouseMotionListeners() + * @since 1.1 */ public synchronized void removeMouseMotionListener(MouseMotionListener l) { mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l); } - /** @since 1.2 */ + /** + * Returns an array of all specified listeners registered on this component. + * + * @return an array of listeners + * @see #addMouseMotionListener(MouseMotionListener) + * @see #removeMouseMotionListener(MouseMotionListener) + * @since 1.4 + */ + public synchronized MouseMotionListener[] getMouseMotionListeners() + { + return (MouseMotionListener[]) + AWTEventMulticaster.getListeners(mouseMotionListener, + MouseMotionListener.class); + } + + /** + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. + * + * @param listener the new listener to add + * @see MouseEvent + * @see MouseWheelEvent + * @see #removeMouseWheelListener(MouseWheelListener) + * @see #getMouseWheelListeners() + * @since 1.4 + */ + public synchronized void addMouseWheelListener(MouseWheelListener l) + { + mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, l); + if (mouseWheelListener != null) + enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK); + } + + /** + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. + * + * @param listener the listener to remove + * @see MouseEvent + * @see MouseWheelEvent + * @see #addMouseWheelListener(MouseWheelListener) + * @see #getMouseWheelListeners() + * @since 1.4 + */ + public synchronized void removeMouseWheelListener(MouseWheelListener l) + { + mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l); + } + + /** + * Returns an array of all specified listeners registered on this component. + * + * @return an array of listeners + * @see #addMouseWheelListener(MouseWheelListener) + * @see #removeMouseWheelListener(MouseWheelListener) + * @since 1.4 + */ + public synchronized MouseWheelListener[] getMouseWheelListeners() + { + return (MouseWheelListener[]) + AWTEventMulticaster.getListeners(mouseWheelListener, + MouseWheelListener.class); + } + + /** + * Adds the specified listener to this component. This is harmless if the + * listener is null, but if the listener has already been registered, it + * will now be registered twice. + * + * @param listener the new listener to add + * @see InputMethodEvent + * @see #removeInputMethodListener(InputMethodListener) + * @see #getInputMethodListeners() + * @see #getInputMethodRequests() + * @since 1.2 + */ public synchronized void addInputMethodListener(InputMethodListener l) { inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l); if (inputMethodListener != null) - enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK); + enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK); } - /** @since 1.2 */ + /** + * Removes the specified listener from the component. This is harmless is + * the listener was not previously registered. + * + * @param listener the listener to remove + * @see InputMethodEvent + * @see #addInputMethodListener(InputMethodListener) + * @see #getInputMethodRequests() + * @since 1.2 + */ public synchronized void removeInputMethodListener(InputMethodListener l) { inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l); } - /** Returns all registered EventListers of the given listenerType. - * listenerType must be a subclass of EventListener, or a - * ClassClassException is thrown. - * @since 1.3 - */ + /** + * Returns an array of all specified listeners registered on this component. + * + * @return an array of listeners + * @see #addInputMethodListener(InputMethodListener) + * @see #removeInputMethodListener(InputMethodListener) + * @since 1.4 + */ + public synchronized InputMethodListener[] getInputMethodListeners() + { + return (InputMethodListener[]) + AWTEventMulticaster.getListeners(inputMethodListener, + InputMethodListener.class); + } + + /** + * Returns all registered EventListers of the given listenerType. + * + * @param listenerType the class of listeners to filter + * @return an array of registered listeners + * @see #getComponentListeners() + * @see #getFocusListeners() + * @see #getHierarchyListeners() + * @see #getHierarchyBoundsListeners() + * @see #getKeyListeners() + * @see #getMouseListeners() + * @see #getMouseMotionListeners() + * @see #getMouseWheelListeners() + * @see #getInputMethodListeners() + * @see #getPropertyChangeListeners() + * @since 1.3 + */ public EventListener[] getListeners(Class listenerType) { if (listenerType == ComponentListener.class) - return getListenersImpl(listenerType, componentListener); - else if (listenerType == FocusListener.class) - return getListenersImpl(listenerType, focusListener); - else if (listenerType == KeyListener.class) - return getListenersImpl(listenerType, keyListener); - else if (listenerType == MouseListener.class) - return getListenersImpl(listenerType, mouseListener); - else if (listenerType == MouseMotionListener.class) - return getListenersImpl(listenerType, mouseMotionListener); - else if (listenerType == InputMethodListener.class) - return getListenersImpl(listenerType, inputMethodListener); - else if (listenerType == HierarchyListener.class) - return getListenersImpl(listenerType, hierarchyListener); - else if (listenerType == HierarchyBoundsListener.class) - return getListenersImpl(listenerType, hierarchyBoundsListener); - else - return getListenersImpl(listenerType, null); - } - - static EventListener[] getListenersImpl(Class listenerType, EventListener el) + return getComponentListeners(); + if (listenerType == FocusListener.class) + return getFocusListeners(); + if (listenerType == HierarchyListener.class) + return getHierarchyListeners(); + if (listenerType == HierarchyBoundsListener.class) + return getHierarchyBoundsListeners(); + if (listenerType == KeyListener.class) + return getKeyListeners(); + if (listenerType == MouseListener.class) + return getMouseListeners(); + if (listenerType == MouseMotionListener.class) + return getMouseMotionListeners(); + if (listenerType == MouseWheelListener.class) + return getMouseWheelListeners(); + if (listenerType == InputMethodListener.class) + return getInputMethodListeners(); + if (listenerType == PropertyChangeListener.class) + return getPropertyChangeListeners(); + return (EventListener[]) Array.newInstance(listenerType, 0); + } + + /** + * Returns the input method request handler, for subclasses which support + * on-the-spot text input. By default, input methods are handled by AWT, + * and this returns null. + * + * @return the input method handler, null by default + * @since 1.2 + */ + public InputMethodRequests getInputMethodRequests() { - if (! EventListener.class.isAssignableFrom(listenerType)) - throw new ClassCastException(); - - Vector v = new Vector(); - if (el != null) - getListenerList (el, v); - EventListener[] el_a = (EventListener[]) Array.newInstance(listenerType, - v.size()); - v.copyInto(el_a); - return el_a; + return null; } - static void getListenerList(EventListener el, Vector v) + /** + * Gets the input context of this component, which is inherited from the + * parent unless this is overridden. + * + * @return the text input context + * @since 1.2 + */ + public InputContext getInputContext() { - if (el instanceof AWTEventMulticaster) - { - AWTEventMulticaster mc = (AWTEventMulticaster) el; - getListenerList(mc.a, v); - getListenerList(mc.b, v); - } - else - v.addElement(el); + return parent == null ? null : parent.getInputContext(); } - // The input method framework is currently unimplemented. - // /** @since 1.2 */ - // - //public InputMethodRequests getInputMethodRequests() - // - // /** @since 1.2 */ - // - // public InputContext getInputContext() - /** - * Enables the specified events. The events to enable are specified + * Enables the specified events. The events to enable are specified * by OR-ing together the desired masks from <code>AWTEvent</code>. - * <p> - * Events are enabled by default when a listener is attached to the - * component for that event type. This method can be used by subclasses + * + * <p>Events are enabled by default when a listener is attached to the + * component for that event type. This method can be used by subclasses * to ensure the delivery of a specified event regardless of whether * or not a listener is attached. * - * @param enable_events The desired events to enable. + * @param eventsToEnable the desired events to enable + * @see #processEvent(AWTEvent) + * @see #disableEvents(long) + * @see AWTEvent + * @since 1.1 */ protected final void enableEvents(long eventsToEnable) { eventMask |= eventsToEnable; - // TODO: Unlike Sun's implementation, I think we should try and - // enable/disable events at the peer (gtk/X) level. This will avoid - // clogging the event pipeline with useless mousemove events that - // we arn't interested in, etc. This will involve extending the peer + // TODO: Unlike Sun's implementation, I think we should try and + // enable/disable events at the peer (gtk/X) level. This will avoid + // clogging the event pipeline with useless mousemove events that + // we arn't interested in, etc. This will involve extending the peer // interface, but thats okay because the peer interfaces have been - // deprecated for a long time, and no longer feature in the + // deprecated for a long time, and no longer feature in the // API specification at all. - - if (isLightweight() && (parent != null)) + if (isLightweight() && parent != null) parent.enableEvents(eventsToEnable); else if (peer != null) - peer.setEventMask (eventMask); + peer.setEventMask(eventMask); } /** - * Disables the specified events. The events to disable are specified + * Disables the specified events. The events to disable are specified * by OR-ing together the desired masks from <code>AWTEvent</code>. * - * @param disable_events The desired events to disable. + * @param eventsToDisable the desired events to disable + * @see #enableEvents(long) + * @since 1.1 */ protected final void disableEvents(long eventsToDisable) { @@ -1795,10 +2682,17 @@ public abstract class Component // forward new event mask to peer? } - /** coalesceEvents is called by the EventQueue if two events with the same - * event id are queued. Returns a new combined event, or null if no - * combining is done. - */ + /** + * This is called by the EventQueue if two events with the same event id + * and owner component are queued. Returns a new combined event, or null if + * no combining is done. The coelesced events are currently mouse moves + * (intermediate ones are discarded) and paint events (a merged paint is + * created in place of the two events). + * + * @param existingEvent the event on the queue + * @param newEvent the new event that might be entered on the queue + * @return null if both events are kept, or the replacement coelesced event + */ protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent) { switch (existingEvent.id) @@ -1811,64 +2705,29 @@ public abstract class Component case PaintEvent.UPDATE: return coalescePaintEvents((PaintEvent) existingEvent, (PaintEvent) newEvent); + default: + return null; } - return null; - } - - /** - * Coalesce paint events. Current heuristic is: Merge if the union of - * areas is less than twice that of the sum of the areas. The X server - * tend to create a lot of paint events that are adjacent but not - * overlapping. - * - * <pre> - * +------+ - * | +-----+ ...will be merged - * | | | - * | | | - * +------+ | - * +-----+ - * - * +---------------+--+ - * | | | ...will not be merged - * +---------------+ | - * | | - * | | - * | | - * | | - * | | - * +--+ - * </pre> - */ - private PaintEvent coalescePaintEvents(PaintEvent queuedEvent, - PaintEvent newEvent) - { - Rectangle r1 = queuedEvent.getUpdateRect(); - Rectangle r2 = newEvent.getUpdateRect(); - Rectangle union = r1.union(r2); - - int r1a = r1.width * r1.height; - int r2a = r2.width * r2.height; - int ua = union.width * union.height; - - if (ua > (r1a+r2a)*2) - return null; - /* The 2 factor should maybe be reconsidered. Perhaps 3/2 - would be better? */ - - newEvent.setUpdateRect(union); - return newEvent; } /** - * Processes the specified event. In this class, this method simply + * Processes the specified event. In this class, this method simply * calls one of the more specific event handlers. - * - * @param event The event to process. + * + * @param event the event to process + * @throws NullPointerException if e is null + * @see #processComponentEvent(ComponentEvent) + * @see #processFocusEvent(FocusEvent) + * @see #processKeyEvent(KeyEvent) + * @see #processMouseEvent(MouseEvent) + * @see #processMouseMotionEvent(MouseEvent) + * @see #processInputMethodEvent(InputMethodEvent) + * @see #processHierarchyEvent(HierarchyEvent) + * @see #processMouseWheelEvent(MouseWheelEvent) + * @since 1.1 */ protected void processEvent(AWTEvent e) { - /* Note: the order of these if statements are important. Subclasses must be checked first. Eg. MouseEvent must be checked before ComponentEvent, since a MouseEvent @@ -1878,9 +2737,11 @@ public abstract class Component processFocusEvent((FocusEvent) e); else if (e instanceof PaintEvent) processPaintEvent((PaintEvent) e); + else if (e instanceof MouseWheelEvent) + processMouseWheelEvent((MouseWheelEvent) e); else if (e instanceof MouseEvent) { - if (e.id == MouseEvent.MOUSE_MOVED + if (e.id == MouseEvent.MOUSE_MOVED || e.id == MouseEvent.MOUSE_DRAGGED) processMouseMotionEvent((MouseEvent) e); else @@ -1903,10 +2764,15 @@ public abstract class Component /** * Called when a component event is dispatched and component events are - * enabled. This method passes the event along to any listeners + * enabled. This method passes the event along to any listeners * that are attached. * - * @param event The <code>ComponentEvent</code> to process. + * @param event the <code>ComponentEvent</code> to process + * @throws NullPointerException if e is null + * @see ComponentListener + * @see #addComponentListener(ComponentListener) + * @see #enableEvents(long) + * @since 1.1 */ protected void processComponentEvent(ComponentEvent e) { @@ -1914,30 +2780,32 @@ public abstract class Component return; switch (e.id) { - case ComponentEvent.COMPONENT_HIDDEN: - componentListener.componentHidden(e); + case ComponentEvent.COMPONENT_HIDDEN: + componentListener.componentHidden(e); break; - - case ComponentEvent.COMPONENT_MOVED: - componentListener.componentMoved(e); + case ComponentEvent.COMPONENT_MOVED: + componentListener.componentMoved(e); break; - - case ComponentEvent.COMPONENT_RESIZED: - componentListener.componentResized(e); + case ComponentEvent.COMPONENT_RESIZED: + componentListener.componentResized(e); break; - - case ComponentEvent.COMPONENT_SHOWN: - componentListener.componentShown(e); + case ComponentEvent.COMPONENT_SHOWN: + componentListener.componentShown(e); break; } } /** * Called when a focus event is dispatched and component events are - * enabled. This method passes the event along to any listeners + * enabled. This method passes the event along to any listeners * that are attached. * - * @param event The <code>FocusEvent</code> to process. + * @param event the <code>FocusEvent</code> to process + * @throws NullPointerException if e is null + * @see FocusListener + * @see #addFocusListener(FocusListener) + * @see #enableEvents(long) + * @since 1.1 */ protected void processFocusEvent(FocusEvent e) { @@ -1951,15 +2819,20 @@ public abstract class Component case FocusEvent.FOCUS_LOST: focusListener.focusLost(e); break; - } + } } /** * Called when a key event is dispatched and component events are - * enabled. This method passes the event along to any listeners + * enabled. This method passes the event along to any listeners * that are attached. * - * @param event The <code>KeyEvent</code> to process. + * @param event the <code>KeyEvent</code> to process + * @throws NullPointerException if e is null + * @see KeyListener + * @see #addKeyListener(KeyListener) + * @see #enableEvents(long) + * @since 1.1 */ protected void processKeyEvent(KeyEvent e) { @@ -1981,10 +2854,15 @@ public abstract class Component /** * Called when a regular mouse event is dispatched and component events are - * enabled. This method passes the event along to any listeners + * enabled. This method passes the event along to any listeners * that are attached. * - * @param event The <code>MouseEvent</code> to process. + * @param event the <code>MouseEvent</code> to process + * @throws NullPointerException if e is null + * @see MouseListener + * @see #addMouseListener(MouseListener) + * @see #enableEvents(long) + * @since 1.1 */ protected void processMouseEvent(MouseEvent e) { @@ -2012,10 +2890,15 @@ public abstract class Component /** * Called when a mouse motion event is dispatched and component events are - * enabled. This method passes the event along to any listeners + * enabled. This method passes the event along to any listeners * that are attached. * - * @param event The <code>MouseMotionEvent</code> to process. + * @param event the <code>MouseMotionEvent</code> to process + * @throws NullPointerException if e is null + * @see MouseMotionListener + * @see #addMouseMotionListener(MouseMotionListener) + * @see #enableEvents(long) + * @since 1.1 */ protected void processMouseMotionEvent(MouseEvent e) { @@ -2029,10 +2912,40 @@ public abstract class Component case MouseEvent.MOUSE_MOVED: mouseMotionListener.mouseMoved(e); break; - } + } } - /** @since 1.2 */ + /** + * Called when a mouse wheel event is dispatched and component events are + * enabled. This method passes the event along to any listeners that are + * attached. + * + * @param event the <code>MouseWheelEvent</code> to process + * @throws NullPointerException if e is null + * @see MouseWheelListener + * @see #addMouseWheelListener(MouseWheelListener) + * @see #enableEvents(long) + * @since 1.4 + */ + protected void processMouseWheelEvent(MouseWheelEvent e) + { + if (mouseWheelListener != null + && e.id == MouseEvent.MOUSE_WHEEL) + mouseWheelListener.mouseWheelMoved(e); + } + + /** + * Called when an input method event is dispatched and component events are + * enabled. This method passes the event along to any listeners that are + * attached. + * + * @param event the <code>InputMethodEvent</code> to process + * @throws NullPointerException if e is null + * @see InputMethodListener + * @see #addInputMethodListener(InputMethodListener) + * @see #enableEvents(long) + * @since 1.2 + */ protected void processInputMethodEvent(InputMethodEvent e) { if (inputMethodListener == null) @@ -2045,10 +2958,21 @@ public abstract class Component case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: inputMethodListener.inputMethodTextChanged(e); break; - } + } } - - /** @since 1.3 */ + + /** + * Called when a hierarchy change event is dispatched and component events + * are enabled. This method passes the event along to any listeners that are + * attached. + * + * @param event the <code>HierarchyEvent</code> to process + * @throws NullPointerException if e is null + * @see HierarchyListener + * @see #addHierarchyListener(HierarchyListener) + * @see #enableEvents(long) + * @since 1.3 + */ protected void processHierarchyEvent(HierarchyEvent e) { if (hierarchyListener == null) @@ -2056,8 +2980,19 @@ public abstract class Component if (e.id == HierarchyEvent.HIERARCHY_CHANGED) hierarchyListener.hierarchyChanged(e); } - - /** @since 1.3 */ + + /** + * Called when a hierarchy bounds event is dispatched and component events + * are enabled. This method passes the event along to any listeners that are + * attached. + * + * @param event the <code>HierarchyEvent</code> to process + * @throws NullPointerException if e is null + * @see HierarchyBoundsListener + * @see #addHierarchyBoundsListener(HierarchyBoundsListener) + * @see #enableEvents(long) + * @since 1.3 + */ protected void processHierarchyBoundsEvent(HierarchyEvent e) { if (hierarchyBoundsListener == null) @@ -2073,147 +3008,169 @@ public abstract class Component } } - private void processPaintEvent(PaintEvent event) - { - // Can't do graphics without peer - if (peer == null) - return; - - Graphics gfx = getGraphics(); - Shape clip = event.getUpdateRect(); - gfx.setClip(clip); - - switch (event.id) - { - case PaintEvent.PAINT: - paint(gfx); - break; - case PaintEvent.UPDATE: - update(gfx); - break; - default: - throw new IllegalArgumentException("unknown paint event"); - } - } - /** * AWT 1.0 event processor. * - * @deprecated Deprecated in favor of <code>processEvent</code>. + * @param evt the event to handle + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processEvent(AWTEvent)} instead */ public boolean handleEvent(Event evt) { + // XXX Add backward compatibility handling. return false; } /** * AWT 1.0 mouse event. * - * @deprecated Deprecated in favor of <code>processMouseEvent()</code>. + * @param evt the event to handle + * @param x the x coordinate, ignored + * @param y the y coordinate, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processMouseEvent(MouseEvent)} instead */ public boolean mouseDown(Event evt, int x, int y) { + // XXX Add backward compatibility handling. return false; } - + /** * AWT 1.0 mouse event. * - * @deprecated Deprecated in favor of <code>processMouseMotionEvent()</code>. + * @param evt the event to handle + * @param x the x coordinate, ignored + * @param y the y coordinate, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead */ public boolean mouseDrag(Event evt, int x, int y) { + // XXX Add backward compatibility handling. return false; } /** * AWT 1.0 mouse event. * - * @deprecated Deprecated in favor of <code>processMouseEvent()</code>. + * @param evt the event to handle + * @param x the x coordinate, ignored + * @param y the y coordinate, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processMouseEvent(MouseEvent)} instead */ public boolean mouseUp(Event evt, int x, int y) { + // XXX Add backward compatibility handling. return false; } /** * AWT 1.0 mouse event. * - * @deprecated Deprecated in favor of <code>processMouseMotionEvent()</code>. + * @param evt the event to handle + * @param x the x coordinate, ignored + * @param y the y coordinate, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processMouseMotionEvent(MouseEvent)} instead */ public boolean mouseMove(Event evt, int x, int y) { + // XXX Add backward compatibility handling. return false; } /** * AWT 1.0 mouse event. * - * @deprecated Deprecated in favor of <code>processMouseEvent()</code>. + * @param evt the event to handle + * @param x the x coordinate, ignored + * @param y the y coordinate, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processMouseEvent(MouseEvent)} instead */ public boolean mouseEnter(Event evt, int x, int y) { + // XXX Add backward compatibility handling. return false; } /** * AWT 1.0 mouse event. * - * @deprecated Deprecated in favor of <code>processMouseEvent()</code>. + * @param evt the event to handle + * @param x the x coordinate, ignored + * @param y the y coordinate, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processMouseEvent(MouseEvent)} instead */ public boolean mouseExit(Event evt, int x, int y) { + // XXX Add backward compatibility handling. return false; } /** * AWT 1.0 key press event. * - * @deprecated Deprecated in favor of <code>processKeyEvent</code>. + * @param evt the event to handle + * @param key the key pressed, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processKeyEvent(KeyEvent)} instead */ public boolean keyDown(Event evt, int key) { + // XXX Add backward compatibility handling. return false; } /** * AWT 1.0 key press event. * - * @deprecated Deprecated in favor of <code>processKeyEvent</code>. + * @param evt the event to handle + * @param key the key pressed, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processKeyEvent(KeyEvent)} instead */ public boolean keyUp(Event evt, int key) { + // XXX Add backward compatibility handling. return false; } /** * AWT 1.0 action event processor. * - * @deprecated Deprecated in favor of the <code>ActionListener</code> - * interface. + * @param evt the event to handle + * @param what the object acted on, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated in classes which support actions, use + * <code>processActionEvent(ActionEvent)</code> instead */ public boolean action(Event evt, Object what) { + // XXX Add backward compatibility handling. return false; } /** * Called to inform this component it has been added to a container. - * A native peer - if any - is created at this time. This method is + * A native peer - if any - is created at this time. This method is * called automatically by the AWT system and should not be called by * user level code. + * + * @see #isDisplayable() + * @see #removeNotify() */ public void addNotify() { if (peer == null) peer = getToolkit().createComponent(this); - /* Now that all the children has gotten their peers, we should have the event mask needed for this component and its lightweight subcomponents. */ - peer.setEventMask(eventMask); - /* We do not invalidate here, but rather leave that job up to the peer. For efficiency, the peer can choose not to invalidate if it is happy with the current dimensions, @@ -2222,62 +3179,308 @@ public abstract class Component /** * Called to inform this component is has been removed from its - * container. Its native peer - if any - is destroyed at this time. + * container. Its native peer - if any - is destroyed at this time. * This method is called automatically by the AWT system and should * not be called by user level code. + * + * @see #isDisplayable() + * @see #addNotify() */ public void removeNotify() - { + { if (peer != null) peer.dispose(); peer = null; } - - /** @deprecated */ + + /** + * AWT 1.0 focus event. + * + * @param evt the event to handle + * @param what the Object focused, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processFocusEvent(FocusEvent)} instead + */ public boolean gotFocus(Event evt, Object what) { + // XXX Add backward compatibility handling. return false; } - - /** @deprecated */ + + /** + * AWT 1.0 focus event. + * + * @param evt the event to handle + * @param what the Object focused, ignored + * @return false: since the method was deprecated, the return has no meaning + * @deprecated use {@link #processFocusEvent(FocusEvent)} instead + */ public boolean lostFocus(Event evt, Object what) { + // XXX Add backward compatibility handling. return false; } /** - * Tests whether or not this component is in the group that can - * be traversed using the keyboard traversal mechanism (such as the TAB - * key). + * Tests whether or not this component is in the group that can be + * traversed using the keyboard traversal mechanism (such as the TAB key). * - * @return <code>true</code> if the component is traversed via the TAB - * key, <code>false</code> otherwise. + * @return true if the component is traversed via the TAB key + * @see #setFocusable(boolean) + * @since 1.1 + * @deprecated use {@link #isFocusable()} instead */ public boolean isFocusTraversable() { - return enabled && visible && (peer == null || peer.isFocusTraversable ()); + return enabled && visible && (peer == null || peer.isFocusTraversable()); + } + + /** + * Tests if this component can receive focus. + * + * @return true if this component can receive focus + * @since 1.4 + */ + public boolean isFocusable() + { + return focusable; + } + + /** + * Specify whether this component can receive focus. + * + * @param focusable the new focusable status + * @since 1.4 + */ + public void setFocusable(boolean focusable) + { + firePropertyChange("focusable", this.focusable, focusable); + this.focusable = focusable; + } + + /** + * Sets the focus traversal keys for a given type of focus events. Normally, + * the default values should match the operating system's native choices. To + * disable a given traversal, use <code>Collections.EMPTY_SET</code>. The + * event dispatcher will consume PRESSED, RELEASED, and TYPED events for the + * specified key, although focus can only transfer on PRESSED or RELEASED. + * + * <p>The defauts are: + * <table> + * <th><td>Identifier</td><td>Meaning</td><td>Default</td></th> + * <tr><td>KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS</td> + * <td>Normal forward traversal</td> + * <td>TAB on KEY_PRESSED, Ctrl-TAB on KEY_PRESSED</td></tr> + * <tr><td>KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS</td> + * <td>Normal backward traversal</td> + * <td>Shift-TAB on KEY_PRESSED, Ctrl-Shift-TAB on KEY_PRESSED</td></tr> + * <tr><td>KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS</td> + * <td>Go up a traversal cycle</td><td>None</td></tr> + * </table> + * + * <p>Specifying null allows inheritance from the parent, or from the current + * KeyboardFocusManager default set. If not null, the set must contain only + * AWTKeyStrokes that are not already focus keys and are not KEY_TYPED + * events. + * + * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or + * UP_CYCLE_TRAVERSAL_KEYS + * @param keystrokes a set of keys, or null + * @throws IllegalArgumentException if id or keystrokes is invalid + * @see #getFocusTraversalKeys(int) + * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS + * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS + * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS + * @since 1.4 + */ + public void setFocusTraversalKeys(int id, Set keystrokes) + { + if (keystrokes == null) + throw new IllegalArgumentException(); + Set sa; + Set sb; + String name; + switch (id) + { + case KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS: + sa = getFocusTraversalKeys + (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); + sb = getFocusTraversalKeys + (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS); + name = "forwardFocusTraversalKeys"; + break; + case KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS: + sa = getFocusTraversalKeys + (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); + sb = getFocusTraversalKeys + (KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS); + name = "backwardFocusTraversalKeys"; + break; + case KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS: + sa = getFocusTraversalKeys + (KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); + sb = getFocusTraversalKeys + (KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); + name = "upCycleFocusTraversalKeys"; + break; + default: + throw new IllegalArgumentException(); + } + int i = keystrokes.size(); + Iterator iter = keystrokes.iterator(); + while (--i >= 0) + { + Object o = iter.next(); + if (! (o instanceof AWTKeyStroke) + || sa.contains(o) || sb.contains(o) + || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED) + throw new IllegalArgumentException(); + } + if (focusTraversalKeys == null) + focusTraversalKeys = new Set[3]; + keystrokes = Collections.unmodifiableSet(new HashSet(keystrokes)); + firePropertyChange(name, focusTraversalKeys[id], keystrokes); + focusTraversalKeys[id] = keystrokes; + } + + /** + * Returns the set of keys for a given focus traversal action, as defined + * in <code>setFocusTraversalKeys</code>. If not set, this is inherited from + * the parent component, which may have gotten it from the + * KeyboardFocusManager. + * + * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or + * UP_CYCLE_TRAVERSAL_KEYS + * @throws IllegalArgumentException if id is invalid + * @see #setFocusTraversalKeys(int, Set) + * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS + * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS + * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS + * @since 1.4 + */ + public Set getFocusTraversalKeys(int id) + { + if (id < KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS + || id > KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS) + throw new IllegalArgumentException(); + Set s = null; + if (focusTraversalKeys != null) + s = focusTraversalKeys[id]; + if (s == null && parent != null) + s = parent.getFocusTraversalKeys(id); + return s == null ? (KeyboardFocusManager.getCurrentKeyboardFocusManager() + .getDefaultFocusTraversalKeys(id)) : s; + } + + /** + * Tests whether the focus traversal keys for a given action are explicitly + * set or inherited. + * + * @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS, or + * UP_CYCLE_TRAVERSAL_KEYS + * @return true if that set is explicitly specified + * @throws IllegalArgumentException if id is invalid + * @see #getFocusTraversalKeys(int) + * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS + * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS + * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS + * @since 1.4 + */ + public boolean areFocusTraversalKeysSet(int id) + { + if (id < KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS + || id > KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS) + throw new IllegalArgumentException(); + return focusTraversalKeys != null && focusTraversalKeys[id] != null; + } + + /** + * Sets whether focus traversal keys are enabled, which consumes traversal + * keys and performs the focus event automatically. + * + * @param focusTraversalKeysEnabled the new value of the flag + * @see #getFocusTraversalKeysEnabled() + * @see #setFocusTraversalKeys(int, Set) + * @see #getFocusTraversalKeys(int) + * @since 1.4 + */ + public void setFocusTraversalKeysEnabled(boolean focusTraversalKeysEnabled) + { + firePropertyChange("focusTraversalKeysEnabled", + this.focusTraversalKeysEnabled, + focusTraversalKeysEnabled); + this.focusTraversalKeysEnabled = focusTraversalKeysEnabled; } /** - * Requests that this component be given focus. The <code>gotFocus()</code> + * Tests whether focus traversal keys are enabled. If they are, then focus + * traversal keys are consumed and focus events performed automatically, + * without the component seeing the keystrokes. + * + * @return true if focus traversal is enabled + * @see #setFocusTraversalKeysEnabled(boolean) + * @see #setFocusTraversalKeys(int, Set) + * @see #getFocusTraversalKeys(int) + * @since 1.4 + */ + public boolean getFocusTraversalKeysEnabled() + { + return focusTraversalKeysEnabled; + } + + /** + * Requests that this component be given focus. The <code>gotFocus()</code> * method on this event will be called when and if this request was - * successful. + * successful. To be successful, the component must be displayable, visible, + * and focusable, and the top-level Window must be able to receive focus. + * Thus, this request may fail, or be delayed until the window receives + * focus. It is recommended that <code>requestFocusInWindow</code> be used + * where possible to be more platform-independent. + * + * @see #requestFocusInWindow() + * @see FocusEvent + * @see #addFocusListener(FocusListener) + * @see #isFocusable() + * @see #isDisplayable() + * @see KeyboardFocusManager#clearGlobalFocusOwner() */ public void requestFocus() { - // If there's no peer then this component can't get the focus. We + // If there's no peer then this component can't get the focus. We // treat it as a silent rejection of the request. if (peer != null) - peer.requestFocus (); + peer.requestFocus(); } - // This method is used to implement transferFocus(). - // CHILD is the child making the request. - // This is overridden by Container; when called for an ordinary - // component there is no child and so we always return null. - Component findNextFocusComponent (Component child) + //XXX Below here, I have not yet had time to document things --EBB + /** + * @since 1.4 + */ + protected boolean requestFocus(boolean temporary) { - return null; + // XXX Implement correctly. + requestFocus(); + return true; + } + + /** + * @since 1.4 + */ + public boolean requestFocusInWindow() + { + // XXX Implement correctly. + requestFocus(); + return true; + } + + /** + * @since 1.4 + */ + protected boolean requestFocusInWindow(boolean temporary) + { + // XXX Implement correctly. + requestFocus(); + return true; } /** @@ -2287,11 +3490,29 @@ public abstract class Component { Component next; if (parent == null) - next = findNextFocusComponent (null); + next = findNextFocusComponent(null); else - next = parent.findNextFocusComponent (this); + next = parent.findNextFocusComponent(this); if (next != null && next != this) - next.requestFocus (); + next.requestFocus(); + } + + /** + * @since 1.4 + */ + public Container getFocusCycleRootAncestor() + { + // XXX Implement. + throw new Error("not implemented"); + } + + /** + * @since 1.4 + */ + public boolean isFocusCycleRoot() + { + // XXX Implement. + throw new Error("not implemented"); } /** @@ -2304,10 +3525,37 @@ public abstract class Component transferFocus(); } + /** + * @since 1.4 + */ + public void transferFocusBackward() + { + // XXX Implement. + throw new Error("not implemented"); + } + + /** + * @since 1.4 + */ + public void transferFocusUpCycle() + { + // XXX Implement. + throw new Error("not implemented"); + } + /** @since 1.2 */ public boolean hasFocus() { - return hasFocus; + return isFocusOwner(); + } + + /** + * @since 1.4 + */ + public boolean isFocusOwner() + { + // XXX Implement. + throw new Error("not implemented"); } /** @@ -2319,7 +3567,7 @@ public abstract class Component { if (popups == null) popups = new Vector(); - popups.addElement(popup); + popups.add(popup); } /** @@ -2329,7 +3577,8 @@ public abstract class Component */ public synchronized void remove(MenuComponent popup) { - popups.removeElement(popup); + if (popups != null) + popups.remove(popup); } /** @@ -2346,25 +3595,18 @@ public abstract class Component param.append(name); param.append(","); } - param.append(width); - param.append("x"); - param.append(height); - param.append("+"); - param.append(x); - param.append("+"); - param.append(y); - - if (!isValid()) + param.append(width).append("x").append(height).append("+").append(x) + .append("+").append(y); + if (! isValid()) param.append(",invalid"); - if (!isVisible()) + if (! isVisible()) param.append(",invisible"); - if (!isEnabled()) + if (! isEnabled()) param.append(",disabled"); - if (!isOpaque()) + if (! isOpaque()) param.append(",translucent"); if (isDoubleBuffered()) param.append(",doublebuffered"); - return param.toString(); } @@ -2375,15 +3617,15 @@ public abstract class Component */ public String toString() { - return this.getClass().getName() + "[" + paramString() + "]"; + return getClass().getName() + "[" + paramString() + "]"; } /** * Prints a listing of this component to the standard output. */ - public void list () + public void list() { - list (System.out, 0); + list(System.out, 0); } /** @@ -2391,9 +3633,9 @@ public abstract class Component * * @param stream The <code>PrintStream</code> to print to. */ - public void list (PrintStream out) + public void list(PrintStream out) { - list (out, 0); + list(out, 0); } /** @@ -2403,11 +3645,11 @@ public abstract class Component * @param stream The <code>PrintStream</code> to print to. * @param indent The indentation point. */ - public void list (PrintStream out, int indent) + public void list(PrintStream out, int indent) { for (int i = 0; i < indent; ++i) - out.print (' '); - out.println (toString ()); + out.print(' '); + out.println(toString()); } /** @@ -2415,9 +3657,9 @@ public abstract class Component * * @param writer The <code>PrintWrinter</code> to print to. */ - public void list (PrintWriter out) + public void list(PrintWriter out) { - list (out, 0); + list(out, 0); } /** @@ -2427,11 +3669,11 @@ public abstract class Component * @param writer The <code>PrintWriter</code> to print to. * @param indent The indentation point. */ - public void list (PrintWriter out, int indent) + public void list(PrintWriter out, int indent) { for (int i = 0; i < indent; ++i) - out.print (' '); - out.println (toString ()); + out.print(' '); + out.println(toString()); } public void addPropertyChangeListener(PropertyChangeListener listener) @@ -2444,7 +3686,16 @@ public abstract class Component public void removePropertyChangeListener(PropertyChangeListener listener) { if (changeSupport != null) - changeSupport.removePropertyChangeListener(listener); + changeSupport.removePropertyChangeListener(listener); + } + + /** + * @since 1.4 + */ + public PropertyChangeListener[] getPropertyChangeListeners() + { + return changeSupport == null ? new PropertyChangeListener[0] + : changeSupport.getPropertyChangeListeners(); } public void addPropertyChangeListener(String propertyName, @@ -2452,7 +3703,7 @@ public abstract class Component { if (changeSupport == null) changeSupport = new PropertyChangeSupport(this); - changeSupport.addPropertyChangeListener(propertyName, listener); + changeSupport.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, @@ -2462,11 +3713,34 @@ public abstract class Component changeSupport.removePropertyChangeListener(propertyName, listener); } - protected void firePropertyChange(String propertyName, Object oldValue, + /** + * @since 1.4 + */ + public PropertyChangeListener[] getPropertyChangeListeners(String property) + { + return changeSupport == null ? new PropertyChangeListener[0] + : changeSupport.getPropertyChangeListeners(property); + } + + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { if (changeSupport != null) - changeSupport.firePropertyChange(propertyName, oldValue, newValue); + changeSupport.firePropertyChange(propertyName, oldValue, newValue); + } + + protected void firePropertyChange(String propertyName, boolean oldValue, + boolean newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, oldValue, newValue); + } + + protected void firePropertyChange(String propertyName, int oldValue, + int newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, oldValue, newValue); } public void setComponentOrientation(ComponentOrientation o) @@ -2479,44 +3753,227 @@ public abstract class Component return orientation; } - /* + public void applyComponentOrientation(ComponentOrientation o) + { + setComponentOrientation(o); + } + public AccessibleContext getAccessibleContext() { - return accessibleContext; + return null; } - */ -/** - * AWT 1.0 focus event processor. - * - * @deprecated Deprecated in favor of <code>processFocusEvent</code>. - -public boolean -gotFocus(Event event, Object what) -{ - return(true); -} -*/ + + // Helper methods; some are package visible for use by subclasses. -/** - * AWT 1.0 focus event processor. - * - * @deprecated Deprecated in favor of <code>processFocusEvent</code>. - -public boolean -lostFocus(Event event, Object what) -{ - return(true); -} -*/ + /** + * Subclasses should override this to return unique component names like + * "menuitem0". + * + * @return the generated name for this component + */ + String generateName() + { + // Component is abstract. + return null; + } + + // Sets the peer for this component. + final void setPeer(ComponentPeer peer) + { + this.peer = peer; + } + + /** Implementation method that allows classes such as Canvas and + Window to override the graphics configuration without violating + the published API. */ + GraphicsConfiguration getGraphicsConfigurationImpl() + { + if (peer != null) + { + GraphicsConfiguration config = peer.getGraphicsConfiguration(); + if (config != null) + return config; + } + + if (parent != null) + return parent.getGraphicsConfiguration(); + + return null; + } + + void dispatchEventImpl(AWTEvent e) + { + // Make use of event id's in order to avoid multiple instanceof tests. + if (e.id <= ComponentEvent.COMPONENT_LAST + && e.id >= ComponentEvent.COMPONENT_FIRST + && (componentListener != null + || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)) + processEvent(e); + else if (e.id <= KeyEvent.KEY_LAST + && e.id >= KeyEvent.KEY_FIRST + && (keyListener != null + || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0)) + processEvent(e); + else if (e.id <= MouseEvent.MOUSE_LAST + && e.id >= MouseEvent.MOUSE_FIRST + && (mouseListener != null + || mouseMotionListener != null + || (eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) + processEvent(e); + else if (e.id <= FocusEvent.FOCUS_LAST + && e.id >= FocusEvent.FOCUS_FIRST + && (focusListener != null + || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0)) + processEvent(e); + else if (e.id <= InputMethodEvent.INPUT_METHOD_LAST + && e.id >= InputMethodEvent.INPUT_METHOD_FIRST + && (inputMethodListener != null + || (eventMask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0)) + processEvent(e); + else if (e.id <= HierarchyEvent.HIERARCHY_LAST + && e.id >= HierarchyEvent.HIERARCHY_FIRST + && (hierarchyListener != null + || hierarchyBoundsListener != null + || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0)) + processEvent(e); + else if (e.id <= PaintEvent.PAINT_LAST + && e.id >= PaintEvent.PAINT_FIRST + && (eventMask & AWTEvent.PAINT_EVENT_MASK) != 0) + processEvent(e); + } + + /** + * Coalesce paint events. Current heuristic is: Merge if the union of + * areas is less than twice that of the sum of the areas. The X server + * tend to create a lot of paint events that are adjacent but not + * overlapping. + * + * <pre> + * +------+ + * | +-----+ ...will be merged + * | | | + * | | | + * +------+ | + * +-----+ + * + * +---------------+--+ + * | | | ...will not be merged + * +---------------+ | + * | | + * | | + * | | + * | | + * | | + * +--+ + * </pre> + */ + private PaintEvent coalescePaintEvents(PaintEvent queuedEvent, + PaintEvent newEvent) + { + Rectangle r1 = queuedEvent.getUpdateRect(); + Rectangle r2 = newEvent.getUpdateRect(); + Rectangle union = r1.union(r2); + + int r1a = r1.width * r1.height; + int r2a = r2.width * r2.height; + int ua = union.width * union.height; + + if (ua > (r1a+r2a)*2) + return null; + /* The 2 factor should maybe be reconsidered. Perhaps 3/2 + would be better? */ + + newEvent.setUpdateRect(union); + return newEvent; + } + + private void processPaintEvent(PaintEvent event) + { + // Can't do graphics without peer + if (peer == null) + return; + + Graphics gfx = getGraphics(); + Shape clip = event.getUpdateRect(); + gfx.setClip(clip); + + switch (event.id) + { + case PaintEvent.PAINT: + paint(gfx); + break; + case PaintEvent.UPDATE: + update(gfx); + break; + default: + throw new IllegalArgumentException("unknown paint event"); + } + } + + // This method is used to implement transferFocus(). + // CHILD is the child making the request. + // This is overridden by Container; when called for an ordinary + // component there is no child and so we always return null. + Component findNextFocusComponent(Component child) + { + return null; + } + + private void readObject(ObjectInputStream s) + throws ClassNotFoundException, IOException + { + s.defaultReadObject(); + String key = (String) s.readObject(); + while (key != null) + { + Object listener = s.readObject(); + if ("componentL".equals(key)) + addComponentListener((ComponentListener) listener); + else if ("focusL".equals(key)) + addFocusListener((FocusListener) listener); + else if ("keyL".equals(key)) + addKeyListener((KeyListener) listener); + else if ("mouseL".equals(key)) + addMouseListener((MouseListener) listener); + else if ("mouseMotionL".equals(key)) + addMouseMotionListener((MouseMotionListener) listener); + else if ("inputMethodL".equals(key)) + addInputMethodListener((InputMethodListener) listener); + else if ("hierarchyL".equals(key)) + addHierarchyListener((HierarchyListener) listener); + else if ("hierarchyBoundsL".equals(key)) + addHierarchyBoundsListener((HierarchyBoundsListener) listener); + else if ("mouseWheelL".equals(key)) + addMouseWheelListener((MouseWheelListener) listener); + key = (String) s.readObject(); + } + } + + private void writeObject(ObjectOutputStream s) throws IOException + { + s.defaultWriteObject(); + AWTEventMulticaster.save(s, "componentL", componentListener); + AWTEventMulticaster.save(s, "focusL", focusListener); + AWTEventMulticaster.save(s, "keyL", keyListener); + AWTEventMulticaster.save(s, "mouseL", mouseListener); + AWTEventMulticaster.save(s, "mouseMotionL", mouseMotionListener); + AWTEventMulticaster.save(s, "inputMethodL", inputMethodListener); + AWTEventMulticaster.save(s, "hierarchyL", hierarchyListener); + AWTEventMulticaster.save(s, "hierarchyBoundsL", hierarchyBoundsListener); + AWTEventMulticaster.save(s, "mouseWheelL", mouseWheelListener); + s.writeObject(null); + } + + + // Nested classes. /** * This class provides accessibility support for subclasses of container. * * @author Eric Blake <ebb9@email.byu.edu> * @since 1.3 - * @XXX Shell class, to allow compilation. This needs documentation and - * correct implementation. + * @status updated to 1.4 */ protected abstract class AccessibleAWTComponent extends AccessibleContext implements Serializable, AccessibleComponent @@ -2527,67 +3984,688 @@ lostFocus(Event event, Object what) private static final long serialVersionUID = 642321655757800191L; /** - * Converts show/hide events to PropertyChange events. + * Converts show/hide events to PropertyChange events, and is registered + * as a component listener on this component. * * @serial the component handler */ - protected ComponentListener accessibleAWTComponentHandler; + protected ComponentListener accessibleAWTComponentHandler + = new AccessibleAWTComponentHandler(); /** - * Converts focus events to PropertyChange events. + * Converts focus events to PropertyChange events, and is registered + * as a focus listener on this component. * * @serial the focus handler */ - protected FocusListener accessibltAWTFocusHandler; + protected FocusListener accessibleAWTFocusHandler + = new AccessibleAWTFocusHandler(); /** * The default constructor. */ protected AccessibleAWTComponent() { + Component.this.addComponentListener(accessibleAWTComponentHandler); + Component.this.addFocusListener(accessibleAWTFocusHandler); + } + + /** + * Adds a global property change listener to the accessible component. + * + * @param l the listener to add + * @see #ACCESSIBLE_NAME_PROPERTY + * @see #ACCESSIBLE_DESCRIPTION_PROPERTY + * @see #ACCESSIBLE_STATE_PROPERTY + * @see #ACCESSIBLE_VALUE_PROPERTY + * @see #ACCESSIBLE_SELECTION_PROPERTY + * @see #ACCESSIBLE_TEXT_PROPERTY + * @see #ACCESSIBLE_VISIBLE_DATA_PROPERTY + */ + public void addPropertyChangeListener(PropertyChangeListener l) + { + Component.this.addPropertyChangeListener(l); + super.addPropertyChangeListener(l); + } + + /** + * Removes a global property change listener from this accessible + * component. + * + * @param l the listener to remove + */ + public void removePropertyChangeListener(PropertyChangeListener l) + { + Component.this.removePropertyChangeListener(l); + super.removePropertyChangeListener(l); + } + + /** + * Returns the accessible name of this component. It is almost always + * wrong to return getName(), since it is not localized. In fact, for + * things like buttons, this should be the text of the button, not the + * name of the object. The tooltip text might also be appropriate. + * + * @return the name + * @see #setAccessibleName(String) + */ + public String getAccessibleName() + { + return accessibleName == null ? getName() : accessibleName; + } + + /** + * Returns a brief description of this accessible context. This should + * be localized. + * + * @return a description of this component + * @see #setAccessibleDescription(String) + */ + public String getAccessibleDescription() + { + return accessibleDescription; } - public void addPropertyChangeListener(PropertyChangeListener l) {} - public void removePropertyChangeListener(PropertyChangeListener l){} - public String getAccessibleName() { return null; } - public String getAccessibleDescription() { return null; } + /** + * Returns the role of this component. + * + * @return the accessible role + */ public AccessibleRole getAccessibleRole() { return AccessibleRole.AWT_COMPONENT; } - public AccessibleStateSet getAccessibleStateSet() { return null; } - public Accessible getAccessibleParent() { return null; } - public int getAccessibleIndexInParent() { return -1; } - public int getAccessibleChildrenCount() { return 0; } - public Accessible getAccessibleChild(int i) { return null; } - public Locale getLocale() { return null; } - public AccessibleComponent getAccessibleComponent() { return null; } - public Color getBackground() { return null; } - public void setBackground(Color c) {} - public Color getForeground() { return null; } - public void setForeground(Color c) {} - public Cursor getCursor() { return null; } - public void setCursor(Cursor cursor) {} - public Font getFont() { return null; } - public void setFont(Font f) {} - public FontMetrics getFontMetrics(Font f) { return null; } - public boolean isEnabled() { return false; } - public void setEnabled(boolean b) {} - public boolean isVisible() { return false; } - public void setVisible(boolean b) {} - public boolean isShowing() { return false; } - public boolean contains(Point p) { return false; } - public Point getLocationOnScreen() { return null; } - public Point getLocation() { return null; } - public void setLocation(Point p) {} - public Rectangle getBounds() { return null; } - public void setBounds(Rectangle r) {} - public Dimension getSize() { return null; } - public void setSize(Dimension d) {} - public Accessible getAccessibleAt(Point p) { return null; } - public boolean isFocusTraversable() { return false; } - public void requestFocus() {} - public void addFocusListener(FocusListener l) {} - public void removeFocusListener(FocusListener l) {} + + /** + * Returns a state set describing this component's state. + * + * @return a new state set + * @see AccessibleState + */ + public AccessibleStateSet getAccessibleStateSet() + { + AccessibleStateSet s = new AccessibleStateSet(); + if (Component.this.isEnabled()) + s.add(AccessibleState.ENABLED); + if (isFocusable()) + s.add(AccessibleState.FOCUSABLE); + if (isFocusOwner()) + s.add(AccessibleState.FOCUSED); + if (isOpaque()) + s.add(AccessibleState.OPAQUE); + if (Component.this.isShowing()) + s.add(AccessibleState.SHOWING); + if (Component.this.isVisible()) + s.add(AccessibleState.VISIBLE); + return s; + } + + /** + * Returns the parent of this component, if it is accessible. + * + * @return the accessible parent + */ + public Accessible getAccessibleParent() + { + if (accessibleParent == null) + { + Container parent = getParent(); + accessibleParent = parent instanceof Accessible + ? (Accessible) parent : null; + } + return accessibleParent; + } + + /** + * Returns the index of this component in its accessible parent. + * + * @return the index, or -1 if the parent is not accessible + * @see #getAccessibleParent() + */ + public int getAccessibleIndexInParent() + { + if (getAccessibleParent() == null) + return -1; + AccessibleContext context + = ((Component) accessibleParent).getAccessibleContext(); + if (context == null) + return -1; + for (int i = context.getAccessibleChildrenCount(); --i >= 0; ) + if (context.getAccessibleChild(i) == Component.this) + return i; + return -1; + } + + /** + * Returns the number of children of this component which implement + * Accessible. Subclasses must override this if they can have children. + * + * @return the number of accessible children, default 0 + */ + public int getAccessibleChildrenCount() + { + return 0; + } + + /** + * Returns the ith accessible child. Subclasses must override this if + * they can have children. + * + * @return the ith accessible child, or null + * @see #getAccessibleChildrenCount() + */ + public Accessible getAccessibleChild(int i) + { + return null; + } + + /** + * Returns the locale of this component. + * + * @return the locale + * @throws IllegalComponentStateException if the locale is unknown + */ + public Locale getLocale() + { + return Component.this.getLocale(); + } + + /** + * Returns this, since it is an accessible component. + * + * @return the accessible component + */ + public AccessibleComponent getAccessibleComponent() + { + return this; + } + + /** + * Gets the background color. + * + * @return the background color + * @see #setBackground(Color) + */ + public Color getBackground() + { + return Component.this.getBackground(); + } + + /** + * Sets the background color. + * + * @param c the background color + * @see #getBackground() + * @see #isOpaque() + */ + public void setBackground(Color c) + { + Component.this.setBackground(c); + } + + /** + * Gets the foreground color. + * + * @return the foreground color + * @see #setForeground(Color) + */ + public Color getForeground() + { + return Component.this.getForeground(); + } + + /** + * Sets the foreground color. + * + * @param c the foreground color + * @see #getForeground() + */ + public void setForeground(Color c) + { + Component.this.setForeground(c); + } + + /** + * Gets the cursor. + * + * @return the cursor + * @see #setCursor(Cursor) + */ + public Cursor getCursor() + { + return Component.this.getCursor(); + } + + /** + * Sets the cursor. + * + * @param cursor the cursor + * @see #getCursor() + */ + public void setCursor(Cursor cursor) + { + Component.this.setCursor(cursor); + } + + /** + * Gets the font. + * + * @return the font + * @see #setFont(Font) + */ + public Font getFont() + { + return Component.this.getFont(); + } + + /** + * Sets the font. + * + * @param f the font + * @see #getFont() + */ + public void setFont(Font f) + { + Component.this.setFont(f); + } + + /** + * Gets the font metrics for a font. + * + * @param f the font to look up + * @return its metrics + * @throws NullPointerException if f is null + * @see #getFont() + */ + public FontMetrics getFontMetrics(Font f) + { + return Component.this.getFontMetrics(f); + } + + /** + * Tests if the component is enabled. + * + * @return true if the component is enabled + * @see #setEnabled(boolean) + * @see #getAccessibleStateSet() + * @see AccessibleState#ENABLED + */ + public boolean isEnabled() + { + return Component.this.isEnabled(); + } + + /** + * Set whether the component is enabled. + * + * @param b the new enabled status + * @see #isEnabled() + */ + public void setEnabled(boolean b) + { + Component.this.setEnabled(b); + } + + /** + * Test whether the component is visible (not necesarily showing). + * + * @return true if it is visible + * @see #setVisible(boolean) + * @see #getAccessibleStateSet() + * @see AccessibleState#VISIBLE + */ + public boolean isVisible() + { + return Component.this.isVisible(); + } + + /** + * Sets the visibility of this component. + * + * @param b the desired visibility + * @see #isVisible() + */ + public void setVisible(boolean b) + { + Component.this.setVisible(b); + } + + /** + * Tests if the component is showing. + * + * @return true if this is showing + */ + public boolean isShowing() + { + return Component.this.isShowing(); + } + + /** + * Tests if the point is contained in this component. + * + * @param p the point to check + * @return true if it is contained + * @throws NullPointerException if p is null + */ + public boolean contains(Point p) + { + return Component.this.contains(p.x, p.y); + } + + /** + * Returns the location of this object on the screen, or null if it is + * not showing. + * + * @return the location relative to screen coordinates, if showing + * @see #getBounds() + * @see #getLocation() + */ + public Point getLocationOnScreen() + { + return Component.this.isShowing() ? Component.this.getLocationOnScreen() + : null; + } + + /** + * Returns the location of this object relative to its parent's coordinate + * system, or null if it is not showing. + * + * @return the location + * @see #getBounds() + * @see #getLocationOnScreen() + */ + public Point getLocation() + { + return Component.this.isShowing() ? Component.this.getLocation() : null; + } + + /** + * Sets the location of this relative to its parent's coordinate system. + * + * @param p the location + * @throws NullPointerException if p is null + * @see #getLocation() + */ + public void setLocation(Point p) + { + Component.this.setLocation(p.x, p.y); + } + + /** + * Gets the bounds of this component, or null if it is not on screen. + * + * @return the bounds + * @see #contains(Point) + * @see #setBounds(Rectangle) + */ + public Rectangle getBounds() + { + return Component.this.isShowing() ? Component.this.getBounds() : null; + } + + /** + * Sets the bounds of this component. + * + * @param r the bounds + * @throws NullPointerException if r is null + * @see #getBounds() + */ + public void setBounds(Rectangle r) + { + Component.this.setBounds(r.x, r.y, r.width, r.height); + } + + /** + * Gets the size of this component, or null if it is not showing. + * + * @return the size + * @see #setSize(Dimension) + */ + public Dimension getSize() + { + return Component.this.isShowing() ? Component.this.getSize() : null; + } + + /** + * Sets the size of this component. + * + * @param d the size + * @throws NullPointerException if d is null + * @see #getSize() + */ + public void setSize(Dimension d) + { + Component.this.setSize(d.width, d.height); + } + + /** + * Returns the Accessible child at a point relative to the coordinate + * system of this component, if one exists, or null. Since components + * have no children, subclasses must override this to get anything besides + * null. + * + * @param p the point to check + * @return the accessible child at that point + * @throws NullPointerException if p is null + */ + public Accessible getAccessibleAt(Point p) + { + return null; + } + + /** + * Tests whether this component can accept focus. + * + * @return true if this is focus traversable + * @see #getAccessibleStateSet() + * @see AccessibleState#FOCUSABLE + * @see AccessibleState#FOCUSED + */ + public boolean isFocusTraversable() + { + return Component.this.isFocusTraversable(); + } + + /** + * Requests focus for this component. + * + * @see #isFocusTraversable() + */ + public void requestFocus() + { + Component.this.requestFocus(); + } + + /** + * Adds a focus listener. + * + * @param l the listener to add + */ + public void addFocusListener(FocusListener l) + { + Component.this.addFocusListener(l); + } + + /** + * Removes a focus listener. + * + * @param l the listener to remove + */ + public void removeFocusListener(FocusListener l) + { + Component.this.removeFocusListener(l); + } + + /** + * Converts component changes into property changes. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.3 + * @status updated to 1.4 + */ + protected class AccessibleAWTComponentHandler implements ComponentListener + { + /** + * Default constructor. + */ + protected AccessibleAWTComponentHandler() + { + } + + /** + * Convert a component hidden to a property change. + * + * @param e the event to convert + */ + public void componentHidden(ComponentEvent e) + { + AccessibleAWTComponent.this.firePropertyChange + (ACCESSIBLE_STATE_PROPERTY, AccessibleState.VISIBLE, null); + } + + /** + * Convert a component shown to a property change. + * + * @param e the event to convert + */ + public void componentShown(ComponentEvent e) + { + AccessibleAWTComponent.this.firePropertyChange + (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.VISIBLE); + } + + /** + * Moving a component does not affect properties. + * + * @param e ignored + */ + public void componentMoved(ComponentEvent e) + { + } + + /** + * Resizing a component does not affect properties. + * + * @param e ignored + */ + public void componentResized(ComponentEvent e) + { + } + } // class AccessibleAWTComponentHandler + + /** + * Converts focus changes into property changes. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.3 + * @status updated to 1.4 + */ + protected class AccessibleAWTFocusHandler implements FocusListener + { + /** + * Default constructor. + */ + protected AccessibleAWTFocusHandler() + { + } + + /** + * Convert a focus gained to a property change. + * + * @param e the event to convert + */ + public void focusGained(FocusEvent e) + { + AccessibleAWTComponent.this.firePropertyChange + (ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.FOCUSED); + } + + /** + * Convert a focus lost to a property change. + * + * @param e the event to convert + */ + public void focusLost(FocusEvent e) + { + AccessibleAWTComponent.this.firePropertyChange + (ACCESSIBLE_STATE_PROPERTY, AccessibleState.FOCUSED, null); + } + } // class AccessibleAWTComponentHandler } // class AccessibleAWTComponent + + /** + * This class provides support for blitting offscreen surfaces. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.4 + * @XXX Shell class, to allow compilation. This needs documentation and + * correct implementation. + */ + protected class BltBufferStrategy extends BufferStrategy + { + protected BufferCapabilities caps; + protected VolatileImage[] backBuffers; + protected boolean validatedContents; + protected int width; + protected int height; + protected BltBufferStrategy(int num, BufferCapabilities caps) + { + this.caps = caps; + createBackBuffers(num); + } + protected void createBackBuffers(int num) + { + backBuffers = new VolatileImage[num]; + } + public BufferCapabilities getCapabilities() + { + return caps; + } + public Graphics getDrawGraphics() { return null; } + public void show() {} + protected void revalidate() {} + public boolean contentsLost() { return false; } + public boolean contentsRestored() { return false; } + } // class BltBufferStrategy + + /** + * This class provides support for flipping component buffers. It is only + * designed for use by Canvas and Window. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.4 + * @XXX Shell class, to allow compilation. This needs documentation and + * correct implementation. + */ + protected class FlipBufferStrategy extends BufferStrategy + { + protected int numBuffers; + protected BufferCapabilities caps; + protected Image drawBuffer; + protected VolatileImage drawVBuffer; + protected boolean validatedContents; + protected FlipBufferStrategy(int num, BufferCapabilities caps) + throws AWTException + { + this.caps = caps; + createBuffers(num, caps); + } + protected void createBuffers(int num, BufferCapabilities caps) + throws AWTException {} + protected Image getBackBuffer() + { + return drawBuffer; + } + protected void flip(BufferCapabilities.FlipContents flipAction) {} + protected void destroyBuffers() {} + public BufferCapabilities getCapabilities() + { + return caps; + } + public Graphics getDrawGraphics() { return null; } + protected void revalidate() {} + public boolean contentsLost() { return false; } + public boolean contentsRestored() { return false; } + public void show() {} + } // class FlipBufferStrategy } // class Component diff --git a/java/awt/ComponentOrientation.java b/java/awt/ComponentOrientation.java index 66a3cbdc3..8d3a40c85 100644 --- a/java/awt/ComponentOrientation.java +++ b/java/awt/ComponentOrientation.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2001, 2002 Free Software Foundation +/* ComponentOrientation.java -- describes a component's orientation + Copyright (C) 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,83 +35,179 @@ this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -/** - * @author Bryce McKinlay <bryce@albatross.co.nz> - */ - -/* Status: Incomplete. Needs a Locale lookup table. */ package java.awt; +import java.io.Serializable; import java.util.Locale; +import java.util.MissingResourceException; import java.util.ResourceBundle; -public final class ComponentOrientation implements java.io.Serializable +/** + * This class is used to differentiate different orientations for text layout. + * It controls whether text flows left-to-right or right-to-left, and whether + * lines are horizontal or vertical, as in this table:<br> + * <pre> + * LT RT TL TR + * A B C C B A A D G G D A + * D E F F E D B E H H E B + * G H I I H G C F I I F C + * </pre> + * <b>LT</b> languages are most common (left-to-right lines, top-to-bottom). + * This includes Western European languages, and optionally includes Japanese, + * Chinese, and Korean. <b>RT</b> languages (right-to-left lines, + * top-to-bottom) are mainly middle eastern, such as Hebrew and Arabic. + * <b>TR</b> languages flow top-to-bottom in a line, right-to-left, and are + * the basis of Japanese, Chinese, and Korean. Finally, <b>TL</b> languages + * flow top-to-bottom in a line, left-to-right, as in Mongolian. + * + * <p>This is a pretty poor excuse for a type-safe enum, since it is not + * guaranteed that orientation objects are unique (thanks to serialization), + * yet there is no equals() method. You would be wise to compare the output + * of isHorizontal() and isLeftToRight() rather than comparing objects with + * ==, especially since more constants may be added in the future. + * + * @author Bryce McKinlay <bryce@albatross.co.nz> + * @since 1.0 + * @status updated to 1.4 + */ +public final class ComponentOrientation implements Serializable { - // Here is a wild guess. - private static int HORIZONTAL_ID = 1 << 0, - LEFT_TO_RIGHT_ID = 1 << 1; + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -4113291392143563828L; + + /** Constant for unknown orientation. */ + private static final int UNKNOWN_ID = 1; + + /** Constant for horizontal line orientation. */ + private static final int HORIZONTAL_ID = 2; + /** Constant for left-to-right orientation. */ + private static final int LEFT_TO_RIGHT_ID = 4; + + /** + * Items run left to right, and lines flow top to bottom. Examples: English, + * French. + */ public static final ComponentOrientation LEFT_TO_RIGHT - = new ComponentOrientation(HORIZONTAL_ID & LEFT_TO_RIGHT_ID); + = new ComponentOrientation(HORIZONTAL_ID | LEFT_TO_RIGHT_ID); + + /** + * Items run right to left, and lines flow top to bottom. Examples: Arabic, + * Hebrew. + */ public static final ComponentOrientation RIGHT_TO_LEFT = new ComponentOrientation(HORIZONTAL_ID); - public static final ComponentOrientation UNKNOWN - = new ComponentOrientation(0); - - // FIXME: This field is from the serialization spec, but what are the - // correct values? - int orientation; - ComponentOrientation(int orientation) + /** + * The orientation is unknown for the locale. For backwards compatibility, + * this behaves like LEFT_TO_RIGHT in the instance methods. + */ + public static final ComponentOrientation UNKNOWN + = new ComponentOrientation(UNKNOWN_ID | HORIZONTAL_ID | LEFT_TO_RIGHT_ID); + + /** + * The orientation of this object; bitwise-or of unknown (1), horizontal (2), + * and left-to-right (4). + * + * @serial the orientation + */ + private final int orientation; + + /** + * Construct a given orientation. + * + * @param orientation the orientation + */ + private ComponentOrientation(int orientation) { this.orientation = orientation; } + /** + * Returns true if the lines are horizontal, in which case lines flow + * top-to-bottom. For example, English, Hebrew. Counterexamples: Japanese, + * Chinese, Korean, Mongolian. + * + * @return true if this orientation has horizontal lines + */ public boolean isHorizontal() { - return ((orientation & HORIZONTAL_ID) != 0); + return (orientation & HORIZONTAL_ID) != 0; } + /** + * If isHorizontal() returns true, then this determines whether items in + * the line flow left-to-right. If isHorizontal() returns false, items in + * a line flow top-to-bottom, and this determines if lines flow + * left-to-right. + * + * @return true if this orientation flows left-to-right + */ public boolean isLeftToRight() { - return ((orientation & LEFT_TO_RIGHT_ID) != 0); + return (orientation & LEFT_TO_RIGHT_ID) != 0; } + /** + * Gets an orientation appropriate for the locale. + * + * @param locale the locale + * @return the orientation for that locale + * @throws NullPointerException if locale is null + */ public static ComponentOrientation getOrientation(Locale locale) { - // FIXME: Use a table to look this up. + // Based on iterating over all languages defined in JDK 1.4, this behavior + // matches Sun's. However, it makes me wonder if any non-horizontal + // orientations even exist, as it sure contradicts their documentation. + String language = locale.getLanguage(); + if ("ar".equals(language) || "fa".equals(language) || "iw".equals(language) + || "ur".equals(language)) + return RIGHT_TO_LEFT; return LEFT_TO_RIGHT; } + /** + * Gets an orientation from a resource bundle. This tries the following:<ol> + * <li>Use the key "Orientation" to find an instance of ComponentOrientation + * in the bundle.</li> + * <li>Get the locale of the resource bundle, and get the orientation of + * that locale.</li> + * <li>Give up and get the orientation of the default locale.<li> + * <ol> + * + * @param bdl the bundle to use + * @return the orientation + * @throws NullPointerException if bdl is null + * @deprecated use {@link #getOrientation(Locale)} instead + */ public static ComponentOrientation getOrientation(ResourceBundle bdl) { ComponentOrientation r; - try - { - Object obj = bdl.getObject("Orientation"); - r = (ComponentOrientation) obj; - if (r != null) - return r; - } - catch (Exception x) - { - // Fall through - } - + { + r = (ComponentOrientation) bdl.getObject("Orientation"); + if (r != null) + return r; + } + catch (MissingResourceException ignored) + { + } + catch (ClassCastException ignored) + { + } try - { - Locale l = bdl.getLocale(); - r = getOrientation(l); - if (r != null) - return r; - } - catch (Exception x) - { - // Fall through - } - - return (getOrientation (Locale.getDefault ())); + { + r = getOrientation(bdl.getLocale()); + if (r != null) + return r; + } + catch (Exception ignored) + { + } + return getOrientation(Locale.getDefault()); } -} +} // class ComponentOrientation diff --git a/java/awt/Container.java b/java/awt/Container.java index f3e0fd8dd..a544b290d 100644 --- a/java/awt/Container.java +++ b/java/awt/Container.java @@ -759,12 +759,19 @@ public class Container extends Component containerListener = AWTEventMulticaster.remove(containerListener, l); } + public synchronized ContainerListener[] getContainerListeners() + { + return (ContainerListener[]) + AWTEventMulticaster.getListeners(containerListener, + ContainerListener.class); + } + /** @since 1.3 */ public EventListener[] getListeners(Class listenerType) { if (listenerType == ContainerListener.class) - return getListenersImpl(listenerType, containerListener); - else return super.getListeners(listenerType); + return getContainerListeners(); + return super.getListeners(listenerType); } /** @@ -1119,13 +1126,15 @@ public class Container extends Component * * @serial the handler for property changes */ - protected ContainerListener accessibleContainerHandler; + protected ContainerListener accessibleContainerHandler + = new AccessibleContainerHandler(); /** * The default constructor. */ protected AccessibleAWTContainer() { + Container.this.addContainerListener(accessibleContainerHandler); } /** @@ -1136,8 +1145,12 @@ public class Container extends Component */ public int getAccessibleChildrenCount() { - // XXX - throw new Error("not implemented"); + int count = 0; + int i = component == null ? 0 : component.length; + while (--i >= 0) + if (component[i] instanceof Accessible) + count++; + return count; } /** @@ -1148,8 +1161,15 @@ public class Container extends Component */ public Accessible getAccessibleChild(int i) { - // XXX - throw new Error("not implemented"); + if (component == null) + return null; + int index = -1; + while (i >= 0 && ++index < component.length) + if (component[index] instanceof Accessible) + i--; + if (i < 0) + return (Accessible) component[index]; + return null; } /** @@ -1158,11 +1178,13 @@ public class Container extends Component * * @param p the point to look at * @return an accessible object at that point, or null + * @throws NullPointerException if p is null */ public Accessible getAccessibleAt(Point p) { - // XXX - throw new Error("not implemented"); + Component c = getComponentAt(p.x, p.y); + return c != Container.this && c instanceof Accessible ? (Accessible) c + : null; } /** @@ -1189,8 +1211,8 @@ public class Container extends Component */ public void componentAdded(ContainerEvent e) { - // XXX - throw new Error("not implemented"); + AccessibleAWTContainer.this.firePropertyChange + (ACCESSIBLE_CHILD_PROPERTY, null, e.getChild()); } /** @@ -1201,8 +1223,8 @@ public class Container extends Component */ public void componentRemoved(ContainerEvent e) { - // XXX - throw new Error("not implemented"); + AccessibleAWTContainer.this.firePropertyChange + (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null); } } // class AccessibleContainerHandler } // class AccessibleAWTPanel diff --git a/java/awt/ContainerOrderFocusTraversalPolicy.java b/java/awt/ContainerOrderFocusTraversalPolicy.java new file mode 100644 index 000000000..4c0d94e47 --- /dev/null +++ b/java/awt/ContainerOrderFocusTraversalPolicy.java @@ -0,0 +1,96 @@ +/* ContainerOrderFocusTraversalPolicy.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.io.Serializable; + +/** + * STUB CLASS ONLY + */ +public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy + implements Serializable +{ + private boolean downCycle = true; + + public ContainerOrderFocusTraversalPolicy() + { + throw new Error("not implemented"); + } + + public Component getComponentAfter(Container root, Component current) + { + return null; + } + + public Component getComponentBefore(Container root, Component current) + { + return null; + } + + public Component getFirstComponent(Container root) + { + return null; + } + + public Component getLastComponent(Container root) + { + return null; + } + + public Component getDefaultComponent(Container root) + { + return null; + } + + public void setImplicitDownCycleTraversal(boolean value) + { + downCycle = value; + } + + public boolean getImplicitDownCycleTraversal() + { + return downCycle; + } + + protected boolean accept(Component current) + { + return current.visible && current.isDisplayable() && current.enabled + && current.focusable; + } +} // class ContainerOrderFocusTraversalPolicy diff --git a/java/awt/DefaultFocusTraversalPolicy.java b/java/awt/DefaultFocusTraversalPolicy.java new file mode 100644 index 000000000..ac3a1786c --- /dev/null +++ b/java/awt/DefaultFocusTraversalPolicy.java @@ -0,0 +1,55 @@ +/* DefaultFocusTraversalPolicy.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +/** + * STUB CLASS ONLY + */ +public class DefaultFocusTraversalPolicy + extends ContainerOrderFocusTraversalPolicy +{ + public DefaultFocusTraversalPolicy() + { + } + + protected boolean accept(Component comp) + { + throw new Error("not implemented"); + } +} // class DefaultFocusTraversalPolicy diff --git a/java/awt/DefaultKeyboardFocusManager.java b/java/awt/DefaultKeyboardFocusManager.java new file mode 100644 index 000000000..e2a2f688e --- /dev/null +++ b/java/awt/DefaultKeyboardFocusManager.java @@ -0,0 +1,96 @@ +/* DefaultKeyboardFocusManager.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.awt.event.KeyEvent; + +/** + * STUB CLASS ONLY + */ +public class DefaultKeyboardFocusManager extends KeyboardFocusManager +{ + public DefaultKeyboardFocusManager() + { + } + + public boolean dispatchEvent(AWTEvent e) + { + throw new Error("not implemented"); + } + public boolean dispatchKeyEvent(KeyEvent e) + { + throw new Error("not implemented"); + } + public boolean postProcessKeyEvent(KeyEvent e) + { + throw new Error("not implemented"); + } + public void processKeyEvent(Component comp, KeyEvent e) + { + throw new Error("not implemented"); + } + protected void enqueueKeyEvents(long after, Component comp) + { + throw new Error("not implemented"); + } + protected void dequeueKeyEvents(long after, Component comp) + { + throw new Error("not implemented"); + } + protected void discardKeyEvents(Component comp) + { + throw new Error("not implemented"); + } + public void focusPreviousComponent(Component comp) + { + throw new Error("not implemented"); + } + public void focusNextComponent(Component comp) + { + throw new Error("not implemented"); + } + public void upFocusCycle(Component comp) + { + throw new Error("not implemented"); + } + public void downFocusCycle(Container cont) + { + throw new Error("not implemented"); + } +} // class DefaultKeyboardFocusManager diff --git a/java/awt/FocusTraversalPolicy.java b/java/awt/FocusTraversalPolicy.java new file mode 100644 index 000000000..fcabeceb3 --- /dev/null +++ b/java/awt/FocusTraversalPolicy.java @@ -0,0 +1,66 @@ +/* FocusTraversalPolicy.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +/** + * STUB CLASS ONLY + */ +public abstract class FocusTraversalPolicy +{ + public FocusTraversalPolicy() + { + } + + public abstract Component getComponentAfter(Container root, + Component current); + + public abstract Component getComponentBefore(Container root, + Component current); + + public abstract Component getFirstComponent(Container root); + + public abstract Component getLastComponent(Container root); + + public abstract Component getDefaultComponent(Container root); + + public Component getInitialComponent(Window window) + { + return getDefaultComponent(window); + } +} // class FocusTraversalPolicy diff --git a/java/awt/GradientPaint.java b/java/awt/GradientPaint.java new file mode 100644 index 000000000..f008b93f8 --- /dev/null +++ b/java/awt/GradientPaint.java @@ -0,0 +1,129 @@ +/* GradientPaint.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.ColorModel; + +/** + * STUB CLASS ONLY + */ +public class GradientPaint implements Paint +{ + private final float x1; + private final float y1; + private final Color c1; + private final float x2; + private final float y2; + private final Color c2; + private final boolean cyclic; + + public GradientPaint(float x1, float y1, Color c1, + float x2, float y2, Color c2) + { + this(x1, y1, c1, x2, y2, c2, false); + } + + public GradientPaint(Point2D p1, Color c1, Point2D p2, Color c2) + { + this((float) p1.getX(), (float) p1.getY(), c1, + (float) p2.getX(), (float) p2.getY(), c2, false); + } + + public GradientPaint(float x1, float y1, Color c1, + float x2, float y2, Color c2, boolean cyclic) + { + if (c1 == null || c2 == null) + throw new NullPointerException(); + this.x1 = x1; + this.y1 = y1; + this.c1 = c1; + this.x2 = x2; + this.y2 = y2; + this.c2 = c2; + this.cyclic = cyclic; + } + + public GradientPaint(Point2D p1, Color c1, Point2D p2, Color c2, + boolean cyclic) + { + this((float) p1.getX(), (float) p1.getY(), c1, + (float) p2.getX(), (float) p2.getY(), c2, cyclic); + } + + public Point2D getPoint1() + { + return new Point2D.Float(x1, y1); + } + + public Color getColor1() + { + return c1; + } + + public Point2D getPoint2() + { + return new Point2D.Float(x2, y2); + } + + public Color getColor2() + { + return c2; + } + + public boolean isCyclic() + { + return cyclic; + } + + public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, + Rectangle2D userBounds, + AffineTransform xform, + RenderingHints hints) + { + throw new Error("not implemented"); + } + + public int getTransparency() + { + throw new Error("not implemented"); + } +} // class GradientPaint diff --git a/java/awt/GraphicsConfiguration.java b/java/awt/GraphicsConfiguration.java index 5497fc65c..c7d0ed4ac 100644 --- a/java/awt/GraphicsConfiguration.java +++ b/java/awt/GraphicsConfiguration.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2001, 2002 Free Software Foundation +/* GraphicsConfiguration.java -- describes characteristics of graphics + Copyright (C) 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,33 +35,184 @@ this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -/* Status: Complete, but commented out until we have the required - GraphicsDevice. */ package java.awt; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; -import java.awt.geom.AffineTransform; +import java.awt.image.VolatileImage; +/** + * This class describes the configuration of various graphics devices, such + * as a monitor or printer. Different configurations may exist for the same + * device, according to the different native modes supported. + * + * <p>Virtual devices are supported (for example, in a multiple screen + * environment, a virtual device covers all screens simultaneously); the + * configuration will have a non-zero relative coordinate system in such + * a case. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Window + * @see Frame + * @see GraphicsEnvironment + * @see GraphicsDevice + * @since 1.0 + * @status updated to 1.4 + */ public abstract class GraphicsConfiguration { - // Can't instantiate directly. Having a protected constructor seems - // redundant, but that is what the docs specify. + /** + * The default constructor. + * + * @see GraphicsDevice#getConfigurations() + * @see GraphicsDevice#getDefaultConfiguration() + * @see GraphicsDevice#getBestConfiguration(GraphicsConfigTemplate) + * @see Graphics2D#getDeviceConfiguration() + */ protected GraphicsConfiguration () { } + /** + * Gets the associated device that this configuration describes. + * + * @return the device + */ public abstract GraphicsDevice getDevice(); - public abstract BufferedImage createCompatibleImage(int width, int height); - public abstract BufferedImage createCompatibleImage(int width, int height, + /** + * Returns a buffered image optimized to this device, so that blitting can + * be supported in the buffered image. + * + * @param w the width of the buffer + * @param h the height of the buffer + * @return the buffered image, or null if none is supported + */ + public abstract BufferedImage createCompatibleImage(int w, int h); + + /** + * Returns a buffered volatile image optimized to this device, so that + * blitting can be supported in the buffered image. Because the buffer is + * volatile, it can be optimized by native graphics accelerators. + * + * @param w the width of the buffer + * @param h the height of the buffer + * @return the buffered image, or null if none is supported + * @see Component#createVolatileImage(int, int) + * @since 1.4 + */ + public abstract VolatileImage createCompatibleVolatileImage(int w, int h); + + /** + * Returns a buffered volatile image optimized to this device, and with the + * given capabilities, so that blitting can be supported in the buffered + * image. Because the buffer is volatile, it can be optimized by native + * graphics accelerators. + * + * @param w the width of the buffer + * @param h the height of the buffer + * @param caps the desired capabilities of the image buffer + * @return the buffered image, or null if none is supported + * @throws AWTException if the capabilities cannot be met + * @since 1.4 + */ + public VolatileImage createCompatibleVolatileImage(int w, int h, + ImageCapabilities caps) + throws AWTException + { + throw new AWTException("not implemented"); + } + + /** + * Returns a buffered image optimized to this device, and with the specified + * transparency, so that blitting can be supported in the buffered image. + * + * @param w the width of the buffer + * @param h the height of the buffer + * @param transparency the transparency of the buffer + * @return the buffered image, or null if none is supported + * @see Transparency#OPAQUE + * @see Transparency#BITMASK + * @see Transparency#TRANSLUCENT + */ + public abstract BufferedImage createCompatibleImage(int w, int h, int transparency); + + /** + * Gets the color model of the corresponding device. + * + * @return the color model + */ public abstract ColorModel getColorModel(); + + /** + * Gets a color model for the corresponding device which supports the desired + * transparency level. + * + * @param transparency the transparency of the model + * @return the color model, with transparency + * @see Transparency#OPAQUE + * @see Transparency#BITMASK + * @see Transparency#TRANSLUCENT + */ public abstract ColorModel getColorModel(int transparency); + + /** + * Returns a transform that maps user coordinates to device coordinates. The + * preferred mapping is about 72 user units to 1 inch (2.54 cm) of physical + * space. This is often the identity transform. The device coordinates have + * the origin at the upper left, with increasing x to the right, and + * increasing y to the bottom. + * + * @return the transformation from user space to device space + * @see #getNormalizingTransform() + */ public abstract AffineTransform getDefaultTransform(); + + /** + * Returns a transform that maps user coordinates to device coordinates. The + * exact mapping is 72 user units to 1 inch (2.54 cm) of physical space. + * This is often the identity transform. The device coordinates have the + * origin at the upper left, with increasing x to the right, and increasing + * y to the bottom. Note that this is more accurate (and thus, sometimes more + * costly) than the default transform. + * + * @return the normalized transformation from user space to device space + * @see #getDefaultTransform() + */ public abstract AffineTransform getNormalizingTransform(); - /* @since 1.3 */ + /** + * Returns the bounds of the configuration, in device coordinates. If this + * is a virtual device (for example, encompassing several screens), the + * bounds may have a non-zero origin. + * + * @return the device bounds + * @since 1.3 + */ public abstract Rectangle getBounds(); -} + + /** + * Returns the buffering capabilities of this configuration. + * + * @return the buffer capabilities + * @since 1.4 + */ + public BufferCapabilities getBufferCapabilities() + { + throw new Error("not implemented"); + } + + /** + * Returns the imaging capabilities of this configuration. + * + * @return the image capabilities + * @since 1.4 + */ + public ImageCapabilities getImageCapabilities() + { + throw new Error("not implemented"); + } +} // class GraphicsConfiguration diff --git a/java/awt/ImageCapabilities.java b/java/awt/ImageCapabilities.java new file mode 100644 index 000000000..4d274e202 --- /dev/null +++ b/java/awt/ImageCapabilities.java @@ -0,0 +1,70 @@ +/* ImageCapabilities.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +/** + * STUBS ONLY + */ +public class ImageCapabilities implements Cloneable +{ + private final boolean accelerated; + public ImageCapabilities(boolean accelerated) + { + this.accelerated = accelerated; + } + public boolean isAccelerated() + { + return accelerated; + } + public boolean isTrueVolatile() + { + return true; + } + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } + } +} // class ImageCapabilities diff --git a/java/awt/Insets.java b/java/awt/Insets.java index fb1d46563..573005a76 100644 --- a/java/awt/Insets.java +++ b/java/awt/Insets.java @@ -1,4 +1,4 @@ -/* Insets.java -- Information about a container border. +/* Insets.java -- information about a container border Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,137 +38,121 @@ exception statement from your version. */ package java.awt; -/** - * This class represents the "margin" or space around a container. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public class Insets implements Cloneable, java.io.Serializable -{ - -/* - * Instance Variable - */ - -/** - * @serial The top inset - */ -public int top; - -/** - * @serial This bottom inset - */ -public int bottom; +import java.io.Serializable; /** - * @serial The left inset - */ -public int left; - -/** - * @serial The right inset - */ -public int right; - -/*************************************************************************/ - -/** - * Initializes a new instance of <code>Inset</code> with the specified - * inset values. - * - * @param top The top inset - * @param left The left inset - * @param bottom The bottom inset - * @param right The right inset - */ -public -Insets(int top, int left, int bottom, int right) -{ - this.top = top; - this.left = left; - this.bottom = bottom; - this.right = right; -} - -/*************************************************************************/ - -/* - * Instance Methods + * This class represents the "margin" or space around a container. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @status */ - -/** - * Tests whether this object is equal to the specified object. This will - * be true if and only if the specified object: - * <p> - * <ul> - * <li>Is not <code>null</code>. - * <li>Is an instance of <code>Insets</code>. - * <li>Has the same top, bottom, left, and right inset values as this object. - * </ul> - * - * @param obj The object to test against. - * - * @return <code>true</code> if the specified object is equal to this - * one, <code>false</code> otherwise. - */ -public boolean -equals(Object obj) -{ - if (!(obj instanceof Insets)) - return(false); - - Insets i = (Insets)obj; - - if (i.top != top) - return(false); - if (i.bottom != bottom) - return(false); - if (i.left != left) - return(false); - if (i.right != right) - return(false); - - return(true); -} - -public int -hashCode() -{ - return top + bottom + left + right; -} - -/*************************************************************************/ - -/** - * Returns a string representation of this object. - * - * @return A string representation of this object. - */ -public String -toString() -{ - return(getClass().getName() + "(top=" + top + ",bottom=" + bottom + - ",left=" + left + ",right=" + right + ")"); -} - -/*************************************************************************/ - -/** - * Returns a copy of this object. - * - * @return A copy of this object. - */ -public Object -clone() +public class Insets implements Cloneable, Serializable { - try - { - return(super.clone()); - } - catch(Exception e) - { - return(null); - } -} - -} // class Insets + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -2272572637695466749L; + + /** + * The gap from the top. + * + * @serial the top inset + */ + public int top; + + /** + * The gap from the left. + * + * @serial the left inset + */ + public int left; + + /** + * The gap from the bottom. + * + * @serial the bottom inset + */ + public int bottom; + + /** + * The gap from the right. + * + * @serial the right inset + */ + public int right; + + /** + * Initializes a new instance of <code>Inset</code> with the specified + * inset values. + * + * @param top the top inset + * @param left the left inset + * @param bottom the bottom inset + * @param right the right inset + */ + public Insets(int top, int left, int bottom, int right) + { + this.top = top; + this.left = left; + this.bottom = bottom; + this.right = right; + } + + /** + * Tests whether this object is equal to the specified object. The other + * object must be an instance of Insets with identical field values. + * + * @param obj the object to test against + * @return true if the specified object is equal to this one + */ + public boolean equals(Object obj) + { + if (! (obj instanceof Insets)) + return false; + Insets i = (Insets) obj; + return top == i.top && bottom == i.bottom + && left == i.left && right == i.right; + } + + /** + * Returns a hashcode for this instance. The formula is unspecified, but + * appears to be <code>XXX what is it? </code>. + * + * @return the hashcode + */ + public int hashCode() + { + // This can't be right... + return top + bottom + left + right; + } + + /** + * Returns a string representation of this object, which will be non-null. + * The format is unspecified, but appears to be <code>XXX what is it?</code>. + * + * @return a string representation of this object + */ + public String toString() + { + return getClass().getName() + "(top=" + top + ",bottom=" + bottom + + ",left=" + left + ",right=" + right + ')'; + } + + /** + * Returns a copy of this object. + * + * @return a copy of this object + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } + } +} // class Insets diff --git a/java/awt/JobAttributes.java b/java/awt/JobAttributes.java new file mode 100644 index 000000000..b64234dda --- /dev/null +++ b/java/awt/JobAttributes.java @@ -0,0 +1,500 @@ +/* JobAttributes.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +/** + * Needs documentation... + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.3 + * @status updated to 1.4, lacks documentation + */ +public final class JobAttributes implements Cloneable +{ + public static final class DefaultSelectionType extends AttributeValue + { + private static final String[] NAMES = { "all", "range", "selection" }; + public static final DefaultSelectionType ALL + = new DefaultSelectionType(0); + public static final DefaultSelectionType RANGE + = new DefaultSelectionType(1); + public static final DefaultSelectionType SELECTION + = new DefaultSelectionType(2); + private DefaultSelectionType(int value) + { + super(value, NAMES); + } + } // class DefaultSelectionType + + public static final class DestinationType extends AttributeValue + { + private static final String[] NAMES = { "file", "printer" }; + public static final DestinationType FILE = new DestinationType(0); + public static final DestinationType PRINTER = new DestinationType(1); + private DestinationType(int value) + { + super(value, NAMES); + } + } // class DestinationType + + public static final class DialogType extends AttributeValue + { + private static final String[] NAMES = { "common", "native", "none" }; + public static final DialogType COMMON = new DialogType(0); + public static final DialogType NATIVE = new DialogType(1); + public static final DialogType NONE = new DialogType(2); + private DialogType(int value) + { + super(value, NAMES); + } + } // class DialogType + + public static final class MultipleDocumentHandlingType + extends AttributeValue + { + private static final String[] NAMES = { + "separate-documents-collated-copies", + "separate-documents-uncollated-copies" + }; + public static final MultipleDocumentHandlingType + SEPARATE_DOCUMENTS_COLLATED_COPIES + = new MultipleDocumentHandlingType(0); + public static final MultipleDocumentHandlingType + SEPARATE_DOCUMENTS_UNCOLLATED_COPIES + = new MultipleDocumentHandlingType(1); + private MultipleDocumentHandlingType(int value) + { + super(value, NAMES); + } + } // class MultipleDocumentHandlingType + + public static final class SidesType extends AttributeValue + { + private static final String[] NAMES + = { "one-sided", "two-sided-long-edge", "two-sided-short-edge" }; + public static final SidesType ONE_SIDED = new SidesType(0); + public static final SidesType TWO_SIDED_LONG_EDGE = new SidesType(1); + public static final SidesType TWO_SIDED_SHORT_EDGE = new SidesType(2); + private SidesType(int value) + { + super(value, NAMES); + } + } // class SidesType + + private int copies; + private DefaultSelectionType selection; + private DestinationType destination; + private DialogType dialog; + private String filename; + private int maxPage; + private int minPage; + private MultipleDocumentHandlingType multiple; + private int[][] pageRanges; // null for default value + private int fromPage; // 0 for default value + private int toPage; // 0 for default value + private String printer; + private SidesType sides; + + public JobAttributes() + { + copies = 1; + selection = DefaultSelectionType.ALL; + destination = DestinationType.PRINTER; + dialog = DialogType.NATIVE; + maxPage = Integer.MAX_VALUE; + minPage = 1; + multiple + = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES; + sides = SidesType.ONE_SIDED; + } + + public JobAttributes(JobAttributes attr) + { + set(attr); + } + + public JobAttributes(int copies, DefaultSelectionType selection, + DestinationType destination, DialogType dialog, + String filename, int max, int min, + MultipleDocumentHandlingType multiple, + int[][] pageRanges, String printer, SidesType sides) + { + if (copies <= 0 || selection == null || destination == null + || dialog == null || max < min || min <= 0 || multiple == null + || sides == null) + throw new IllegalArgumentException(); + this.copies = copies; + this.selection = selection; + this.destination = destination; + this.dialog = dialog; + this.filename = filename; + maxPage = max; + minPage = min; + this.multiple = multiple; + setPageRanges(pageRanges); + this.printer = printer; + this.sides = sides; + } + + public Object clone() + { + return new JobAttributes(this); + } + + public void set(JobAttributes attr) + { + copies = attr.copies; + selection = attr.selection; + destination = attr.destination; + dialog = attr.dialog; + filename = attr.filename; + maxPage = attr.maxPage; + minPage = attr.minPage; + multiple = attr.multiple; + pageRanges = (int[][]) attr.pageRanges.clone(); + printer = attr.printer; + sides = attr.sides; + fromPage = attr.fromPage; + toPage = attr.toPage; + } + + public int getCopies() + { + return copies; + } + + public void setCopies(int copies) + { + if (copies <= 0) + throw new IllegalArgumentException(); + this.copies = copies; + } + + public void setCopiesToDefault() + { + copies = 1; + } + + public DefaultSelectionType getDefaultSelection() + { + return selection; + } + + public void setDefaultSelection(DefaultSelectionType selection) + { + if (selection == null) + throw new IllegalArgumentException(); + this.selection = selection; + } + + public DestinationType getDestination() + { + return destination; + } + + public void setDestination(DestinationType destination) + { + if (destination == null) + throw new IllegalArgumentException(); + this.destination = destination; + } + + public DialogType getDialog() + { + return dialog; + } + + public void setDialog(DialogType dialog) + { + if (dialog == null) + throw new IllegalArgumentException(); + this.dialog = dialog; + } + + public String getFileName() + { + return filename; + } + + public void setFileName(String filename) + { + this.filename = filename; + } + + public int getFromPage() + { + return fromPage != 0 ? fromPage + : pageRanges != null ? pageRanges[0][0] + : toPage != 0 ? toPage : minPage; + } + + public void setFromPage(int fromPage) + { + if (fromPage < minPage || (fromPage > toPage && toPage != 0) + || fromPage > maxPage) + throw new IllegalArgumentException(); + if (pageRanges == null) + this.fromPage = fromPage; + } + + public int getMaxPage() + { + return maxPage; + } + + public void setMaxPage(int maxPage) + { + if (maxPage < minPage) + throw new IllegalArgumentException(); + this.maxPage = maxPage; + if (maxPage < fromPage) + fromPage = maxPage; + if (maxPage < toPage) + toPage = maxPage; + if (pageRanges != null) + { + int i = pageRanges.length - 1; + while (i >= 0 && maxPage < pageRanges[i][1]) + i--; + if (maxPage >= pageRanges[++i][0]) + pageRanges[i++][1] = maxPage; + if (i == 0) + pageRanges = null; + else if (i < pageRanges.length) + { + int[][] tmp = new int[i][]; + System.arraycopy(pageRanges, 0, tmp, 0, i); + pageRanges = tmp; + } + } + } + + public int getMinPage() + { + return minPage; + } + + public void setMinPage(int minPage) + { + if (minPage <= 0 || minPage > maxPage) + throw new IllegalArgumentException(); + this.minPage = minPage; + if (minPage > toPage) + toPage = minPage; + if (minPage > fromPage) + fromPage = minPage; + if (pageRanges != null) + { + int size = pageRanges.length; + int i = 0; + while (i < size && minPage > pageRanges[i][0]) + i++; + if (minPage <= pageRanges[i - 1][1]) + pageRanges[--i][0] = minPage; + if (i == size) + pageRanges = null; + else if (i > 0) + { + int[][] tmp = new int[size - i][]; + System.arraycopy(pageRanges, i, tmp, 0, size - i); + pageRanges = tmp; + } + } + } + + public MultipleDocumentHandlingType getMultipleDocumentHandling() + { + return multiple; + } + + public void setMultipleDocumentHandling + (MultipleDocumentHandlingType multiple) + { + if (multiple == null) + throw new IllegalArgumentException(); + this.multiple = multiple; + } + + public void setMultipleDocumentHandlingToDefault() + { + multiple + = MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES; + } + + public int[][] getPageRanges() + { + if (pageRanges == null) + return new int[][] { { getFromPage(), getToPage() } }; + // Perform a deep clone, so user code cannot affect original arrays. + int i = pageRanges.length; + int[][] result = new int[i][]; + while (--i >= 0) + result[i] = (int[]) pageRanges[i].clone(); + return result; + } + + public void setPageRanges(int[][] pageRanges) + { + int size = pageRanges == null ? 0 : pageRanges.length; + if (size == 0) + throw new IllegalArgumentException(); + while (--size >= 0) + { + int[] range = pageRanges[size]; + if (range == null || range.length != 2 + || range[0] < minPage || range[1] < range[0] || range[1] > maxPage + || (size != 0 && range[0] <= pageRanges[size - 1][1])) + throw new IllegalArgumentException(); + } + size = pageRanges.length; + if (fromPage > 0 && pageRanges[0][0] > fromPage) + fromPage = pageRanges[0][0]; + if (toPage > 0 && pageRanges[size - 1][1] < toPage) + toPage = pageRanges[size - 1][1]; + this.pageRanges = new int[size][]; + while (--size >= 0) + this.pageRanges[size] = (int[]) pageRanges[size].clone(); + } + + public String getPrinter() + { + return printer; + } + + public void setPrinter(String printer) + { + this.printer = printer; + } + + public SidesType getSides() + { + return sides; + } + + public void setSides(SidesType sides) + { + if (sides == null) + throw new IllegalArgumentException(); + this.sides = sides; + } + + public void setSidesToDefault() + { + sides = SidesType.ONE_SIDED; + } + + public int getToPage() + { + return toPage != 0 ? toPage + : pageRanges != null ? pageRanges[pageRanges.length - 1][1] + : fromPage != 0 ? fromPage : maxPage; + } + + public void setToPage(int toPage) + { + if (toPage < minPage || (fromPage > toPage && fromPage != 0) + || toPage > maxPage) + throw new IllegalArgumentException(); + if (pageRanges == null) + this.toPage = toPage; + } + + public boolean equals(Object o) + { + if (this == o) + return true; + if (! (o instanceof JobAttributes)) + return false; + JobAttributes ja = (JobAttributes) o; + if (copies != ja.copies || selection != ja.selection + || destination != ja.destination || dialog != ja.dialog + || ! filename.equals(ja.filename) || maxPage != ja.maxPage + || minPage != ja.minPage || multiple != ja.multiple + || fromPage != ja.fromPage || toPage != ja.toPage + || ! printer.equals(ja.printer) || sides != ja.sides + || (pageRanges == null) != (ja.pageRanges == null)) + return false; + if (pageRanges != ja.pageRanges) + for (int i = pageRanges.length; --i >= 0; ) + if (pageRanges[i][0] != ja.pageRanges[i][0] + || pageRanges[i][1] != ja.pageRanges[i][1]) + return false; + return true; + } + + public int hashCode() + { + int hash = (selection.value << 6) ^ (destination.value << 5) + ^ (dialog.value << 3) ^ (multiple.value << 2) ^ sides.value + ^ (filename == null ? 0 : filename.hashCode()) + ^ (printer == null ? 0 : printer.hashCode()); + // The effect of the above fields on the hashcode match the JDK. However, + // I am unable to reverse engineer the effect of the fields listed below, + // so I am using my own implementation. Note that this still satisfies + // the general contract of hashcode, it just doesn't match the JDK. + hash ^= (copies << 27) ^ (maxPage << 22) ^ (minPage << 17); + if (pageRanges == null) + hash ^= (getFromPage() << 13) ^ (getToPage() << 8); + else + for (int i = pageRanges.length; --i >= 0; ) + hash ^= (pageRanges[i][0] << 13) ^ (pageRanges[i][1] << 8); + return hash; + } + + public String toString() + { + StringBuffer s = new StringBuffer("copies=").append(copies) + .append(",defaultSelection=").append(selection).append(",destination=") + .append(destination).append(",dialog=").append(dialog) + .append(",fileName=").append(filename).append(",fromPage=") + .append(getFromPage()).append(",maxPage=").append(maxPage) + .append(",minPage=").append(minPage) + .append(",multiple-document-handling=").append(multiple) + .append(",page-ranges=["); + if (pageRanges == null) + s.append(minPage).append(':').append(minPage).append(']'); + else + for (int i = 0; i < pageRanges.length; i++) + s.append(pageRanges[i][0]).append(':').append(pageRanges[i][1]) + .append(','); + s.setLength(s.length() - 1); + return s.append("],printer=").append(printer).append(",sides=") + .append(sides).append(",toPage=").append(getToPage()).toString(); + } +} // class JobAttributes diff --git a/java/awt/KeyboardFocusManager.java b/java/awt/KeyboardFocusManager.java new file mode 100644 index 000000000..2bb17a823 --- /dev/null +++ b/java/awt/KeyboardFocusManager.java @@ -0,0 +1,555 @@ +/* KeyboardFocusManager.java -- manage component focusing via the keyboard + Copyright (C) 2002 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; +import java.beans.VetoableChangeSupport; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.4 + * @status partially updated to 1.4, needs documentation. + */ +public abstract class KeyboardFocusManager + implements KeyEventDispatcher, KeyEventPostProcessor +{ + public static final int FORWARD_TRAVERSAL_KEYS = 0; + public static final int BACKWARD_TRAVERSAL_KEYS = 1; + public static final int UP_CYCLE_TRAVERSAL_KEYS = 2; + public static final int DOWN_CYCLE_TRAVERSAL_KEYS = 3; + + private static final Set DEFAULT_FORWARD_KEYS; + private static final Set DEFAULT_BACKWARD_KEYS; + static + { + Set s = new HashSet(); + s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0)); + s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, + KeyEvent.CTRL_DOWN_MASK)); + DEFAULT_FORWARD_KEYS = Collections.unmodifiableSet(s); + s = new HashSet(); + s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, + KeyEvent.SHIFT_DOWN_MASK)); + s.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, + KeyEvent.SHIFT_DOWN_MASK + | KeyEvent.CTRL_DOWN_MASK)); + DEFAULT_BACKWARD_KEYS = Collections.unmodifiableSet(s); + } + + private static KeyboardFocusManager current + = new DefaultKeyboardFocusManager(); + + // XXX Not implemented correctly. I think a good implementation here may + // be to have permanentFocusOwner be null, and fall back to focusOwner, + // unless a temporary focus change is in effect. + private static Component focusOwner; + private static Component permanentFocusOwner; + + private static Window focusedWindow; + private static Window activeWindow; + private static Container focusCycleRoot; + + private FocusTraversalPolicy defaultPolicy; + private Set[] defaultFocusKeys = new Set[] { + DEFAULT_FORWARD_KEYS, DEFAULT_BACKWARD_KEYS, + Collections.EMPTY_SET, Collections.EMPTY_SET + }; + + private final PropertyChangeSupport propertyChangeSupport + = new PropertyChangeSupport(this); + private final VetoableChangeSupport vetoableChangeSupport + = new VetoableChangeSupport(this); + private final ArrayList keyEventDispatchers = new ArrayList(); + private final ArrayList keyEventPostProcessors = new ArrayList(); + + + public KeyboardFocusManager() + { + } + + public static KeyboardFocusManager getCurrentKeyboardFocusManager() + { + // XXX Need a way to divide this into contexts. + return current; + } + + public static void setCurrentKeyboardFocusManager(KeyboardFocusManager m) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new AWTPermission("replaceKeyboardFocusManager")); + // XXX Need a way to divide this into contexts. + current = m == null ? new DefaultKeyboardFocusManager() : m; + } + + public Component getFocusOwner() + { + // XXX Need an easy way to test if this thread is in the context of the + // global focus owner, to avoid creating the exception in the first place. + try + { + return getGlobalFocusOwner(); + } + catch (SecurityException e) + { + return null; + } + } + + protected Component getGlobalFocusOwner() + { + // XXX Need a way to test if this thread is in the context of the focus + // owner, and throw a SecurityException if that is the case. + // XXX Implement. + return focusOwner; + } + + protected void setGlobalFocusOwner(Component owner) + { + // XXX Should this send focus events to the components involved? + if (owner == null || owner.focusable) + { + firePropertyChange("focusOwner", focusOwner, owner); + try + { + fireVetoableChange("focusOwner", focusOwner, owner); + focusOwner = owner; + } + catch (PropertyVetoException e) + { + } + } + } + + public void clearGlobalFocusOwner() + { + // XXX Is this enough? + setGlobalFocusOwner(null); + } + + public Component getPermanentFocusOwner() + { + // XXX Need an easy way to test if this thread is in the context of the + // global focus owner, to avoid creating the exception in the first place. + try + { + return getGlobalPermanentFocusOwner(); + } + catch (SecurityException e) + { + return null; + } + } + + protected Component getGlobalPermanentFocusOwner() + { + // XXX Need a way to test if this thread is in the context of the focus + // owner, and throw a SecurityException if that is the case. + // XXX Implement. + return permanentFocusOwner == null ? focusOwner : permanentFocusOwner; + } + + protected void setGlobalPermanentFocusOwner(Component focusOwner) + { + // XXX Should this send focus events to the components involved? + if (focusOwner == null || focusOwner.focusable) + { + firePropertyChange("permanentFocusOwner", permanentFocusOwner, + focusOwner); + try + { + fireVetoableChange("permanentFocusOwner", permanentFocusOwner, + focusOwner); + permanentFocusOwner = focusOwner; + } + catch (PropertyVetoException e) + { + } + } + } + + public Window getFocusedWindow() + { + // XXX Need an easy way to test if this thread is in the context of the + // global focus owner, to avoid creating the exception in the first place. + try + { + return getGlobalFocusedWindow(); + } + catch (SecurityException e) + { + return null; + } + } + + protected Window getGlobalFocusedWindow() + { + // XXX Need a way to test if this thread is in the context of the focus + // owner, and throw a SecurityException if that is the case. + // XXX Implement. + return focusedWindow; + } + + protected void setGlobalFocusedWindow(Window window) + { + // XXX Should this send focus events to the windows involved? + if (window == null || window.focusable) + { + firePropertyChange("focusedWindow", focusedWindow, window); + try + { + fireVetoableChange("focusedWindow", focusedWindow, window); + focusedWindow = window; + } + catch (PropertyVetoException e) + { + } + } + } + + public Window getActiveWindow() + { + // XXX Need an easy way to test if this thread is in the context of the + // global focus owner, to avoid creating the exception in the first place. + try + { + return getGlobalActiveWindow(); + } + catch (SecurityException e) + { + return null; + } + } + + protected Window getGlobalActiveWindow() + { + // XXX Need a way to test if this thread is in the context of the focus + // owner, and throw a SecurityException if that is the case. + // XXX Implement. + return activeWindow; + } + + protected void setGlobalActiveWindow(Window window) + { + // XXX Should this send focus events to the windows involved? + firePropertyChange("activeWindow", activeWindow, window); + try + { + fireVetoableChange("activeWindow", activeWindow, window); + activeWindow = window; + } + catch (PropertyVetoException e) + { + } + } + + public FocusTraversalPolicy getDefaultFocusTraversalPolicy() + { + if (defaultPolicy == null) + defaultPolicy = new DefaultFocusTraversalPolicy(); + return defaultPolicy; + } + + public void setDefaultFocusTraversalPolicy(FocusTraversalPolicy policy) + { + if (policy == null) + throw new IllegalArgumentException(); + firePropertyChange("defaultFocusTraversalPolicy", defaultPolicy, policy); + defaultPolicy = policy; + } + + public void setDefaultFocusTraversalKeys(int id, Set keystrokes) + { + if (keystrokes == null) + throw new IllegalArgumentException(); + Set sa; + Set sb; + Set sc; + String type; + switch (id) + { + case FORWARD_TRAVERSAL_KEYS: + sa = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS]; + sb = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS]; + sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS]; + type = "forwardDefaultFocusTraversalKeys"; + break; + case BACKWARD_TRAVERSAL_KEYS: + sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS]; + sb = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS]; + sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS]; + type = "backwardDefaultFocusTraversalKeys"; + break; + case UP_CYCLE_TRAVERSAL_KEYS: + sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS]; + sb = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS]; + sc = defaultFocusKeys[DOWN_CYCLE_TRAVERSAL_KEYS]; + type = "upCycleDefaultFocusTraversalKeys"; + break; + case DOWN_CYCLE_TRAVERSAL_KEYS: + sa = defaultFocusKeys[FORWARD_TRAVERSAL_KEYS]; + sb = defaultFocusKeys[BACKWARD_TRAVERSAL_KEYS]; + sc = defaultFocusKeys[UP_CYCLE_TRAVERSAL_KEYS]; + type = "downCycleDefaultFocusTraversalKeys"; + break; + default: + throw new IllegalArgumentException(); + } + int i = keystrokes.size(); + Iterator iter = keystrokes.iterator(); + while (--i >= 0) + { + Object o = iter.next(); + if (! (o instanceof AWTKeyStroke) + || sa.contains(o) || sb.contains(o) || sc.contains(o) + || ((AWTKeyStroke) o).keyCode == KeyEvent.VK_UNDEFINED) + throw new IllegalArgumentException(); + } + keystrokes = Collections.unmodifiableSet(new HashSet(keystrokes)); + firePropertyChange(type, defaultFocusKeys[id], keystrokes); + defaultFocusKeys[id] = keystrokes; + } + + public Set getDefaultFocusTraversalKeys(int id) + { + if (id < FORWARD_TRAVERSAL_KEYS || id > DOWN_CYCLE_TRAVERSAL_KEYS) + throw new IllegalArgumentException(); + return defaultFocusKeys[id]; + } + + public Container getCurrentFocusCycleRoot() + { + // XXX Need an easy way to test if this thread is in the context of the + // global focus owner, to avoid creating the exception in the first place. + try + { + return getGlobalCurrentFocusCycleRoot(); + } + catch (SecurityException e) + { + return null; + } + } + + protected Container getGlobalCurrentFocusCycleRoot() + { + // XXX Need a way to test if this thread is in the context of the focus + // owner, and throw a SecurityException if that is the case. + // XXX Implement. + return focusCycleRoot; + } + + protected void setGlobalCurrentFocusCycleRoot(Container cycleRoot) + { + firePropertyChange("currentFocusCycleRoot", focusCycleRoot, cycleRoot); + focusCycleRoot = cycleRoot; + } + + public void addPropertyChangeListener(PropertyChangeListener l) + { + if (l != null) + propertyChangeSupport.addPropertyChangeListener(l); + } + + public void removePropertyChangeListener(PropertyChangeListener l) + { + if (l != null) + propertyChangeSupport.removePropertyChangeListener(l); + } + + public PropertyChangeListener[] getPropertyChangeListeners() + { + return propertyChangeSupport.getPropertyChangeListeners(); + } + + public void addPropertyChangeListener(String name, PropertyChangeListener l) + { + if (l != null) + propertyChangeSupport.addPropertyChangeListener(name, l); + } + + public void removePropertyChangeListener(String name, + PropertyChangeListener l) + { + if (l != null) + propertyChangeSupport.removePropertyChangeListener(name, l); + } + + public PropertyChangeListener[] getPropertyChangeListeners(String name) + { + return propertyChangeSupport.getPropertyChangeListeners(name); + } + + protected void firePropertyChange(String name, Object o, Object n) + { + propertyChangeSupport.firePropertyChange(name, o, n); + } + + public void addVetoableChangeListener(VetoableChangeListener l) + { + if (l != null) + vetoableChangeSupport.addVetoableChangeListener(l); + } + + public void removeVetoableChangeListener(VetoableChangeListener l) + { + if (l != null) + vetoableChangeSupport.removeVetoableChangeListener(l); + } + + public VetoableChangeListener[] getVetoableChangeListeners() + { + return vetoableChangeSupport.getVetoableChangeListeners(); + } + + public void addVetoableChangeListener(String name, VetoableChangeListener l) + { + if (l != null) + vetoableChangeSupport.addVetoableChangeListener(name, l); + } + + public void removeVetoableChangeListener(String name, + VetoableChangeListener l) + { + if (l != null) + vetoableChangeSupport.removeVetoableChangeListener(name, l); + } + + public VetoableChangeListener[] getVetoableChangeListeners(String name) + { + return vetoableChangeSupport.getVetoableChangeListeners(name); + } + + protected void fireVetoableChange(String name, Object o, Object n) + throws PropertyVetoException + { + vetoableChangeSupport.fireVetoableChange(name, o, n); + } + + public void addKeyEventDispatcher(KeyEventDispatcher dispatcher) + { + if (dispatcher != null) + keyEventDispatchers.add(dispatcher); + } + + public void removeKeyEventDispatcher(KeyEventDispatcher dispatcher) + { + keyEventDispatchers.remove(dispatcher); + } + + protected List getKeyEventDispatchers() + { + return (List) keyEventDispatchers.clone(); + } + + public void addKeyEventPostProcessor(KeyEventPostProcessor postProcessor) + { + if (postProcessor != null) + keyEventPostProcessors.add(postProcessor); + } + + public void removeKeyEventPostProcessor(KeyEventPostProcessor postProcessor) + { + keyEventPostProcessors.remove(postProcessor); + } + + protected List getKeyEventPostProcessors() + { + return (List) keyEventPostProcessors.clone(); + } + + public abstract boolean dispatchEvent(AWTEvent e); + + public final void redispatchEvent(Component target, AWTEvent e) + { + throw new Error("not implemented"); + } + + public abstract boolean dispatchKeyEvent(KeyEvent e); + + public abstract boolean postProcessKeyEvent(KeyEvent e); + + public abstract void processKeyEvent(Component focused, KeyEvent e); + + protected abstract void enqueueKeyEvents(long after, Component untilFocused); + + protected abstract void dequeueKeyEvents(long after, Component untilFocused); + + protected abstract void discardKeyEvents(Component comp); + + public abstract void focusNextComponent(Component comp); + + public abstract void focusPreviousComponent(Component comp); + + public abstract void upFocusCycle(Component comp); + + public abstract void downFocusCycle(Container cont); + + public final void focusNextComponent() + { + focusNextComponent(focusOwner); + } + + public final void focusPreviousComponent() + { + focusPreviousComponent(focusOwner); + } + + public final void upFocusCycle() + { + upFocusCycle(focusOwner); + } + + public final void downFocusCycle() + { + if (focusOwner instanceof Container && focusOwner.isFocusCycleRoot()) + downFocusCycle((Container) focusOwner); + } +} // class KeyboardFocusManager diff --git a/java/awt/MenuItem.java b/java/awt/MenuItem.java index ea92f9ab8..ffef30ecf 100644 --- a/java/awt/MenuItem.java +++ b/java/awt/MenuItem.java @@ -42,6 +42,7 @@ import java.awt.peer.MenuItemPeer; import java.awt.peer.MenuComponentPeer; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.lang.reflect.Array; import java.util.EventListener; /** @@ -385,19 +386,24 @@ removeActionListener(ActionListener l) action_listeners = AWTEventMulticaster.remove(action_listeners, l); } + public synchronized ActionListener[] getActionListeners() + { + return (ActionListener[]) + AWTEventMulticaster.getListeners(action_listeners, + ActionListener.class); + } + /** Returns all registered EventListers of the given listenerType. * listenerType must be a subclass of EventListener, or a * ClassClassException is thrown. * @since 1.3 */ -public EventListener[] -getListeners(Class listenerType) -{ - if (listenerType == ActionListener.class) - return Component.getListenersImpl(listenerType, action_listeners); - else - return Component.getListenersImpl(listenerType, null); -} + public EventListener[] getListeners(Class listenerType) + { + if (listenerType == ActionListener.class) + return getActionListeners(); + return (EventListener[]) Array.newInstance(listenerType, 0); + } /*************************************************************************/ diff --git a/java/awt/PageAttributes.java b/java/awt/PageAttributes.java new file mode 100644 index 000000000..2501aa3ee --- /dev/null +++ b/java/awt/PageAttributes.java @@ -0,0 +1,482 @@ +/* PageAttributes.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.util.Locale; + +/** + * Missing Documentation + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.3 + * @status updated to 1.4, but missing documentation + */ +public final class PageAttributes implements Cloneable +{ + public static final class ColorType extends AttributeValue + { + private static final String[] NAMES = { "color", "monochrome" }; + public static final ColorType COLOR = new ColorType(0); + public static final ColorType MONOCHROME = new ColorType(1); + private ColorType(int value) + { + super(value, NAMES); + } + } // class ColorType + public static final class MediaType extends AttributeValue + { + private static final String[] NAMES + = { "iso-4a0", "iso-2a0", "iso-a0", "iso-a1", "iso-a2", "iso-a3", + "iso-a4", "iso-a5", "iso-a6", "iso-a7", "iso-a8", "iso-a9", + "iso-a10", "iso-b0", "iso-b1", "iso-b2", "iso-b3", "iso-b4", + "iso-b5", "iso-b6", "iso-b7", "iso-b8", "iso-b9", "iso-b10", + "jis-b0", "jis-b1", "jis-b2", "jis-b3", "jis-b4", "jis-b5", + "jis-b6", "jis-b7", "jis-b8", "jis-b9", "jis-b10", "iso-c0", + "iso-c1", "iso-c2", "iso-c3", "iso-c4", "iso-c5", "iso-c6", + "iso-c7", "iso-c8", "iso-c9", "iso-c10", "iso-designated-long", + "executive", "folio", "invoice", "ledger", "na-letter", "na-legal", + "quarto", "a", "b", "c", "d", "e", "na-10x15-envelope", + "na-10x14-envelope", "na-10x13-envelope", "na-9x12-envelope", + "na-9x11-envelope", "na-7x9-envelope", "na-6x9-envelope", + "na-number-9-envelope", "na-number-10-envelope", + "na-number-11-envelope", "na-number-12-envelope", + "na-number-14-envelope", "invite-envelope", "italy-envelope", + "monarch-envelope", "personal-envelope" }; + public static final MediaType ISO_4A0 = new MediaType(0); + public static final MediaType ISO_2A0 = new MediaType(1); + public static final MediaType ISO_A0 = new MediaType(2); + public static final MediaType ISO_A1 = new MediaType(3); + public static final MediaType ISO_A2 = new MediaType(4); + public static final MediaType ISO_A3 = new MediaType(5); + public static final MediaType ISO_A4 = new MediaType(6); + public static final MediaType ISO_A5 = new MediaType(7); + public static final MediaType ISO_A6 = new MediaType(8); + public static final MediaType ISO_A7 = new MediaType(9); + public static final MediaType ISO_A8 = new MediaType(10); + public static final MediaType ISO_A9 = new MediaType(11); + public static final MediaType ISO_A10 = new MediaType(12); + public static final MediaType ISO_B0 = new MediaType(13); + public static final MediaType ISO_B1 = new MediaType(14); + public static final MediaType ISO_B2 = new MediaType(15); + public static final MediaType ISO_B3 = new MediaType(16); + public static final MediaType ISO_B4 = new MediaType(17); + public static final MediaType ISO_B5 = new MediaType(18); + public static final MediaType ISO_B6 = new MediaType(19); + public static final MediaType ISO_B7 = new MediaType(20); + public static final MediaType ISO_B8 = new MediaType(21); + public static final MediaType ISO_B9 = new MediaType(22); + public static final MediaType ISO_B10 = new MediaType(23); + public static final MediaType JIS_B0 = new MediaType(24); + public static final MediaType JIS_B1 = new MediaType(25); + public static final MediaType JIS_B2 = new MediaType(26); + public static final MediaType JIS_B3 = new MediaType(27); + public static final MediaType JIS_B4 = new MediaType(28); + public static final MediaType JIS_B5 = new MediaType(29); + public static final MediaType JIS_B6 = new MediaType(30); + public static final MediaType JIS_B7 = new MediaType(31); + public static final MediaType JIS_B8 = new MediaType(32); + public static final MediaType JIS_B9 = new MediaType(33); + public static final MediaType JIS_B10 = new MediaType(34); + public static final MediaType ISO_C0 = new MediaType(35); + public static final MediaType ISO_C1 = new MediaType(36); + public static final MediaType ISO_C2 = new MediaType(37); + public static final MediaType ISO_C3 = new MediaType(38); + public static final MediaType ISO_C4 = new MediaType(39); + public static final MediaType ISO_C5 = new MediaType(40); + public static final MediaType ISO_C6 = new MediaType(41); + public static final MediaType ISO_C7 = new MediaType(42); + public static final MediaType ISO_C8 = new MediaType(43); + public static final MediaType ISO_C9 = new MediaType(44); + public static final MediaType ISO_C10 = new MediaType(45); + public static final MediaType ISO_DESIGNATED_LONG = new MediaType(46); + public static final MediaType EXECUTIVE = new MediaType(47); + public static final MediaType FOLIO = new MediaType(48); + public static final MediaType INVOICE = new MediaType(49); + public static final MediaType LEDGER = new MediaType(50); + public static final MediaType NA_LETTER = new MediaType(51); + public static final MediaType NA_LEGAL = new MediaType(52); + public static final MediaType QUARTO = new MediaType(53); + public static final MediaType A = new MediaType(54); + public static final MediaType B = new MediaType(55); + public static final MediaType C = new MediaType(56); + public static final MediaType D = new MediaType(57); + public static final MediaType E = new MediaType(58); + public static final MediaType NA_10X15_ENVELOPE = new MediaType(59); + public static final MediaType NA_10X14_ENVELOPE = new MediaType(60); + public static final MediaType NA_10X13_ENVELOPE = new MediaType(61); + public static final MediaType NA_9X12_ENVELOPE = new MediaType(62); + public static final MediaType NA_9X11_ENVELOPE = new MediaType(63); + public static final MediaType NA_7X9_ENVELOPE = new MediaType(64); + public static final MediaType NA_6X9_ENVELOPE = new MediaType(65); + public static final MediaType NA_NUMBER_9_ENVELOPE = new MediaType(66); + public static final MediaType NA_NUMBER_10_ENVELOPE = new MediaType(67); + public static final MediaType NA_NUMBER_11_ENVELOPE = new MediaType(68); + public static final MediaType NA_NUMBER_12_ENVELOPE = new MediaType(69); + public static final MediaType NA_NUMBER_14_ENVELOPE = new MediaType(70); + public static final MediaType INVITE_ENVELOPE = new MediaType(71); + public static final MediaType ITALY_ENVELOPE = new MediaType(72); + public static final MediaType MONARCH_ENVELOPE = new MediaType(73); + public static final MediaType PERSONAL_ENVELOPE = new MediaType(74); + public static final MediaType A0 = ISO_A0; + public static final MediaType A1 = ISO_A1; + public static final MediaType A2 = ISO_A2; + public static final MediaType A3 = ISO_A3; + public static final MediaType A4 = ISO_A4; + public static final MediaType A5 = ISO_A5; + public static final MediaType A6 = ISO_A6; + public static final MediaType A7 = ISO_A7; + public static final MediaType A8 = ISO_A8; + public static final MediaType A9 = ISO_A9; + public static final MediaType A10 = ISO_A10; + public static final MediaType B0 = ISO_B0; + public static final MediaType B1 = ISO_B1; + public static final MediaType B2 = ISO_B2; + public static final MediaType B3 = ISO_B3; + public static final MediaType B4 = ISO_B4; + public static final MediaType ISO_B4_ENVELOPE = ISO_B4; + public static final MediaType B5 = ISO_B5; + public static final MediaType ISO_B5_ENVELOPE = ISO_B4; + public static final MediaType B6 = ISO_B6; + public static final MediaType B7 = ISO_B7; + public static final MediaType B8 = ISO_B8; + public static final MediaType B9 = ISO_B9; + public static final MediaType B10 = ISO_B10; + public static final MediaType C0 = ISO_B0; + public static final MediaType ISO_C0_ENVELOPE = ISO_C0; + public static final MediaType C1 = ISO_C1; + public static final MediaType ISO_C1_ENVELOPE = ISO_C1; + public static final MediaType C2 = ISO_C2; + public static final MediaType ISO_C2_ENVELOPE = ISO_C2; + public static final MediaType C3 = ISO_C3; + public static final MediaType ISO_C3_ENVELOPE = ISO_C3; + public static final MediaType C4 = ISO_C4; + public static final MediaType ISO_C4_ENVELOPE = ISO_C4; + public static final MediaType C5 = ISO_C5; + public static final MediaType ISO_C5_ENVELOPE = ISO_C5; + public static final MediaType C6 = ISO_C6; + public static final MediaType ISO_C6_ENVELOPE = ISO_C6; + public static final MediaType C7 = ISO_C7; + public static final MediaType ISO_C7_ENVELOPE = ISO_C7; + public static final MediaType C8 = ISO_C8; + public static final MediaType ISO_C8_ENVELOPE = ISO_C8; + public static final MediaType C9 = ISO_C9; + public static final MediaType ISO_C9_ENVELOPE = ISO_C9; + public static final MediaType C10 = ISO_C10; + public static final MediaType ISO_C10_ENVELOPE = ISO_C10; + public static final MediaType ISO_DESIGNATED_LONG_ENVELOPE + = ISO_DESIGNATED_LONG; + public static final MediaType STATEMENT = INVOICE; + public static final MediaType TABLOID = LEDGER; + public static final MediaType LETTER = NA_LETTER; + public static final MediaType NOTE = NA_LETTER; + public static final MediaType LEGAL = NA_LEGAL; + public static final MediaType ENV_10X15 = NA_10X15_ENVELOPE; + public static final MediaType ENV_10X14 = NA_10X14_ENVELOPE; + public static final MediaType ENV_10X13 = NA_10X13_ENVELOPE; + public static final MediaType ENV_9X12 = NA_9X12_ENVELOPE; + public static final MediaType ENV_9X11 = NA_9X11_ENVELOPE; + public static final MediaType ENV_7X9 = NA_7X9_ENVELOPE; + public static final MediaType ENV_6X9 = NA_6X9_ENVELOPE; + public static final MediaType ENV_9 = NA_NUMBER_9_ENVELOPE; + public static final MediaType ENV_10 = NA_NUMBER_10_ENVELOPE; + public static final MediaType ENV_11 = NA_NUMBER_11_ENVELOPE; + public static final MediaType ENV_12 = NA_NUMBER_12_ENVELOPE; + public static final MediaType ENV_14 = NA_NUMBER_14_ENVELOPE; + public static final MediaType ENV_INVITE = INVITE_ENVELOPE; + public static final MediaType ENV_ITALY = ITALY_ENVELOPE; + public static final MediaType ENV_MONARCH = MONARCH_ENVELOPE; + public static final MediaType ENV_PERSONAL = PERSONAL_ENVELOPE; + public static final MediaType INVITE = INVITE_ENVELOPE; + public static final MediaType ITALY = ITALY_ENVELOPE; + public static final MediaType MONARCH = MONARCH_ENVELOPE; + public static final MediaType PERSONAL = PERSONAL_ENVELOPE; + private MediaType(int value) + { + super(value, NAMES); + } + } // class MediaType + public static final class OrientationRequestedType extends AttributeValue + { + private static final String[] NAMES = { "portrait", "landscape" }; + public static final OrientationRequestedType PORTRAIT + = new OrientationRequestedType(0); + public static final OrientationRequestedType LANDSCAPE + = new OrientationRequestedType(1); + private OrientationRequestedType(int value) + { + super(value, NAMES); + } + } // class OrientationRequestedType + public static final class OriginType extends AttributeValue + { + private static final String[] NAMES = { "physical", "printable" }; + public static final OriginType PHYSICAL = new OriginType(0); + public static final OriginType PRINTABLE = new OriginType(1); + private OriginType(int value) + { + super(value, NAMES); + } + } // class OriginType + public static final class PrintQualityType extends AttributeValue + { + private static final String[] NAMES = { "high", "normal", "draft" }; + public static final PrintQualityType HIGH = new PrintQualityType(0); + public static final PrintQualityType NORMAL = new PrintQualityType(1); + public static final PrintQualityType DRAFT = new PrintQualityType(2); + private PrintQualityType(int value) + { + super(value, NAMES); + } + } // class PrintQualityType + + + private ColorType color; + private MediaType media; + private OrientationRequestedType orientation; + private OriginType origin; + private PrintQualityType quality; + private int resolutionX; + private int resolutionY; + private int resolutionScale; + public PageAttributes() + { + color = ColorType.MONOCHROME; + setMediaToDefault(); + orientation = OrientationRequestedType.PORTRAIT; + origin = OriginType.PHYSICAL; + quality = PrintQualityType.NORMAL; + setPrinterResolutionToDefault(); + } + + public PageAttributes(PageAttributes attr) + { + set(attr); + } + + public PageAttributes(ColorType color, MediaType media, + OrientationRequestedType orientation, + OriginType origin, PrintQualityType quality, + int[] resolution) + { + if (color == null || media == null || orientation == null + || origin == null || quality == null) + throw new IllegalArgumentException(); + setPrinterResolution(resolution); + this.color = color; + this.media = media; + this.orientation = orientation; + this.origin = origin; + this.quality = quality; + } + + public Object clone() + { + return new PageAttributes(this); + } + + public void set(PageAttributes attr) + { + color = attr.color; + media = attr.media; + orientation = attr.orientation; + origin = attr.origin; + quality = attr.quality; + resolutionX = attr.resolutionX; + resolutionY = attr.resolutionY; + resolutionScale = attr.resolutionScale; + } + + public ColorType getColor() + { + return color; + } + + public void setColor(ColorType color) + { + if (color == null) + throw new IllegalArgumentException(); + this.color = color; + } + + public MediaType getMedia() + { + return media; + } + + public void setMedia(MediaType media) + { + if (media == null) + throw new IllegalArgumentException(); + this.media = media; + } + + public void setMediaToDefault() + { + String country = Locale.getDefault().getCountry(); + media = ("US".equals(country) || "CA".equals(country)) ? MediaType.LETTER + : MediaType.A4; + } + + public OrientationRequestedType getOrientationRequested() + { + return orientation; + } + + public void setOrientationRequested(OrientationRequestedType orientation) + { + if (orientation == null) + throw new IllegalArgumentException(); + this.orientation = orientation; + } + + public void setOrientationRequested(int orientation) + { + if (orientation == 3) + this.orientation = OrientationRequestedType.PORTRAIT; + else if (orientation == 4) + this.orientation = OrientationRequestedType.LANDSCAPE; + else + throw new IllegalArgumentException(); + } + + public void setOrientationRequestedToDefault() + { + orientation = OrientationRequestedType.PORTRAIT; + } + + public OriginType getOrigin() + { + return origin; + } + + public void setOrigin(OriginType origin) + { + if (origin == null) + throw new IllegalArgumentException(); + this.origin = origin; + } + + public PrintQualityType getPrintQuality() + { + return quality; + } + + public void setPrintQuality(PrintQualityType quality) + { + if (quality == null) + throw new IllegalArgumentException(); + this.quality = quality; + } + + public void setPrintQuality(int quality) + { + if (quality == 3) + this.quality = PrintQualityType.DRAFT; + else if (quality == 4) + this.quality = PrintQualityType.NORMAL; + else if (quality == 5) + this.quality = PrintQualityType.HIGH; + else + throw new IllegalArgumentException(); + } + + public void setPrintQualityToDefault() + { + quality = PrintQualityType.NORMAL; + } + + public int[] getPrinterResolution() + { + return new int[] { resolutionX, resolutionY, resolutionScale }; + } + + public void setPrinterResolution(int[] resolution) + { + if (resolution == null || resolution.length != 3 || resolution[0] <= 0 + || resolution[1] <= 0 || resolution[2] < 3 || resolution[2] > 4) + throw new IllegalArgumentException(); + resolutionX = resolution[0]; + resolutionY = resolution[1]; + resolutionScale = resolution[2]; + } + + public void setPrinterResolution(int resolution) + { + if (resolution <= 0) + throw new IllegalArgumentException(); + resolutionX = resolution; + resolutionY = resolution; + resolutionScale = 3; + } + + public void setPrinterResolutionToDefault() + { + resolutionX = 72; + resolutionY = 72; + resolutionScale = 3; + } + + public boolean equals(Object o) + { + if (this == o) + return true; + if (! (o instanceof PageAttributes)) + return false; + PageAttributes pa = (PageAttributes) o; + return color == pa.color && media == pa.media + && orientation == pa.orientation && origin == pa.origin + && quality == pa.quality && resolutionX == pa.resolutionX + && resolutionY == pa.resolutionY + && resolutionScale == pa.resolutionScale; + } + public int hashCode() + { + return (color.value << 31) ^ (media.value << 24) + ^ (orientation.value << 23) ^ (origin.value << 22) + ^ (quality.value << 20) ^ (resolutionScale << 19) + ^ (resolutionY << 10) ^ resolutionX; + } + public String toString() + { + return "color=" + color + ",media=" + media + ",orientation-requested=" + + orientation + ",origin=" + origin + ",print-quality=" + quality + + ",printer-resolution=[" + resolutionX + ',' + resolutionY + ',' + + resolutionScale + ']'; + } +} // class PageAttributes diff --git a/java/awt/PaintContext.java b/java/awt/PaintContext.java index e080dc0dd..fa26061f0 100644 --- a/java/awt/PaintContext.java +++ b/java/awt/PaintContext.java @@ -52,7 +52,7 @@ public interface PaintContext /** * Release the resources allocated for the paint. */ - public void dispose(); + void dispose(); /** * Return the color model of this context. It may be different from the diff --git a/java/awt/PrintJob.java b/java/awt/PrintJob.java index 4e6ae29ff..9cf95f214 100644 --- a/java/awt/PrintJob.java +++ b/java/awt/PrintJob.java @@ -1,5 +1,5 @@ /* PrintJob.java -- A print job class - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,90 +39,64 @@ exception statement from your version. */ package java.awt; /** - * This abstract class represents a print job. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public abstract class PrintJob -{ - -/* - * Constructors + * This abstract class represents a print job. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see Toolkit#getPrintJob(Frame, String, Properties) + * @since 1.0 + * @status updated to 1.4 */ - -/** - * This method initializes a new instance of <code>PrintJob</code>. - */ -public -PrintJob() -{ -} - -/*************************************************************************/ - -/* - * Instance Methods - */ - -/** - * Returns a graphics context suitable for rendering the next page. - * - * @return A graphics context for printing the next page. - */ -public abstract Graphics -getGraphics(); - -/*************************************************************************/ - -/** - * Returns the dimension of the page in pixels. The resolution will be - * chosen to be similar to the on screen image. - * - * @return The page dimensions. - */ -public abstract Dimension -getPageDimension(); - -/*************************************************************************/ - -/** - * Returns the resolution of the page in pixels per inch. - * - * @return The resolution of the page in pixels per inch. - */ -public abstract int -getPageResolution(); - -/*************************************************************************/ - -/** - * Tests whether or not the last page will be printed first. - * - * @return <code>true</code> if the last page prints first, <code>false</code> - * otherwise. - */ -public abstract boolean -lastPageFirst(); - -/*************************************************************************/ - -/** - * Informs the print job that printing is complete. - */ -public abstract void -end(); - -/*************************************************************************/ - -/** - * This method explicitly ends the print job in the event the job - * becomes un-referenced without the application having done so. - */ -public void -finalize() +public abstract class PrintJob { - end(); -} - + /** + * Create a new PrintJob. + */ + public PrintJob() + { + } + + /** + * Returns a graphics context suitable for rendering the next page. The + * return must also implement {@link PrintGraphics}. + * + * @return a graphics context for printing the next page + */ + public abstract Graphics getGraphics(); + + /** + * Returns the dimension of the page in pixels. The resolution will be + * chosen to be similar to the on screen image. + * + * @return the page dimensions + */ + public abstract Dimension getPageDimension(); + + /** + * Returns the resolution of the page in pixels per inch. Note that this is + * not necessarily the printer's resolution. + * + * @return the resolution of the page in pixels per inch + */ + public abstract int getPageResolution(); + + /** + * Tests whether or not the last page will be printed first. + * + * @return true if the last page prints first + */ + public abstract boolean lastPageFirst(); + + /** + * Informs the print job that printing is complete or should be aborted. + */ + public abstract void end(); + + /** + * This method explicitly ends the print job in the event the job + * becomes un-referenced without the application having done so. + */ + public void finalize() + { + end(); + } } // class PrintJob - diff --git a/java/awt/RenderingHints.java b/java/awt/RenderingHints.java index 9bdbd547a..9dc6d5f64 100644 --- a/java/awt/RenderingHints.java +++ b/java/awt/RenderingHints.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2001, 2002 Free Software Foundation +/* RenderingHints.java -- + Copyright (C) 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,50 +35,59 @@ this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ + package java.awt; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + /** + * NEEDS DOCUMENTATION + * * @author Rolf W. Rasmussen <rolfwr@ii.uib.no> + * @author Eric Blake <ebb9@email.byu.edu> */ -public class RenderingHints implements - //java.util.Map, - Cloneable +public class RenderingHints implements Map, Cloneable { - public abstract static class Key { - private int intKey; + private final int key; protected Key(int privateKey) { - intKey = privateKey; + key = privateKey; } public abstract boolean isCompatibleValue(Object value); - - protected final int intKey() + + protected final int intKey() { - return intKey; - } + return key; + } - public final int hashCode() + public final int hashCode() { return System.identityHashCode(this); } - - public final boolean equals(Object other) + + public final boolean equals(Object other) { - return (this == other); + return this == other; } - } + } // class Key - private static class KeyImpl extends Key + private static final class KeyImpl extends Key { - String description; - Object v1, v2, v3; + final String description; + final Object v1; + final Object v2; + final Object v3; KeyImpl(int privateKey, String description, - Object v1, Object v2, Object v3) + Object v1, Object v2, Object v3) { super(privateKey); this.description = description; @@ -85,243 +95,268 @@ public class RenderingHints implements this.v2 = v2; this.v3 = v3; } - - public boolean isCompatibleValue(Object value) + + public boolean isCompatibleValue(Object value) { - return (value == v1) || (value == v2) || (value == v3); + return value == v1 || value == v2 || value == v3; } - public String toString() + public String toString() { return description; } - } + } // class KeyImpl - - //java.util.HashMap hintMap; + private HashMap hintMap = new HashMap(); public static final Key KEY_ANTIALIASING; - public static final Object - VALUE_ANTIALIAS_ON = "Antialiased rendering mode", - VALUE_ANTIALIAS_DEFAULT = "Default antialiasing rendering mode"; - static - { - KEY_ANTIALIASING = new KeyImpl(1, "Global antialiasing enable key", - VALUE_ANTIALIAS_ON, - VALUE_ANTIALIAS_DEFAULT, - VALUE_ANTIALIAS_DEFAULT); - } + public static final Object VALUE_ANTIALIAS_ON + = "Antialiased rendering mode"; + + public static final Object VALUE_ANTIALIAS_OFF + = "Nonantialiased rendering mode"; + + public static final Object VALUE_ANTIALIAS_DEFAULT + = "Default antialiasing rendering mode"; public static final Key KEY_RENDERING; - public static final Object - VALUE_RENDER_SPEED = "Fastest rendering methods", - VALUE_RENDER_QUALITY = "Highest quality rendering methods", - VALUE_RENDER_DEFAULT = "Default rendering methods"; - static - { - KEY_RENDERING = new KeyImpl(2, "Global rendering quality key", - VALUE_RENDER_SPEED, - VALUE_RENDER_QUALITY, - VALUE_RENDER_DEFAULT); - } - + public static final Object VALUE_RENDER_SPEED + = "Fastest rendering methods"; + + public static final Object VALUE_RENDER_QUALITY + = "Highest quality rendering methods"; + + public static final Object VALUE_RENDER_DEFAULT + = "Default rendering methods"; + public static final Key KEY_DITHERING; - public static final Object - VALUE_DITHER_DISABLE = "Nondithered rendering mode", - VALUE_DITHER_ENABLE = "Dithered rendering mode", - VALUE_DITHER_DEFAULT = "Default dithering mode"; - static - { - KEY_DITHERING = new KeyImpl(3, "Dithering quality key", - VALUE_DITHER_DISABLE, - VALUE_DITHER_ENABLE, - VALUE_DITHER_DEFAULT); - } - + public static final Object VALUE_DITHER_DISABLE + = "Nondithered rendering mode"; + + public static final Object VALUE_DITHER_ENABLE + = "Dithered rendering mode"; + + public static final Object VALUE_DITHER_DEFAULT + = "Default dithering mode"; + public static final Key KEY_TEXT_ANTIALIASING; - public static final Object - VALUE_TEXT_ANTIALIAS_ON = "Antialiased text mode", - VALUE_TEXT_ANTIALIAS_OFF = "Nonantialiased text mode", - VALUE_TEXT_ANTIALIAS_DEFAULT = "Default antialiasing text mode"; - static - { - KEY_TEXT_ANTIALIASING = new KeyImpl(4, "Text-specific antialiasing enable key", - VALUE_TEXT_ANTIALIAS_ON, - VALUE_TEXT_ANTIALIAS_OFF, - VALUE_TEXT_ANTIALIAS_DEFAULT); - } - + public static final Object VALUE_TEXT_ANTIALIAS_ON + = "Antialiased text mode"; + + public static final Object VALUE_TEXT_ANTIALIAS_OFF + = "Nonantialiased text mode"; + + public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT + = "Default antialiasing text mode"; + public static final Key KEY_FRACTIONALMETRICS; - public static final Object - VALUE_FRACTIONALMETRICS_OFF = "Integer text metrics mode", - VALUE_FRACTIONALMETRICS_ON = "Fractional text metrics mode", - VALUE_FRACTIONALMETRICS_DEFAULT = "Default fractional text metrics mode"; - static - { - KEY_FRACTIONALMETRICS = new KeyImpl(5, "Fractional metrics enable key", - VALUE_FRACTIONALMETRICS_OFF, - VALUE_FRACTIONALMETRICS_ON, - VALUE_FRACTIONALMETRICS_DEFAULT); - } - + public static final Object VALUE_FRACTIONALMETRICS_OFF + = "Integer text metrics mode"; + + public static final Object VALUE_FRACTIONALMETRICS_ON + = "Fractional text metrics mode"; + + public static final Object VALUE_FRACTIONALMETRICS_DEFAULT + = "Default fractional text metrics mode"; + public static final Key KEY_INTERPOLATION; - public static final Object - VALUE_INTERPOLATION_NEAREST_NEIGHBOR = "Nearest Neighbor image interpolation mode", - VALUE_INTERPOLATION_BILINEAR = "Bilinear image interpolation mode", - VALUE_INTERPOLATION_BICUBIC = "Bicubic image interpolation mode"; - static - { - KEY_INTERPOLATION = new KeyImpl(6, "Image interpolation method key", - VALUE_INTERPOLATION_NEAREST_NEIGHBOR, - VALUE_INTERPOLATION_BILINEAR, - VALUE_INTERPOLATION_BICUBIC); - } - + public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR + = "Nearest Neighbor image interpolation mode"; + + public static final Object VALUE_INTERPOLATION_BILINEAR + = "Bilinear image interpolation mode"; + + public static final Object VALUE_INTERPOLATION_BICUBIC + = "Bicubic image interpolation mode"; + public static final Key KEY_ALPHA_INTERPOLATION; - public static final Object - VALUE_ALPHA_INTERPOLATION_SPEED = "Fastest alpha blending methods", - VALUE_ALPHA_INTERPOLATION_QUALITY = "Highest quality alpha blending methods", - VALUE_ALPHA_INTERPOLATION_DEFAULT = "Default alpha blending methods"; - static - { - KEY_ALPHA_INTERPOLATION = new KeyImpl(7, "Alpha blending interpolation method key", - VALUE_ALPHA_INTERPOLATION_SPEED, - VALUE_ALPHA_INTERPOLATION_QUALITY, - VALUE_ALPHA_INTERPOLATION_DEFAULT); - } - + public static final Object VALUE_ALPHA_INTERPOLATION_SPEED + = "Fastest alpha blending methods"; + + public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY + = "Highest quality alpha blending methods"; + + public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT + = "Default alpha blending methods"; + public static final Key KEY_COLOR_RENDERING; - public static final Object - VALUE_COLOR_RENDER_SPEED = "Fastest color rendering mode", - VALUE_COLOR_RENDER_QUALITY = "Highest quality color rendering mode", - VALUE_COLOR_RENDER_DEFAULT = "Default color rendering mode"; - static - { - KEY_COLOR_RENDERING = new KeyImpl(8, "Color rendering quality key", - VALUE_COLOR_RENDER_SPEED, - VALUE_COLOR_RENDER_QUALITY, - VALUE_COLOR_RENDER_DEFAULT); - } + public static final Object VALUE_COLOR_RENDER_SPEED + = "Fastest color rendering mode"; + + public static final Object VALUE_COLOR_RENDER_QUALITY + = "Highest quality color rendering mode"; + + public static final Object VALUE_COLOR_RENDER_DEFAULT + = "Default color rendering mode"; public static final Key KEY_STROKE_CONTROL; - public static final Object - VALUE_STROKE_DEFAULT = "Default stroke control mode", - VALUE_STROKE_NORMALIZE = "Normalize stroke control mode", - VALUE_STROKE_PURE = "Pure stroke control mode"; - static + public static final Object VALUE_STROKE_DEFAULT + = "Default stroke normalization"; + + public static final Object VALUE_STROKE_NORMALIZE + = "Normalize strokes for consistent rendering"; + + public static final Object VALUE_STROKE_PURE + = "Pure stroke conversion for accurate paths"; + + static { + KEY_ANTIALIASING = new KeyImpl(1, "Global antialiasing enable key", + VALUE_ANTIALIAS_ON, + VALUE_ANTIALIAS_OFF, + VALUE_ANTIALIAS_DEFAULT); + KEY_RENDERING = new KeyImpl(2, "Global rendering quality key", + VALUE_RENDER_SPEED, + VALUE_RENDER_QUALITY, + VALUE_RENDER_DEFAULT); + KEY_DITHERING = new KeyImpl(3, "Dithering quality key", + VALUE_DITHER_DISABLE, + VALUE_DITHER_ENABLE, + VALUE_DITHER_DEFAULT); + KEY_TEXT_ANTIALIASING + = new KeyImpl(4, "Text-specific antialiasing enable key", + VALUE_TEXT_ANTIALIAS_ON, + VALUE_TEXT_ANTIALIAS_OFF, + VALUE_TEXT_ANTIALIAS_DEFAULT); + KEY_FRACTIONALMETRICS = new KeyImpl(5, "Fractional metrics enable key", + VALUE_FRACTIONALMETRICS_OFF, + VALUE_FRACTIONALMETRICS_ON, + VALUE_FRACTIONALMETRICS_DEFAULT); + KEY_INTERPOLATION = new KeyImpl(6, "Image interpolation method key", + VALUE_INTERPOLATION_NEAREST_NEIGHBOR, + VALUE_INTERPOLATION_BILINEAR, + VALUE_INTERPOLATION_BICUBIC); + KEY_ALPHA_INTERPOLATION + = new KeyImpl(7, "Alpha blending interpolation method key", + VALUE_ALPHA_INTERPOLATION_SPEED, + VALUE_ALPHA_INTERPOLATION_QUALITY, + VALUE_ALPHA_INTERPOLATION_DEFAULT); + KEY_COLOR_RENDERING = new KeyImpl(8, "Color rendering quality key", + VALUE_COLOR_RENDER_SPEED, + VALUE_COLOR_RENDER_QUALITY, + VALUE_COLOR_RENDER_DEFAULT); KEY_STROKE_CONTROL = new KeyImpl(9, "Stroke normalization control key", - VALUE_STROKE_DEFAULT, - VALUE_STROKE_NORMALIZE, - VALUE_STROKE_PURE); + VALUE_STROKE_DEFAULT, + VALUE_STROKE_NORMALIZE, + VALUE_STROKE_PURE); + } + + public RenderingHints(Map init) + { + putAll(init); } - - //public RenderingHints(Map init); public RenderingHints(Key key, Object value) { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + put(key, value); } - public int size() + public int size() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.size(); } - - public boolean isEmpty() + + public boolean isEmpty() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.isEmpty(); } - public boolean containsKey(Object key) - { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + public boolean containsKey(Object key) + { + if (key == null) + throw new NullPointerException(); + return hintMap.containsKey((Key) key); } - - public boolean containsValue(Object value) + + public boolean containsValue(Object value) { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.containsValue(value); } - + public Object get(Object key) { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.get((Key) key); } - - public Object put(Object key, Object value) + + public Object put(Object key, Object value) { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + if (key == null || value == null) + throw new NullPointerException(); + if (! ((Key) key).isCompatibleValue(value)) + throw new IllegalArgumentException(); + return hintMap.put(key, value); } - - public void add(RenderingHints hints) + + public void add(RenderingHints hints) { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + hintMap.putAll(hints); } - public void clear() + public void clear() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + hintMap.clear(); } - - public Object remove(Object key) + + public Object remove(Object key) { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return remove((Key) key); } - - /* - public void putAll(Map m) + + public void putAll(Map m) { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + hintMap.putAll(m); } - */ - - /* - public Set keySet() + + public Set keySet() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.keySet(); } - */ - - /* - public Collection values() + + public Collection values() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.values(); } - */ - - /* - public Set entrySet() + + public Set entrySet() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return Collections.unmodifiableSet(hintMap.entrySet()); } - */ - - public boolean equals(Object o) + + public boolean equals(Object o) { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.equals(o); } - - public int hashCode() + + public int hashCode() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.hashCode(); } - - public Object clone() + + public Object clone() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + try + { + RenderingHints copy = (RenderingHints) super.clone(); + copy.hintMap = (HashMap) hintMap.clone(); + return copy; + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } } - - public String toString() + + public String toString() { - throw new UnsupportedOperationException("FIXME, not implemented yet"); + return hintMap.toString(); } -} +} // class RenderingHints diff --git a/java/awt/Robot.java b/java/awt/Robot.java new file mode 100644 index 000000000..1de5f3f37 --- /dev/null +++ b/java/awt/Robot.java @@ -0,0 +1,112 @@ +/* Robot.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.awt.image.BufferedImage; + +/** STUB CLASS ONLY */ +public class Robot +{ + private boolean waitForIdle; + private int autoDelay; + public Robot() throws AWTException + { + throw new Error("not implemented"); + } + public Robot(GraphicsDevice screen) throws AWTException + { + this(); + } + public void mouseMove(int x, int y) + { + } + public void mousePress(int buttons) + { + } + public void mouseRelease(int buttons) + { + } + public void mouseWheel(int wheelAmt) + { + } + public void keyPress(int keycode) + { + } + public void keyRelease(int keycode) + { + } + public Color getPixelColor(int x, int y) + { + return null; + } + public BufferedImage createScreenCapture(Rectangle screen) + { + return null; + } + public boolean isAutoWaitForIdle() + { + return waitForIdle; + } + public void setAutoWaitForIdle(boolean value) + { + waitForIdle = value; + } + public int getAutoDelay() + { + return autoDelay; + } + public void setAutoDelay(int ms) + { + if (ms < 0 || ms > 60000) + throw new IllegalArgumentException(); + autoDelay = ms; + } + public void delay(int ms) + { + if (ms < 0 || ms > 60000) + throw new IllegalArgumentException(); + } + public void waitForIdle() + { + } + public String toString() + { + return "unimplemented"; + } +} // class Robot diff --git a/java/awt/TexturePaint.java b/java/awt/TexturePaint.java new file mode 100644 index 000000000..5ff0b57ec --- /dev/null +++ b/java/awt/TexturePaint.java @@ -0,0 +1,75 @@ +/* TexturePaint.java -- + Copyright (C) 2002 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.awt; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; + +/** STUB CLASS ONLY */ +public class TexturePaint implements Paint +{ + private final BufferedImage texture; + private final Rectangle2D anchor; + public TexturePaint(BufferedImage texture, Rectangle2D anchor) + { + this.texture = texture; + this.anchor = anchor; + } + public BufferedImage getImage() + { + return texture; + } + public Rectangle2D getAnchorRect() + { + return anchor; + } + public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, + Rectangle2D userBounds, + AffineTransform xform, + RenderingHints hints) + { + throw new Error("not implemented"); + } + public int getTransparency() + { + throw new Error("not implemented"); + } +} // class TexturePaint diff --git a/java/awt/Window.java b/java/awt/Window.java index 6af7c3450..44884d754 100644 --- a/java/awt/Window.java +++ b/java/awt/Window.java @@ -328,12 +328,19 @@ public class Window extends Container windowListener = AWTEventMulticaster.remove (windowListener, listener); } + public synchronized WindowListener[] getWindowListeners() + { + return (WindowListener[]) + AWTEventMulticaster.getListeners(windowListener, + WindowListener.class); + } + /** @since 1.3 */ public EventListener[] getListeners(Class listenerType) { if (listenerType == WindowListener.class) - return getListenersImpl(listenerType, windowListener); - else return super.getListeners(listenerType); + return getWindowListeners(); + return super.getListeners(listenerType); } void dispatchEventImpl(AWTEvent e) diff --git a/java/awt/geom/Arc2D.java b/java/awt/geom/Arc2D.java index 71e4e47fd..d62fa676f 100644 --- a/java/awt/geom/Arc2D.java +++ b/java/awt/geom/Arc2D.java @@ -41,17 +41,47 @@ package java.awt.geom; import java.util.NoSuchElementException; /** - * STUBS ONLY - * XXX Implement and document. + * This class represents all arcs (segments of an ellipse in 2-D space). The + * arcs are defined by starting angle and extent (arc length) in degrees, as + * opposed to radians (like the rest of Java), and can be open, chorded, or + * wedge shaped. The angles are skewed according to the ellipse, so that 45 + * degrees always points to the upper right corner (positive x, negative y) + * of the bounding rectangle. A positive extent draws a counterclockwise arc, + * and while the angle can be any value, the path iterator only traverses the + * first 360 degrees. Storage is up to the subclasses. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4, but still missing functionality */ public abstract class Arc2D extends RectangularShape { + /** + * An open arc, with no segment connecting the endpoints. This type of + * arc still contains the same points as a chorded version. + */ public static final int OPEN = 0; + + /** + * A closed arc with a single segment connecting the endpoints (a chord). + */ public static final int CHORD = 1; + + /** + * A closed arc with two segments, one from each endpoint, meeting at the + * center of the ellipse. + */ public static final int PIE = 2; + /** The closure type of this arc. */ private int type; + /** + * Create a new arc, with the specified closure type. + * + * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}. + * @throws IllegalArgumentException if type is invalid + */ protected Arc2D(int type) { if (type < OPEN || type > PIE) @@ -59,144 +89,443 @@ public abstract class Arc2D extends RectangularShape this.type = type; } - /** Start in degrees. */ + /** + * Get the starting angle of the arc in degrees. + * + * @return the starting angle + * @see #setAngleStart(double) + */ public abstract double getAngleStart(); - /** Extent in degrees. */ + + /** + * Get the extent angle of the arc in degrees. + * + * @return the extent angle + * @see #setAngleExtent(double) + */ public abstract double getAngleExtent(); + /** + * Return the closure type of the arc. + * + * @return the closure type + * @see #OPEN + * @see #CHORD + * @see #PIE + * @see #setArcType(int) + */ public int getArcType() { return type; } + + /** + * Returns the starting point of the arc. + * + * @return the start point + */ public Point2D getStartPoint() { - // XXX Implement. - throw new Error("not implemented"); + double angle = getAngleStart() * (-180 / Math.PI); + double x = (Math.cos(angle) * getWidth() + getX()) / 2; + double y = (Math.sin(angle) * getHeight() + getY()) / 2; + return new Point2D.Double(x, y); } + + /** + * Returns the ending point of the arc. + * + * @return the end point + */ public Point2D getEndPoint() { - // XXX Implement. - throw new Error("not implemented"); + double angle = (getAngleStart() + getAngleExtent()) * (-180 / Math.PI); + double x = (Math.cos(angle) * getWidth() + getX()) / 2; + double y = (Math.sin(angle) * getHeight() + getY()) / 2; + return new Point2D.Double(x, y); } - /** Start, extent in degrees. */ + + /** + * Set the parameters of the arc. The angles are in degrees, and a positive + * extent sweeps counterclockwise (from the positive x-axis to the negative + * y-axis). + * + * @param x the new x coordinate of the lower left of the bounding box + * @param y the new y coordinate of the lower left of the bounding box + * @param w the new width of the bounding box + * @param h the new height of the bounding box + * @param start the start angle, in degrees + * @param extent the arc extent, in degrees + * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + */ public abstract void setArc(double x, double y, double w, double h, double start, double extent, int type); + /** + * Set the parameters of the arc. The angles are in degrees, and a positive + * extent sweeps counterclockwise (from the positive x-axis to the negative + * y-axis). + * + * @param p the lower left point of the bounding box + * @param d the dimensions of the bounding box + * @param start the start angle, in degrees + * @param extent the arc extent, in degrees + * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + * @throws NullPointerException if p or d is null + */ public void setArc(Point2D p, Dimension2D d, double start, double extent, int type) { setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(), start, extent, type); } + + /** + * Set the parameters of the arc. The angles are in degrees, and a positive + * extent sweeps counterclockwise (from the positive x-axis to the negative + * y-axis). + * + * @param r the new bounding box + * @param start the start angle, in degrees + * @param extent the arc extent, in degrees + * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + * @throws NullPointerException if r is null + */ public void setArc(Rectangle2D r, double start, double extent, int type) { setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(), start, extent, type); } + + /** + * Set the parameters of the arc from the given one. + * + * @param a the arc to copy + * @throws NullPointerException if a is null + */ public void setArc(Arc2D a) { setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(), a.getAngleStart(), a.getAngleExtent(), a.getArcType()); } + + /** + * Set the parameters of the arc. The angles are in degrees, and a positive + * extent sweeps counterclockwise (from the positive x-axis to the negative + * y-axis). This controls the center point and radius, so the arc will be + * circular. + * + * @param x the x coordinate of the center of the circle + * @param y the y coordinate of the center of the circle + * @param r the radius of the circle + * @param start the start angle, in degrees + * @param extent the arc extent, in degrees + * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + */ public void setArcByCenter(double x, double y, double r, double start, double extent, int type) { setArc(x - r, y - r, r + r, r + r, start, extent, type); } + + /** + * Sets the parameters of the arc by finding the tangents of two lines, and + * using the specified radius. The arc will be circular, will begin on the + * tangent point of the line extending from p1 to p2, and will end on the + * tangent point of the line extending from p2 to p3. + * + * XXX What happens if the points are colinear, or the radius negative? + * + * @param p1 the first point + * @param p2 the tangent line intersection point + * @param p3 the third point + * @param r the radius of the arc + * @throws NullPointerException if any point is null + */ public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double r) { // XXX Implement. throw new Error("not implemented"); } - /** Start in degrees. */ + /** + * Set the start, in degrees. + * + * @param start the new start angle + * @see #getAngleStart() + */ public abstract void setAngleStart(double start); - /** Extent in degrees. */ + + /** + * Set the extent, in degrees. + * + * @param extent the new extent angle + * @see #getAngleExtent() + */ public abstract void setAngleExtent(double extent); + + /** + * Sets the starting angle to the angle of the given point relative to + * the center of the arc. The extent remains constant; in other words, + * this rotates the arc. + * + * @param p the new start point + * @throws NullPointerException if p is null + * @see #getStartPoint() + * @see #getAngleStart() + */ public void setAngleStart(Point2D p) { - setAngleStart(Math.atan2(p.getY() - getCenterY(), - p.getX() - getCenterX())); + double x = ((p.getX() * 2) - getX()) / getWidth(); + double y = ((p.getY() * 2) - getY()) / getHeight(); + setAngleStart(Math.atan2(y, x) * (-180 / Math.PI)); } + + /** + * Sets the starting and extent angles to those of the given points + * relative to the center of the arc. The arc will be non-empty, and will + * extend counterclockwise. + * + * @param x1 the first x coordinate + * @param y1 the first y coordinate + * @param x2 the second x coordinate + * @param y2 the second y coordinate + * @see #setAngleStart(Point2D) + */ public void setAngles(double x1, double y1, double x2, double y2) { - // XXX Implement. - throw new Error("not implemented"); + // Normalize the points. + double mx = getX(); + double my = getY(); + double mw = getWidth(); + double mh = getHeight(); + x1 = ((x1 * 2) - mx) / mw; + y1 = ((y1 * 2) - my) / mh; + x2 = ((x2 * 2) - mx) / mw; + y2 = ((y2 * 2) - my) / mh; + double start = Math.atan2(y1, x1) * (-180 / Math.PI); + double extent = Math.atan2(y2, x2) * (-180 / Math.PI) - start; + if (extent < 0) + extent += 360; + setAngleStart(start); + setAngleExtent(extent); } + + /** + * Sets the starting and extent angles to those of the given points + * relative to the center of the arc. The arc will be non-empty, and will + * extend counterclockwise. + * + * @param p1 the first point + * @param p2 the second point + * @throws NullPointerException if either point is null + * @see #setAngleStart(Point2D) + */ public void setAngles(Point2D p1, Point2D p2) { setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY()); } + + /** + * Set the closure type of this arc. + * + * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + * @see #getArcType() + */ public void setArcType(int type) { if (type < OPEN || type > PIE) throw new IllegalArgumentException(); this.type = type; } + + /** + * Sets the location and bounds of the ellipse of which this arc is a part. + * + * @param x the new x coordinate + * @param y the new y coordinate + * @param w the new width + * @param h the new height + * @see #getFrame() + */ public void setFrame(double x, double y, double w, double h) { - // XXX Implement. - throw new Error("not implemented"); + setArc(x, y, w, h, getAngleStart(), getAngleExtent(), type); } + + /** + * Gets the bounds of the arc. This is much tighter than + * <code>getBounds</code>, as it takes into consideration the start and + * end angles, and the center point of a pie wedge, rather than just the + * overall ellipse. + * + * @return the bounds of the arc + * @see #getBounds() + */ public Rectangle2D getBounds2D() { - // XXX Implement. + double extent = getAngleExtent(); + if (Math.abs(extent) >= 360) + return makeBounds(getX(), getY(), getWidth(), getHeight()); + // XXX Finish implementing. throw new Error("not implemented"); } + + /** + * Construct a bounding box in a precision appropriate for the subclass. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + * @return the rectangle for use in getBounds2D + */ protected abstract Rectangle2D makeBounds(double x, double y, double w, double h); + + /** + * Tests if the given angle, in degrees, is included in the arc. + * + * XXX Does this normalize all angles to -180 - 180 first? + * + * @param a the angle to test + * @return true if it is contained + */ public boolean containsAngle(double a) { // XXX Implement. throw new Error("not implemented"); } + + /** + * Determines if the arc contains the given point. If the bounding box + * is empty, then this will return false. + * + * @param x the x coordinate to test + * @param y the y coordinate to test + * @return true if the point is inside the arc + */ public boolean contains(double x, double y) { - // XXX Implement. + double w = getWidth(); + double h = getHeight(); + if (w <= 0 || h <= 0) + return false; + // XXX Finish implementing. throw new Error("not implemented"); } + + /** + * Tests if a given rectangle intersects the area of the arc. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @return true if the two shapes share common points + */ public boolean intersects(double x, double y, double w, double h) { - // XXX Implement. + double mw = getWidth(); + double mh = getHeight(); + if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0) + return false; + // XXX Finish implementing. throw new Error("not implemented"); } + + /** + * Tests if a given rectangle is contained in the area of the arc. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle + * @param h the height of the rectangle + * @return true if the arc contains the rectangle + */ public boolean contains(double x, double y, double w, double h) { - // XXX Implement. + double mw = getWidth(); + double mh = getHeight(); + if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0) + return false; + // XXX Finish implementing. throw new Error("not implemented"); } + + /** + * Tests if a given rectangle is contained in the area of the arc. + * + * @param r the rectangle + * @return true if the arc contains the rectangle + */ public boolean contains(Rectangle2D r) { return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } + + /** + * Returns an iterator over this arc, with an optional transformation. + * This iterator is threadsafe, so future modifications to the arc do not + * affect the iteration. + * + * @param at the transformation, or null + * @return a path iterator + */ public PathIterator getPathIterator(AffineTransform at) { return new ArcIterator(this, at); } /** - * STUBS ONLY - * Used by Ellipse2D as well. + * This class is used to iterate over an arc. Since ellipses are a subclass + * of arcs, this is used by Ellipse2D as well. + * + * @author Eric Blake <ebb9@email.byu.edu> */ static final class ArcIterator implements PathIterator { - /** Current coordinate. */ + /** The current iteration. */ private int current; - /** Last iteration. */ + + /** The last iteration. */ private final int limit; + /** The optional transformation. */ private final AffineTransform xform; + /** The x coordinate of the bounding box. */ private final double x; + + /** The y coordinate of the bounding box. */ private final double y; + + /** The width of the bounding box. */ private final double w; + + /** The height of the bounding box. */ private final double h; - /** Start in radians. */ + + /** The start angle, in radians (not degrees). */ private final double start; - /** Extent in radians. */ + + /** The extent angle, in radians (not degrees). */ private final double extent; + + /** The arc closure type. */ private final int type; + /** + * Construct a new iterator over an arc. + * + * @param a the arc + * @param xform the transform + */ ArcIterator(Arc2D a, AffineTransform xform) { this.xform = xform; @@ -222,6 +551,12 @@ public abstract class Arc2D extends RectangularShape limit = type + 4; } + /** + * Construct a new iterator over an ellipse. + * + * @param e the ellipse + * @param xform the transform + */ ArcIterator(Ellipse2D e, AffineTransform xform) { this.xform = xform; @@ -235,30 +570,50 @@ public abstract class Arc2D extends RectangularShape limit = (w < 0 || h < 0) ? -1 : 5; } + /** + * Return the winding rule. + * + * @return {@link PathIterator#WIND_NON_ZERO} + */ public int getWindingRule() { return WIND_NON_ZERO; } + /** + * Test if the iteration is complete. + * + * @return true if more segments exist + */ public boolean isDone() { return current > limit; } + /** + * Advance the iterator. + */ public void next() { current++; } + /** + * Put the current segment into the array, and return the segment type. + * + * @param coords an array of 6 elements + * @return the segment type + * @throws NullPointerException if coords is null + * @throws ArrayIndexOutOfBoundsException if coords is too small + */ public int currentSegment(float[] coords) { if (current > limit) throw new NoSuchElementException("arc iterator out of bounds"); if (current == 0) { - // XXX Fill coords[0-1] with starting point. - coords[0] = (float) 0; - coords[1] = (float) 0; + coords[0] = (float) (Math.cos(start) * w + x) / 2; + coords[1] = (float) (Math.sin(start) * h + y) / 2; if (xform != null) xform.transform(coords, 0, coords, 0, 1); return SEG_MOVETO; @@ -285,15 +640,22 @@ public abstract class Arc2D extends RectangularShape return SEG_CUBICTO; } + /** + * Put the current segment into the array, and return the segment type. + * + * @param coords an array of 6 elements + * @return the segment type + * @throws NullPointerException if coords is null + * @throws ArrayIndexOutOfBoundsException if coords is too small + */ public int currentSegment(double[] coords) { if (current > limit) throw new NoSuchElementException("arc iterator out of bounds"); if (current == 0) { - // XXX Fill coords[0-1] with starting point. - coords[0] = 0; - coords[1] = 0; + coords[0] = (Math.cos(start) * w + x) / 2; + coords[1] = (Math.sin(start) * h + y) / 2; if (xform != null) xform.transform(coords, 0, coords, 0, 1); return SEG_MOVETO; @@ -322,25 +684,62 @@ public abstract class Arc2D extends RectangularShape } // class ArcIterator /** - * STUBS ONLY + * This class implements an arc in double precision. + * + * @author Eric Blake <ebb9@email.byu.edu + * @since 1.2 */ public static class Double extends Arc2D { + /** The x coordinate of the box bounding the ellipse of this arc. */ public double x; + + /** The y coordinate of the box bounding the ellipse of this arc. */ public double y; + + /** The width of the box bounding the ellipse of this arc. */ public double width; + + /** The height of the box bounding the ellipse of this arc. */ public double height; + + /** The start angle of this arc, in degrees. */ public double start; + + /** The extent angle of this arc, in degrees. */ public double extent; + /** + * Create a new, open arc at (0,0) with 0 extent. + */ public Double() { super(OPEN); } + + /** + * Create a new arc of the given type at (0,0) with 0 extent. + * + * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + */ public Double(int type) { super(type); } + + /** + * Create a new arc with the given dimensions. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + * @param start the start angle, in degrees + * @param extent the extent, in degrees + * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + */ public Double(double x, double y, double w, double h, double start, double extent, int type) { @@ -353,6 +752,16 @@ public abstract class Arc2D extends RectangularShape this.extent = extent; } + /** + * Create a new arc with the given dimensions. + * + * @param r the bounding box + * @param start the start angle, in degrees + * @param extent the extent, in degrees + * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + * @throws NullPointerException if r is null + */ public Double(Rectangle2D r, double start, double extent, int type) { super(type); @@ -364,34 +773,88 @@ public abstract class Arc2D extends RectangularShape this.extent = extent; } + /** + * Return the x coordinate of the bounding box. + * + * @return the value of x + */ public double getX() { return x; } + + /** + * Return the y coordinate of the bounding box. + * + * @return the value of y + */ public double getY() { return y; } + + /** + * Return the width of the bounding box. + * + * @return the value of width + */ public double getWidth() { return width; } + + /** + * Return the height of the bounding box. + * + * @return the value of height + */ public double getHeight() { return height; } + + /** + * Return the start angle of the arc, in degrees. + * + * @return the value of start + */ public double getAngleStart() { return start; } + + /** + * Return the extent of the arc, in degrees. + * + * @return the value of extent + */ public double getAngleExtent() { return extent; } + + /** + * Tests if the arc contains points. + * + * @return true if the arc has no interior + */ public boolean isEmpty() { return width <= 0 || height <= 0; } + + /** + * Sets the arc to the given dimensions. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + * @param start the start angle, in degrees + * @param extent the extent, in degrees + * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + */ public void setArc(double x, double y, double w, double h, double start, double extent, int type) { @@ -403,14 +866,36 @@ public abstract class Arc2D extends RectangularShape this.extent = extent; setArcType(type); } + + /** + * Sets the start angle of the arc. + * + * @param start the new start angle + */ public void setAngleStart(double start) { this.start = start; } + + /** + * Sets the extent angle of the arc. + * + * @param start the new extent angle + */ public void setAngleExtent(double extent) { this.extent = extent; } + + /** + * Creates a tight bounding box given dimensions that more precise than + * the bounding box of the ellipse. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + */ protected Rectangle2D makeBounds(double x, double y, double w, double h) { return new Rectangle2D.Double(x, y, w, h); @@ -418,27 +903,64 @@ public abstract class Arc2D extends RectangularShape } // class Double /** - * STUBS ONLY + * This class implements an arc in float precision. + * + * @author Eric Blake <ebb9@email.byu.edu + * @since 1.2 */ public static class Float extends Arc2D { + /** The x coordinate of the box bounding the ellipse of this arc. */ public float x; + + /** The y coordinate of the box bounding the ellipse of this arc. */ public float y; + + /** The width of the box bounding the ellipse of this arc. */ public float width; + + /** The height of the box bounding the ellipse of this arc. */ public float height; + + /** The start angle of this arc, in degrees. */ public float start; + + /** The extent angle of this arc, in degrees. */ public float extent; + /** + * Create a new, open arc at (0,0) with 0 extent. + */ public Float() { super(OPEN); } + + /** + * Create a new arc of the given type at (0,0) with 0 extent. + * + * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + */ public Float(int type) { super(type); } + + /** + * Create a new arc with the given dimensions. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + * @param start the start angle, in degrees + * @param extent the extent, in degrees + * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + */ public Float(float x, float y, float w, float h, - float start, float extent, int type) + float start, float extent, int type) { super(type); this.x = x; @@ -449,6 +971,16 @@ public abstract class Arc2D extends RectangularShape this.extent = extent; } + /** + * Create a new arc with the given dimensions. + * + * @param r the bounding box + * @param start the start angle, in degrees + * @param extent the extent, in degrees + * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + * @throws NullPointerException if r is null + */ public Float(Rectangle2D r, float start, float extent, int type) { super(type); @@ -460,34 +992,88 @@ public abstract class Arc2D extends RectangularShape this.extent = extent; } + /** + * Return the x coordinate of the bounding box. + * + * @return the value of x + */ public double getX() { return x; } + + /** + * Return the y coordinate of the bounding box. + * + * @return the value of y + */ public double getY() { return y; } + + /** + * Return the width of the bounding box. + * + * @return the value of width + */ public double getWidth() { return width; } + + /** + * Return the height of the bounding box. + * + * @return the value of height + */ public double getHeight() { return height; } + + /** + * Return the start angle of the arc, in degrees. + * + * @return the value of start + */ public double getAngleStart() { return start; } + + /** + * Return the extent of the arc, in degrees. + * + * @return the value of extent + */ public double getAngleExtent() { return extent; } + + /** + * Tests if the arc contains points. + * + * @return true if the arc has no interior + */ public boolean isEmpty() { return width <= 0 || height <= 0; } + + /** + * Sets the arc to the given dimensions. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + * @param start the start angle, in degrees + * @param extent the extent, in degrees + * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE} + * @throws IllegalArgumentException if type is invalid + */ public void setArc(double x, double y, double w, double h, double start, double extent, int type) { @@ -499,17 +1085,39 @@ public abstract class Arc2D extends RectangularShape this.extent = (float) extent; setArcType(type); } + + /** + * Sets the start angle of the arc. + * + * @param start the new start angle + */ public void setAngleStart(double start) { this.start = (float) start; } + + /** + * Sets the extent angle of the arc. + * + * @param start the new extent angle + */ public void setAngleExtent(double extent) { this.extent = (float) extent; } + + /** + * Creates a tight bounding box given dimensions that more precise than + * the bounding box of the ellipse. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + */ protected Rectangle2D makeBounds(double x, double y, double w, double h) { - return new Rectangle2D.Float(x, y, w, h); + return new Rectangle2D.Float((float) x, (float) y, (float) w, (float) h); } } // class Float } // class Arc2D diff --git a/java/awt/geom/Rectangle2D.java b/java/awt/geom/Rectangle2D.java index f05d66f1b..e0a278a57 100644 --- a/java/awt/geom/Rectangle2D.java +++ b/java/awt/geom/Rectangle2D.java @@ -250,9 +250,6 @@ public abstract class Rectangle2D extends RectangularShape /** * Tests if this rectangle contains the given one. In other words, test if * this rectangle contains all points in the given one. - /** - * Tests if the given rectangle intersects this one. In other words, test if - * the two rectangles share at least one internal point. * * @param x the x coordinate of the other rectangle * @param y the y coordinate of the other rectangle |