diff options
author | bryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-08-09 04:26:17 +0000 |
---|---|---|
committer | bryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-08-09 04:26:17 +0000 |
commit | 71946bc3b406beb3d1fb9b447204e4236d645c43 (patch) | |
tree | cdf9958b411887bead2263ea8ef0bdfc8eae6319 /libjava/java | |
parent | 0fc014c9ce8232f14be66144bf5a4c08a3e5ffe7 (diff) | |
download | gcc-71946bc3b406beb3d1fb9b447204e4236d645c43.tar.gz |
AWT/Swing merge from GNU Classpath.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56147 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/java')
176 files changed, 33291 insertions, 8821 deletions
diff --git a/libjava/java/awt/AWTError.java b/libjava/java/awt/AWTError.java index 6d3ad61d2f3..1c253cb41a6 100644 --- a/libjava/java/awt/AWTError.java +++ b/libjava/java/awt/AWTError.java @@ -1,5 +1,5 @@ /* AWTError.java -- A serious AWT error occurred. - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,24 +39,26 @@ exception statement from your version. */ package java.awt; /** - * This error is thrown when a critical AWT error occurs. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This error is thrown when a critical Abstract Window Toolkit (AWT) error + * occurs. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @status updated to 1.4 + */ public class AWTError extends Error { + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -1819846354050686206L; -/** - * Initializes a new instance of <code>AWTError</code> with the specified - * descriptive error message. - * - * @param message The descriptive error message. - */ -public -AWTError(String message) -{ - super(message); -} - -} // class AWTError - + /** + * Create a new instance with the specified descriptive error message. + * + * @param message the descriptive error message + */ + public AWTError(String message) + { + super(message); + } +} // class AWTError diff --git a/libjava/java/awt/AWTEvent.java b/libjava/java/awt/AWTEvent.java index 17975fcfe75..41cdad53fd6 100644 --- a/libjava/java/awt/AWTEvent.java +++ b/libjava/java/awt/AWTEvent.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2002 Free Software Foundation +/* AWTEvent.java -- the root event in AWT + Copyright (C) 1999, 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,123 +38,169 @@ exception statement from your version. */ package java.awt; -/* Written using on-line Java 2 Platform Standard Edition v1.3 API - * Specification, as well as "The Java Class Libraries", 2nd edition - * (Addison-Wesley, 1998). - * Status: Believed complete and correct, except for the java.awt.Event - * compatibility constructor. - */ +import java.util.EventObject; /** * AWTEvent is the root event class for all AWT events in the JDK 1.1 event - * model. It supersedes the Event class from JDK 1.0. + * model. It supersedes the Event class from JDK 1.0. Subclasses outside of + * the java.awt package should have IDs greater than RESERVED_ID_MAX. + * + * <p>Event masks defined here are used by components in + * <code>enableEvents</code> to select event types not selected by registered + * listeners. Event masks are appropriately set when registering on + * components. + * * @author Warren Levy <warrenl@cygnus.com> - * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.1 + * @status updated to 1.4 */ -public abstract class AWTEvent extends java.util.EventObject +public abstract class AWTEvent extends EventObject { /** - * @serial Indicates whether or not this event has been consumed. + * Compatible with JDK 1.1+. */ - protected boolean consumed; + private static final long serialVersionUID = -1825314779160409405L; /** - * @serial The identifier number of this event. + * The ID of the event. + * + * @see #getID() + * @see #AWTEvent(Object, int) + * @serial the identifier number of this event */ protected int id; /** - * Mask for selecting component events. - */ - public static final long COMPONENT_EVENT_MASK = 0x001; + * Indicates if the event has been consumed. False mean it is passed to + * the peer, true means it has already been processed. Semantic events + * generated by low-level events always have the value true. + * + * @see #consume() + * @see #isConsumed() + * @serial whether the event has been consumed + */ + protected boolean consumed; /** - * Mask for selecting container events. - */ - public static final long CONTAINER_EVENT_MASK = 0x002; + * Who knows? It's in the serial version. + * + * @serial No idea what this is for. + */ + byte[] bdata; + + /** Mask for selecting component events. */ + public static final long COMPONENT_EVENT_MASK = 0x00001; + + /** Mask for selecting container events. */ + public static final long CONTAINER_EVENT_MASK = 0x00002; + + /** Mask for selecting component focus events. */ + public static final long FOCUS_EVENT_MASK = 0x00004; + + /** Mask for selecting keyboard events. */ + public static final long KEY_EVENT_MASK = 0x00008; + + /** Mask for mouse button events. */ + public static final long MOUSE_EVENT_MASK = 0x00010; + + /** Mask for mouse motion events. */ + public static final long MOUSE_MOTION_EVENT_MASK = 0x00020; + + /** Mask for window events. */ + public static final long WINDOW_EVENT_MASK = 0x00040; + + /** Mask for action events. */ + public static final long ACTION_EVENT_MASK = 0x00080; + + /** Mask for adjustment events. */ + public static final long ADJUSTMENT_EVENT_MASK = 0x00100; + + /** Mask for item events. */ + public static final long ITEM_EVENT_MASK = 0x00200; + + /** Mask for text events. */ + public static final long TEXT_EVENT_MASK = 0x00400; /** - * Mask for selecting component focus events. - */ - public static final long FOCUS_EVENT_MASK = 0x004; + * Mask for input method events. + * @since 1.3 + */ + public static final long INPUT_METHOD_EVENT_MASK = 0x00800; /** - * Mask for selecting keyboard events. - */ - public static final long KEY_EVENT_MASK = 0x008; + * Mask if input methods are enabled. Package visible only. + */ + static final long INPUT_ENABLED_EVENT_MASK = 0x01000; /** - * Mask for mouse button events. - */ - public static final long MOUSE_EVENT_MASK = 0x010; + * Mask for paint events. + * @since 1.3 + */ + public static final long PAINT_EVENT_MASK = 0x02000; /** - * Mask for mouse motion events. - */ - public static final long MOUSE_MOTION_EVENT_MASK = 0x020; + * Mask for invocation events. + * @since 1.3 + */ + public static final long INVOCATION_EVENT_MASK = 0x04000; /** - * Mask for window events. - */ - public static final long WINDOW_EVENT_MASK = 0x040; + * Mask for hierarchy events. + * @since 1.3 + */ + public static final long HIERARCHY_EVENT_MASK = 0x08000; /** - * Mask for action events. - */ - public static final long ACTION_EVENT_MASK = 0x080; + * Mask for hierarchy bounds events. + * @since 1.3 + */ + public static final long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000; /** - * Mask for adjustment events. - */ - public static final long ADJUSTMENT_EVENT_MASK = 0x100; + * Mask for mouse wheel events. + * @since 1.4 + */ + public static final long MOUSE_WHEEL_EVENT_MASK = 0x20000; /** - * Mask for item events. - */ - public static final long ITEM_EVENT_MASK = 0x200; + * Mask for window state events. + * @since 1.4 + */ + public static final long WINDOW_STATE_EVENT_MASK = 0x40000; /** - * Mask for text events. - */ - public static final long TEXT_EVENT_MASK = 0x400; + * Mask for window focus events. + * @since 1.4 + */ + public static final long WINDOW_FOCUS_EVENT_MASK = 0x80000; /** * This is the highest number for event ids that are reserved for use by - * the AWT system itself. + * the AWT system itself. Subclasses outside of java.awt should use higher + * ids. */ public static final int RESERVED_ID_MAX = 1999; - public static final long INPUT_METHOD_EVENT_MASK = 1 << 11; - - /* Additional event selection masks from JDK 1.3 javadocs */ - public static final long PAINT_EVENT_MASK = 1 << 13, - INVOCATION_EVENT_MASK = 1 << 14, - HIERARCHY_EVENT_MASK = 1 << 15, - HIERARCHY_BOUNDS_EVENT_MASK = 1 << 16; - + /** - * Initializes a new instance of <code>AWTEvent</code> from the - * specified Java 1.0 event object. - * - * @param event The Java 1.0 event to initialize from. - * - * - * Removed this method because we no longer support Java 1.0 + * Initializes a new AWTEvent from the old Java 1.0 event object. * + * @param event the old-style event + * @throws NullPointerException if event is null */ public AWTEvent(Event event) { - // FIXME?? - super(event.target); - this.id = event.id; + this(event.target, event.id); + consumed = event.consumed; } /** - * Initializes a new instance of <code>AWTEvent</code> with the specified - * source and id. + * Create an event on the specified source object and id. * - * @param source The object that caused the event. - * @param id The event id. + * @param source the object that caused the event + * @param id the event id + * @throws IllegalArgumentException if source is null */ public AWTEvent(Object source, int id) { @@ -162,9 +209,21 @@ public abstract class AWTEvent extends java.util.EventObject } /** - * Returns the id number of this event. + * Retarget the event, such as converting a heavyweight component to a + * lightweight child of the original. This is not for general use, but + * is for event targeting systems like KeyboardFocusManager. * - * @return The id number of this event. + * @param source the new source + */ + public void setSource(Object source) + { + this.source = source; + } + + /** + * Returns the event type id. + * + * @return the id number of this event */ public int getID() { @@ -172,23 +231,26 @@ public abstract class AWTEvent extends java.util.EventObject } /** - * Returns a string representation of this event. + * Returns a string representation of this event. This is in the format + * <code>getClass().getName() + '[' + paramString() + "] on " + * + source</code>. * - * @return A string representation of this event. + * @return a string representation of this event */ - public String paramString () + public String toString() { - return ""; + return getClass().getName() + "[" + paramString() + "] on " + source; } /** - * Returns a string representation of this event. + * Returns a string representation of the state of this event. It may be + * empty, but must not be null; it is implementation defined. * - * @return A string representation of this event. + * @return a string representation of this event */ - public String toString () + public String paramString() { - return getClass().getName() + "[" + paramString() + "] on " + source; + return ""; } /** @@ -201,14 +263,13 @@ public abstract class AWTEvent extends java.util.EventObject } /** - * Tests whether not not this event has been consumed. A consumed event + * Tests whether not not this event has been consumed. A consumed event * is not processed in the default manner. * - * @return <code>true</code> if this event has been consumed, - * <code>false</code> otherwise. + * @return true if this event has been consumed */ protected boolean isConsumed() { return consumed; } -} +} // class AWTEvent diff --git a/libjava/java/awt/AWTEventMulticaster.java b/libjava/java/awt/AWTEventMulticaster.java index 7bbb999daba..58950ef0b98 100644 --- a/libjava/java/awt/AWTEventMulticaster.java +++ b/libjava/java/awt/AWTEventMulticaster.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2002 Free Software Foundation +/* AWTEventMulticaster.java -- allows multicast chaining of listeners + Copyright (C) 1999, 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,60 +38,87 @@ exception statement from your version. */ package java.awt; -import java.awt.event.*; -import java.util.EventListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.HierarchyBoundsListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import java.awt.event.InputMethodEvent; +import java.awt.event.InputMethodListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.event.TextEvent; +import java.awt.event.TextListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; +import java.awt.event.WindowListener; +import java.awt.event.WindowStateListener; +import java.io.IOException; import java.io.ObjectOutputStream; - -/* Written using on-line Java 2 Platform Standard Edition v1.3 API - * Specification, as well as "The Java Class Libraries", 2nd edition - * (Addison-Wesley, 1998). - * Status: Believed complete and correct to J2SE 1.3, except for - * serialization support methods, save() and saveInternal(), which are - * stubbed. - */ +import java.io.Serializable; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.EventListener; /** - * This class is used to implement a chain of event handlers. Dispatching - * using this class is thread safe. Here is a quick example of how to - * add and delete listeners using this class. For this example, we will - * assume are firing <code>AdjustableEvent</code>'s. However, this - * same approach is useful for all events in the <code>java.awt.event</code> - * package, and more if this class is subclassed. - * <p> - * <code> - * AdjustmentListener al; - * - * public void - * addAdjustmentListener(AdjustmentListener listener) - * { - * al = AWTEventMulticaster.add(al, listener); - * } - * - * public void - * removeAdjustmentListener(AdjustmentListener listener) - * { - * al = AWTEventMulticaster.remove(al, listener); - * } - * </code> - * <p> - * When it come time to process an event, simply call <code>al</code>, - * assuming it is not <code>null</code>. - * <p> - * The first time <code>add</code> is called it is passed - * <code>null</code> and <code>listener</code> as its arguments. This - * starts building the chain. This class returns <code>listener</code> - * which becomes the new <code>al</code>. The next time, <code>add</code> - * is called with <code>al</code> and <code>listener</code> and the - * new listener is then chained to the old. - * - * @author Bryce McKinlay - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public class AWTEventMulticaster implements ComponentListener, - ContainerListener, FocusListener, KeyListener, MouseListener, - MouseMotionListener, WindowListener, ActionListener, ItemListener, - AdjustmentListener, TextListener, InputMethodListener, HierarchyListener, - HierarchyBoundsListener + * This class is used to implement a chain of event handlers. Dispatching + * using this class is thread safe. Here is a quick example of how to + * add and delete listeners using this class. For this example, we will + * assume are firing <code>AdjustmentEvent</code>'s. However, this + * same approach is useful for all events in the <code>java.awt.event</code> + * package, and more if this class is subclassed. + * + * <p><code> + * AdjustmentListener al; + * public void addAdjustmentListener(AdjustmentListener listener) + * { + * al = AWTEventMulticaster.add(al, listener); + * } + * public void removeAdjustmentListener(AdjustmentListener listener) + * { + * al = AWTEventMulticaster.remove(al, listener); + * } + * </code> + * + * <p>When it come time to process an event, simply call <code>al</code>, + * assuming it is not <code>null</code>, and all listeners in the chain will + * be fired. + * + * <p>The first time <code>add</code> is called it is passed + * <code>null</code> and <code>listener</code> as its arguments. This + * starts building the chain. This class returns <code>listener</code> + * which becomes the new <code>al</code>. The next time, <code>add</code> + * is called with <code>al</code> and <code>listener</code> and the + * new listener is then chained to the old. + * + * @author Bryce McKinlay + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.1 + * @status updated to 1.4 + */ +public class AWTEventMulticaster + implements ComponentListener, ContainerListener, FocusListener, KeyListener, + MouseListener, MouseMotionListener, WindowListener, + WindowFocusListener, WindowStateListener, ActionListener, + ItemListener, AdjustmentListener, TextListener, + InputMethodListener, HierarchyListener, HierarchyBoundsListener, + MouseWheelListener { /** * A variable in the event chain. @@ -98,72 +126,32 @@ public class AWTEventMulticaster implements ComponentListener, protected final EventListener a; /** - * A variable in the event chain + * A variable in the event chain. */ protected final EventListener b; /** * Initializes a new instance of <code>AWTEventMulticaster</code> with - * the specified event listener parameters. + * the specified event listener parameters. The parameters should not be + * null, although it is not required to enforce this with a + * NullPointerException. * - * @param a The "a" listener object. - * @param b The "b" listener object. + * @param a the "a" listener object + * @param b the "b" listener object */ - protected AWTEventMulticaster(EventListener a, - EventListener b) + protected AWTEventMulticaster(EventListener a, EventListener b) { this.a = a; this.b = b; } /** - * Chain <code>EventListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Removes one instance of the specified listener from this multicaster + * chain. This descends recursively if either child is a multicaster, and + * returns a multicaster chain with the old listener removed. * - * @return Latest entry in the chain. - */ - protected static EventListener addInternal(EventListener a, EventListener b) - { - if (a == null) - return b; - else if (b == null) - return a; - else return new AWTEventMulticaster(a, b); - } - - /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. - * - * @return The resulting listener after the remove operation. - */ - protected static EventListener removeInternal(EventListener l, - EventListener oldl) - { - if (l == oldl) - return null; - else if (l instanceof AWTEventMulticaster) - { - AWTEventMulticaster mc = (AWTEventMulticaster) l; - return mc.remove(oldl); - } - return l; - } - - /** - * Removes the specified object from this multicaster object. If the - * object to remove is not part of this multicaster, then the remove - * method on the parent multicaster (if it exists) is called and a - * new multicaster object is returned based on that object and this - * multicaster's non-parent object. - * - * @param old The object to remove from this multicaster. - * - * @return The resulting multicaster with the specified listener removed. + * @param oldl the object to remove from this multicaster + * @return the resulting multicaster with the specified listener removed */ protected EventListener remove(EventListener oldl) { @@ -172,361 +160,369 @@ public class AWTEventMulticaster implements ComponentListener, return b; if (b == oldl) return a; - // If a and/or b are Multicaster's, search them recursively. if (a instanceof AWTEventMulticaster) { - AWTEventMulticaster mc = (AWTEventMulticaster) a; - EventListener newa = mc.remove(oldl); - if (newa != a) - return new AWTEventMulticaster (newa, b); - } + EventListener newa = ((AWTEventMulticaster) a).remove(oldl); + if (newa != a) + return new AWTEventMulticaster(newa, b); + } if (b instanceof AWTEventMulticaster) { - AWTEventMulticaster mc = (AWTEventMulticaster) a; - EventListener newb = mc.remove(oldl); - if (newb != b) - return new AWTEventMulticaster (a, newb); + EventListener newb = ((AWTEventMulticaster) b).remove(oldl); + if (newb != b) + return new AWTEventMulticaster(a, newb); } - // oldl was not found. return this; } /** - * Chain <code>ActionListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static ActionListener add(ActionListener a, ActionListener b) + public void componentResized(ComponentEvent e) { - return (ActionListener) addInternal(a, b); + ((ComponentListener) a).componentResized(e); + ((ComponentListener) b).componentResized(e); } /** - * Chain <code>AdjustmentListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static AdjustmentListener add(AdjustmentListener a, - AdjustmentListener b) + public void componentMoved(ComponentEvent e) { - return (AdjustmentListener) addInternal(a, b); - } + ((ComponentListener) a).componentMoved(e); + ((ComponentListener) b).componentMoved(e); + } /** - * Chain <code>ComponentListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static ComponentListener add(ComponentListener a, ComponentListener b) + public void componentShown(ComponentEvent e) { - return (ComponentListener) addInternal(a, b); + ((ComponentListener) a).componentShown(e); + ((ComponentListener) b).componentShown(e); } /** - * Chain <code>ContainerListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static ContainerListener add(ContainerListener a, ContainerListener b) + public void componentHidden(ComponentEvent e) { - return (ContainerListener) addInternal(a, b); + ((ComponentListener) a).componentHidden(e); + ((ComponentListener) b).componentHidden(e); } /** - * Chain <code>FocusListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static FocusListener add(FocusListener a, FocusListener b) + public void componentAdded(ContainerEvent e) { - return (FocusListener) addInternal(a, b); + ((ContainerListener) a).componentAdded(e); + ((ContainerListener) b).componentAdded(e); } - public static HierarchyBoundsListener add(HierarchyBoundsListener a, - HierarchyBoundsListener b) + /** + * Handles this event by dispatching it to the "a" and "b" listener + * instances. + * + * @param event the event to handle + */ + public void componentRemoved(ContainerEvent e) { - return (HierarchyBoundsListener) addInternal(a, b); + ((ContainerListener) a).componentRemoved(e); + ((ContainerListener) b).componentRemoved(e); } - public static HierarchyListener add(HierarchyListener a, HierarchyListener b) + /** + * Handles this event by dispatching it to the "a" and "b" listener + * instances. + * + * @param event the event to handle + */ + public void focusGained(FocusEvent e) { - return (HierarchyListener) addInternal(a, b); + ((FocusListener) a).focusGained(e); + ((FocusListener) b).focusGained(e); } - public static InputMethodListener add(InputMethodListener a, - InputMethodListener b) + /** + * Handles this event by dispatching it to the "a" and "b" listener + * instances. + * + * @param event the event to handle + */ + public void focusLost(FocusEvent e) { - return (InputMethodListener) addInternal(a, b); + ((FocusListener) a).focusLost(e); + ((FocusListener) b).focusLost(e); } /** - * Chain <code>ItemListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static ItemListener add(ItemListener a, ItemListener b) + public void keyTyped(KeyEvent e) { - return (ItemListener) addInternal(a, b); + ((KeyListener) a).keyTyped(e); + ((KeyListener) b).keyTyped(e); } /** - * Chain <code>KeyListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static KeyListener add(KeyListener a, KeyListener b) + public void keyPressed(KeyEvent e) { - return (KeyListener) addInternal(a, b); + ((KeyListener) a).keyPressed(e); + ((KeyListener) b).keyPressed(e); } /** - * Chain <code>MouseListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static MouseListener add(MouseListener a, MouseListener b) + public void keyReleased(KeyEvent e) { - return (MouseListener) addInternal(a, b); + ((KeyListener) a).keyReleased(e); + ((KeyListener) b).keyReleased(e); } /** - * Chain <code>MouseMotionListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static MouseMotionListener add(MouseMotionListener a, - MouseMotionListener b) + public void mouseClicked(MouseEvent e) { - return (MouseMotionListener) addInternal(a, b); + ((MouseListener) a).mouseClicked(e); + ((MouseListener) b).mouseClicked(e); } /** - * Chain <code>AdjustmentListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static TextListener add(TextListener a, TextListener b) + public void mousePressed(MouseEvent e) { - return (TextListener) addInternal(a, b); + ((MouseListener) a).mousePressed(e); + ((MouseListener) b).mousePressed(e); } /** - * Chain <code>WindowListener</code> b to a. - * - * @param a - Listener to chain to. - * @param b - Listener to chain. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return Latest entry in the chain. + * @param event the event to handle */ - public static WindowListener add(WindowListener a, WindowListener b) + public void mouseReleased(MouseEvent e) { - return (WindowListener) addInternal(a, b); + ((MouseListener) a).mouseReleased(e); + ((MouseListener) b).mouseReleased(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle */ - public static ActionListener remove(ActionListener l, ActionListener oldl) + public void mouseEntered(MouseEvent e) { - return (ActionListener) removeInternal(l, oldl); + ((MouseListener) a).mouseEntered(e); + ((MouseListener) b).mouseEntered(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle */ - public static AdjustmentListener remove(AdjustmentListener l, - AdjustmentListener oldl) + public void mouseExited(MouseEvent e) { - return (AdjustmentListener) removeInternal(l, oldl); + ((MouseListener) a).mouseExited(e); + ((MouseListener) b).mouseExited(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle */ - public static ComponentListener remove(ComponentListener l, - ComponentListener oldl) + public void mouseDragged(MouseEvent e) { - return (ComponentListener) removeInternal(l, oldl); + ((MouseMotionListener) a).mouseDragged(e); + ((MouseMotionListener) b).mouseDragged(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle */ - public static ContainerListener remove(ContainerListener l, - ContainerListener oldl) + public void mouseMoved(MouseEvent e) { - return (ContainerListener) removeInternal(l, oldl); + ((MouseMotionListener) a).mouseMoved(e); + ((MouseMotionListener) b).mouseMoved(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle */ - public static FocusListener remove(FocusListener l, FocusListener oldl) + public void windowOpened(WindowEvent e) { - return (FocusListener) removeInternal(l, oldl); + ((WindowListener) a).windowOpened(e); + ((WindowListener) b).windowOpened(e); } - public static HierarchyBoundsListener remove(HierarchyBoundsListener l, - HierarchyBoundsListener oldl) + /** + * Handles this event by dispatching it to the "a" and "b" listener + * instances. + * + * @param event the event to handle + */ + public void windowClosing(WindowEvent e) { - return (HierarchyBoundsListener) removeInternal(l, oldl); + ((WindowListener) a).windowClosing(e); + ((WindowListener) b).windowClosing(e); } - public static HierarchyListener remove(HierarchyListener l, - HierarchyListener oldl) + /** + * Handles this event by dispatching it to the "a" and "b" listener + * instances. + * + * @param event the event to handle + */ + public void windowClosed(WindowEvent e) { - return (HierarchyListener) removeInternal(l, oldl); + ((WindowListener) a).windowClosed(e); + ((WindowListener) b).windowClosed(e); } - public static InputMethodListener remove(InputMethodListener l, - InputMethodListener oldl) + /** + * Handles this event by dispatching it to the "a" and "b" listener + * instances. + * + * @param event the event to handle + */ + public void windowIconified(WindowEvent e) { - return (InputMethodListener) removeInternal(l, oldl); + ((WindowListener) a).windowIconified(e); + ((WindowListener) b).windowIconified(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle */ - public static ItemListener remove(ItemListener l, ItemListener oldl) + public void windowDeiconified(WindowEvent e) { - return (ItemListener) removeInternal(l, oldl); + ((WindowListener) a).windowDeiconified(e); + ((WindowListener) b).windowDeiconified(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle */ - public static KeyListener remove(KeyListener l, KeyListener oldl) + public void windowActivated(WindowEvent e) { - return (KeyListener) removeInternal(l, oldl); + ((WindowListener) a).windowActivated(e); + ((WindowListener) b).windowActivated(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle */ - public static MouseListener remove(MouseListener l, MouseListener oldl) + public void windowDeactivated(WindowEvent e) { - return (MouseListener) removeInternal(l, oldl); + ((WindowListener) a).windowDeactivated(e); + ((WindowListener) b).windowDeactivated(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle + * @since 1.4 */ - public static MouseMotionListener remove(MouseMotionListener l, - MouseMotionListener oldl) + public void windowStateChanged(WindowEvent e) { - return (MouseMotionListener) removeInternal(l, oldl); + ((WindowStateListener) a).windowStateChanged(e); + ((WindowStateListener) b).windowStateChanged(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle + * @since 1.4 */ - public static TextListener remove(TextListener l, TextListener oldl) + public void windowGainedFocus(WindowEvent e) { - return (TextListener) removeInternal(l, oldl); + ((WindowFocusListener) a).windowGainedFocus(e); + ((WindowFocusListener) b).windowGainedFocus(e); } /** - * Removes the listener <code>old</code> from the listener <code>lis</code>. - * - * @param lis The listener to remove <code>old</code> from. - * @param old The listener to remove. + * Handles this event by dispatching it to the "a" and "b" listener + * instances. * - * @return The resulting listener after the remove operation. + * @param event the event to handle + * @since 1.4 */ - public static WindowListener remove(WindowListener l, WindowListener oldl) + public void windowLostFocus(WindowEvent e) { - return (WindowListener) removeInternal(l, oldl); + ((WindowFocusListener) a).windowLostFocus(e); + ((WindowFocusListener) b).windowLostFocus(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle */ - public void actionPerformed(ActionEvent e) + public void actionPerformed(ActionEvent e) { ((ActionListener) a).actionPerformed(e); ((ActionListener) b).actionPerformed(e); @@ -536,405 +532,678 @@ public class AWTEventMulticaster implements ComponentListener, * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle */ - public void adjustmentValueChanged(AdjustmentEvent e) + public void itemStateChanged(ItemEvent e) { - ((AdjustmentListener) a).adjustmentValueChanged(e); - ((AdjustmentListener) b).adjustmentValueChanged(e); + ((ItemListener) a).itemStateChanged(e); + ((ItemListener) b).itemStateChanged(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle */ - public void componentHidden(ComponentEvent e) + public void adjustmentValueChanged(AdjustmentEvent e) { - ((ComponentListener) a).componentHidden(e); - ((ComponentListener) b).componentHidden(e); + ((AdjustmentListener) a).adjustmentValueChanged(e); + ((AdjustmentListener) b).adjustmentValueChanged(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle */ - public void componentMoved(ComponentEvent e) + public void textValueChanged(TextEvent e) { - ((ComponentListener) a).componentMoved(e); - ((ComponentListener) b).componentMoved(e); + ((TextListener) a).textValueChanged(e); + ((TextListener) b).textValueChanged(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle + * @since 1.2 */ - public void componentResized(ComponentEvent e) + public void inputMethodTextChanged(InputMethodEvent e) { - ((ComponentListener) a).componentResized(e); - ((ComponentListener) b).componentResized(e); + ((InputMethodListener) a).inputMethodTextChanged(e); + ((InputMethodListener) b).inputMethodTextChanged(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle + * @since 1.2 */ - public void componentShown(ComponentEvent e) + public void caretPositionChanged(InputMethodEvent e) { - ((ComponentListener) a).componentShown(e); - ((ComponentListener) b).componentShown(e); + ((InputMethodListener) a).caretPositionChanged(e); + ((InputMethodListener) b).caretPositionChanged(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle + * @since 1.3 */ - public void componentAdded(ContainerEvent e) + public void hierarchyChanged(HierarchyEvent e) { - ((ContainerListener) a).componentAdded(e); - ((ContainerListener) b).componentAdded(e); + ((HierarchyListener) a).hierarchyChanged(e); + ((HierarchyListener) b).hierarchyChanged(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle + * @since 1.3 */ - public void componentRemoved(ContainerEvent e) + public void ancestorMoved(HierarchyEvent e) { - ((ContainerListener) a).componentRemoved(e); - ((ContainerListener) b).componentRemoved(e); + ((HierarchyBoundsListener) a).ancestorMoved(e); + ((HierarchyBoundsListener) b).ancestorMoved(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle + * @since 1.3 */ - public void focusGained(FocusEvent e) + public void ancestorResized(HierarchyEvent e) { - ((FocusListener) a).focusGained(e); - ((FocusListener) b).focusGained(e); + ((HierarchyBoundsListener) a).ancestorResized(e); + ((HierarchyBoundsListener) b).ancestorResized(e); } /** * Handles this event by dispatching it to the "a" and "b" listener * instances. * - * @param event The event to handle. + * @param event the event to handle + * @since 1.4 */ - public void focusLost(FocusEvent e) + public void mouseWheelMoved(MouseWheelEvent e) { - ((FocusListener) a).focusLost(e); - ((FocusListener) b).focusLost(e); + ((MouseWheelListener) a).mouseWheelMoved(e); + ((MouseWheelListener) b).mouseWheelMoved(e); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>ComponentListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void ancestorMoved(HierarchyEvent e) + public static ComponentListener add(ComponentListener a, ComponentListener b) { - ((HierarchyBoundsListener) a).ancestorMoved(e); - ((HierarchyBoundsListener) b).ancestorMoved(e); + return (ComponentListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>ContainerListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void ancestorResized(HierarchyEvent e) + public static ContainerListener add(ContainerListener a, ContainerListener b) { - ((HierarchyBoundsListener) a).ancestorResized(e); - ((HierarchyBoundsListener) b).ancestorResized(e); + return (ContainerListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>FocusListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void hierarchyChanged(HierarchyEvent e) + public static FocusListener add(FocusListener a, FocusListener b) { - ((HierarchyListener) a).hierarchyChanged(e); - ((HierarchyListener) b).hierarchyChanged(e); + return (FocusListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>KeyListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void caretPositionChanged(InputMethodEvent e) + public static KeyListener add(KeyListener a, KeyListener b) { - ((InputMethodListener) a).caretPositionChanged(e); - ((InputMethodListener) b).caretPositionChanged(e); + return (KeyListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>MouseListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void inputMethodTextChanged(InputMethodEvent e) + public static MouseListener add(MouseListener a, MouseListener b) { - ((InputMethodListener) a).inputMethodTextChanged(e); - ((InputMethodListener) b).inputMethodTextChanged(e); + return (MouseListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>MouseMotionListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void itemStateChanged(ItemEvent e) + public static MouseMotionListener add(MouseMotionListener a, + MouseMotionListener b) { - ((ItemListener) a).itemStateChanged(e); - ((ItemListener) b).itemStateChanged(e); - } + return (MouseMotionListener) addInternal(a, b); + } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>WindowListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void keyPressed(KeyEvent e) + public static WindowListener add(WindowListener a, WindowListener b) { - ((KeyListener) a).keyPressed(e); - ((KeyListener) b).keyPressed(e); + return (WindowListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>WindowStateListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain + * @since 1.4 */ - public void keyReleased(KeyEvent e) + public static WindowStateListener add(WindowStateListener a, + WindowStateListener b) { - ((KeyListener) a).keyReleased(e); - ((KeyListener) b).keyReleased(e); + return (WindowStateListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>WindowFocusListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain + * @since 1.4 */ - public void keyTyped(KeyEvent e) + public static WindowFocusListener add(WindowFocusListener a, + WindowFocusListener b) { - ((KeyListener) a).keyTyped(e); - ((KeyListener) b).keyTyped(e); + return (WindowFocusListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>ActionListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void mouseClicked(MouseEvent e) + public static ActionListener add(ActionListener a, ActionListener b) { - ((MouseListener) a).mouseClicked(e); - ((MouseListener) b).mouseClicked(e); + return (ActionListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>ItemListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void mouseEntered(MouseEvent e) + public static ItemListener add(ItemListener a, ItemListener b) { - ((MouseListener) a).mouseEntered(e); - ((MouseListener) b).mouseEntered(e); + return (ItemListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>AdjustmentListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void mouseExited(MouseEvent e) + public static AdjustmentListener add(AdjustmentListener a, + AdjustmentListener b) { - ((MouseListener) a).mouseExited(e); - ((MouseListener) b).mouseExited(e); + return (AdjustmentListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>AdjustmentListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain */ - public void mousePressed(MouseEvent e) + public static TextListener add(TextListener a, TextListener b) { - ((MouseListener) a).mousePressed(e); - ((MouseListener) b).mousePressed(e); + return (TextListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>InputMethodListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain + * @since 1.2 */ - public void mouseReleased(MouseEvent e) + public static InputMethodListener add(InputMethodListener a, + InputMethodListener b) { - ((MouseListener) a).mouseReleased(e); - ((MouseListener) b).mouseReleased(e); + return (InputMethodListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>HierarchyListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain + * @since 1.3 */ - public void mouseDragged(MouseEvent e) + public static HierarchyListener add(HierarchyListener a, HierarchyListener b) { - ((MouseMotionListener) a).mouseDragged(e); - ((MouseMotionListener) b).mouseDragged(e); + return (HierarchyListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>HierarchyBoundsListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain + * @since 1.3 */ - public void mouseMoved(MouseEvent e) + public static HierarchyBoundsListener add(HierarchyBoundsListener a, + HierarchyBoundsListener b) { - ((MouseMotionListener) a).mouseMoved(e); - ((MouseMotionListener) b).mouseMoved(e); + return (HierarchyBoundsListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Chain <code>MouseWheelListener</code> a and b. * - * @param event The event to handle. + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain + * @since 1.4 */ - public void textValueChanged(TextEvent e) + public static MouseWheelListener add(MouseWheelListener a, + MouseWheelListener b) { - ((TextListener) a).textValueChanged(e); - ((TextListener) b).textValueChanged(e); + return (MouseWheelListener) addInternal(a, b); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Removes the listener <code>oldl</code> from the listener <code>l</code>. * - * @param event The event to handle. + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain */ - public void windowActivated(WindowEvent e) + public static ComponentListener remove(ComponentListener l, + ComponentListener oldl) { - ((WindowListener) a).windowActivated(e); - ((WindowListener) b).windowActivated(e); + return (ComponentListener) removeInternal(l, oldl); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Removes the listener <code>oldl</code> from the listener <code>l</code>. * - * @param event The event to handle. + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain */ - public void windowClosed(WindowEvent e) + public static ContainerListener remove(ContainerListener l, + ContainerListener oldl) { - ((WindowListener) a).windowClosed(e); - ((WindowListener) b).windowClosed(e); + return (ContainerListener) removeInternal(l, oldl); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Removes the listener <code>oldl</code> from the listener <code>l</code>. * - * @param event The event to handle. + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain */ - public void windowClosing(WindowEvent e) + public static FocusListener remove(FocusListener l, FocusListener oldl) { - ((WindowListener) a).windowClosing(e); - ((WindowListener) b).windowClosing(e); + return (FocusListener) removeInternal(l, oldl); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Removes the listener <code>oldl</code> from the listener <code>l</code>. * - * @param event The event to handle. + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain */ - public void windowDeactivated(WindowEvent e) + public static KeyListener remove(KeyListener l, KeyListener oldl) { - ((WindowListener) a).windowDeactivated(e); - ((WindowListener) b).windowDeactivated(e); + return (KeyListener) removeInternal(l, oldl); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Removes the listener <code>oldl</code> from the listener <code>l</code>. * - * @param event The event to handle. + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain */ - public void windowDeiconified(WindowEvent e) + public static MouseListener remove(MouseListener l, MouseListener oldl) { - ((WindowListener) a).windowDeiconified(e); - ((WindowListener) b).windowDeiconified(e); + return (MouseListener) removeInternal(l, oldl); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Removes the listener <code>oldl</code> from the listener <code>l</code>. * - * @param event The event to handle. + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain */ - public void windowIconified(WindowEvent e) + public static MouseMotionListener remove(MouseMotionListener l, + MouseMotionListener oldl) { - ((WindowListener) a).windowIconified(e); - ((WindowListener) b).windowIconified(e); + return (MouseMotionListener) removeInternal(l, oldl); } /** - * Handles this event by dispatching it to the "a" and "b" listener - * instances. + * Removes the listener <code>oldl</code> from the listener <code>l</code>. * - * @param event The event to handle. + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain */ - public void windowOpened(WindowEvent e) + public static WindowListener remove(WindowListener l, WindowListener oldl) { - ((WindowListener) a).windowOpened(e); - ((WindowListener) b).windowOpened(e); + return (WindowListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + * @since 1.4 + */ + public static WindowStateListener remove(WindowStateListener l, + WindowStateListener oldl) + { + return (WindowStateListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + * @since 1.4 + */ + public static WindowFocusListener remove(WindowFocusListener l, + WindowFocusListener oldl) + { + return (WindowFocusListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + */ + public static ActionListener remove(ActionListener l, ActionListener oldl) + { + return (ActionListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + */ + public static ItemListener remove(ItemListener l, ItemListener oldl) + { + return (ItemListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + */ + public static AdjustmentListener remove(AdjustmentListener l, + AdjustmentListener oldl) + { + return (AdjustmentListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + */ + public static TextListener remove(TextListener l, TextListener oldl) + { + return (TextListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + * @since 1.2 + */ + public static InputMethodListener remove(InputMethodListener l, + InputMethodListener oldl) + { + return (InputMethodListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + * @since 1.3 + */ + public static HierarchyListener remove(HierarchyListener l, + HierarchyListener oldl) + { + return (HierarchyListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + * @since 1.3 + */ + public static HierarchyBoundsListener remove(HierarchyBoundsListener l, + HierarchyBoundsListener oldl) + { + return (HierarchyBoundsListener) removeInternal(l, oldl); + } + + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + * @since 1.4 + */ + public static MouseWheelListener remove(MouseWheelListener l, + MouseWheelListener oldl) + { + return (MouseWheelListener) removeInternal(l, oldl); + } + + /** + * Chain <code>EventListener</code> a and b. + * + * @param a the "a" listener, may be null + * @param b the "b" listener, may be null + * @return latest entry in the chain + */ + protected static EventListener addInternal(EventListener a, EventListener b) + { + if (a == null) + return b; + if (b == null) + return a; + return new AWTEventMulticaster(a, b); } - protected static void save(ObjectOutputStream s, String k, EventListener l) + /** + * Removes the listener <code>oldl</code> from the listener <code>l</code>. + * + * @param l the listener chain to reduce + * @param oldl the listener to remove + * @return the resulting listener chain + */ + protected static EventListener removeInternal(EventListener l, + EventListener oldl) { - throw new RuntimeException("Not Implemented"); + if (l == oldl) + return null; + if (l instanceof AWTEventMulticaster) + return ((AWTEventMulticaster) l).remove(oldl); + return l; } + /** + * Saves all Serializable listeners to a serialization stream. + * + * @param s the stream to save to + * @param k a prefix stream put before each serializable listener + * @throws IOException if serialization fails + */ protected void saveInternal(ObjectOutputStream s, String k) + throws IOException + { + // This is not documented by Sun, but I think it is correct. + if (a instanceof AWTEventMulticaster) + ((AWTEventMulticaster) a).saveInternal(s, k); + else if (a instanceof Serializable) + { + s.writeObject(k); + s.writeObject(a); + } + if (b instanceof AWTEventMulticaster) + ((AWTEventMulticaster) b).saveInternal(s, k); + else if (b instanceof Serializable) + { + s.writeObject(k); + s.writeObject(b); + } + } + + /** + * Saves a Serializable listener chain to a serialization stream. + * + * @param s the stream to save to + * @param k a prefix stream put before each serializable listener + * @param l the listener chain to save + * @throws IOException if serialization fails + */ + protected static void save(ObjectOutputStream s, String k, EventListener l) + throws IOException + { + // This is not documented by Sun, but I think it is correct. + if (l instanceof AWTEventMulticaster) + ((AWTEventMulticaster) l).saveInternal(s, k); + else if (l instanceof Serializable) + { + s.writeObject(k); + s.writeObject(l); + } + } + + /** + * Returns an array of all chained listeners of the specified type in the + * given chain. A null listener returns an empty array, and a listener + * which is not an AWTEventMulticaster returns an array of one element. If + * no listeners in the chain are of the specified type, an empty array is + * returned. + * + * @param l the listener chain to convert to an array + * @param type the type of listeners to collect + * @return an array of the listeners of that type in the chain + * @throws ClassCastException if type is not assignable from EventListener + * @throws NullPointerException if type is null + * @throws IllegalArgumentException if type is Void.TYPE + * @since 1.4 + */ + public static EventListener[] getListeners(EventListener l, Class type) { - throw new RuntimeException("Not Implemented"); + ArrayList list = new ArrayList(); + if (l instanceof AWTEventMulticaster) + ((AWTEventMulticaster) l).getListeners(list, type); + else if (type.isInstance(l)) + list.add(l); + EventListener[] r = (EventListener[]) Array.newInstance(type, list.size()); + list.toArray(r); + return r; + } + + /** + * Collects all instances of the given type in the chain into the list. + * + * @param l the list to collect into + * @param type the type of listeners to collect + * @throws NullPointerException if type is null + * @see #getListeners(EventListener, Class) + */ + private void getListeners(ArrayList l, Class type) + { + if (a instanceof AWTEventMulticaster) + ((AWTEventMulticaster) a).getListeners(l, type); + else if (type.isInstance(a)) + l.add(a); + if (b instanceof AWTEventMulticaster) + ((AWTEventMulticaster) b).getListeners(l, type); + else if (type.isInstance(b)) + l.add(b); } -} +} // class AWTEventMulticaster diff --git a/libjava/java/awt/AWTException.java b/libjava/java/awt/AWTException.java index 03926914884..e4ab6c9961f 100644 --- a/libjava/java/awt/AWTException.java +++ b/libjava/java/awt/AWTException.java @@ -1,5 +1,5 @@ /* AWTException.java -- Generic AWT exception - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,25 +39,26 @@ exception statement from your version. */ package java.awt; /** - * This is a generic exception that indicates an error occurred in the - * AWT system. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This is a generic exception that indicates an exception occurred in the + * Abstract Window Toolkit (AWT) system. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @status updated to 1.4 + */ public class AWTException extends Exception { + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -1900414231151323879L; -/** - * Initializes a new instance of <code>AWTException</code> with the - * specified detailed error message. - * - * @param message The detailed error message. - */ -public -AWTException(String message) -{ - super(message); -} - -} // class AWTException - + /** + * Create a new instance with the specified detailed error message. + * + * @param message the detailed error message + */ + public AWTException(String message) + { + super(message); + } +} // class AWTException diff --git a/libjava/java/awt/AWTKeyStroke.java b/libjava/java/awt/AWTKeyStroke.java new file mode 100644 index 00000000000..9848d43ef63 --- /dev/null +++ b/libjava/java/awt/AWTKeyStroke.java @@ -0,0 +1,653 @@ +/* AWTKeyStroke.java -- an immutable key stroke + 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.io.ObjectStreamException; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Map; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.StringTokenizer; + +/** + * This class mirrors KeyEvents, representing both low-level key presses and + * key releases, and high level key typed inputs. However, this class forms + * immutable strokes, and can be efficiently reused via the factory methods + * for creating them. + * + * <p>For backwards compatibility with Swing, this supports a way to build + * instances of a subclass, using reflection, provided the subclass has a + * no-arg constructor (of any accessibility). + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see #getAWTKeyStroke(char) + * @since 1.4 + * @status updated to 1.4 + */ +public class AWTKeyStroke implements Serializable +{ + /** + * Compatible with JDK 1.4+. + */ + private static final long serialVersionUID = -6430539691155161871L; + + /** The mask for modifiers. */ + private static final int MODIFIERS_MASK = 0x3fef; + + /** + * The cache of recently created keystrokes. This maps KeyStrokes to + * KeyStrokes in a cache which removes the least recently accessed entry, + * under the assumption that garbage collection of a new keystroke is + * easy when we find the old one that it matches in the cache. + */ + private static final LinkedHashMap cache = new LinkedHashMap(11, 0.75f, true) + { + /** The largest the keystroke cache can grow. */ + private static final int MAX_CACHE_SIZE = 2048; + + /** Prune stale entries. */ + protected boolean removeEldestEntry(Map.Entry eldest) + { // XXX - FIXME Use Map.Entry, not just Entry as gcj 3.1 workaround. + return size() > MAX_CACHE_SIZE; + } + }; + + /** The most recently generated keystroke, or null. */ + private static AWTKeyStroke recent; + + /** + * The no-arg constructor of a subclass, or null to use AWTKeyStroke. Note + * that this will be left accessible, to get around private access; but + * it should not be a security risk as it is highly unlikely that creating + * protected instances of the subclass via reflection will do much damage. + */ + private static Constructor ctor; + + /** + * A table of keyCode names to values. + * + * @see #getAWTKeyStroke(String) + */ + private static final HashMap vktable = new HashMap(); + static + { + // Using reflection saves the hassle of keeping this in sync with KeyEvent, + // at the price of an expensive initialization. + AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + Field[] fields = KeyEvent.class.getFields(); + int i = fields.length; + try + { + while (--i >= 0) + { + Field f = fields[i]; + String name = f.getName(); + if (name.startsWith("VK_")) + vktable.put(name.substring(3), f.get(null)); + } + } + catch (Exception e) + { + throw (Error) new InternalError().initCause(e); + } + return null; + } + }); + } + + /** + * The typed character, or CHAR_UNDEFINED for key presses and releases. + * + * @serial the keyChar + */ + private char keyChar; + + /** + * The virtual key code, or VK_UNDEFINED for key typed. Package visible for + * use by Component. + * + * @serial the keyCode + */ + int keyCode; + + /** + * The modifiers in effect. To match Sun, this stores the old style masks + * for shift, control, alt, meta, and alt-graph (but not button1); as well + * as the new style of extended modifiers for all modifiers. + * + * @serial bitwise or of the *_DOWN_MASK modifiers + */ + private int modifiers; + + /** + * True if this is a key release; should only be true if keyChar is + * CHAR_UNDEFINED. + * + * @serial true to distinguish key pressed from key released + */ + private boolean onKeyRelease; + + /** + * Construct a keystroke with default values: it will be interpreted as a + * key typed event with an invalid character and no modifiers. Client code + * should use the factory methods instead. + * + * @see #getAWTKeyStroke(char) + * @see #getAWTKeyStroke(Character, int) + * @see #getAWTKeyStroke(int, int, boolean) + * @see #getAWTKeyStroke(int, int) + * @see #getAWTKeyStrokeForEvent(KeyEvent) + * @see #getAWTKeyStroke(String) + */ + protected AWTKeyStroke() + { + keyChar = KeyEvent.CHAR_UNDEFINED; + } + + /** + * Construct a keystroke with the given values. Client code should use the + * factory methods instead. + * + * @param keyChar the character entered, if this is a key typed + * @param keyCode the key pressed or released, or VK_UNDEFINED for key typed + * @param modifiers the modifier keys for the keystroke, in old or new style + * @param onKeyRelease true if this is a key release instead of a press + * @see #getAWTKeyStroke(char) + * @see #getAWTKeyStroke(Character, int) + * @see #getAWTKeyStroke(int, int, boolean) + * @see #getAWTKeyStroke(int, int) + * @see #getAWTKeyStrokeForEvent(KeyEvent) + * @see #getAWTKeyStroke(String) + */ + protected AWTKeyStroke(char keyChar, int keyCode, int modifiers, + boolean onKeyRelease) + { + this.keyChar = keyChar; + this.keyCode = keyCode; + // No need to call extend(), as only trusted code calls this constructor. + this.modifiers = modifiers; + this.onKeyRelease = onKeyRelease; + } + + /** + * Registers a new subclass as being the type of keystrokes to generate in + * the factory methods. This operation flushes the cache of stored keystrokes + * if the class differs from the current one. The new class must be + * AWTKeyStroke or a subclass, and must have a no-arg constructor (which may + * be private). + * + * @param subclass the new runtime type of generated keystrokes + * @throws IllegalArgumentException subclass doesn't have no-arg constructor + * @throws ClassCastException subclass doesn't extend AWTKeyStroke + */ + protected static void registerSubclass(final Class subclass) + { + if (subclass == null) + throw new IllegalArgumentException(); + if (subclass.equals(ctor == null ? AWTKeyStroke.class + : ctor.getDeclaringClass())) + return; + if (subclass.equals(AWTKeyStroke.class)) + { + cache.clear(); + recent = null; + ctor = null; + return; + } + try + { + ctor = (Constructor) AccessController.doPrivileged + (new PrivilegedExceptionAction() + { + public Object run() + throws NoSuchMethodException, InstantiationException, + IllegalAccessException, InvocationTargetException + { + Constructor c = subclass.getDeclaredConstructor(null); + c.setAccessible(true); + // Create a new instance, to make sure that we can, and + // to cause any ClassCastException. + AWTKeyStroke dummy = (AWTKeyStroke) c.newInstance(null); + return c; + } + }); + } + catch (PrivilegedActionException e) + { + // e.getCause() will not ever be ClassCastException; that should + // escape on its own. + throw (RuntimeException) + new IllegalArgumentException().initCause(e.getCause()); + } + cache.clear(); + recent = null; + } + + /** + * Returns a keystroke representing a typed character. + * + * @param keyChar the typed character + * @return the specified keystroke + */ + public static AWTKeyStroke getAWTKeyStroke(char keyChar) + { + return getAWTKeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, false); + } + + /** + * Returns a keystroke representing a typed character with the given + * modifiers. Note that keyChar is a <code>Character</code> instead of a + * <code>char</code> to avoid accidental ambiguity with + * <code>getAWTKeyStroke(int, int)</code>. The modifiers are the bitwise + * or of the masks found in {@link InputEvent}; the new style (*_DOWN_MASK) + * is preferred, but the old style will work. + * + * @param keyChar the typed character + * @param modifiers the modifiers, or 0 + * @return the specified keystroke + * @throws IllegalArgumentException if keyChar is null + */ + public static AWTKeyStroke getAWTKeyStroke(Character keyChar, int modifiers) + { + if (keyChar == null) + throw new IllegalArgumentException(); + return getAWTKeyStroke(keyChar.charValue(), KeyEvent.VK_UNDEFINED, + extend(modifiers), false); + } + + /** + * Returns a keystroke representing a pressed or released key event, with + * the given modifiers. The "virtual key" should be one of the VK_* + * constants in {@link KeyEvent}. The modifiers are the bitwise or of the + * masks found in {@link InputEvent}; the new style (*_DOWN_MASK) is + * preferred, but the old style will work. + * + * @param keyCode the virtual key + * @param modifiers the modifiers, or 0 + * @param release true if this is a key release instead of a key press + * @return the specified keystroke + */ + public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers, + boolean release) + { + return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode, + extend(modifiers), release); + } + + /** + * Returns a keystroke representing a pressed key event, with the given + * modifiers. The "virtual key" should be one of the VK_* constants in + * {@link KeyEvent}. The modifiers are the bitwise or of the masks found + * in {@link InputEvent}; the new style (*_DOWN_MASK) is preferred, but the + * old style will work. + * + * @param keyCode the virtual key + * @param modifiers the modifiers, or 0 + * @return the specified keystroke + */ + public static AWTKeyStroke getAWTKeyStroke(int keyCode, int modifiers) + { + return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, keyCode, + extend(modifiers), false); + } + + /** + * Returns a keystroke representing what caused the key event. + * + * @param event the key event to convert + * @return the specified keystroke, or null if the event is invalid + * @throws NullPointerException if event is null + */ + public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent event) + { + switch (event.id) + { + case KeyEvent.KEY_TYPED: + return getAWTKeyStroke(event.getKeyChar(), KeyEvent.VK_UNDEFINED, + extend(event.getModifiersEx()), false); + case KeyEvent.KEY_PRESSED: + return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, event.getKeyCode(), + extend(event.getModifiersEx()), false); + case KeyEvent.KEY_RELEASED: + return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, event.getKeyCode(), + extend(event.getModifiersEx()), true); + default: + return null; + } + } + + /** + * Parses a string and returns the keystroke that it represents. The syntax + * for keystrokes is listed below, with tokens separated by an arbitrary + * number of spaces: + * <pre> + * keyStroke := <modifiers>* ( <typedID> | <codeID> ) + * modifiers := ( shift | control | ctrl | meta | alt + * | button1 | button2 | button3 ) + * typedID := typed <single Unicode character> + * codeID := ( pressed | released )? <name> + * name := <the KeyEvent field name less the leading "VK_"> + * </pre> + * + * <p>Note that the grammar is rather weak, and not all valid keystrokes + * can be generated in this manner (for example, a typed space, or anything + * with the alt-graph modifier!). The output of AWTKeyStroke.toString() + * will not meet the grammar. If pressed or released is not specified, + * pressed is assumed. Examples:<br> + * <code> + * "INSERT" => getAWTKeyStroke(KeyEvent.VK_INSERT, 0);<br> + * "control DELETE" => + * getAWTKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK);<br> + * "alt shift X" => getAWTKeyStroke(KeyEvent.VK_X, + * InputEvent.ALT_MASK | InputEvent.SHIFT_MASK);<br> + * "alt shift released X" => getAWTKeyStroke(KeyEvent.VK_X, + * InputEvent.ALT_MASK | InputEvent.SHIFT_MASK, true);<br> + * "typed a" => getAWTKeyStroke('a'); + * </code> + * + * @param s the string to parse + * @return the specified keystroke + * @throws NullPointerException if s is null + * @throws IllegalArgumentException if s cannot be parsed + */ + public static AWTKeyStroke getAWTKeyStroke(String s) + { + StringTokenizer t = new StringTokenizer(s, " "); + if (! t.hasMoreTokens()) + throw new IllegalArgumentException(); + int modifiers = 0; + boolean released = false; + String token = null; + do + { + token = t.nextToken(); + if ("shift".equals(token)) + modifiers |= KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK; + else if ("ctrl".equals(token) || "control".equals(token)) + modifiers |= KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK; + else if ("meta".equals(token)) + modifiers |= KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK; + else if ("alt".equals(token)) + modifiers |= KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK; + else if ("button1".equals(token)) + modifiers |= KeyEvent.BUTTON1_DOWN_MASK; + else if ("button2".equals(token)) + modifiers |= KeyEvent.BUTTON2_DOWN_MASK; + else if ("button3".equals(token)) + modifiers |= KeyEvent.BUTTON3_DOWN_MASK; + else if ("typed".equals(token)) + { + if (t.hasMoreTokens()) + { + token = t.nextToken(); + if (! t.hasMoreTokens() && token.length() == 1) + return getAWTKeyStroke(token.charAt(0), + KeyEvent.VK_UNDEFINED, modifiers, + false); + } + throw new IllegalArgumentException(); + } + else if ("pressed".equals(token)) + { + if (t.hasMoreTokens()) + token = t.nextToken(); + break; + } + else if ("released".equals(token)) + { + released = true; + if (t.hasMoreTokens()) + token = t.nextToken(); + break; + } + else + break; + } + while (t.hasMoreTokens()); + // Now token contains the VK name we must parse. + Integer code = (Integer) vktable.get(token); + if (code == null || t.hasMoreTokens()) + throw new IllegalArgumentException(); + return getAWTKeyStroke(KeyEvent.CHAR_UNDEFINED, code.intValue(), + modifiers, released); + } + + /** + * Returns the character of this keystroke, if it was typed. + * + * @return the character value, or CHAR_UNDEFINED + * @see #getAWTKeyStroke(char) + */ + public final char getKeyChar() + { + return keyChar; + } + + /** + * Returns the virtual key code of this keystroke, if it was pressed or + * released. This will be a VK_* constant from KeyEvent. + * + * @return the virtual key code value, or VK_UNDEFINED + * @see #getAWTKeyStroke(int, int) + */ + public final int getKeyCode() + { + return keyCode; + } + + /** + * Returns the modifiers for this keystroke. This will be a bitwise or of + * constants from InputEvent; it includes the old style masks for shift, + * control, alt, meta, and alt-graph (but not button1); as well as the new + * style of extended modifiers for all modifiers. + * + * @return the modifiers + * @see #getAWTKeyStroke(Character, int) + * @see #getAWTKeyStroke(int, int) + */ + public final int getModifiers() + { + return modifiers; + } + + /** + * Tests if this keystroke is a key release. + * + * @return true if this is a key release + * @see #getAWTKeyStroke(int, int, boolean) + */ + public final boolean isOnKeyRelease() + { + return onKeyRelease; + } + + /** + * Returns the AWT event type of this keystroke. This is one of + * {@link KeyEvent#KEY_TYPED}, {@link KeyEvent#KEY_PRESSED}, or + * {@link KeyEvent#KEY_RELEASED}. + * + * @return the key event type + */ + public final int getKeyEventType() + { + return keyCode == KeyEvent.VK_UNDEFINED ? KeyEvent.KEY_TYPED + : onKeyRelease ? KeyEvent.KEY_RELEASED : KeyEvent.KEY_PRESSED; + } + + /** + * Returns a hashcode for this key event. It is not documented, but appears + * to be: <code>(getKeyChar() + 1) * (getKeyCode() + 1) + * * (getModifiers() + 1) * 2 + (isOnKeyRelease() ? 1 : 2)</code>. + * + * @return the hashcode + */ + public int hashCode() + { + return (keyChar + 1) * (keyCode + 1) * (modifiers + 1) * 2 + + (onKeyRelease ? 1 : 2); + } + + /** + * Tests two keystrokes for equality. + * + * @param o the object to test + * @return true if it is equal + */ + public final boolean equals(Object o) + { + if (! (o instanceof AWTKeyStroke)) + return false; + AWTKeyStroke s = (AWTKeyStroke) o; + return this == o || (keyChar == s.keyChar && keyCode == s.keyCode + && modifiers == s.modifiers + && onKeyRelease == s.onKeyRelease); + } + + /** + * Returns a string representation of this keystroke. For typed keystrokes, + * this is <code>"keyChar " + KeyEvent.getKeyModifiersText(getModifiers()) + + getKeyChar()</code>; for pressed and released keystrokes, this is + * <code>"keyCode " + KeyEvent.getKeyModifiersText(getModifiers()) + * + KeyEvent.getKeyText(getKeyCode()) + * + (isOnKeyRelease() ? "-R" : "-P")</code>. + * + * @return a string representation + */ + public String toString() + { + if (keyCode == KeyEvent.VK_UNDEFINED) + return "keyChar " + KeyEvent.getKeyModifiersText(modifiers) + keyChar; + return "keyCode " + KeyEvent.getKeyModifiersText(modifiers) + + KeyEvent.getKeyText(keyCode) + (onKeyRelease ? "-R" : "-P"); + } + + /** + * Returns a cached version of the deserialized keystroke, if available. + * + * @return a cached replacement + * @throws ObjectStreamException if something goes wrong + */ + protected Object readResolve() throws ObjectStreamException + { + AWTKeyStroke s = (AWTKeyStroke) cache.get(this); + if (s != null) + return s; + cache.put(this, this); + return this; + } + + /** + * Gets the appropriate keystroke, creating one if necessary. + * + * @param keyChar the keyChar + * @param keyCode the keyCode + * @param modifiers the modifiers + * @param release true for key release + * @return the specified keystroke + */ + private static AWTKeyStroke getAWTKeyStroke(char keyChar, int keyCode, + int modifiers, boolean release) + { + // Check level 0 cache. + AWTKeyStroke stroke = recent; // Avoid thread races. + if (stroke != null && stroke.keyChar == keyChar + && stroke.keyCode == keyCode && stroke.modifiers == modifiers + && stroke.onKeyRelease == release) + return stroke; + // Create a new object, on the assumption that if it has a match in the + // cache, the VM can easily garbage collect it as it is temporary. + Constructor c = ctor; // Avoid thread races. + if (c == null) + stroke = new AWTKeyStroke(keyChar, keyCode, modifiers, release); + else + try + { + stroke = (AWTKeyStroke) c.newInstance(null); + stroke.keyChar = keyChar; + stroke.keyCode = keyCode; + stroke.modifiers = modifiers; + stroke.onKeyRelease = release; + } + catch (Exception e) + { + throw (Error) new InternalError().initCause(e); + } + // Check level 1 cache. + AWTKeyStroke cached = (AWTKeyStroke) cache.get(stroke); + if (cached == null) + cache.put(stroke, stroke); + else + stroke = cached; + return recent = stroke; + } + + /** + * Converts the modifiers to the appropriate format. + * + * @param mod the modifiers to convert + * @return the adjusted modifiers + */ + private static int extend(int mod) + { + if ((mod & (KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK)) != 0) + mod |= KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK; + if ((mod & (KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK)) != 0) + mod |= KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK; + if ((mod & (KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK)) != 0) + mod |= KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK; + if ((mod & (KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK)) != 0) + mod |= KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK; + if ((mod & (KeyEvent.ALT_GRAPH_MASK | KeyEvent.ALT_GRAPH_DOWN_MASK)) != 0) + mod |= KeyEvent.ALT_GRAPH_MASK | KeyEvent.ALT_GRAPH_DOWN_MASK; + if ((mod & KeyEvent.BUTTON1_MASK) != 0) + mod |= KeyEvent.BUTTON1_DOWN_MASK; + return mod & MODIFIERS_MASK; + } +} // class AWTKeyStroke diff --git a/libjava/java/awt/AWTPermission.java b/libjava/java/awt/AWTPermission.java index 914ecd7d058..993c60d50d4 100644 --- a/libjava/java/awt/AWTPermission.java +++ b/libjava/java/awt/AWTPermission.java @@ -1,6 +1,5 @@ -// AWTPermission.java - AWT permissions - -/* Copyright (C) 2000, 2002 Free Software Foundation +/* AWTPermission.java -- AWT related permissions + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,11 +36,6 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -/** - * @author Tom Tromey <tromey@redhat.com> - * @date December 2, 2000 - */ - package java.awt; import java.security.BasicPermission; @@ -49,25 +43,79 @@ import java.security.BasicPermission; /** * This class implements permissions for AWT. This is a named * permission. No actions are defined. + * + * <p>The following table provides a list of all the possible AWTPermission + * permission names with a description of what that permission allows.<br> + * <table border=1> + * <tr><th>Permission Name</th><th>Permission Allows</th><th>Risks</th</tr> + * <tr> + * <td><code>accessClipboard</code></td> + * <td>posting and reading the AWT clipboard</td> + * <td>the clipboard may contain sensitive data</td></tr> + * <tr> + * <td><code>accessEventQueue</code></td> + * <td>access to the AWT event queue</td> + * <td>malicious code could remove real events and replace them with bogus + * ones, including simulating the user granting permission</td></tr> + * <tr> + * <td><code>listenToAllAWTEvents</code></td> + * <td>listen to system-wide AWT events</td> + * <td>malicious code can read passwords entered in an AWT event, and in + * combination with accessEventQueue, could fake system events</td></tr> + * <tr> + * <td><code>showWindowWithoutWarningBanner</code></td> + * <td>display a window without a banner notification of insecurity</td> + * <td>malicious code could install a Trojan horse applet that looks like + * a normal window, and thus steal data like passwords</td></tr> + * <tr> + * <td><code>readDisplayPixels</code></td> + * <td>read back pixels from the display screen</td> + * <td>malicious code could snoop on the user's actions</td></tr> + * <tr> + * <td><code>createRobot</code></td> + * <td>create an instance of java.awt.Robot</td> + * <td>these objects can generate events as though they were the user; so + * malicious code could control the system</td></tr> + * <tr> + * <td><code>fullScreenExclusive</code></td> + * <td>enter full-screen exclusive mode</td> + * <td>malicious code could masquerade as a trusted program</td><tr> + * </table> + * + * @author Tom Tromey <tromey@redhat.com> + * @since 1.2 + * @status updated to 1.4 */ public final class AWTPermission extends BasicPermission { /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 8890392402588814465L; + + /** * Construct a AWTPermission with the given name. - * @param name The permission name + * + * @param name the permission name + * @throws NullPointerException if name is null + * @throws IllegalArgumentException if name is invalid */ - public AWTPermission (String name) + public AWTPermission(String name) { - super (name); + super(name); } /** - * Construct a AWTPermission with the given name. - * @param name The permission name - * @param actions The actions; this is ignored and should be null. + * Create a new permission with the specified name. The actions argument + * is ignored, as AWT permissions have no actions. + * + * @param name the permission name + * @param actions ignored + * @throws NullPointerException if name is null + * @throws IllegalArgumentException if name is invalid */ - public AWTPermission (String name, String actions) + public AWTPermission(String name, String actions) { - super (name, actions); + super(name); } -} +} // class AWTPermission diff --git a/libjava/java/awt/ActiveEvent.java b/libjava/java/awt/ActiveEvent.java index d48a09b321b..357627dbd05 100644 --- a/libjava/java/awt/ActiveEvent.java +++ b/libjava/java/awt/ActiveEvent.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* ActiveEvent.java -- a self-dispatching event + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -38,13 +39,23 @@ exception statement from your version. */ package java.awt; /** + * An interface for events which can dispatch themselves in another thread. + * This has two uses: first, if your code is in a critical section, calling a + * synchronized method might deadlock. But by using an ActiveEvent to call + * the second section, it will not obtain the lock until you have left the + * critical section, avoiding deadlock. The second use is for calling + * untrusted code. For example, system code should use an ActiveEvent to + * invoke user code securely. + * * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * @since 1.2 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public interface ActiveEvent { - public void dispatch (); -} + /** + * Dispatch the event, according to what the event needs done. Invoked + * automatically if this is placed on the <code>EventDispatchQueue</code>. + */ + public void dispatch(); +} // interface ActiveEvent diff --git a/libjava/java/awt/Adjustable.java b/libjava/java/awt/Adjustable.java index ce7b5bb8ddb..58116e4e5b3 100644 --- a/libjava/java/awt/Adjustable.java +++ b/libjava/java/awt/Adjustable.java @@ -1,5 +1,5 @@ -/* Adjustable.java -- Objects with a numeric adjustment scale. - Copyright (C) 1999 Free Software Foundation, Inc. +/* Adjustable.java -- Objects with a numeric adjustment scale + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,183 +41,131 @@ package java.awt; import java.awt.event.AdjustmentListener; /** - * This interface is for objects that take a numeric value that - * can be adjusted within a bounded range. For example, a scroll bar. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This interface is for objects that take a numeric value that can be + * adjusted within a bounded range. For example, a scroll bar. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.0 + * @status updated to 1.4 + */ public interface Adjustable { - -/* - * Static Variables - */ - -/** - * Constant for a horizontal orientation - */ -public static final int HORIZONTAL = 0; - -/** - * Constant for a vertical orientation - */ -public static final int VERTICAL = 1; - -/*************************************************************************/ - -/* - * Instance Methods - */ - -/** - * Returns the current value of the object. - * - * @return The current value of the object. - */ -public abstract int -getValue(); - -/*************************************************************************/ - -/** - * Sets the current value of the object. - * - * @param value The current value of the object. - */ -public abstract void -setValue(int value); - -/*************************************************************************/ - -/** - * Returns the orientation of the object, either <code>HORIZONTAL</code> - * or <code>VERTICAL</code>. - * - * @return The orientation of this object. - */ -public abstract int -getOrientation(); - -/*************************************************************************/ - -/** - * Returns the minimum value this object can take. - * - * @return The minimum value this object can take. - */ -public abstract int -getMinimum(); - -/*************************************************************************/ - -/** - * Sets the minimum value this object can take to the specified value. - * - * @param minimum The new minimum value for this object. - */ -public abstract void -setMinimum(int minimum); - -/*************************************************************************/ - -/** - * Returns the maximum value this object can take. - * - * @return The maximum value this object can take. - */ -public abstract int -getMaximum(); - -/*************************************************************************/ - -/** - * Sets the maximum value this object can take to the specified value. - * - * @param maximum The new maximum value for this object. - */ -public abstract void -setMaximum(int maximum); - -/*************************************************************************/ - -/** - * Returns the increment value for incrementing by units. - * - * @return The unit increment value. - */ -public abstract int -getUnitIncrement(); - -/*************************************************************************/ - -/** - * Sets the increment value for incrementing by units to the specified value. - * - * @param increment The unit increment value. - */ -public abstract void -setUnitIncrement(int increment); - -/*************************************************************************/ - -/** - * Returns the increment value for incrementing by blocks. - * - * @return The block increment value. - */ -public abstract int -getBlockIncrement(); - -/*************************************************************************/ - -/** - * Sets the increment value for incrementing by blocks to the specified value. - * - * @param increment The block increment value. - */ -public abstract void -setBlockIncrement(int increment); - -/*************************************************************************/ - -/** - * Returns the length of the indicator for this object. - * - * @return The indicator length. - */ -public abstract int -getVisibleAmount(); - -/*************************************************************************/ - -/** - * Sets the length of the indicator for this object to the specified value. - * - * @param length The indicator length - */ -public abstract void -setVisibleAmount(int length); - -/*************************************************************************/ - -/** - * Adds a listener that will receive adjustment events for this object. - * - * @param listener The adjustment listener to add. - */ -public abstract void -addAdjustmentListener(AdjustmentListener listener); - -/*************************************************************************/ - -/** - * Removes an adjustment listener from this object. It will no longer - * receive adjustment events. - * - * @param listener The adjustment listener to remove. - */ -public abstract void -removeAdjustmentListener(AdjustmentListener listener); - + /** Constant for an adjustable object with horizontal orientation. */ + int HORIZONTAL = 0; + + /** Constant for an adjustable object with vertical orientation. */ + int VERTICAL = 1; + + /** Constant for an adjustable object with no orientation. */ + int NO_ORIENTATION = 2; + + /** + * Returns a constant representing the orientation of the object. + * + * @return the orientation of this object + * @see #HORIZONTAL + * @see #VERTICAL + * @see #NO_ORIENTATION + */ + int getOrientation(); + + /** + * Sets the minimum value this object can have. + * + * @param minimum the new minimum value + */ + void setMinimum(int minimum); + + /** + * Returns the minimum value this object can have. + * + * @return the minimum value + */ + int getMinimum(); + + /** + * Sets the maximum value this object can have. + * + * @param maximum the new maximum value + */ + void setMaximum(int maximum); + + /** + * Returns the maximum value this object can have. + * + * @return the maximum value + */ + int getMaximum(); + + /** + * Sets the increment value for incrementing the value by units. + * + * @param increment the unit increment value + */ + void setUnitIncrement(int increment); + + /** + * Returns the increment value for incrementing the value by units. + * + * @return the unit increment value + */ + int getUnitIncrement(); + + /** + * Sets the increment value for incrementing the value by blocks. + * + * @param increment the block increment value + */ + void setBlockIncrement(int increment); + + /** + * Returns the increment value for incrementing the value by blocks. + * + * @return the block increment value + */ + int getBlockIncrement(); + + /** + * Sets the length of the indicator for this object to the specified value. + * + * @param length the indicator length + */ + void setVisibleAmount(int length); + + /** + * Returns the length of the indicator for this object. + * + * @return the indicator length + */ + int getVisibleAmount(); + + /** + * Sets the current value of the object. + * + * @param value the new value + */ + void setValue(int value); + + /** + * Returns the current value of the object. + * + * @return the current value + */ + int getValue(); + + /** + * Adds a listener that will receive adjustment events for this object. + * + * @param listener the adjustment listener to add + * @see AdjustmentEvent + */ + void addAdjustmentListener(AdjustmentListener listener); + + /** + * Removes an adjustment listener from this object. + * + * @param listener the adjustment listener to remove + * @see AdjustmentEvent + */ + void removeAdjustmentListener(AdjustmentListener listener); } // interface Adjustable - diff --git a/libjava/java/awt/AlphaComposite.java b/libjava/java/awt/AlphaComposite.java new file mode 100644 index 00000000000..14649fc74a3 --- /dev/null +++ b/libjava/java/awt/AlphaComposite.java @@ -0,0 +1,143 @@ +/* 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; +import java.util.Map; + +/** + * + * @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(Map.Entry eldest) + { // XXX - FIXME Use Map.Entry, not just Entry as gcj 3.1 workaround. + 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/libjava/java/awt/AttributeValue.java b/libjava/java/awt/AttributeValue.java new file mode 100644 index 00000000000..f692c012f9f --- /dev/null +++ b/libjava/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/libjava/java/awt/BasicStroke.java b/libjava/java/awt/BasicStroke.java new file mode 100644 index 00000000000..c3290336cd9 --- /dev/null +++ b/libjava/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/libjava/java/awt/BorderLayout.java b/libjava/java/awt/BorderLayout.java index 32e200aadb0..d1bbd1f235a 100644 --- a/libjava/java/awt/BorderLayout.java +++ b/libjava/java/awt/BorderLayout.java @@ -77,27 +77,107 @@ public static final String WEST = "West"; */ public static final String CENTER = "Center"; -/** - * Constant indicating the position just after the last line of the - * layout. - */ -public static final String AFTER_LAST_LINE = "Last"; -/** - * Constant indicating the position just after the end of the line. - */ -public static final String AFTER_LINE_ENDS = "After"; + /** + * The constant indicating the position before the first line of the + * layout. The exact position depends on the writing system: For a + * top-to-bottom orientation, it is the same as {@link #NORTH}, for + * a bottom-to-top orientation, it is the same as {@link #SOUTH}. + * + * <p>This constant is an older name for {@link #PAGE_START} which + * has exactly the same value. + * + * @since 1.2 + */ + public static final String BEFORE_FIRST_LINE = "First"; + + + /** + * The constant indicating the position after the last line of the + * layout. The exact position depends on the writing system: For a + * top-to-bottom orientation, it is the same as {@link #SOUTH}, for + * a bottom-to-top orientation, it is the same as {@link #NORTH}. + * + * <p>This constant is an older name for {@link #PAGE_END} which + * has exactly the same value. + * + * @since 1.2 + */ + public static final String AFTER_LAST_LINE = "Last"; + + + /** + * The constant indicating the position before the first item of the + * layout. The exact position depends on the writing system: For a + * left-to-right orientation, it is the same as {@link #WEST}, for + * a right-to-left orientation, it is the same as {@link #EAST}. + * + * <p>This constant is an older name for {@link #LINE_START} which + * has exactly the same value. + * + * @since 1.2 + */ + public static final String BEFORE_LINE_BEGINS = "Before"; + + + /** + * The constant indicating the position after the last item of the + * layout. The exact position depends on the writing system: For a + * left-to-right orientation, it is the same as {@link #EAST}, for + * a right-to-left orientation, it is the same as {@link #WEST}. + * + * <p>This constant is an older name for {@link #LINE_END} which + * has exactly the same value. + * + * @since 1.2 + */ + public static final String AFTER_LINE_ENDS = "After"; + + + /** + * The constant indicating the position before the first line of the + * layout. The exact position depends on the writing system: For a + * top-to-bottom orientation, it is the same as {@link #NORTH}, for + * a bottom-to-top orientation, it is the same as {@link #SOUTH}. + * + * @since 1.4 + */ + public static final String PAGE_START = BEFORE_FIRST_LINE; + + + /** + * The constant indicating the position after the last line of the + * layout. The exact position depends on the writing system: For a + * top-to-bottom orientation, it is the same as {@link #SOUTH}, for + * a bottom-to-top orientation, it is the same as {@link #NORTH}. + * + * @since 1.4 + */ + public static final String PAGE_END = AFTER_LAST_LINE; + + + /** + * The constant indicating the position before the first item of the + * layout. The exact position depends on the writing system: For a + * left-to-right orientation, it is the same as {@link #WEST}, for + * a right-to-left orientation, it is the same as {@link #EAST}. + * + * @since 1.4 + */ + public static final String LINE_START = BEFORE_LINE_BEGINS; + + + /** + * The constant indicating the position after the last item of the + * layout. The exact position depends on the writing system: For a + * left-to-right orientation, it is the same as {@link #EAST}, for + * a right-to-left orientation, it is the same as {@link #WEST}. + * + * @since 1.4 + */ + public static final String LINE_END = AFTER_LINE_ENDS; -/** - * Constant indicating the position just before the first line of the - * layout. - */ -public static final String BEFORE_FIRST_LINE = "First"; -/** - * Constant indicating the position at the beginning of the line. - */ -public static final String BEFORE_LINE_BEGINS = "Before"; // Serialization constant private static final long serialVersionUID = -8658291919501921765L; diff --git a/libjava/java/awt/BufferCapabilities.java b/libjava/java/awt/BufferCapabilities.java new file mode 100644 index 00000000000..389594b76b5 --- /dev/null +++ b/libjava/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/libjava/java/awt/Button.java b/libjava/java/awt/Button.java index 139890f7315..ed954ddcfda 100644 --- a/libjava/java/awt/Button.java +++ b/libjava/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/libjava/java/awt/Choice.java b/libjava/java/awt/Choice.java index e90346cc30a..ab04c21cda5 100644 --- a/libjava/java/awt/Choice.java +++ b/libjava/java/awt/Choice.java @@ -234,7 +234,7 @@ remove(String item) * * @param index The index of the item to remove. * - * @exception ArrayIndexOutOfBoundException If the index is not valid. + * @exception ArrayIndexOutOfBoundsException If the index is not valid. */ public synchronized void remove(int index) diff --git a/libjava/java/awt/Color.java b/libjava/java/awt/Color.java index 3a33769a532..761b738e448 100644 --- a/libjava/java/awt/Color.java +++ b/libjava/java/awt/Color.java @@ -1,4 +1,4 @@ -/* Color.java -- Class representing a color in Java +/* Color.java -- represents a color in Java Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,496 +38,966 @@ exception statement from your version. */ package java.awt; -/** - * This class represents a color value in the AWT system. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public class Color implements java.io.Serializable -{ - -/* - * Static Variables - */ - -/** - * Constant for the color white - */ -public static final Color white = new Color(255,255,255,255); - -/** - * Constant for the color light gray - */ -public static final Color lightGray = new Color(192,192,192,255); - -/** - * Constant for the color gray - */ -public static final Color gray = new Color(128,128,128,255); - -/** - * Constant for the color dark gray - */ -public static final Color darkGray = new Color(64,64,64,255); - -/** - * Constant for the color black - */ -public static final Color black = new Color(0,0,0,255); - -/** - * Constant for the color red - */ -public static final Color red = new Color(255,0,0,255); - -/** - * Constant for the color pink - */ -public static final Color pink = new Color(255, 175, 175,255); - -/** - * Constant for the color orange - */ -public static final Color orange = new Color(255, 200, 0,255); - -/** - * Constant for the color yellow - */ -public static final Color yellow = new Color(255,255,0,255); - -/** - * Constant for the color green - */ -public static final Color green = new Color(0,255,0,255); - -/** - * Constant for the color magenta - */ -public static final Color magenta = new Color(255,0,255,255); - -/** - * Constant for the color cyan - */ -public static final Color cyan = new Color(0,255,255,255); - -/** - * Constant for the color blue - */ -public static final Color blue = new Color(0,0,255,255); - -// Serialization Constant -private static final long serialVersionUID = 118526816881161077L; - -// Masks for individual color components -private static final int redmask = 255 << 16; -private static final int greenmask = 255 << 8; -private static final int bluemask = 255; -private static final int alphamask = 255 << 24; - -private static final int BRIGHT_STEP = 0x30; - -/*************************************************************************/ - -/* - * Instance Variables - */ - -/** - * @serial The RGB value of the color. - */ -private int value = 0xFFFFFFFF; - -/*************************************************************************/ - -/* - * Static Methods - */ - -/** - * Converts the specified string to a number and creates a new instance - * of <code>Color</code> from the value. - * - * @param str The numeric color string. - * - * @return A new instance of <code>Color</code> for the string. - * - * @exception NumberFormatException If the string cannot be parsed. - */ -public static Color -decode(String str) throws NumberFormatException -{ - Integer i = Integer.decode(str); - return(new Color(i.intValue())); -} - -/*************************************************************************/ - -/** - * Returns a new instance of <code>Color</code> from the value of - * the system property named by the specified string. If the property - * does not exist, or cannot be parsed, then <code>null</code> will be - * returned. - * - * @param prop The system property to retrieve. - */ -public static Color -getColor(String prop) -{ - return(getColor(prop, null)); -} - -/*************************************************************************/ - -/** - * Returns a new instance of <code>Color</code> from the value of the - * system property named by the specified string. If the property does - * not exist, or cannot be parsed, then the default RGB value will be - * used to create a return value. - * - * @param prop The system property to retrieve. - * @param defrgb The default RGB value. - */ -public static Color -getColor(String prop, int defrgb) -{ - return(getColor(prop, new Color(defrgb))); -} - -/*************************************************************************/ - -/** - * Returns a new instance of <code>Color</code> from the value of the - * system property named by the specified string. If the property does - * not exist, or cannot be parsed, then the default color value will be - * returned - * - * @param prop The system property to retrieve. - * @param defcolor The default color - */ -public static Color -getColor(String prop, Color defcolor) -{ - String val = System.getProperty(prop); - if (val == null) - return(defcolor); - - try - { - return(decode(val)); - } - catch(NumberFormatException e) - { - return(defcolor); - } -} - -/*************************************************************************/ - -/** - * Converts from the HSB (hue, saturation, brightness) color model to - * the RGB (red, green, blue) color model. - * - * @param hue The hue of the HSB value. - * @param saturation The saturation of the HSB value. - * @param brightness The brightness of the HSB value. - * - * @return The RGB value. - */ -public static int -HSBtoRGB(float hue, float saturation, float brightness) -{ - // FIXME: Implement - throw new RuntimeException("Not implemented yet"); -} - -/*************************************************************************/ - -/** - * Converts from the RGB (red, green, blue) color model to the HSB - * (hue, saturation, brightness) color model. - * - * @param red The red part of the RGB value. - * @param green The green part of the RGB value. - * @param blue The blue part of the RGB value. - * @param hsbvals An array of three floats used for storing the HSB values, - * or <code>null</code> if this return mechanism is not used. - * - * @return The HSB value. - */ -public static float[] -RGBtoHSB(int red, int green, int blue, float hsbvals[]) -{ - // FIXME: Implement - throw new RuntimeException("Not implemented yet"); -} - -/*************************************************************************/ - -/** - * Returns a new instance of <code>Color</code> based on the specified - * HSB values. - * - * @param hue The hue of the HSB value. - * @param saturation The saturation of the HSB value. - * @param brightness The brightness of the HSB value. - * - * @return The new <code>Color</code> object. - */ -public static Color -getHSBColor(float hue, float saturation, float brightness) -{ - return(new Color(HSBtoRGB(hue, saturation, brightness))); -} - -/*************************************************************************/ - -/* - * Constructors - */ - -/** - * Initializes a new instance of <code>Color</code> using the specified - * red, green, and blue values, which must be given as integers in the - * range of 0-255. - * - * @param red The red component of the RGB value. - * @param green The green component of the RGB value. - * @param blue The blue component of the RGB value. - * - * @exception IllegalArgumentException If the values are out of range. - */ -public -Color(int red, int green, int blue) -{ - if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || - (blue < 0) || (blue > 255)) - throw new IllegalArgumentException("Bad RGB values"); - - value = blue + (green << 8) + (red << 16); -} - -public -Color(int red, int green, int blue, int alpha) -{ - if ((red < 0) || (red > 255) || (green < 0) || (green > 255) || - (blue < 0) || (blue > 255)) - throw new IllegalArgumentException("Bad RGB values"); - - value = blue + (green << 8) + (red << 16) + (alpha << 24); -} - -/*************************************************************************/ - -/** - * Initializes a new instance of <code>Color</code> using the specified - * RGB value. The blue value is in bits 0-7, green in bits 8-15, and - * red in bits 16-23. The other bits are ignored. - * - * @param value The RGB value - */ -public -Color(int value) -{ - this.value = value; -} - -public -Color(int value, boolean hasalpha) -{ - this.value = value; - if (! hasalpha) - this.value |= 0xFF000000; -} - -/*************************************************************************/ - -/** - * Initializes a new instance of <code>Color</code> using the specified - * RGB values. These must be in the range of 0.0-1.0. - * - * @param red The red component of the RGB value. - * @param green The green component of the RGB value. - * @param blue The blue component of the RGB value. - * - * @exception IllegalArgumentException If the values are out of range. - */ -public -Color(float red, float green, float blue) -{ - if ((red < 0.0) || (red > 1.0) || (green < 0.0) || (green > 1.0) || - (blue < 0.0) || (blue > 1.0)) - throw new IllegalArgumentException("Bad RGB values"); - - int redval = (int)(255 * red); - int greenval = (int)(255 * green); - int blueval = (int)(255 * blue); - - value = blueval + (greenval << 8) + (redval << 16); -} - -/*************************************************************************/ - -/* - * Instance Methods +import java.awt.color.ColorSpace; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.ColorModel; +import java.io.Serializable; + +/** + * This class represents a color value in the AWT system. It uses the sRGB + * (standard Red-Green-Blue) system, along with an alpha value ranging from + * transparent (0.0f or 0) and opaque (1.0f or 255). The color is not + * pre-multiplied by the alpha value an any of the accessor methods. Further + * information about sRGB can be found at + * <a href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html"> + * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html</a>. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ColorSpace + * @see AlphaComposite + * @since 1.0 + * @status updated to 1.4 */ - -/** - * Returns the red value for this color. - * - * @return The red value for this color. - */ -public int -getRed() -{ - int redval = (value & redmask) >> 16; - - return(redval); -} - -/*************************************************************************/ - -/** - * Returns the green value for this color. - * - * @return The green value for this color. - */ -public int -getGreen() -{ - int greenval = (value & greenmask) >> 8; - - return(greenval); -} - -/*************************************************************************/ - -/** - * Returns the blue value for this color. - * - * @return The blue value for this color. - */ -public int -getBlue() -{ - int blueval = (value & bluemask); - - return(blueval); -} - -public int -getAlpha() -{ - int alphaval = (value & alphamask); - - return(alphaval); -} - -public int -getTransparency() -{ - if (getAlpha() == 0xFF) - return Transparency.OPAQUE; - else - return Transparency.TRANSLUCENT; -} - -/*************************************************************************/ - -/** - * Returns the RGB value for this color. The blue value will be in bits - * 0-7, green in 8-15, and red in 6-23. The upper bits should be ignored. - * - * @return The RGB value for this color. - */ -public int -getRGB() -{ - return(value); -} - -/*************************************************************************/ - -/** - * Returns a brighter version of this color. This is done by increasing - * the RGB values by an arbitrary scale factor. Note that this method - * and the <code>darker()</code> method are not necessarily inverses. - * - * @return A brighter version of this color. - */ -public Color -brighter() -{ - return new Color(Math.min(255, getRed() + BRIGHT_STEP), - Math.min(255, getGreen() + BRIGHT_STEP), - Math.min(255, getBlue() + BRIGHT_STEP), - getAlpha()); -} - -/*************************************************************************/ - -/** - * Returns a darker version of this color. This is done by decreasing - * the RGB values by an arbitrary scale factor. Note that this method - * and the <code>brighter()</code> method are not necessarily inverses. - * - * @return A darker version of this color. - */ -public Color -darker() +public class Color implements Paint, Serializable { - return new Color(Math.max(0, getRed() - BRIGHT_STEP), - Math.max(0, getGreen() - BRIGHT_STEP), - Math.max(0, getBlue() - BRIGHT_STEP), - getAlpha()); -} - -/*************************************************************************/ - -/** - * Returns a hash value for this color. - * - * @return A hash value for this color. - */ -public int -hashCode() -{ - return(value); -} - -/*************************************************************************/ - -/** - * Tests this object for equality against the specified object. This will - * be true if and only if the specified object is an instance of - * <code>Color</code> and has the same red, green, and blue values as - * this object. - * - * @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 Color)) - return(false); - - Color c = (Color)obj; - return value == c.value; -} - -/*************************************************************************/ - -/** - * Returns a string representation of this object. - * - * @return A string representation of this object. - */ -public String -toString() -{ - return(getClass().getName() + "(red=" + getRed() + ",green=" + getGreen() + - ",blue=" + getBlue() + ")"); -} - + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = 118526816881161077L; + + /** Constant for the color white: R=255, G=255, B=255. */ + public static final Color white = new Color(0xffffff, false); + + /** + * Constant for the color white: R=255, G=255, B=255. + * + * @since 1.4 + */ + public static final Color WHITE = white; + + /** Constant for the color light gray: R=192, G=192, B=192. */ + public static final Color lightGray = new Color(0xc0c0c0, false); + + /** + * Constant for the color light gray: R=192, G=192, B=192. + * + * @since 1.4 + */ + public static final Color LIGHT_GRAY = lightGray; + + /** Constant for the color gray: R=128, G=128, B=128. */ + public static final Color gray = new Color(0x808080, false); + + /** + * Constant for the color gray: R=128, G=128, B=128. + * + * @since 1.4 + */ + public static final Color GRAY = gray; + + /** Constant for the color dark gray: R=64, G=64, B=64. */ + public static final Color darkGray = new Color(0x404040, false); + + /** + * Constant for the color dark gray: R=64, G=64, B=64. + * + * @since 1.4 + */ + public static final Color DARK_GRAY = darkGray; + + /** Constant for the color black: R=0, G=0, B=0. */ + public static final Color black = new Color(0x000000, false); + + /** + * Constant for the color black: R=0, G=0, B=0. + * + * @since 1.4 + */ + public static final Color BLACK = black; + + /** Constant for the color red: R=255, G=0, B=0. */ + public static final Color red = new Color(0xff0000, false); + + /** + * Constant for the color red: R=255, G=0, B=0. + * + * @since 1.4 + */ + public static final Color RED = red; + + /** Constant for the color pink: R=255, G=175, B=175. */ + public static final Color pink = new Color(0xffafaf, false); + + /** + * Constant for the color pink: R=255, G=175, B=175. + * + * @since 1.4 + */ + public static final Color PINK = pink; + + /** Constant for the color orange: R=255, G=200, B=0. */ + public static final Color orange = new Color(0xffc800, false); + + /** + * Constant for the color orange: R=255, G=200, B=0. + * + * @since 1.4 + */ + public static final Color ORANGE = orange; + + /** Constant for the color yellow: R=255, G=255, B=0. */ + public static final Color yellow = new Color(0xffff00, false); + + /** + * Constant for the color yellow: R=255, G=255, B=0. + * + * @since 1.4 + */ + public static final Color YELLOW = yellow; + + /** Constant for the color green: R=0, G=255, B=0. */ + public static final Color green = new Color(0x00ff00, false); + + /** + * Constant for the color green: R=0, G=255, B=0. + * + * @since 1.4 + */ + public static final Color GREEN = green; + + /** Constant for the color magenta: R=255, G=0, B=255. */ + public static final Color magenta = new Color(0xff00ff, false); + + /** + * Constant for the color magenta: R=255, G=0, B=255. + * + * @since 1.4 + */ + public static final Color MAGENTA = magenta; + + /** Constant for the color cyan: R=0, G=255, B=255. */ + public static final Color cyan = new Color(0x00ffff, false); + + /** + * Constant for the color cyan: R=0, G=255, B=255. + * + * @since 1.4 + */ + public static final Color CYAN = cyan; + + /** Constant for the color blue: R=0, G=0, B=255. */ + public static final Color blue = new Color(0x0000ff, false); + + /** + * Constant for the color blue: R=0, G=0, B=255. + * + * @since 1.4 + */ + public static final Color BLUE = blue; + + /** Internal mask for red. */ + private static final int RED_MASK = 255 << 16; + + /** Internal mask for green. */ + private static final int GREEN_MASK = 255 << 8; + + /** Internal mask for blue. */ + private static final int BLUE_MASK = 255; + + /** Internal mask for alpha. Package visible for use in subclass. */ + static final int ALPHA_MASK = 255 << 24; + + /** Amount to scale a color by when brightening or darkening. */ + private static final float BRIGHT_SCALE = 0.7f; + + /** + * The color value, in sRGB. Note that the actual color may be more + * precise if frgbvalue or fvalue is non-null. This class stores alpha, red, + * green, and blue, each 0-255, packed in an int. However, the subclass + * SystemColor stores an index into an array. Therefore, for serial + * compatibility (and because of poor design on Sun's part), this value + * cannot be used directly; instead you must use <code>getRGB()</code>. + * + * @see #getRGB() + * @serial the value of the color, whether an RGB literal or array index + */ + final int value; + + /** + * The color value, in sRGB. This may be null if the color was constructed + * with ints; and it does not include alpha. This stores red, green, and + * blue, in the range 0.0f - 1.0f. + * + * @see #getRGBColorComponents(float[]) + * @see #getRGBComponents(float[]) + * @serial the rgb components of the value + * @since 1.2 + */ + private float[] frgbvalue; + + /** + * The color value, in the native ColorSpace components. This may be null + * if the color was constructed with ints or in the sRGB color space; and + * it does not include alpha. + * + * @see #getRGBColorComponents(float[]) + * @see #getRGBComponents(float[]) + * @serial the original color space components of the color + * @since 1.2 + */ + private float[] fvalue; + + /** + * The alpha value. This is in the range 0.0f - 1.0f, but is invalid if + * deserialized as 0.0 when frgbvalue is null. + * + * @see #getRGBComponents(float[]) + * @see #getComponents(float[]) + * @serial the alpha component of this color + * @since 1.2 + */ + private final float falpha; + + /** + * The ColorSpace. Null means the default sRGB space. + * + * @see #getColor(String) + * @see #getColorSpace() + * @see #getColorComponents(float[]) + * @serial the color space for this color + * @since 1.2 + */ + private final ColorSpace cs; + + /** + * The paint context for this solid color. Package visible for use in + * subclass. + */ + transient ColorPaintContext context; + + /** + * Initializes a new instance of <code>Color</code> using the specified + * red, green, and blue values, which must be given as integers in the + * range of 0-255. Alpha will default to 255 (opaque). When drawing to + * screen, the actual color may be adjusted to the best match of hardware + * capabilities. + * + * @param red the red component of the RGB value + * @param green the green component of the RGB value + * @param blue the blue component of the RGB value + * @throws IllegalArgumentException if the values are out of range 0-255 + * @see #getRed() + * @see #getGreen() + * @see #getBlue() + * @see #getRGB() + * @see #Color(int, int, int, int) + */ + public Color(int red, int green, int blue) + { + this(red, green, blue, 255); + } + + /** + * Initializes a new instance of <code>Color</code> using the specified + * red, green, blue, and alpha values, which must be given as integers in + * the range of 0-255. When drawing to screen, the actual color may be + * adjusted to the best match of hardware capabilities. + * + * @param red the red component of the RGB value + * @param green the green component of the RGB value + * @param blue the blue component of the RGB value + * @param alpha the alpha value of the color + * @throws IllegalArgumentException if the values are out of range 0-255 + * @see #getRed() + * @see #getGreen() + * @see #getBlue() + * @see #getAlpha() + * @see #getRGB() + */ + public Color(int red, int green, int blue, int alpha) + { + if ((red & 255) != red || (green & 255) != green || (blue & 255) != blue + || (alpha & 255) != alpha) + throw new IllegalArgumentException("Bad RGB values"); + value = (alpha << 24) | (red << 16) | (green << 8) | blue; + falpha = 1; + cs = null; + } + + /** + * Initializes a new instance of <code>Color</code> using the specified + * RGB value. The blue value is in bits 0-7, green in bits 8-15, and + * red in bits 16-23. The other bits are ignored. The alpha value is set + * to 255 (opaque). When drawing to screen, the actual color may be + * adjusted to the best match of hardware capabilities. + * + * @param value the RGB value + * @see ColorModel#getRGBdefault() + * @see #getRed() + * @see #getGreen() + * @see #getBlue() + * @see #getRGB() + * @see #Color(int, boolean) + */ + public Color(int value) + { + this(value, false); + } + + /** + * Initializes a new instance of <code>Color</code> using the specified + * RGB value. The blue value is in bits 0-7, green in bits 8-15, and + * red in bits 16-23. The alpha value is in bits 24-31, unless hasalpha + * is false, in which case alpha is set to 255. When drawing to screen, the + * actual color may be adjusted to the best match of hardware capabilities. + * + * @param value the RGB value + * @param hasalpha true if value includes the alpha + * @see ColorModel#getRGBdefault() + * @see #getRed() + * @see #getGreen() + * @see #getBlue() + * @see #getAlpha() + * @see #getRGB() + */ + public Color(int value, boolean hasalpha) + { + // Note: SystemColor calls this constructor, setting falpha to 0; but + // code in getRGBComponents correctly reports falpha as 1.0 to the user + // for all instances of SystemColor since frgbvalue is left null here. + if (hasalpha) + falpha = ((value & ALPHA_MASK) >> 24) / 255f; + else + { + value |= ALPHA_MASK; + falpha = 1; + } + this.value = value; + cs = null; + } + + /** + * Initializes a new instance of <code>Color</code> using the specified + * RGB values. These must be in the range of 0.0-1.0. Alpha is assigned + * the value of 1.0 (opaque). When drawing to screen, the actual color may + * be adjusted to the best match of hardware capabilities. + * + * @param red the red component of the RGB value + * @param green the green component of the RGB value + * @param blue the blue component of the RGB value + * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f + * @see #getRed() + * @see #getGreen() + * @see #getBlue() + * @see #getRGB() + * @see #Color(float, float, float, float) + */ + public Color(float red, float green, float blue) + { + this(red, green, blue, 1.0f); + } + + /** + * Initializes a new instance of <code>Color</code> using the specified + * RGB and alpha values. These must be in the range of 0.0-1.0. When drawing + * to screen, the actual color may be adjusted to the best match of + * hardware capabilities. + * + * @param red the red component of the RGB value + * @param green the green component of the RGB value + * @param blue the blue component of the RGB value + * @param alpha the alpha value of the color + * @throws IllegalArgumentException tf the values are out of range 0.0f-1.0f + * @see #getRed() + * @see #getGreen() + * @see #getBlue() + * @see #getAlpha() + * @see #getRGB() + */ + public Color(float red, float green, float blue, float alpha) + { + value = convert(red, green, blue, alpha); + frgbvalue = new float[] {red, green, blue}; + falpha = alpha; + cs = null; + } + + /** + * Creates a color in the given ColorSpace with the specified alpha. The + * array must be non-null and have enough elements for the color space + * (for example, RGB requires 3 elements, CMYK requires 4). When drawing + * to screen, the actual color may be adjusted to the best match of + * hardware capabilities. + * + * @param space the color space of components + * @param components the color components, except alpha + * @param alpha the alpha value of the color + * @throws NullPointerException if cpsace or components is null + * @throws ArrayIndexOutOfBoundsException if components is too small + * @throws IllegalArgumentException if alpha or any component is out of range + * @see #getComponents(float[]) + * @see #getColorComponents(float[]) + */ + public Color(ColorSpace space, float[] components, float alpha) + { + frgbvalue = space.toRGB(components); + fvalue = components; + falpha = alpha; + cs = space; + value = convert(frgbvalue[0], frgbvalue[1], frgbvalue[2], alpha); + } + + /** + * Returns the red value for this color, as an integer in the range 0-255 + * in the sRGB color space. + * + * @return the red value for this color + * @see #getRGB() + */ + public int getRed() + { + // Do not inline getRGB() to value, because of SystemColor. + return (getRGB() & RED_MASK) >> 16; + } + + /** + * Returns the green value for this color, as an integer in the range 0-255 + * in the sRGB color space. + * + * @return the green value for this color + * @see #getRGB() + */ + public int getGreen() + { + // Do not inline getRGB() to value, because of SystemColor. + return (getRGB() & GREEN_MASK) >> 8; + } + + /** + * Returns the blue value for this color, as an integer in the range 0-255 + * in the sRGB color space. + * + * @return the blue value for this color + * @see #getRGB() + */ + public int getBlue() + { + // Do not inline getRGB() to value, because of SystemColor. + return getRGB() & BLUE_MASK; + } + + /** + * Returns the alpha value for this color, as an integer in the range 0-255. + * + * @return the alpha value for this color + * @see #getRGB() + */ + public int getAlpha() + { + // Do not inline getRGB() to value, because of SystemColor. + return (getRGB() & ALPHA_MASK) >> 24; + } + + /** + * Returns the RGB value for this color, in the sRGB color space. The blue + * value will be in bits 0-7, green in 8-15, red in 6-23, and alpha value in + * 24-31. + * + * @return the RGB value for this color + * @see ColorModel#getRGBdefault() + * @see #getRed() + * @see #getGreen() + * @see #getBlue() + * @see #getAlpha() + */ + public int getRGB() + { + return value; + } + + /** + * Returns a brighter version of this color. This is done by increasing the + * RGB values by an arbitrary scale factor. The new color is opaque (an + * alpha of 255). Note that this method and the <code>darker()</code> + * method are not necessarily inverses. + * + * @return a brighter version of this color + * @see #darker() + */ + public Color brighter() + { + // Do not inline getRGB() to this.value, because of SystemColor. + int value = getRGB(); + int red = (value & RED_MASK) >> 16; + int green = (value & GREEN_MASK) >> 8; + int blue = value & BLUE_MASK; + // We have to special case 0-2 because they won't scale by division. + red = red < 3 ? 3 : (int) Math.min(255, red / BRIGHT_SCALE); + green = green < 3 ? 3 : (int) Math.min(255, green / BRIGHT_SCALE); + blue = blue < 3 ? 3 : (int) Math.min(255, blue / BRIGHT_SCALE); + return new Color(red, green, blue, 255); + } + + /** + * Returns a darker version of this color. This is done by decreasing the + * RGB values by an arbitrary scale factor. The new color is opaque (an + * alpha of 255). Note that this method and the <code>brighter()</code> + * method are not necessarily inverses. + * + * @return a darker version of this color + * @see #brighter() + */ + public Color darker() + { + // Do not inline getRGB() to this.value, because of SystemColor. + int value = getRGB(); + return new Color((int) (((value & RED_MASK) >> 16) * BRIGHT_SCALE), + (int) (((value & GREEN_MASK) >> 8) * BRIGHT_SCALE), + (int) ((value & BLUE_MASK) * BRIGHT_SCALE), 255); + } + + /** + * Returns a hash value for this color. This is simply the color in 8-bit + * precision, in the format 0xAARRGGBB (alpha, red, green, blue). + * + * @return a hash value for this color + */ + public int hashCode() + { + return value; + } + + /** + * Tests this object for equality against the specified object. This will + * be true if and only if the specified object is an instance of + * <code>Color</code> and has the same 8-bit integer red, green, and blue + * values as this object. Note that two colors may be slightly different + * as float values, but round to the same integer values. Also note that + * this does not accurately compare SystemColors, since that class does + * not store its internal data in RGB format like regular colors. + * + * @param obj the object to compare to + * @return true if the specified object is semantically equal to this one + */ + public boolean equals(Object obj) + { + return obj instanceof Color && ((Color) obj).value == value; + } + + /** + * Returns a string representation of this object. Subclasses may return + * any desired format, except for null, but this implementation returns + * <code>getClass().getName() + "[r=" + getRed() + ",g=" + getGreen() + * + ",b=" + getBlue() + ']'</code>. + * + * @return a string representation of this object + */ + public String toString() + { + return getClass().getName() + "[r=" + ((value & RED_MASK) >> 16) + + ",g=" + ((value & GREEN_MASK) >> 8) + ",b=" + (value & BLUE_MASK) + + ']'; + } + + /** + * Converts the specified string to a number, using Integer.decode, and + * creates a new instance of <code>Color</code> from the value. The alpha + * value will be 255 (opaque). + * + * @param str the numeric color string + * @return a new instance of <code>Color</code> for the string + * @throws NumberFormatException if the string cannot be parsed + * @throws NullPointerException if the string is null + * @see Integer#decode(String) + * @see #Color(int) + * @since 1.1 + */ + public static Color decode(String str) + { + return new Color(Integer.decode(str).intValue(), false); + } + + /** + * Returns a new instance of <code>Color</code> from the value of the + * system property named by the specified string. If the property does not + * exist, or cannot be parsed, then <code>null</code> will be returned. + * + * @param prop the system property to retrieve + * @throws SecurityException if getting the property is denied + * @see #getColor(String, Color) + * @see Integer#getInteger(String) + */ + public static Color getColor(String prop) + { + return getColor(prop, null); + } + + /** + * Returns a new instance of <code>Color</code> from the value of the + * system property named by the specified string. If the property does + * not exist, or cannot be parsed, then the default color value will be + * returned. + * + * @param prop the system property to retrieve + * @param defcolor the default color + * @throws SecurityException if getting the property is denied + * @see Integer#getInteger(String) + */ + public static Color getColor(String prop, Color defcolor) + { + Integer val = Integer.getInteger(prop, null); + return val == null ? defcolor + : new Color(val.intValue(), false); + } + + /** + * Returns a new instance of <code>Color</code> from the value of the + * system property named by the specified string. If the property does + * not exist, or cannot be parsed, then the default RGB value will be + * used to create a return value. + * + * @param prop the system property to retrieve + * @param defrgb the default RGB value + * @throws SecurityException if getting the property is denied + * @see #getColor(String, Color) + * @see Integer#getInteger(String, int) + */ + public static Color getColor(String prop, int defrgb) + { + Color c = getColor(prop, null); + return c == null ? new Color(defrgb, false) : c; + } + + /** + * Converts from the HSB (hue, saturation, brightness) color model to the + * RGB (red, green, blue) color model. The hue may be any floating point; + * it's fractional portion is used to select the angle in the HSB model. + * The saturation and brightness must be between 0 and 1. The result is + * suitable for creating an RGB color with the one-argument constructor. + * + * @param hue the hue of the HSB value + * @param saturation the saturation of the HSB value + * @param brightness the brightness of the HSB value + * @return the RGB value + * @see #getRGB() + * @see #Color(int) + * @see ColorModel#getRGBdefault() + */ + public static int HSBtoRGB(float hue, float saturation, float brightness) + { + if (saturation == 0) + return convert(brightness, brightness, brightness, 0); + if (saturation < 0 || saturation > 1 || brightness < 0 || brightness > 1) + throw new IllegalArgumentException(); + hue = hue - (float) Math.floor(hue); + int i = (int) (6 * hue); + float f = 6 * hue - i; + float p = brightness * (1 - saturation); + float q = brightness * (1 - saturation * f); + float t = brightness * (1 - saturation * (1 - f)); + switch (i) + { + case 0: + return convert(brightness, t, p, 0); + case 1: + return convert(q, brightness, p, 0); + case 2: + return convert(p, brightness, t, 0); + case 3: + return convert(p, q, brightness, 0); + case 4: + return convert(t, p, brightness, 0); + case 5: + return convert(brightness, p, q, 0); + default: + throw new InternalError("impossible"); + } + } + + /** + * Converts from the RGB (red, green, blue) color model to the HSB (hue, + * saturation, brightness) color model. If the array is null, a new one + * is created, otherwise it is recycled. The results will be in the range + * 0.0-1.0 if the inputs are in the range 0-255. + * + * @param red the red part of the RGB value + * @param green the green part of the RGB value + * @param blue the blue part of the RGB value + * @param array an array for the result (at least 3 elements), or null + * @return the array containing HSB value + * @throws ArrayIndexOutOfBoundsException of array is too small + * @see #getRGB() + * @see #Color(int) + * @see ColorModel#getRGBdefault() + */ + public static float[] RGBtoHSB(int red, int green, int blue, float array[]) + { + if (array == null) + array = new float[3]; + // Calculate brightness. + int min; + int max; + if (red < green) + { + min = red; + max = green; + } + else + { + min = green; + max = red; + } + if (blue > max) + max = blue; + else if (blue < min) + min = blue; + array[2] = max / 255f; + // Calculate saturation. + if (max == 0) + array[1] = 0; + else + array[1] = (max - min) / max; + // Calculate hue. + if (array[1] == 0) + array[0] = 0; + else + { + float delta = (max - min) * 6; + if (red == max) + array[0] = (green - blue) / delta; + else if (green == max) + array[0] = 1 / 3 + (blue - red) / delta; + else + array[0] = 2 / 3 + (red - green) / delta; + if (array[0] < 0) + array[0]++; + } + return array; + } + + /** + * Returns a new instance of <code>Color</code> based on the specified + * HSB values. The hue may be any floating point; it's fractional portion + * is used to select the angle in the HSB model. The saturation and + * brightness must be between 0 and 1. + * + * @param hue the hue of the HSB value + * @param saturation the saturation of the HSB value + * @param brightness the brightness of the HSB value + * @return the new <code>Color</code> object + */ + public static Color getHSBColor(float hue, float saturation, + float brightness) + { + return new Color(HSBtoRGB(hue, saturation, brightness), false); + } + + /** + * Returns a float array with the red, green, and blue components, and the + * alpha value, in the default sRGB space, with values in the range 0.0-1.0. + * If the array is null, a new one is created, otherwise it is recycled. + * + * @param array the array to put results into (at least 4 elements), or null + * @return the RGB components and alpha value + * @throws ArrayIndexOutOfBoundsException if array is too small + */ + public float[] getRGBComponents(float[] array) + { + if (array == null) + array = new float[4]; + getRGBColorComponents(array); + // Stupid serialization issues require this check. + array[3] = (falpha == 0 && frgbvalue == null + ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha); + return array; + } + + /** + * Returns a float array with the red, green, and blue components, in the + * default sRGB space, with values in the range 0.0-1.0. If the array is + * null, a new one is created, otherwise it is recycled. + * + * @param array the array to put results into (at least 3 elements), or null + * @return the RGB components + * @throws ArrayIndexOutOfBoundsException if array is too small + */ + public float[] getRGBColorComponents(float[] array) + { + if (array == null) + array = new float[3]; + else if (array == frgbvalue) + return array; // Optimization for getColorComponents(float[]). + if (frgbvalue == null) + { + // Do not inline getRGB() to this.value, because of SystemColor. + int value = getRGB(); + frgbvalue = new float[] { ((value & RED_MASK) >> 16) / 255f, + ((value & GREEN_MASK) >> 8) / 255f, + (value & BLUE_MASK) / 255f }; + } + array[0] = frgbvalue[0]; + array[1] = frgbvalue[1]; + array[2] = frgbvalue[2]; + return array; + } + + /** + * Returns a float array containing the color and alpha components of this + * color in the ColorSpace it was created with (the constructors which do + * not take a ColorSpace parameter use a default sRGB ColorSpace). If the + * array is null, a new one is created, otherwise it is recycled, and must + * have at least one more position than components used in the color space. + * + * @param array the array to put results into, or null + * @return the original color space components and alpha value + * @throws ArrayIndexOutOfBoundsException if array is too small + */ + public float[] getComponents(float[] array) + { + int numComponents = cs == null ? 3 : cs.getNumComponents(); + if (array == null) + array = new float[1 + numComponents]; + getColorComponents(array); + // Stupid serialization issues require this check. + array[numComponents] = (falpha == 0 && frgbvalue == null + ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha); + return array; + } + + /** + * Returns a float array containing the color components of this color in + * the ColorSpace it was created with (the constructors which do not take + * a ColorSpace parameter use a default sRGB ColorSpace). If the array is + * null, a new one is created, otherwise it is recycled, and must have at + * least as many positions as used in the color space. + * + * @param array the array to put results into, or null + * @return the original color space components + * @throws ArrayIndexOutOfBoundsException if array is too small + */ + public float[] getColorComponents(float[] array) + { + int numComponents = cs == null ? 3 : cs.getNumComponents(); + if (array == null) + array = new float[numComponents]; + if (fvalue == null) // If fvalue is null, cs should be null too. + fvalue = getRGBColorComponents(frgbvalue); + System.arraycopy(fvalue, 0, array, 0, numComponents); + return array; + } + + /** + * Returns a float array containing the color and alpha components of this + * color in the given ColorSpace. If the array is null, a new one is + * created, otherwise it is recycled, and must have at least one more + * position than components used in the color space. + * + * @param space the color space to translate to + * @param array the array to put results into, or null + * @return the color space components and alpha value + * @throws ArrayIndexOutOfBoundsException if array is too small + * @throws NullPointerException if space is null + */ + public float[] getComponents(ColorSpace space, float[] array) + { + int numComponents = space.getNumComponents(); + if (array == null) + array = new float[1 + numComponents]; + getColorComponents(space, array); + // Stupid serialization issues require this check. + array[numComponents] = (falpha == 0 && frgbvalue == null + ? ((getRGB() & ALPHA_MASK) >> 24) / 255f : falpha); + return array; + } + + /** + * Returns a float array containing the color components of this color in + * the given ColorSpace. If the array is null, a new one is created, + * otherwise it is recycled, and must have at least as many positions as + * used in the color space. + * + * @param space the color space to translate to + * @return the color space components + * @throws ArrayIndexOutOfBoundsException if array is too small + * @throws NullPointerException if space is null + */ + public float[] getColorComponents(ColorSpace space, float[] array) + { + float[] components = space.fromRGB(getRGBColorComponents(frgbvalue)); + if (array == null) + return components; + System.arraycopy(components, 0, array, 0, components.length); + return array; + } + + /** + * Returns the color space of this color. Except for the constructor which + * takes a ColorSpace argument, this will be an implementation of + * ColorSpace.CS_sRGB. + * + * @return the color space + */ + public ColorSpace getColorSpace() + { + return cs == null ? ColorSpace.getInstance(ColorSpace.CS_sRGB) : cs; + } + + /** + * Returns a paint context, used for filling areas of a raster scan with + * this color. Since the color is constant across the entire rectangle, and + * since it is always in sRGB space, this implementation returns the same + * object, regardless of the parameters. Subclasses, however, may have a + * mutable result. + * + * @param cm the requested color model, ignored + * @param deviceBounds the bounding box in device coordinates, ignored + * @param userBounds the bounding box in user coordinates, ignored + * @param xform the bounds transformation, ignored + * @param hints any rendering hints, ignored + * @return a context for painting this solid color + */ + public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, + Rectangle2D userBounds, + AffineTransform xform, + RenderingHints hints) + { + if (context == null) + context = new ColorPaintContext(value); + return context; + } + + /** + * Returns the transparency level of this color. + * + * @return one of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT} + */ + public int getTransparency() + { + // Do not inline getRGB() to this.value, because of SystemColor. + int alpha = getRGB() & ALPHA_MASK; + return alpha == (255 << 24) ? OPAQUE : alpha == 0 ? BITMASK : TRANSLUCENT; + } + + /** + * Converts float values to integer value. + * + * @param red the red value + * @param green the green value + * @param blue the blue value + * @param alpha the alpha value + * @return the integer value made of 8-bit sections + * @throws IllegalArgumentException if parameters are out of range 0.0-1.0 + */ + private static int convert(float red, float green, float blue, float alpha) + { + if (red < 0 || red > 1 || green < 0 || green > 1 || blue < 0 || blue > 1 + || alpha < 0 || alpha > 1) + throw new IllegalArgumentException("Bad RGB values"); + int redval = Math.round(255 * red); + int greenval = Math.round(255 * green); + int blueval = Math.round(255 * blue); + int alphaval = Math.round(255 * alpha); + return (alphaval << 24) | (redval << 16) | (greenval << 8) | blueval; + } } // class Color - diff --git a/libjava/java/awt/ColorPaintContext.java b/libjava/java/awt/ColorPaintContext.java new file mode 100644 index 00000000000..a365812a866 --- /dev/null +++ b/libjava/java/awt/ColorPaintContext.java @@ -0,0 +1,103 @@ +/* ColorPaintContext.java -- context for painting solid colors + 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.awt.image.Raster; + +/** + * This class provides a paint context which will fill a rectanglar region of + * a raster scan with the given color. However, it is not yet completely + * implemented. + * + * @author Eric Blake <ebb9@email.byu.edu> + */ +class ColorPaintContext implements PaintContext +{ + /** + * The color to fill any raster with. Package visible for use in + * SystemColor. + */ + final int color; + + /** + * Create the context for a given color. + * + * @param c the solid color to use + */ + ColorPaintContext(int c) + { + color = c; + } + + /** + * Release the resources allocated for the paint. As the color is constant, + * there aren't any resources. + */ + public void dispose() + { + } + + /** + * Return the color model of this context. This ignores the model passed + * in the request, since colors are always in sRGB. + * + * @return the context color model + */ + public ColorModel getColorModel() + { + return ColorModel.getRGBdefault(); + } + + /** + * Return a raster containing the colors for the graphics operation. + * + * @param x the x-coordinate, in device space + * @param y the y-coordinate, in device space + * @param w the width, in device space + * @param h the height, in device space + * @return a raster for the given area and color + */ + public Raster getRaster(int x, int y, int w, int h) + { + // XXX Implement. Sun uses undocumented implementation class + // sun.awt.image.IntegerInterleavedRaster. + throw new Error("not implemented"); + } +} // class ColorPaintContext diff --git a/libjava/java/awt/Component.java b/libjava/java/awt/Component.java index 9ea43edb1f1..fd039116bb8 100644 --- a/libjava/java/awt/Component.java +++ b/libjava/java/awt/Component.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation +/* Component.java -- a graphics component + Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,122 +35,533 @@ 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.*; -import java.awt.image.*; + +import java.awt.dnd.DropTarget; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.HierarchyBoundsListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.InputMethodEvent; +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.lang.reflect.*; +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 java.awt.peer.ComponentPeer; -import java.awt.peer.LightweightPeer; -import java.beans.PropertyChangeSupport; -import java.beans.PropertyChangeListener; -// import javax.accessibility.AccessibleContext; +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. - * - * 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 present but - * commented out. - */ -public abstract class Component implements ImageObserver, MenuContainer, - java.io.Serializable + * 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()); + * } + * } + * + * <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 + * present but commented out. + * + * @author original author unknown + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.0 + * @status still missing 1.4 support + */ +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. - /* Serialized fields from the serialization spec. */ - // FIXME: Default values? + /** + * 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 java.awt.peer.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() { @@ -158,11 +570,13 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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; } @@ -170,136 +584,130 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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 java.awt.peer.ComponentPeer getPeer() + public ComponentPeer getPeer() { 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() { if (peer != null) { - Toolkit tk = peer.getToolkit(); - if (tk != null) - return tk; + Toolkit tk = peer.getToolkit(); + if (tk != null) + 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) @@ -308,10 +716,11 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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() { @@ -320,25 +729,26 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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() { @@ -346,12 +756,14 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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) { @@ -363,7 +775,7 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * Enables this component. * - * @deprecated Deprecated in favor of <code>setEnabled()</code>. + * @deprecated use {@link #setEnabled(boolean)} instead */ public void enable() { @@ -373,10 +785,8 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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) { @@ -386,206 +796,268 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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; } /** - * Returns this component's background color. + * Tests if the foreground was explicitly set, or just 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 true if the foreground has been set + * @since 1.4 + */ + public boolean isForegroundSet() + { + return foreground != null; + } + + /** + * Returns this component's background color. If not set, this is inherited + * from the parent. + * + * @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; + } + + /** + * Tests if the font was explicitly set, or just inherited from the parent. + * + * @return true if the font has been set + * @since 1.4 + */ + 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. If the - * component has no parent, the system default locale is returned. + * 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. + * @return the locale for this component + * @throws IllegalComponentStateException if it has no locale or parent + * @see setLocale(Locale) + * @since 1.1 */ - public Locale getLocale() throws IllegalComponentStateException + 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() { @@ -596,25 +1068,23 @@ public abstract class Component implements ImageObserver, MenuContainer, * 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() { @@ -622,19 +1092,20 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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) @@ -642,24 +1113,29 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * Moves this component to the specified location. 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. + * Moves this component to the specified location, relative to the parent's + * coordinates. The coordinates are the new upper left corner 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) { @@ -669,7 +1145,9 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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() { @@ -679,9 +1157,8 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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() { @@ -690,17 +1167,17 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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) @@ -709,11 +1186,10 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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) { @@ -722,8 +1198,12 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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) { @@ -732,10 +1212,10 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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) { @@ -743,25 +1223,27 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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() { @@ -769,46 +1251,42 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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) { @@ -817,100 +1295,169 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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() { @@ -920,22 +1467,23 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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() { @@ -945,7 +1493,10 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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() { @@ -953,10 +1504,11 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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() { @@ -964,10 +1516,11 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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() { @@ -975,8 +1528,11 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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() { @@ -984,10 +1540,10 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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() { @@ -995,7 +1551,13 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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() { @@ -1003,41 +1565,43 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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() { if (peer != null) { - Graphics gfx = peer.getGraphics(); - if (gfx != null) - return gfx; - - // create graphics for lightweight: - Container parent = getParent(); - if (parent != null) - { - gfx = parent.getGraphics(); - Rectangle bounds = getBounds(); - gfx.setClip(bounds); - gfx.translate(bounds.x, bounds.y); - return gfx; - } + Graphics gfx = peer.getGraphics(); + if (gfx != null) + return gfx; + // create graphics for lightweight: + Container parent = getParent(); + if (parent != null) + { + gfx = parent.getGraphics(); + Rectangle bounds = getBounds(); + gfx.setClip(bounds); + gfx.translate(bounds.x, bounds.y); + return gfx; + } } return null; } @@ -1045,57 +1609,89 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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(); } /** - * Paints this component on the screen. The clipping region in the - * graphics context will indicate the region that requires painting. + * Tests if the cursor was explicitly set, or just inherited from the parent. * - * @param graphics The graphics context for this paint job. + * @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. 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 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) { @@ -1105,92 +1701,93 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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; + if (parent != null) + 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) { @@ -1198,12 +1795,13 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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) { @@ -1211,83 +1809,130 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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. + * double buffering. Headless environments do not support images. * - * @param width The width of the image. - * @param height The height of the image. - * - * @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 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. * - * @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 + * @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. * - * @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 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), - image.getHeight(observer), observer); + return prepareImage(image, image.getWidth(observer), + image.getHeight(observer), observer); } /** * 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) + ImageObserver observer) { return peer.prepareImage(image, width, height, observer); } @@ -1296,78 +1941,105 @@ public abstract class Component implements ImageObserver, MenuContainer, * 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), - image.getHeight(observer), observer); + return checkImage(image, image.getWidth(observer), + image.getHeight(observer), observer); } /** * 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. + * component. Coordinates are relative to this component. * - * @param point The point to test. - * - * @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) { @@ -1375,36 +2047,29 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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) { @@ -1412,14 +2077,15 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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) { @@ -1429,91 +2095,55 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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) { @@ -1523,9 +2153,14 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * Removes the specified listener from the component. + * Removes the specified listener from the component. This is harmless if + * 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) { @@ -1533,74 +2168,194 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * 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 if + * 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 if + * 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 if + * 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 if + * 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) { @@ -1608,158 +2363,318 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * Adds the specified listener to this component. + * Returns an array of all specified listeners registered on this component. + * + * @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. + * @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 if + * 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); + } + + /** + * Returns an array of all specified listeners registered on this component. + * + * @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. + * 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 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 if + * 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 if + * 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 if + * 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) { @@ -1767,80 +2682,52 @@ public abstract class Component implements ImageObserver, MenuContainer, // 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) { case MouseEvent.MOUSE_MOVED: case MouseEvent.MOUSE_DRAGGED: - // Just drop the old (intermediate) event and return the new one. - return newEvent; + // Just drop the old (intermediate) event and return the new one. + return newEvent; case PaintEvent.PAINT: case PaintEvent.UPDATE: - return coalescePaintEvents((PaintEvent) existingEvent, - (PaintEvent) newEvent); + 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 @@ -1850,13 +2737,15 @@ public abstract class Component implements ImageObserver, MenuContainer, 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 - || e.id == MouseEvent.MOUSE_DRAGGED) - processMouseMotionEvent((MouseEvent) e); - else - processMouseEvent((MouseEvent) e); + if (e.id == MouseEvent.MOUSE_MOVED + || e.id == MouseEvent.MOUSE_DRAGGED) + processMouseMotionEvent((MouseEvent) e); + else + processMouseEvent((MouseEvent) e); } else if (e instanceof KeyEvent) processKeyEvent((KeyEvent) e); @@ -1867,18 +2756,23 @@ public abstract class Component implements ImageObserver, MenuContainer, else if (e instanceof HierarchyEvent) { if (e.id == HierarchyEvent.HIERARCHY_CHANGED) - processHierarchyEvent((HierarchyEvent) e); - else - processHierarchyBoundsEvent((HierarchyEvent) e); + processHierarchyEvent((HierarchyEvent) e); + else + processHierarchyBoundsEvent((HierarchyEvent) e); } } /** * 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) { @@ -1886,30 +2780,32 @@ public abstract class Component implements ImageObserver, MenuContainer, return; switch (e.id) { - case ComponentEvent.COMPONENT_HIDDEN: - componentListener.componentHidden(e); - break; - - case ComponentEvent.COMPONENT_MOVED: - componentListener.componentMoved(e); - break; - - case ComponentEvent.COMPONENT_RESIZED: - componentListener.componentResized(e); - break; - - case ComponentEvent.COMPONENT_SHOWN: - componentListener.componentShown(e); - break; + case ComponentEvent.COMPONENT_HIDDEN: + componentListener.componentHidden(e); + break; + case ComponentEvent.COMPONENT_MOVED: + componentListener.componentMoved(e); + break; + case ComponentEvent.COMPONENT_RESIZED: + componentListener.componentResized(e); + break; + 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) { @@ -1918,20 +2814,25 @@ public abstract class Component implements ImageObserver, MenuContainer, switch (e.id) { case FocusEvent.FOCUS_GAINED: - focusListener.focusGained(e); - break; + focusListener.focusGained(e); + break; case FocusEvent.FOCUS_LOST: - focusListener.focusLost(e); - break; - } + 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) { @@ -1939,24 +2840,29 @@ public abstract class Component implements ImageObserver, MenuContainer, return; switch (e.id) { - case KeyEvent.KEY_PRESSED: - keyListener.keyPressed(e); - break; - case KeyEvent.KEY_RELEASED: - keyListener.keyReleased(e); - break; - case KeyEvent.KEY_TYPED: - keyListener.keyTyped(e); - break; + case KeyEvent.KEY_PRESSED: + keyListener.keyPressed(e); + break; + case KeyEvent.KEY_RELEASED: + keyListener.keyReleased(e); + break; + case KeyEvent.KEY_TYPED: + keyListener.keyTyped(e); + break; } } /** * 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) { @@ -1964,30 +2870,35 @@ public abstract class Component implements ImageObserver, MenuContainer, return; switch (e.id) { - case MouseEvent.MOUSE_CLICKED: - mouseListener.mouseClicked(e); - break; + case MouseEvent.MOUSE_CLICKED: + mouseListener.mouseClicked(e); + break; case MouseEvent.MOUSE_ENTERED: - mouseListener.mouseEntered(e); - break; - case MouseEvent.MOUSE_EXITED: - mouseListener.mouseExited(e); - break; - case MouseEvent.MOUSE_PRESSED: - mouseListener.mousePressed(e); - break; - case MouseEvent.MOUSE_RELEASED: - mouseListener.mouseReleased(e); - break; + mouseListener.mouseEntered(e); + break; + case MouseEvent.MOUSE_EXITED: + mouseListener.mouseExited(e); + break; + case MouseEvent.MOUSE_PRESSED: + mouseListener.mousePressed(e); + break; + case MouseEvent.MOUSE_RELEASED: + mouseListener.mouseReleased(e); + break; } } /** * 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) { @@ -1995,32 +2906,73 @@ public abstract class Component implements ImageObserver, MenuContainer, return; switch (e.id) { - case MouseEvent.MOUSE_DRAGGED: - mouseMotionListener.mouseDragged(e); - break; + case MouseEvent.MOUSE_DRAGGED: + mouseMotionListener.mouseDragged(e); + break; case MouseEvent.MOUSE_MOVED: - mouseMotionListener.mouseMoved(e); - break; - } + 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) return; switch (e.id) { - case InputMethodEvent.CARET_POSITION_CHANGED: + case InputMethodEvent.CARET_POSITION_CHANGED: inputMethodListener.caretPositionChanged(e); - break; - case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: + break; + case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED: inputMethodListener.inputMethodTextChanged(e); - break; - } + 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) @@ -2028,8 +2980,19 @@ public abstract class Component implements ImageObserver, MenuContainer, 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) @@ -2037,155 +3000,177 @@ public abstract class Component implements ImageObserver, MenuContainer, switch (e.id) { case HierarchyEvent.ANCESTOR_MOVED: - hierarchyBoundsListener.ancestorMoved(e); - break; - case HierarchyEvent.ANCESTOR_RESIZED: - hierarchyBoundsListener.ancestorResized(e); - break; - } - } - - 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"); + hierarchyBoundsListener.ancestorMoved(e); + break; + case HierarchyEvent.ANCESTOR_RESIZED: + hierarchyBoundsListener.ancestorResized(e); + break; } } /** * 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, @@ -2194,218 +3179,631 @@ public abstract class Component implements ImageObserver, MenuContainer, /** * 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; + } + + /** + * 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. + * Requests that this component be given focus. A <code>FOCUS_GAINED</code> + * event will be fired if and only if this request is 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) + /** + * Requests that this component be given focus. A <code>FOCUS_GAINED</code> + * event will be fired if and only if this request is 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. + * + * <p>If the return value is false, the request is guaranteed to fail. If + * it is true, it will likely succeed unless the action is vetoed or + * something in the native windowing system intervenes. The temporary flag, + * and thus this method in general, is not designed for public use; rather + * it is a hook for lightweight components to notify their container in + * an attempt to reduce the amount of repainting necessary. + * + * @param temporary true if the focus request is temporary + * @return true if the request has a chance of success + * @see #requestFocusInWindow() + * @see FocusEvent + * @see #addFocusListener(FocusListener) + * @see #isFocusable() + * @see #isDisplayable() + * @see KeyboardFocusManager#clearGlobalFocusOwner() + * @since 1.4 + */ + protected boolean requestFocus(boolean temporary) { - return null; + // XXX Implement correctly. + requestFocus(); + return true; + } + + /** + * Requests that this component be given focus, if it resides in the + * top-level window which already has focus. A <code>FOCUS_GAINED</code> + * event will be fired if and only if this request is successful. To be + * successful, the component must be displayable, visible, and focusable, + * and the top-level Window must be focused. + * + * <p>If the return value is false, the request is guaranteed to fail. If + * it is true, it will likely succeed unless the action is vetoed or + * something in the native windowing system intervenes. The temporary flag, + * and thus this method in general, is not designed for public use; rather + * it is a hook for lightweight components to notify their container in + * an attempt to reduce the amount of repainting necessary. + * + * @return true if the request has a chance of success + * @see #requestFocus() + * @see FocusEvent + * @see #addFocusListener(FocusListener) + * @see #isFocusable() + * @see #isDisplayable() + * @see KeyboardFocusManager#clearGlobalFocusOwner() + * @since 1.4 + */ + public boolean requestFocusInWindow() + { + // XXX Implement correctly. + requestFocus(); + return true; } /** - * Transfers focus to the next component in the focus traversal order. + * Requests that this component be given focus, if it resides in the + * top-level window which already has focus. A <code>FOCUS_GAINED</code> + * event will be fired if and only if this request is successful. To be + * successful, the component must be displayable, visible, and focusable, + * and the top-level Window must be focused. + * + * <p>If the return value is false, the request is guaranteed to fail. If + * it is true, it will likely succeed unless the action is vetoed or + * something in the native windowing system intervenes. The temporary flag, + * and thus this method in general, is not designed for public use; rather + * it is a hook for lightweight components to notify their container in + * an attempt to reduce the amount of repainting necessary. + * + * @param temporary true if the focus request is temporary + * @return true if the request has a chance of success + * @see #requestFocus() + * @see FocusEvent + * @see #addFocusListener(FocusListener) + * @see #isFocusable() + * @see #isDisplayable() + * @see KeyboardFocusManager#clearGlobalFocusOwner() + * @since 1.4 + */ + protected boolean requestFocusInWindow(boolean temporary) + { + // XXX Implement correctly. + requestFocus(); + return true; + } + + /** + * Transfers focus to the next component in the focus traversal order, as + * though this were the current focus owner. + * + * @see #requestFocus() + * @since 1.1 */ public void transferFocus() { 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(); + } + + /** + * Returns the root container that owns the focus cycle where this component + * resides. A focus cycle root is in two cycles, one as the ancestor, and + * one as the focusable element; this call always returns the ancestor. + * + * @return the ancestor container that owns the focus cycle + * @since 1.4 + */ + public Container getFocusCycleRootAncestor() + { + // XXX Implement. + throw new Error("not implemented"); + } + + /** + * Tests if the container is the ancestor of the focus cycle that this + * component belongs to. + * + * @param c the container to test + * @return true if c is the focus cycle root + * @since 1.4 + */ + public boolean isFocusCycleRoot(Container c) + { + return c == getFocusCycleRootAncestor(); } /** * AWT 1.0 focus event processor. * - * @deprecated Deprecated in favor of <code>transferFocus()</code>. + * @deprecated use {@link #transferFocus()} instead */ public void nextFocus() { transferFocus(); } - /** @since 1.2 */ + /** + * Transfers focus to the previous component in the focus traversal order, as + * though this were the current focus owner. + * + * @see #requestFocus() + * @since 1.4 + */ + public void transferFocusBackward() + { + // XXX Implement. + throw new Error("not implemented"); + } + + /** + * Transfers focus to the focus cycle root of this component. However, if + * this is a Window, the default focus owner in the window in the current + * focus cycle is focused instead. + * + * @see #requestFocus() + * @see #isFocusCycleRoot() + * @since 1.4 + */ + public void transferFocusUpCycle() + { + // XXX Implement. + throw new Error("not implemented"); + } + + /** + * Tests if this component is the focus owner. Use {@link #isFocusOwner()} + * instead. + * + * @return true if this component owns focus + * @since 1.2 + */ public boolean hasFocus() { - return hasFocus; + return isFocusOwner(); + } + + /** + * Tests if this component is the focus owner. + * + * @return true if this component owns focus + * @since 1.4 + */ + public boolean isFocusOwner() + { + // XXX Implement. + throw new Error("not implemented"); } /** * Adds the specified popup menu to this component. * - * @param menu The popup menu to be added. + * @param menu the popup menu to be added + * @see #remove(MenuComponent) + * @since 1.1 */ public synchronized void add(PopupMenu popup) { if (popups == null) popups = new Vector(); - popups.addElement(popup); + popups.add(popup); } /** * Removes the specified popup menu from this component. * - * @param menu The popup menu to remove. + * @param menu the popup menu to remove + * @see #add(PopupMenu) + * @since 1.1 */ public synchronized void remove(MenuComponent popup) { - popups.removeElement(popup); + if (popups != null) + popups.remove(popup); } /** - * Returns a debugging string representing this component. + * Returns a debugging string representing this component. The string may + * be empty but not null. * - * @return A string representing this component. + * @return a string representing this component */ protected String paramString() { StringBuffer param = new StringBuffer(); String name = getName(); if (name != null) - { - 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(name).append(","); + 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(); } /** - * Returns a string representation of this component. + * Returns a string representation of this component. This is implemented + * as <code>getClass().getName() + '[' + paramString() + ']'</code>. * - * @return A string representation of this component + * @return a string representation of this component */ public String toString() { - return this.getClass().getName() + "[" + paramString() + "]"; + return getClass().getName() + '[' + paramString() + ']'; } /** - * Prints a listing of this component to the standard output. + * Prints a listing of this component to <code>System.out</code>. + * + * @see #list(PrintStream) */ - public void list () + public void list() { - list (System.out, 0); + list(System.out, 0); } /** * Prints a listing of this component to the specified print stream. * - * @param stream The <code>PrintStream</code> to print to. + * @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); } /** * Prints a listing of this component to the specified print stream, * starting at the specified indentation point. * - * @param stream The <code>PrintStream</code> to print to. - * @param indent The indentation point. + * @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()); } /** * Prints a listing of this component to the specified print writer. * - * @param writer The <code>PrintWrinter</code> to print to. + * @param writer the <code>PrintWrinter</code> to print to + * @since 1.1 */ - public void list (PrintWriter out) + public void list(PrintWriter out) { - list (out, 0); + list(out, 0); } /** * Prints a listing of this component to the specified print writer, * starting at the specified indentation point. * - * @param writer The <code>PrintWriter</code> to print to. - * @param indent The indentation point. + * @param writer the <code>PrintWriter</code> to print to + * @param indent the indentation point + * @since 1.1 */ - 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()); + } + + /** + * Adds the specified property 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. The property listener ignores inherited + * properties. Recognized properties include:<br> + * <ul> + * <li>the font (<code>"font"</code>)</li> + * <li>the background color (<code>"background"</code>)</li> + * <li>the foreground color (<code>"foreground"</code>)</li> + * <li>the focusability (<code>"focusable"</code>)</li> + * <li>the focus key traversal enabled state + * (<code>"focusTraversalKeysEnabled"</code>)</li> + * <li>the set of forward traversal keys + * (<code>"forwardFocusTraversalKeys"</code>)</li> + * <li>the set of backward traversal keys + * (<code>"backwardFocusTraversalKeys"</code>)</li> + * <li>the set of up-cycle traversal keys + * (<code>"upCycleFocusTraversalKeys"</code>)</li> + * </ul> + * + * @param listener the new listener to add + * @see #removePropertyChangeListener(PropertyChangeListener) + * @see #getPropertyChangeListeners() + * @see #addPropertyChangeListener(String, PropertyChangeListener) + * @since 1.1 + */ public void addPropertyChangeListener(PropertyChangeListener listener) { if (changeSupport == null) @@ -2413,20 +3811,85 @@ public abstract class Component implements ImageObserver, MenuContainer, changeSupport.addPropertyChangeListener(listener); } + /** + * Removes the specified property listener from the component. This is + * harmless if the listener was not previously registered. + * + * @param listener the listener to remove + * @see #addPropertyChangeListener(PropertyChangeListener) + * @see #getPropertyChangeListeners() + * @see #removePropertyChangeListener(String, PropertyChangeListener) + * @since 1.1 + */ public void removePropertyChangeListener(PropertyChangeListener listener) { if (changeSupport != null) - changeSupport.removePropertyChangeListener(listener); + changeSupport.removePropertyChangeListener(listener); } + /** + * Returns an array of all specified listeners registered on this component. + * + * @return an array of listeners + * @see #addPropertyChangeListener(PropertyChangeListener) + * @see #removePropertyChangeListener(PropertyChangeListener) + * @see #getPropertyChangeListeners(String) + * @since 1.4 + */ + public PropertyChangeListener[] getPropertyChangeListeners() + { + return changeSupport == null ? new PropertyChangeListener[0] + : changeSupport.getPropertyChangeListeners(); + } + + /** + * Adds the specified property 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. The property listener ignores inherited + * properties. The listener is keyed to a single property. Recognized + * properties include:<br> + * <ul> + * <li>the font (<code>"font"</code>)</li> + * <li>the background color (<code>"background"</code>)</li> + * <li>the foreground color (<code>"foreground"</code>)</li> + * <li>the focusability (<code>"focusable"</code>)</li> + * <li>the focus key traversal enabled state + * (<code>"focusTraversalKeysEnabled"</code>)</li> + * <li>the set of forward traversal keys + * (<code>"forwardFocusTraversalKeys"</code>)</li> +p * <li>the set of backward traversal keys + * (<code>"backwardFocusTraversalKeys"</code>)</li> + * <li>the set of up-cycle traversal keys + * (<code>"upCycleFocusTraversalKeys"</code>)</li> + * </ul> + * + * @param propertyName the property name to filter on + * @param listener the new listener to add + * @see #removePropertyChangeListener(String, PropertyChangeListener) + * @see #getPropertyChangeListeners(String) + * @see #addPropertyChangeListener(PropertyChangeListener) + * @since 1.1 + */ public void addPropertyChangeListener(String propertyName, - PropertyChangeListener listener) + PropertyChangeListener listener) { if (changeSupport == null) changeSupport = new PropertyChangeSupport(this); - changeSupport.addPropertyChangeListener(propertyName, listener); + changeSupport.addPropertyChangeListener(propertyName, listener); } + /** + * Removes the specified property listener on a particular property from + * the component. This is harmless if the listener was not previously + * registered. + * + * @param propertyName the property name to filter on + * @param listener the listener to remove + * @see #addPropertyChangeListener(String, PropertyChangeListener) + * @see #getPropertyChangeListeners(String) + * @see #removePropertyChangeListener(PropertyChangeListener) + * @since 1.1 + */ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { @@ -2434,52 +3897,1067 @@ public abstract class Component implements ImageObserver, MenuContainer, changeSupport.removePropertyChangeListener(propertyName, listener); } - protected void firePropertyChange(String propertyName, Object oldValue, + /** + * Returns an array of all specified listeners on the named property that + * are registered on this component. + * + * @return an array of listeners + * @see #addPropertyChangeListener(String, PropertyChangeListener) + * @see #removePropertyChangeListener(String, PropertyChangeListener) + * @see #getPropertyChangeListeners() + * @since 1.4 + */ + public PropertyChangeListener[] getPropertyChangeListeners(String property) + { + return changeSupport == null ? new PropertyChangeListener[0] + : changeSupport.getPropertyChangeListeners(property); + } + + /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + */ + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { if (changeSupport != null) - changeSupport.firePropertyChange(propertyName, oldValue, newValue); + changeSupport.firePropertyChange(propertyName, oldValue, newValue); + } + + /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + */ + protected void firePropertyChange(String propertyName, boolean oldValue, + boolean newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, oldValue, newValue); } + /** + * Report a change in a bound property to any registered property listeners. + * + * @param propertyName the property that changed + * @param oldValue the old property value + * @param newValue the new property value + */ + protected void firePropertyChange(String propertyName, int oldValue, + int newValue) + { + if (changeSupport != null) + changeSupport.firePropertyChange(propertyName, oldValue, newValue); + } + + /** + * Sets the text layout orientation of this component. New components default + * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects only + * the current component, while + * {@link #applyComponentOrientation(ComponentOrientation)} affects the + * entire hierarchy. + * + * @param o the new orientation + * @throws NullPointerException if o is null + * @see #getComponentOrientation() + */ public void setComponentOrientation(ComponentOrientation o) { + if (o == null) + throw new NullPointerException(); orientation = o; } + /** + * Determines the text layout orientation used by this component. + * + * @return the component orientation + * @see #setComponentOrientation(ComponentOrientation) + */ public ComponentOrientation getComponentOrientation() { return orientation; } - /* + /** + * Sets the text layout orientation of this component. New components default + * to UNKNOWN (which behaves like LEFT_TO_RIGHT). This method affects the + * entire hierarchy, while + * {@link #setComponentOrientation(ComponentOrientation)} affects only the + * current component. + * + * @param o the new orientation + * @throws NullPointerException if o is null + * @see #getComponentOrientation() + * @since 1.4 + */ + public void applyComponentOrientation(ComponentOrientation o) + { + setComponentOrientation(o); + } + + /** + * Returns the accessibility framework context of this class. Component is + * not accessible, so the default implementation returns null. Subclasses + * must override this behavior, and return an appropriate subclass of + * {@link AccessibleAWTComponent}. + * + * @return the accessibility context + */ 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. + * + * @param peer the new peer + */ + 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. + * + * @return the graphics configuration + */ + GraphicsConfiguration getGraphicsConfigurationImpl() + { + if (peer != null) + { + GraphicsConfiguration config = peer.getGraphicsConfiguration(); + if (config != null) + return config; + } + + if (parent != null) + return parent.getGraphicsConfiguration(); + + return null; + } + + /** + * Implementation of dispatchEvent. Allows trusted package classes to + * dispatch additional events first. + * + * @param e the event to dispatch + */ + 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> + * + * @param queuedEvent the first paint event + * @param newEvent the second paint event + * @return the combined paint event, or null + */ + 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; + } + + /** + * Does the work for a paint event. + * + * @param event the event to process + */ + 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. + * + * @param child the component making the request + * @return the next component to focus on + */ + Component findNextFocusComponent(Component child) + { + return null; + } + + /** + * Deserializes this component. This regenerates all serializable listeners + * which were registered originally. + * + * @param s the stream to read from + * @throws ClassNotFoundException if deserialization fails + * @throws IOException if the stream fails + */ + 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(); + } + } + + /** + * Serializes this component. This ignores all listeners which do not + * implement Serializable, but includes those that do. + * + * @param s the stream to write to + * @throws IOException if the stream fails + */ + 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 + * @status updated to 1.4 + */ + protected abstract class AccessibleAWTComponent extends AccessibleContext + implements Serializable, AccessibleComponent + { + /** + * Compatible with JDK 1.3+. + */ + private static final long serialVersionUID = 642321655757800191L; + + /** + * Converts show/hide events to PropertyChange events, and is registered + * as a component listener on this component. + * + * @serial the component handler + */ + protected ComponentListener accessibleAWTComponentHandler + = new AccessibleAWTComponentHandler(); + + /** + * Converts focus events to PropertyChange events, and is registered + * as a focus listener on this component. + * + * @serial the focus handler + */ + 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; + } + + /** + * Returns the role of this component. + * + * @return the accessible role + */ + public AccessibleRole getAccessibleRole() + { + return AccessibleRole.AWT_COMPONENT; + } + + /** + * 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/libjava/java/awt/ComponentOrientation.java b/libjava/java/awt/ComponentOrientation.java index 66a3cbdc363..8d3a40c8599 100644 --- a/libjava/java/awt/ComponentOrientation.java +++ b/libjava/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/libjava/java/awt/Composite.java b/libjava/java/awt/Composite.java new file mode 100644 index 00000000000..de873981652 --- /dev/null +++ b/libjava/java/awt/Composite.java @@ -0,0 +1,73 @@ +/* Composite.java -- graphics formed from composite layers + 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; + +/** + * This interface is for graphics which are formed as composites of others. + * It combines {@link Graphics2D} shapes according to defined rules to form + * the new image. Implementations of this interface must be immutable, because + * they are not cloned when a Graphics2D container is cloned. + * + * <p>Since this can expose pixels to untrusted code, there is a security + * check on custom objects, <code>readDisplayPixels</code>, to prevent leaking + * restricted information graphically. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see AlphaComposite + * @see CompositeContext + * @see Graphics2D#setComposite(Composite) + * @since 1.2 + * @status updated to 1.4 + */ +public interface Composite +{ + /** + * Create a context state for performing the compositing operation. Several + * contexts may exist for this object, in a multi-threaded environment. + * + * @param srcColorModel the color model of the source + * @param dstColorModel the color model of the destination + * @param hints hints for choosing between rendering alternatives + */ + CompositeContext createContext(ColorModel srcColorModel, + ColorModel dstColorModel, + RenderingHints hints); +} // interface Composite diff --git a/libjava/java/awt/CompositeContext.java b/libjava/java/awt/CompositeContext.java new file mode 100644 index 00000000000..dc3448b114b --- /dev/null +++ b/libjava/java/awt/CompositeContext.java @@ -0,0 +1,71 @@ +/* Composite.java -- the context for compositing graphics layers + 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.Raster; +import java.awt.image.WritableRaster; + +/** + * This interface provides an optimized environment for compositing graphics. + * Several such contexts may exist for a given <code>Composite</code> object. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Composite + * @since 1.2 + * @status updated to 1.4 + */ +public interface CompositeContext +{ + /** + * Release resources allocated for the compositing. + */ + void dispose(); + + /** + * Compose the two source images into the composite image. The destination + * can be the same as one of the two inputs, and the destination must be + * compatible with the ColorModel chosen in {@link Composite#createContext}. + * + * @param src the lower image source in compositing + * @param dstIn the upper image source in compositing + * @param dstOut the destination for the composite + * @see Composite + */ + void compose(Raster src, Raster dstIn, WritableRaster dstOut); +} // interface CompositeContext diff --git a/libjava/java/awt/Container.java b/libjava/java/awt/Container.java index 0995a743cd8..c5c7c245606 100644 --- a/libjava/java/awt/Container.java +++ b/libjava/java/awt/Container.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2002 Free Software Foundation +/* Container.java -- parent container class in AWT + Copyright (C) 1999, 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -36,28 +37,54 @@ exception statement from your version. */ package java.awt; -import java.awt.event.*; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.util.EventListener; +import java.awt.event.AWTEventListener; +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; +import java.awt.event.MouseEvent; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; import java.awt.peer.LightweightPeer; - -/* A somewhat incomplete class. */ - +import java.beans.PropertyChangeListener; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Serializable; +import java.util.EventListener; +import java.util.Set; +import javax.accessibility.Accessible; + +/** + * A generic window toolkit object that acts as a container for other objects. + * Components are tracked in a list, and new elements are at the end of the + * list or bottom of the stacking order. + * + * @author original author unknown + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.0 + * @status still missing 1.4 support + */ public class Container extends Component { + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = 4613797578919906343L; + /* Serialized fields from the serialization spec. */ int ncomponents; Component[] component; LayoutManager layoutMgr; - /* LightweightDispatcher dispatcher; */ // wtf? + + LightweightDispatcher dispatcher; + Dimension maxSize; + + /** @since 1.4 */ + boolean focusCycleRoot; + int containerSerializedDataVersion; /* Anything else is non-serializable, and should be declared "transient". */ - transient ContainerListener containerListener; + transient ContainerListener containerListener; /** * Default constructor for subclasses. @@ -80,26 +107,21 @@ public class Container extends Component * Returns the number of components in this container. * * @return The number of components in this container. - * - * @deprecated This method is deprecated in favor of - * <code>getComponentCount()</code>. + * @deprecated use {@link #getComponentCount()} instead */ public int countComponents() { - return ncomponents; + return getComponentCount(); } /** * Returns the component at the specified index. * * @param index The index of the component to retrieve. - * * @return The requested component. - * - * @exception ArrayIndexOutOfBoundsException If the specified index is not - * valid. + * @throws ArrayIndexOutOfBoundsException If the specified index is invalid */ - public Component getComponent (int n) + public Component getComponent(int n) { if (n < 0 || n >= ncomponents) throw new ArrayIndexOutOfBoundsException("no such component"); @@ -137,9 +159,7 @@ public class Container extends Component * borders, the margin, etc. * * @return The insets for this container. - * - * @deprecated This method is deprecated in favor of - * <code>getInsets()</code>. + * @deprecated use {@link #getInsets()} instead */ public Insets insets() { @@ -151,12 +171,11 @@ public class Container extends Component * component list. * * @param component The component to add to the container. - * * @return The same component that was added. */ - public Component add (Component comp) + public Component add(Component comp) { - addImpl (comp, null, -1); + addImpl(comp, null, -1); return comp; } @@ -170,9 +189,9 @@ public class Container extends Component * * @return The same component that was added. */ - public Component add (String name, Component comp) + public Component add(String name, Component comp) { - addImpl (comp, name, -1); + addImpl(comp, name, -1); return comp; } @@ -188,9 +207,9 @@ public class Container extends Component * * @param throws ArrayIndexOutOfBounds If the specified index is invalid. */ - public Component add (Component comp, int index) + public Component add(Component comp, int index) { - addImpl (comp, null, index); + addImpl(comp, null, index); return comp; } @@ -202,9 +221,9 @@ public class Container extends Component * @param component The component to be added to this container. * @param constraints The layout constraints for this component. */ - public void add (Component comp, Object constraints) + public void add(Component comp, Object constraints) { - addImpl (comp, constraints, -1); + addImpl(comp, constraints, -1); } /** @@ -219,9 +238,9 @@ public class Container extends Component * * @param throws ArrayIndexOutOfBounds If the specified index is invalid. */ - public void add (Component comp, Object constraints, int index) + public void add(Component comp, Object constraints, int index) { - addImpl (comp, constraints, index); + addImpl(comp, constraints, index); } /** @@ -239,29 +258,29 @@ public class Container extends Component * * @param throws ArrayIndexOutOfBounds If the specified index is invalid. */ - protected void addImpl (Component comp, Object constraints, int index) + protected void addImpl(Component comp, Object constraints, int index) { if (index > ncomponents - || (index < 0 && index != -1) - || comp instanceof Window - || (comp instanceof Container - && ((Container) comp).isAncestorOf (this))) - throw new IllegalArgumentException (); + || (index < 0 && index != -1) + || comp instanceof Window + || (comp instanceof Container + && ((Container) comp).isAncestorOf(this))) + throw new IllegalArgumentException(); // Reparent component, and make sure component is instantiated if // we are. if (comp.parent != null) - comp.parent.remove (comp); + comp.parent.remove(comp); comp.parent = this; if (peer != null) { - comp.addNotify (); + comp.addNotify(); - if (comp.isLightweight()) - enableEvents(comp.eventMask); + if (comp.isLightweight()) + enableEvents(comp.eventMask); } - invalidate (); + invalidate(); if (component == null) component = new Component[4]; // FIXME, better initial size? @@ -270,39 +289,39 @@ public class Container extends Component // copying when growing the array. It probably doesn't matter. if (ncomponents >= component.length) { - int nl = component.length * 2; - Component[] c = new Component[nl]; - System.arraycopy (component, 0, c, 0, ncomponents); - component = c; + int nl = component.length * 2; + Component[] c = new Component[nl]; + System.arraycopy(component, 0, c, 0, ncomponents); + component = c; } if (index == -1) component[ncomponents++] = comp; else { - System.arraycopy (component, index, component, index + 1, - ncomponents - index); - component[index] = comp; - ++ncomponents; + System.arraycopy(component, index, component, index + 1, + ncomponents - index); + component[index] = comp; + ++ncomponents; } // Notify the layout manager. if (layoutMgr != null) { - if (layoutMgr instanceof LayoutManager2) - { - LayoutManager2 lm2 = (LayoutManager2) layoutMgr; - lm2.addLayoutComponent (comp, constraints); - } - else if (constraints instanceof String) - layoutMgr.addLayoutComponent ((String) constraints, comp); - else - layoutMgr.addLayoutComponent (null, comp); + if (layoutMgr instanceof LayoutManager2) + { + LayoutManager2 lm2 = (LayoutManager2) layoutMgr; + lm2.addLayoutComponent(comp, constraints); + } + else if (constraints instanceof String) + layoutMgr.addLayoutComponent((String) constraints, comp); + else + layoutMgr.addLayoutComponent(null, comp); } // Post event to notify of adding the container. - ContainerEvent ce = new ContainerEvent (this, - ContainerEvent.COMPONENT_ADDED, - comp); + ContainerEvent ce = new ContainerEvent(this, + ContainerEvent.COMPONENT_ADDED, + comp); getToolkit().getSystemEventQueue().postEvent(ce); } @@ -311,25 +330,25 @@ public class Container extends Component * * @param index The index of the component to remove. */ - public void remove (int index) + public void remove(int index) { Component r = component[index]; - r.removeNotify (); + r.removeNotify(); - System.arraycopy (component, index + 1, component, index, - ncomponents - index - 1); + System.arraycopy(component, index + 1, component, index, + ncomponents - index - 1); component[--ncomponents] = null; - invalidate (); + invalidate(); if (layoutMgr != null) - layoutMgr.removeLayoutComponent (r); + layoutMgr.removeLayoutComponent(r); // Post event to notify of adding the container. - ContainerEvent ce = new ContainerEvent (this, - ContainerEvent.COMPONENT_REMOVED, - r); + ContainerEvent ce = new ContainerEvent(this, + ContainerEvent.COMPONENT_REMOVED, + r); getToolkit().getSystemEventQueue().postEvent(ce); } @@ -338,15 +357,15 @@ public class Container extends Component * * @return component The component to remove from this container. */ - public void remove (Component comp) + public void remove(Component comp) { for (int i = 0; i < ncomponents; ++i) { - if (component[i] == comp) - { - remove (i); - break; - } + if (component[i] == comp) + { + remove(i); + break; + } } } @@ -356,7 +375,7 @@ public class Container extends Component public void removeAll() { while (ncomponents > 0) - remove (0); + remove(0); } /** @@ -378,7 +397,7 @@ public class Container extends Component public void setLayout(LayoutManager mgr) { layoutMgr = mgr; - invalidate (); + invalidate(); } /** @@ -387,14 +406,13 @@ public class Container extends Component public void doLayout() { if (layoutMgr != null) - layoutMgr.layoutContainer (this); + layoutMgr.layoutContainer(this); } /** * Layout the components in this container. * - * @deprecated This method is deprecated in favor of - * <code>doLayout()</code>. + * @deprecated use {@link #doLayout()} instead */ public void layout() { @@ -407,7 +425,7 @@ public class Container extends Component */ public void invalidate() { - super.invalidate (); + super.invalidate(); } /** @@ -418,10 +436,10 @@ public class Container extends Component // FIXME: use the tree lock? synchronized (this) { - if (! isValid ()) - { - validateTree (); - } + if (! isValid()) + { + validateTree(); + } } } @@ -432,30 +450,30 @@ public class Container extends Component protected void validateTree() { if (valid) - return; + return; ContainerPeer cPeer = null; - if ((peer != null) && !(peer instanceof LightweightPeer)) + if (peer != null && ! (peer instanceof LightweightPeer)) { - cPeer = (ContainerPeer) peer; - cPeer.beginValidate(); + cPeer = (ContainerPeer) peer; + cPeer.beginValidate(); } - doLayout (); + doLayout(); for (int i = 0; i < ncomponents; ++i) { - Component comp = component[i]; - if (! comp.isValid ()) - { - if (comp instanceof Container) - { - ((Container) comp).validateTree(); - } - else - { - component[i].validate(); - } - } + Component comp = component[i]; + if (! comp.isValid()) + { + if (comp instanceof Container) + { + ((Container) comp).validateTree(); + } + else + { + component[i].validate(); + } + } } /* children will call invalidate() when they are layed out. It @@ -481,18 +499,16 @@ public class Container extends Component public Dimension getPreferredSize() { if (layoutMgr != null) - return layoutMgr.preferredLayoutSize (this); + return layoutMgr.preferredLayoutSize(this); else - return super.getPreferredSize (); + return super.getPreferredSize(); } /** * Returns the preferred size of this container. * * @return The preferred size of this container. - * - * @deprecated This method is deprecated in favor of - * <code>getPreferredSize()</code>. + * @deprecated use {@link #getPreferredSize()} instead */ public Dimension preferredSize() { @@ -507,18 +523,16 @@ public class Container extends Component public Dimension getMinimumSize() { if (layoutMgr != null) - return layoutMgr.minimumLayoutSize (this); + return layoutMgr.minimumLayoutSize(this); else - return super.getMinimumSize (); + return super.getMinimumSize(); } /** * Returns the minimum size of this container. * * @return The minimum size of this container. - * - * @deprecated This method is deprecated in favor of - * <code>getMinimumSize()</code>. + * @deprecated use {@link #getMinimumSize()} instead */ public Dimension minimumSize() { @@ -534,11 +548,11 @@ public class Container extends Component { if (layoutMgr != null && layoutMgr instanceof LayoutManager2) { - LayoutManager2 lm2 = (LayoutManager2) layoutMgr; - return lm2.maximumLayoutSize (this); + LayoutManager2 lm2 = (LayoutManager2) layoutMgr; + return lm2.maximumLayoutSize(this); } else - return super.getMaximumSize (); + return super.getMaximumSize(); } /** @@ -552,8 +566,8 @@ public class Container extends Component { if (layoutMgr instanceof LayoutManager2) { - LayoutManager2 lm2 = (LayoutManager2) layoutMgr; - return lm2.getLayoutAlignmentX (this); + LayoutManager2 lm2 = (LayoutManager2) layoutMgr; + return lm2.getLayoutAlignmentX(this); } else return super.getAlignmentX(); @@ -570,8 +584,8 @@ public class Container extends Component { if (layoutMgr instanceof LayoutManager2) { - LayoutManager2 lm2 = (LayoutManager2) layoutMgr; - return lm2.getLayoutAlignmentY (this); + LayoutManager2 lm2 = (LayoutManager2) layoutMgr; + return lm2.getLayoutAlignmentY(this); } else return super.getAlignmentY(); @@ -594,64 +608,6 @@ public class Container extends Component visitChildren(g, GfxPaintVisitor.INSTANCE, true); } - /** - * Perform a graphics operation on the children of this container. - * For each applicable child, the visitChild() method will be called - * to perform the graphics operation. - * - * @param gfx The graphics object that will be used to derive new - * graphics objects for the children. - * - * @param visitor Object encapsulating the graphics operation that - * should be performed. - * - * @param lightweightOnly If true, only lightweight components will - * be visited. - */ - private void visitChildren(Graphics gfx, GfxVisitor visitor, - boolean lightweightOnly) - { - // FIXME: do locking - - for (int i = 0; i < ncomponents; ++i) - { - Component comp = component[i]; - boolean applicable = comp.isVisible() - && (comp.isLightweight() || !lightweightOnly); - - if (applicable) - visitChild(gfx, visitor, comp); - } - } - - /** - * Perform a graphics operation on a child. A translated and clipped - * graphics object will be created, and the visit() method of the - * visitor will be called to perform the operation. - * - * @param gfx The graphics object that will be used to derive new - * graphics objects for the child. - * - * @param visitor Object encapsulating the graphics operation that - * should be performed. - * - * @param comp The child component that should be visited. - */ - private void visitChild(Graphics gfx, GfxVisitor visitor, - Component comp) - { - Rectangle bounds = comp.getBounds(); - Rectangle clip = gfx.getClipBounds().intersection(bounds); - - if (clip.isEmpty()) return; - - Graphics gfx2 = gfx.create(); - gfx2.setClip(clip.x, clip.y, clip.width, clip.height); - gfx2.translate(bounds.x, bounds.y); - - visitor.visit(comp, gfx2); - } - /** * Updates this container. The implementation of this method in this * class forwards to any lightweight components in this container. If @@ -703,17 +659,6 @@ public class Container extends Component visitChildren(g, GfxPrintAllVisitor.INSTANCE, true); } - void dispatchEventImpl(AWTEvent e) - { - if ((e.id <= ContainerEvent.CONTAINER_LAST - && e.id >= ContainerEvent.CONTAINER_FIRST) - && (containerListener != null - || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0)) - processEvent(e); - else - super.dispatchEventImpl(e); - } - /** * Adds the specified container listener to this object's list of * container listeners. @@ -722,7 +667,7 @@ public class Container extends Component */ public synchronized void addContainerListener(ContainerListener l) { - containerListener = AWTEventMulticaster.add (containerListener, l); + containerListener = AWTEventMulticaster.add(containerListener, l); } /** @@ -736,12 +681,24 @@ public class Container extends Component containerListener = AWTEventMulticaster.remove(containerListener, l); } - /** @since 1.3 */ + /** + * @since 1.4 + */ + 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); } /** @@ -772,12 +729,12 @@ public class Container extends Component switch (e.id) { case ContainerEvent.COMPONENT_ADDED: - containerListener.componentAdded(e); - break; + containerListener.componentAdded(e); + break; case ContainerEvent.COMPONENT_REMOVED: - containerListener.componentRemoved(e); - break; + containerListener.componentRemoved(e); + break; } } @@ -785,9 +742,7 @@ public class Container extends Component * AWT 1.0 event processor. * * @param event The event that occurred. - * - * @deprecated This method is deprecated in favor of - * <code>dispatchEvent()</code>. + * @deprecated use {@link #dispatchEvent(AWTEvent)} instead */ public void deliverEvent(Event e) { @@ -807,20 +762,20 @@ public class Container extends Component * @return The component containing the specified point, or * <code>null</code> if there is no such point. */ - public Component getComponentAt (int x, int y) + public Component getComponentAt(int x, int y) { - if (! contains (x, y)) + if (! contains(x, y)) return null; for (int i = 0; i < ncomponents; ++i) { - // Ignore invisible children... - if (!component[i].isVisible()) - continue; - - int x2 = x - component[i].x; - int y2 = y - component[i].y; - if (component[i].contains (x2, y2)) - return component[i]; + // Ignore invisible children... + if (!component[i].isVisible()) + continue; + + int x2 = x - component[i].x; + int y2 = y - component[i].y; + if (component[i].contains(x2, y2)) + return component[i]; } return this; } @@ -837,9 +792,7 @@ public class Container extends Component * * @return The component containing the specified point, or <code>null</code> * if there is no such point. - * - * @deprecated This method is deprecated in favor of - * <code>getComponentAt(int, int)</code>. + * @deprecated use {@link #getComponentAt(int, int)} instead */ public Component locate(int x, int y) { @@ -855,7 +808,6 @@ public class Container extends Component * case <code>null</code> is returned. * * @param point The point to return the component at. - * * @return The component containing the specified point, or <code>null</code> * if there is no such point. */ @@ -864,30 +816,30 @@ public class Container extends Component return getComponentAt(p.x, p.y); } - public Component findComponentAt (int x, int y) + public Component findComponentAt(int x, int y) { - if (! contains (x, y)) + if (! contains(x, y)) return null; for (int i = 0; i < ncomponents; ++i) { - // Ignore invisible children... - if (!component[i].isVisible()) - continue; - - int x2 = x - component[i].x; - int y2 = y - component[i].y; - // We don't do the contains() check right away because - // findComponentAt would redundantly do it first thing. - if (component[i] instanceof Container) - { - Container k = (Container) component[i]; - Component r = k.findComponentAt (x2, y2); - if (r != null) - return r; - } - else if (component[i].contains (x2, y2)) - return component[i]; + // Ignore invisible children... + if (!component[i].isVisible()) + continue; + + int x2 = x - component[i].x; + int y2 = y - component[i].y; + // We don't do the contains() check right away because + // findComponentAt would redundantly do it first thing. + if (component[i] instanceof Container) + { + Container k = (Container) component[i]; + Component r = k.findComponentAt(x2, y2); + if (r != null) + return r; + } + else if (component[i].contains(x2, y2)) + return component[i]; } return this; @@ -903,22 +855,12 @@ public class Container extends Component * to create its peer. Peers for any child components will also be * created. */ - public void addNotify () + public void addNotify() { - addNotifyContainerChildren (); + addNotifyContainerChildren(); super.addNotify(); } - private void addNotifyContainerChildren() - { - for (int i = ncomponents; --i >= 0; ) - { - component[i].addNotify(); - if (component[i].isLightweight()) - enableEvents(component[i].eventMask); - } - } - /** * Called when this container is removed from its parent container to * inform it to destroy its peer. This causes the peers of all child @@ -927,7 +869,7 @@ public class Container extends Component public void removeNotify() { for (int i = 0; i < ncomponents; ++i) - component[i].removeNotify (); + component[i].removeNotify(); super.removeNotify(); } @@ -940,15 +882,15 @@ public class Container extends Component * @return <code>true</code> if this container is an ancestor of the * specified component, <code>false</code>. */ - public boolean isAncestorOf (Component comp) + public boolean isAncestorOf(Component comp) { - for (;;) + while (true) { - if (comp == null) - return false; - if (comp == this) - return true; - comp = comp.getParent(); + if (comp == null) + return false; + if (comp == this) + return true; + comp = comp.getParent(); } } @@ -974,11 +916,11 @@ public class Container extends Component * @param stream The <code>PrintStream</code> to write to. * @param indent The indentation point. */ - public void list (PrintStream out, int indent) + public void list(PrintStream out, int indent) { - super.list (out, indent); + super.list(out, indent); for (int i = 0; i < ncomponents; ++i) - component[i].list (out, indent + 2); + component[i].list(out, indent + 2); } /** @@ -990,11 +932,193 @@ public class Container extends Component */ public void list(PrintWriter out, int indent) { - super.list (out, indent); + super.list(out, indent); + for (int i = 0; i < ncomponents; ++i) + component[i].list(out, indent + 2); + } + + public void setFocusTraversalKeys(int id, Set keys) + { + } + public Set getFocusTraversalKeys(int id) + { + return null; + } + public boolean areFocusTraversalKeysSet(int id) + { + return false; + } + public boolean isFocusCycleRoot(Container c) + { + return false; + } + public void transferFocusBackward() + { + } + public void setFocusTraversalPolicy(FocusTraversalPolicy policy) + { + } + public FocusTraversalPolicy getFocusTraversalPolicy() + { + return null; + } + public boolean isFocusTraversalPolicySet() + { + return false; + } + public void setFocusCycleRoot(boolean focusCycleRoot) + { + } + public boolean isFocusCycleRoot() + { + return false; + } + public void transferFocusDownCycle() + { + } + public void applyComponentOrientation(ComponentOrientation o) + { + } + public void addPropertyChangeListener(PropertyChangeListener l) + { + } + public void addPropertyChangeListener(String name, PropertyChangeListener l) + { + } + + + // Hidden helper methods. + + /** + * Perform a graphics operation on the children of this container. + * For each applicable child, the visitChild() method will be called + * to perform the graphics operation. + * + * @param gfx The graphics object that will be used to derive new + * graphics objects for the children. + * + * @param visitor Object encapsulating the graphics operation that + * should be performed. + * + * @param lightweightOnly If true, only lightweight components will + * be visited. + */ + private void visitChildren(Graphics gfx, GfxVisitor visitor, + boolean lightweightOnly) + { + // FIXME: do locking + for (int i = 0; i < ncomponents; ++i) - component[i].list (out, indent + 2); + { + Component comp = component[i]; + boolean applicable = comp.isVisible() + && (comp.isLightweight() || !lightweightOnly); + + if (applicable) + visitChild(gfx, visitor, comp); + } + } + + /** + * Perform a graphics operation on a child. A translated and clipped + * graphics object will be created, and the visit() method of the + * visitor will be called to perform the operation. + * + * @param gfx The graphics object that will be used to derive new + * graphics objects for the child. + * + * @param visitor Object encapsulating the graphics operation that + * should be performed. + * + * @param comp The child component that should be visited. + */ + private void visitChild(Graphics gfx, GfxVisitor visitor, + Component comp) + { + Rectangle bounds = comp.getBounds(); + Rectangle clip = gfx.getClipBounds().intersection(bounds); + + if (clip.isEmpty()) return; + + Graphics gfx2 = gfx.create(); + gfx2.setClip(clip.x, clip.y, clip.width, clip.height); + gfx2.translate(bounds.x, bounds.y); + + visitor.visit(comp, gfx2); + } + + void dispatchEventImpl(AWTEvent e) + { + if ((e.id <= ContainerEvent.CONTAINER_LAST + && e.id >= ContainerEvent.CONTAINER_FIRST) + && (containerListener != null + || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0)) + processEvent(e); + else + super.dispatchEventImpl(e); } + // This is used to implement Component.transferFocus. + Component findNextFocusComponent(Component child) + { + int start, end; + if (child != null) + { + for (start = 0; start < ncomponents; ++start) + { + if (component[start] == child) + break; + } + end = start; + // This special case lets us be sure to terminate. + if (end == 0) + end = ncomponents; + ++start; + } + else + { + start = 0; + end = ncomponents; + } + + for (int j = start; j != end; ++j) + { + if (j >= ncomponents) + { + // The JCL says that we should wrap here. However, that + // seems wrong. To me it seems that focus order should be + // global within in given window. So instead if we reach + // the end we try to look in our parent, if we have one. + if (parent != null) + return parent.findNextFocusComponent(this); + j -= ncomponents; + } + if (component[j] instanceof Container) + { + Component c = component[j]; + c = c.findNextFocusComponent(null); + if (c != null) + return c; + } + else if (component[j].isFocusTraversable()) + return component[j]; + } + + return null; + } + + private void addNotifyContainerChildren() + { + for (int i = ncomponents; --i >= 0; ) + { + component[i].addNotify(); + if (component[i].isLightweight()) + enableEvents(component[i].eventMask); + } + } + + + // Nested classes. /* The following classes are used in concert with the visitChildren() method to implement all the graphics operations @@ -1029,52 +1153,177 @@ public class Container extends Component public static final GfxVisitor INSTANCE = new GfxPrintAllVisitor(); } - // This is used to implement Component.transferFocus. - Component findNextFocusComponent (Component child) + /** + * This class provides accessibility support for subclasses of container. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.3 + */ + protected class AccessibleAWTContainer extends AccessibleAWTComponent { - int start, end; - if (child != null) + /** + * Compatible with JDK 1.4+. + */ + private static final long serialVersionUID = 5081320404842566097L; + + /** + * The handler to fire PropertyChange when children are added or removed. + * + * @serial the handler for property changes + */ + protected ContainerListener accessibleContainerHandler + = new AccessibleContainerHandler(); + + /** + * The default constructor. + */ + protected AccessibleAWTContainer() + { + Container.this.addContainerListener(accessibleContainerHandler); + } + + /** + * Return the number of accessible children of the containing accessible + * object (at most the total number of its children). + * + * @return the number of accessible children + */ + public int getAccessibleChildrenCount() + { + int count = 0; + int i = component == null ? 0 : component.length; + while (--i >= 0) + if (component[i] instanceof Accessible) + count++; + return count; + } + + /** + * Return the nth accessible child of the containing accessible object. + * + * @param i the child to grab, zero-based + * @return the accessible child, or null + */ + public Accessible getAccessibleChild(int i) + { + 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; + } + + /** + * Return the accessible child located at point (in the parent's + * coordinates), if one exists. + * + * @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) + { + Component c = getComponentAt(p.x, p.y); + return c != Container.this && c instanceof Accessible ? (Accessible) c + : null; + } + + /** + * This class fires a <code>PropertyChange</code> listener, if registered, + * when children are added or removed from the enclosing accessible object. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.3 + */ + protected class AccessibleContainerHandler implements ContainerListener + { + /** + * Default constructor. + */ + protected AccessibleContainerHandler() { - for (start = 0; start < ncomponents; ++start) - { - if (component[start] == child) - break; - } - end = start; - // This special case lets us be sure to terminate. - if (end == 0) - end = ncomponents; - ++start; } - else + + /** + * Fired when a component is added; forwards to the PropertyChange + * listener. + * + * @param e the container event for adding + */ + public void componentAdded(ContainerEvent e) { - start = 0; - end = ncomponents; + AccessibleAWTContainer.this.firePropertyChange + (ACCESSIBLE_CHILD_PROPERTY, null, e.getChild()); } - for (int j = start; j != end; ++j) + /** + * Fired when a component is removed; forwards to the PropertyChange + * listener. + * + * @param e the container event for removing + */ + public void componentRemoved(ContainerEvent e) { - if (j >= ncomponents) - { - // The JCL says that we should wrap here. However, that - // seems wrong. To me it seems that focus order should be - // global within in given window. So instead if we reach - // the end we try to look in our parent, if we have one. - if (parent != null) - return parent.findNextFocusComponent (this); - j -= ncomponents; - } - if (component[j] instanceof Container) - { - Component c = component[j]; - c = c.findNextFocusComponent (null); - if (c != null) - return c; - } - else if (component[j].isFocusTraversable ()) - return component[j]; + AccessibleAWTContainer.this.firePropertyChange + (ACCESSIBLE_CHILD_PROPERTY, e.getChild(), null); } - - return null; + } // class AccessibleContainerHandler + } // class AccessibleAWTPanel +} // class Container + + +/** + * Undocumented helper class. + * STUBBED + */ +class LightweightDispatcher implements Serializable, AWTEventListener +{ + private static final long serialVersionUID = 5184291520170872969L; + private Container nativeContainer; + private Component focus; + private transient Component mouseEventTarget; + private transient Component targetLastEntered; + private transient boolean isMouseInNativeContainer; + private Cursor nativeCursor; + private long eventMask; + LightweightDispatcher(Container c) + { + } + void dispose() + { + } + void enableEvents(long l) + { + } + boolean dispatchEvent(AWTEvent e) + { + return true; + } + boolean isMouseGrab(MouseEvent e) + { + return true; + } + boolean processMouseEvent(MouseEvent e) + { + return true; + } + void trackMouseEnterExit(Component c, MouseEvent e) + { + } + void startListeningForOtherDrags() + { + } + void stopListeningForOtherDrags() + { + } + public void eventDispatched(AWTEvent e) + { + } + void retargetMouseEvent(Component c, int i, MouseEvent e) + { } -} +} // class LightweightDispatcher diff --git a/libjava/java/awt/ContainerOrderFocusTraversalPolicy.java b/libjava/java/awt/ContainerOrderFocusTraversalPolicy.java new file mode 100644 index 00000000000..4c0d94e477d --- /dev/null +++ b/libjava/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/libjava/java/awt/DefaultFocusTraversalPolicy.java b/libjava/java/awt/DefaultFocusTraversalPolicy.java new file mode 100644 index 00000000000..ac3a1786cc6 --- /dev/null +++ b/libjava/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/libjava/java/awt/DefaultKeyboardFocusManager.java b/libjava/java/awt/DefaultKeyboardFocusManager.java new file mode 100644 index 00000000000..e2a2f688e74 --- /dev/null +++ b/libjava/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/libjava/java/awt/Dimension.java b/libjava/java/awt/Dimension.java index 6d4777f9f3b..282291d7ca7 100644 --- a/libjava/java/awt/Dimension.java +++ b/libjava/java/awt/Dimension.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2002 Free Software Foundation +/* Dimension.java -- represents a 2-dimensional span + Copyright (C) 1999, 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,136 +38,197 @@ exception statement from your version. */ package java.awt; -/* Written using "Java Class Libraries", 2nd edition, plus online - * API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct, except that neither toString - * has not been compared with JDK output. - */ +import java.awt.geom.Dimension2D; +import java.io.Serializable; /** - * This class holds a width and height value pair. - * - * @author Per Bothner <bothner@cygnus.com> - * @author Aaron M. Renn (arenn@urbanophile.com) - * @date Fenruary 8, 1999. - */ -public class Dimension extends java.awt.geom.Dimension2D - implements java.io.Serializable + * This class holds a width and height value pair. This is used in plenty + * of windowing classes, but also has geometric meaning. + * + * <p>It is valid for a dimension to have negative width or height; but it + * is considered to have no area. Therefore, the behavior in various methods + * is undefined in such a case. + * + * <p>There are some public fields; if you mess with them in an inconsistent + * manner, it is your own fault when you get invalid results. Also, this + * class is not threadsafe. + * + * @author Per Bothner <bothner@cygnus.com> + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @see Component + * @see LayoutManager + * @since 1.0 + * @status updated to 1.14 + */ +public class Dimension extends Dimension2D implements Serializable { /** - * This width of this object. + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = 4723952579491349524L; + + /** + * The width of this object. + * + * @see #getSize() + * @see #setSize(double, double) + * @serial the width */ public int width; /** * The height of this object. + * + * @see #getSize() + * @see #setSize(double, double) + * @serial the height */ public int height; /** - * Initializes a new instance of <code>Dimension</code> with a width - * and height of zero. + * Create a new Dimension with a width and height of zero. */ - public Dimension () { } + public Dimension() + { + } /** - * Initializes a new instance of <code>Dimension</code> to have a width - * and height identical to that of the specified dimension object. + * Create a new Dimension with width and height identical to that of the + * specified dimension. * - * @param dim The <code>Dimension</code> to take the width and height from. + * @param d the Dimension to copy + * @throws NullPointerException if d is null */ - public Dimension (Dimension dim) + public Dimension(Dimension d) { - this.width = dim.width; - this.height = dim.height; + width = d.width; + height = d.height; } /** - * Initializes a new instance of <code>Dimension</code> with the - * specified width and height. + * Create a new Dimension with the specified width and height. * - * @param width The width of this object. - * @param height The height of this object. + * @param w the width of this object + * @param h the height of this object */ - public Dimension (int width, int height) + public Dimension(int w, int h) { - this.width = width; - this.height = height; + width = w; + height = h; } /** - * Tests this object for equality against 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>Dimension</code>. - * <li>Has width and height values identical to this object. - * </ul> + * Gets the width of this dimension. * - * @param obj The object to test against. + * @return the width, as a double + */ + public double getWidth() + { + return width; + } + + /** + * Gets the height of this dimension. * - * @return <code>true</code> if the specified object is equal to this - * object, <code>false</code> otherwise. + * @return the height, as a double */ - public boolean equals (Object obj) + public double getHeight() { - if (! (obj instanceof Dimension)) - return false; - Dimension dim = (Dimension) obj; - return height == dim.height && width == dim.width; + return height; } /** - * Returns the size of this object. Not very useful. + * Sets the size of this dimension. The values are rounded to int. * - * @return This object. + * @param w the new width + * @param h the new height + * @since 1.2 */ - public Dimension getSize () { return new Dimension(this); } + public void setSize(double w, double h) + { + width = (int) w; + height = (int) h; + } + + /** + * Returns the size of this dimension. A pretty useless method, as this is + * already a dimension. + * + * @return a copy of this dimension + * @see #setSize(Dimension) + * @since 1.1 + */ + public Dimension getSize() + { + return new Dimension(width, height); + } /** * Sets the width and height of this object to match that of the * specified object. * - * @param dim The <code>Dimension</code> object to get the new width and - * height from. + * @param d the Dimension to get the new width and height from + * @throws NullPointerException if d is null + * @see #getSize() + * @since 1.1 */ - public void setSize (Dimension dim) + public void setSize(Dimension d) { - this.width = dim.width; - this.height = dim.height; + width = d.width; + height = d.height; } /** * Sets the width and height of this object to the specified values. * - * @param width The new width value. - * @param height The new height value. + * @param w the new width value + * @param h the new height value */ - public void setSize (int width, int height) + public void setSize(int w, int h) { - this.width = width; - this.height = height; + width = w; + height = h; } /** - * Returns a string representation of this object. + * Tests this object for equality against the specified object. This will + * be true if and only if the specified object is an instance of + * Dimension2D, and has the same width and height. * - * @return A string representation of this object. + * @param obj the object to test against + * @return true if the object is equal to this */ - public String toString () + public boolean equals(Object obj) { - return "Dimension[w:"+width+",h:"+height+']'; + if (! (obj instanceof Dimension)) + return false; + Dimension dim = (Dimension) obj; + return height == dim.height && width == dim.width; } - /* Note: There is no Dimension.hashCode. */ - - public double getWidth() { return width; } - public double getHeight() { return height; } + /** + * Return the hashcode for this object. It is not documented, but appears + * to be <code>((width + height) * (width + height + 1) / 2) + width</code>. + * + * @return the hashcode + */ + public int hashCode() + { + // Reverse engineering this was fun! + return (width + height) * (width + height + 1) / 2 + width; + } - public void setSize (double width, double height) + /** + * Returns a string representation of this object. The format is: + * <code>getClass().getName() + "[width=" + width + ",height=" + height + * + ']'</code>. + * + * @return a string representation of this object + */ + public String toString() { - this.width = (int) width; - this.height = (int) height; + return getClass().getName() + + "[width=" + width + ",height=" + height + ']'; } -} +} // class Dimension diff --git a/libjava/java/awt/DisplayMode.java b/libjava/java/awt/DisplayMode.java new file mode 100644 index 00000000000..b988e20be5e --- /dev/null +++ b/libjava/java/awt/DisplayMode.java @@ -0,0 +1,164 @@ +/* DisplayMode.java -- a description of display mode configurations + 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 encapsulates information about the display mode for a graphics + * device configuration. They are device dependent, and may not always be + * available. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see GraphicsDevice + * @since 1.4 + * @status updated to 1.4 + */ +public final class DisplayMode +{ + /** + * Value of the bit depth if multiple depths are supported. + * + * @see #getBitDepth() + */ + public static final int BIT_DEPTH_MULTI = -1; + + /** + * Value of an unknown refresh rate. + * + * @see #getRefreshRate() + */ + public static final int REFRESH_RATE_UNKNOWN = 0; + + /** The width. */ + private final int width; + + /** The height. */ + private final int height; + + /** The bit depth. */ + private final int bitDepth; + + /** The refresh rate. */ + private final int refreshRate; + + /** + * Create a mode with the given parameters. + * + * @param width the width + * @param height the height + * @param bitDepth the bitDepth + * @param refreshRate the refreshRate + * @see #BIT_DEPTH_MULTI + * @see #REFRESH_RATE_UNKNOWN + */ + public DisplayMode(int width, int height, int bitDepth, int refreshRate) + { + this.width = width; + this.height = height; + this.bitDepth = bitDepth; + this.refreshRate = refreshRate; + } + + /** + * Returns the height, in pixels. + * + * @return the height + */ + public int getHeight() + { + return height; + } + + /** + * Returns the width, in pixels. + * + * @return the width + */ + public int getWidth() + { + return width; + } + + /** + * Returns the bit depth, in bits per pixel. This may be BIT_DEPTH_MULTI. + * + * @return the bit depth + * @see #BIT_DEPTH_MULTI + */ + public int getBitDepth() + { + return bitDepth; + } + + /** + * Returns the refresh rate, in hertz. This may be REFRESH_RATE_UNKNOWN. + * + * @return the refresh rate + * @see #REFRESH_RATE_UNKNOWN + */ + public int getRefreshRate() + { + return refreshRate; + } + + /** + * Test for equality. This returns true for two modes with identical + * parameters. + * + * @param o the object to compare to + * @return true if it is equal + */ + public boolean equals(Object o) + { + if (! (o instanceof DisplayMode)) + return false; + DisplayMode m = (DisplayMode) o; + return width == m.width && height == m.height && bitDepth == m.bitDepth + && refreshRate == m.refreshRate; + } + + /** + * Returns a hash code for the display mode. + * + * @return the hash code + */ + public int hashCode() + { + return width + height + bitDepth + refreshRate; + } +} // class DisplayMode diff --git a/libjava/java/awt/EventQueue.java b/libjava/java/awt/EventQueue.java index 6696b0c7480..1ce3d163181 100644 --- a/libjava/java/awt/EventQueue.java +++ b/libjava/java/awt/EventQueue.java @@ -320,4 +320,27 @@ public class EventQueue } } } -} + + /** + * Returns the timestamp of the most recent event that had a timestamp, or + * the initialization time of the event queue if no events have been fired. + * At present, only <code>InputEvent</code>s, <code>ActionEvent</code>s, + * <code>InputMethodEvent</code>s, and <code>InvocationEvent</code>s have + * timestamps, but this may be added to other events in future versions. + * If this is called by the event dispatching thread, it can be any + * (sequential) value, but to other threads, the safest bet is to return + * System.currentTimeMillis(). + * + * @return the most recent timestamp + * @see InputEvent#getWhen() + * @see ActionEvent#getWhen() + * @see InvocationEvent#getWhen() + * @see InputMethodEvent#getWhen() + * @since 1.4 + */ + public static long getMostRecentEventTime() + { + // XXX For now, this ONLY does the current time. + return System.currentTimeMillis(); + } +} // class EventQueue diff --git a/libjava/java/awt/FocusTraversalPolicy.java b/libjava/java/awt/FocusTraversalPolicy.java new file mode 100644 index 00000000000..fcabeceb375 --- /dev/null +++ b/libjava/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/libjava/java/awt/Font.java b/libjava/java/awt/Font.java index b426a990eb8..730a7003e59 100644 --- a/libjava/java/awt/Font.java +++ b/libjava/java/awt/Font.java @@ -73,6 +73,66 @@ public static final int ROMAN_BASELINE = 0; public static final int CENTER_BASELINE = 1; public static final int HANGING_BASELINE = 2; + + /** + * Indicates to <code>createFont</code> that the supplied font data + * is in TrueType format. + * + * <p><em>Specification Note:</em> The Sun JavaDoc for J2SE 1.4 does + * not indicate whether this value also subsumes OpenType. OpenType + * is essentially the same format as TrueType, but allows to define + * glyph shapes in the same way as PostScript, using cubic bezier + * curves. + * + * @since 1.3 + */ + public static final int TRUETYPE_FONT = 0; + + + /** + * A flag for <code>layoutGlyphVector</code>, indicating that the + * orientation of a text run is from left to right. + * + * @since 1.4 + */ + public static final int LAYOUT_LEFT_TO_RIGHT = 0; + + + /** + * A flag for <code>layoutGlyphVector</code>, indicating that the + * orientation of a text run is from right to left. + * + * @since 1.4 + */ + public static final int LAYOUT_RIGHT_TO_LEFT = 1; + + + /** + * A flag for <code>layoutGlyphVector</code>, indicating that the + * text does not contain valid characters before the + * <code>start</code> position. If this flag is set, + * <code>layoutGlyphVector</code> does not examine the text before + * <code>start</code>, even if this would be necessary to select the + * correct glyphs (e.g., for Arabic text). + * + * @since 1.4 + */ + public static final int LAYOUT_NO_START_CONTEXT = 2; + + + /** + * A flag for <code>layoutGlyphVector</code>, indicating that the + * text does not contain valid characters after the + * <code>limit</code> position. If this flag is set, + * <code>layoutGlyphVector</code> does not examine the text after + * <code>limit</code>, even if this would be necessary to select the + * correct glyphs (e.g., for Arabic text). + * + * @since 1.4 + */ + public static final int LAYOUT_NO_LIMIT_CONTEXT = 4; + + // Serialization constant private static final long serialVersionUID = -4206021311591459213L; @@ -162,7 +222,7 @@ decode(String fontspec) { tokenval = Integer.parseInt(token); } - catch(Exception e) { ; } + catch(NumberFormatException e) { ; } if (tokenval != 0) size = tokenval; diff --git a/libjava/java/awt/FontFormatException.java b/libjava/java/awt/FontFormatException.java new file mode 100644 index 00000000000..4ab53bbe834 --- /dev/null +++ b/libjava/java/awt/FontFormatException.java @@ -0,0 +1,65 @@ +/* FontFormatException.java -- the specified font is bad + 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; + +/** + * Thrown when a specified font is bad. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Font + * @since 1.3 + * @status updated to 1.4 + */ +public class FontFormatException extends Exception +{ + /** + * Compatible with JDK 1.4+. + */ + private static final long serialVersionUID = -4481290147811361272L; + + /** + * Create a new instance with the specified detailed error message. + * + * @param message the detailed error message + */ + public FontFormatException(String message) + { + super(message); + } +} // class FontFormatException diff --git a/libjava/java/awt/GradientPaint.java b/libjava/java/awt/GradientPaint.java new file mode 100644 index 00000000000..f008b93f820 --- /dev/null +++ b/libjava/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/libjava/java/awt/GraphicsConfigTemplate.java b/libjava/java/awt/GraphicsConfigTemplate.java new file mode 100644 index 00000000000..52da16799b7 --- /dev/null +++ b/libjava/java/awt/GraphicsConfigTemplate.java @@ -0,0 +1,106 @@ +/* GraphicsConfigTemplate.java -- a template for selecting configurations + 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; + +/** + * This allows filtering an array of GraphicsConfigurations for the best + * one based on various requirements. The resulting configuration has had + * all non-default attributes set as required to meet or exceed the request. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see GraphicsConfiguration + * @see GraphicsDevice + * @since 1.2 + * @status updated to 1.4 + */ +public abstract class GraphicsConfigTemplate implements Serializable +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = -8061369279557787079L; + + /** States that a feature is required to select a configuration. */ + public static final int REQUIRED = 1; + + /** + * States that a feature is preferred, but not required, to select a + * configuration. In the case of multiple valid configurations, the tie + * breaks in favor of the one with the feature. + */ + public static final int PREFERRED = 2; + + /** + * States that a feature is not necessary in the configuration. In the case + * of multiple valid configurations, the tie breaks in favor of the one + * without the feature, to reduce overhead. + */ + public static final int UNNECESSARY = 3; + + /** + * The default constructor. + */ + public GraphicsConfigTemplate() + { + } + + /** + * Returns the "best" match among the array of possible configurations, given + * the criteria of this template. + * + * @param array the array to choose from + * @return the best match + * @throws NullPointerException if array is null + */ + public abstract GraphicsConfiguration getBestConfiguration + (GraphicsConfiguration[] array); + + /** + * Returns true if the given configuration supports all the features required + * by this template. + * + * @param config the configuration to test + * @return true if it is a match + * @throws NullPointerException if config is null + */ + public abstract boolean isGraphicsConfigSupported + (GraphicsConfiguration config); +} // class GraphicsConfigTemplate diff --git a/libjava/java/awt/GraphicsConfiguration.java b/libjava/java/awt/GraphicsConfiguration.java index 4e0fa64723e..c7d0ed4ac8a 100644 --- a/libjava/java/awt/GraphicsConfiguration.java +++ b/libjava/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,35 +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/libjava/java/awt/GraphicsDevice.java b/libjava/java/awt/GraphicsDevice.java new file mode 100644 index 00000000000..27d3cd67ca0 --- /dev/null +++ b/libjava/java/awt/GraphicsDevice.java @@ -0,0 +1,271 @@ +/* GraphicsDevice.java -- information about a graphics device + 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 describes a graphics device available to the given environment. This + * includes screen and printer devices, and the different configurations for + * each device. Also, this allows you to create virtual devices which operate + * over a multi-screen environment. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see GraphicsEnvironment + * @see GraphicsConfiguration + * @since 1.3 + * @status updated to 1.4 + */ +public abstract class GraphicsDevice +{ + /** Device is a raster screen. */ + public static final int TYPE_RASTER_SCREEN = 0; + + /** Device is a printer. */ + public static final int TYPE_PRINTER = 1; + + /** Device is an image buffer not visible to the user. */ + public static final int TYPE_IMAGE_BUFFER = 2; + + /** The current full-screen window, or null if there is none. */ + private Window full_screen; + + /** The current display mode, or null if unknown. */ + private DisplayMode mode; + + /** + * The default constructor. + * + * @see GraphicsEnvironment#getScreenDevices() + * @see GraphicsEnvironment#getDefaultScreenDevice() + * @see GraphicsConfiguration#getDevice() + */ + protected GraphicsDevice() + { + } + + /** + * Returns the type of the device. + * + * @return the device type + * @see #TYPE_RASTER_SCREEN + * @see #TYPE_PRINTER + * @see #TYPE_IMAGE_BUFFER + */ + public abstract int getType(); + + /** + * Returns an identification string for the device. This can be + * vendor-specific, and may be useful for debugging. + * + * @return the identification + */ + public abstract String getIDstring(); + + /** + * Return all configurations valid for this device. + * + * @return an array of configurations + */ + public abstract GraphicsConfiguration[] getConfigurations(); + + /** + * Return the default configuration for this device. + * + * @return the default configuration + */ + public abstract GraphicsConfiguration getDefaultConfiguration(); + + /** + * Return the best configuration, according to the criteria in the given + * template. + * + * @param template the template to adjust by + * @return the best configuration + * @throws NullPointerException if template is null + */ + public GraphicsConfiguration getBestConfiguration + (GraphicsConfigTemplate template) + { + return template.getBestConfiguration(getConfigurations()); + } + + /** + * Returns true if the device supports full-screen exclusive mode. The + * default implementation returns true; subclass it if this is not the case. + * + * @return true if full screen support is available + * @since 1.4 + */ + public boolean isFullScreenSupported() + { + return true; + } + + /** + * Toggle the given window between full screen and normal mode. The previous + * full-screen window, if different, is restored; if the given window is + * null, no window will be full screen. If + * <code>isFullScreenSupported()</code> returns true, full screen mode is + * considered to be exclusive, which implies:<ul> + * <li>Windows cannot overlap the full-screen window. All other application + * windows will always appear beneath the full-screen window in the + * Z-order.</li> + * <li>Input method windows are disabled. It is advisable to call + * <code>Component.enableInputMethods(false)</code> to make a component + * a non-client of the input method framework.</li> + * </ul><br> + * If <code>isFullScreenSupported()</code> returns false, full-screen + * exclusive mode is simulated by resizing the window to the size of the + * screen and positioning it at (0,0). + * + * XXX Not yet implemented in Classpath. + * + * @param w the window to toggle + * @see #isFullScreenSupported() + * @see getFullScreenWindow() + * @see setDisplayMode(DisplayMode) + * @see Component#enableInputMethods(boolean) + * @since 1.4 + */ + public synchronized void setFullScreenWindow(Window w) + { + if (full_screen != null) + ; // XXX Restore the previous window to normal mode. + full_screen = w; + // XXX If w != null, make it full-screen. + throw new Error("not implemented"); + } + + /** + * Returns the current full-screen window of the device, or null if no + * window is full-screen. + * + * @return the full-screen window + * @see #setFullScreenWindow(Window) + * @since 1.4 + */ + public Window getFullScreenWindow() + { + return full_screen; + } + + /** + * Returns whether this device supports low-level display changes. This may + * depend on whether full-screen exclusive mode is available. + * + * XXX The default implementation returns false for now. + * + * @return true if display changes are supported + * @see #setDisplayMode(DisplayMode) + * @since 1.4 + */ + public boolean isDisplayChangeSupported() + { + return false; + } + + /** + * Sets the display mode. This may be dependent on the availability of + * full-screen exclusive mode. + * + * @param mode the new mode + * @throws IllegalArgumentException if the new mode is not in getDisplayModes + * @throws UnsupportedOperationException if ! isDisplayChangeSupported() + * @see #getDisplayMode() + * @see #getDisplayModes() + * @see #isDisplayChangeSupported() + * @since 1.4 + */ + public void setDisplayMode(DisplayMode mode) + { + DisplayMode[] array = getDisplayModes(); + if (! isDisplayChangeSupported()) + throw new UnsupportedOperationException(); + int i = array == null ? 0 : array.length; + while (--i >= 0) + if (array[i].equals(mode)) + break; + if (i < 0) + throw new IllegalArgumentException(); + this.mode = mode; + } + + /** + * Returns the current display mode of this device, or null if unknown. + * + * @return the current display mode + * @see #setDisplayMode(DisplayMode) + * @see #getDisplayModes() + * @since 1.4 + */ + public DisplayMode getDisplayMode() + { + return mode; + } + + /** + * Return an array of all available display modes. This implementation + * returns a 0-length array, so subclasses must override this. + * + * @return the array of available modes + * @since 1.4 + */ + public DisplayMode[] getDisplayModes() + { + return new DisplayMode[0]; + } + + /** + * Return the number of bytes available in accelerated memory on this + * device. The device may support creation or caching on a first-come, + * first-served basis, depending on the operating system and driver. + * Memory may be a finite resource, and because of multi-threading, you + * are not guaranteed that the result of this method ensures your image + * will successfully be put in accelerated memory. A negative result means + * the memory is unlimited. The default implementation assumes no special + * memory is available, and returns 0. + * + * @return the size of accelerated memory available + * @see VolatileImage#flush() + * @see ImageCapabilities#isAccelerated() + */ + public int getAvailableAcceleratedMemory() + { + return 0; + } +} // class GraphicsDevice diff --git a/libjava/java/awt/GraphicsEnvironment.java b/libjava/java/awt/GraphicsEnvironment.java new file mode 100644 index 00000000000..63e23e2f108 --- /dev/null +++ b/libjava/java/awt/GraphicsEnvironment.java @@ -0,0 +1,210 @@ +/* GraphicsEnvironment.java -- information about the graphics environment + 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; +import java.util.Locale; + +/** + * This descibes the collection of GraphicsDevice and Font objects available + * on a given platform. The resources might be local or remote, and specify + * the valid configurations for displaying graphics. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see GraphicsDevice + * @see GraphicsConfiguration + * @since 1.4 + * @status updated to 1.4 + */ +public abstract class GraphicsEnvironment +{ + /** + * The environment must be obtained from a factory or query method, hence + * this constructor is protected. + */ + protected GraphicsEnvironment() + { + } + + /** + * Returns the local graphics environment. + * + * XXX Not implemented in Classpath yet. + * @return the local environment + */ + public static GraphicsEnvironment getLocalGraphicsEnvironment() + { + throw new Error("not implemented"); + } + + /** + * Check if the local environment is headless, meaning that it does not + * support a display, keyboard, or mouse. Many methods in the Abstract + * Windows Toolkit (java.awt) throw a {@link HeadlessException} if this + * returns true. + * + * XXX For now, Classpath assumes that it is never headless. + * + * @return true if the environment is headless, meaning that graphics are + * unsupported + * @since 1.4 + */ + public static boolean isHeadless() + { + // XXX Should be: getLocalGraphicsEnvironment().isHeadlessInstance(); + return false; + } + + /** + * Check if the given environment is headless, meaning that it does not + * support a display, keyboard, or mouse. Many methods in the Abstract + * Windows Toolkit (java.awt) throw a {@link HeadlessException} if this + * returns true. This default implementation returns false, so subclasses + * need only override it if they are headless. + * + * @return true if the environment is headless, meaning that graphics are + * unsupported + * @since 1.4 + */ + public boolean isHeadlessInstance() + { + return false; + } + + /** + * Get an array of all the GraphicsDevice objects. + * + * @return the available graphics devices, may be 0 length + * @throws HeadlessException if the environment is headless + */ + public abstract GraphicsDevice[] getScreenDevices(); + + /** + * Get the default screen GraphicsDevice object. + * + * @return the default screen device + * @throws HeadlessException if the environment is headless + */ + public abstract GraphicsDevice getDefaultScreenDevice(); + + /** + * Return a Graphics2D object which will render into the specified image. + * + * @param image the image to render into + * @return the object that renders into the image + */ + public abstract Graphics2D createGraphics(BufferedImage image); + + /** + * Returns an array of the one-point size fonts available in this + * environment. From there, the user can select the font and derive the + * correct one of proper size and attributes, using <code>deriveFont</code>. + * Only one master version of each font appears in this array; if a font + * can be derived from another, it must be created in that way. + * + * @return the array of available fonts + * @see #getAvailableFontFamilyNames() + * @see Font#deriveFont(int, float) + * @since 1.2 + */ + public abstract Font[] getAllFonts(); + + /** + * Returns an array of the font family names available in this environment. + * This allows flexibility in choosing the style of font, while still letting + * the Font class decide its best match. + * + * @return the array of available font families + * @see #getAllFonts() + * @see Font#getFamily() + * @since 1.2 + */ + public abstract String[] getAvailableFontFamilyNames(); + + /** + * Returns an array of the font family names available in this environment, + * localized to the current Locale if l is non-null. This allows + * flexibility in choosing the style of font, while still letting the Font + * class decide its best match. + * + * @param l the locale to use + * @return the array of available font families, localized + * @see #getAllFonts() + * @see Font#getFamily() + * @since 1.2 + */ + public abstract String[] getAvailableFontFamilyNames(Locale l); + + /** + * Returns the point where a window should be centered. You should probably + * also check that the window fits within the screen bounds. The default + * simply returns the center of the maximum window bounds; subclasses should + * override this if native objects (like scrollbars) make that off-centered. + * + * @return the centering point + * @throws HeadlessException if the environment is headless + * @see #getMaximumWindowBounds() + * @since 1.4 + */ + public Point getCenterPoint() + { + Rectangle r = getMaximumWindowBounds(); + return new Point(r.x + r.width / 2, r.y + r.height / 2); + } + + /** + * Returns the maximum bounds for a centered window object. The default + * implementation simply returns the bounds of the default configuration + * of the default screen; subclasses should override this to if native + * objects (like scrollbars) reduce what is truly available. Also, + * subclasses should override this if the window should be centered across + * a multi-screen display. + * + * @return the maximum window bounds + * @throws HeadlessException if the environment is headless + * @see #getCenterPoint() + * @see GraphicsConfiguration#getBounds() + * @see Toolkit#getScreenInsets(GraphicsConfiguration) + * @since 1.4 + */ + public Rectangle getMaximumWindowBounds() + { + return getDefaultScreenDevice().getDefaultConfiguration().getBounds(); + } +} // class GraphicsEnvironment diff --git a/libjava/java/awt/HeadlessException.java b/libjava/java/awt/HeadlessException.java new file mode 100644 index 00000000000..4e7ef337f23 --- /dev/null +++ b/libjava/java/awt/HeadlessException.java @@ -0,0 +1,72 @@ +/* HeadlessException.java -- operation not possible in headless environment + 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 exception is thrown when code dependent on a keyboard, mouse, or + * display is executed in a headless environment. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.4 + * @status updated to 1.4 + */ +public class HeadlessException extends UnsupportedOperationException +{ + /** + * Compatible with JDK 1.4+. + */ + private static final long serialVersionUID = 167183644944358563L; + + /** + * Create a new instance with no detailed error message. + */ + public HeadlessException() + { + } + + /** + * Create a new instance with the specified detailed error message. + * + * @param message the detailed error message + */ + public HeadlessException(String message) + { + super(message); + } +} // class HeadlessException diff --git a/libjava/java/awt/IllegalComponentStateException.java b/libjava/java/awt/IllegalComponentStateException.java index d10d107ac88..413ed33a4f9 100644 --- a/libjava/java/awt/IllegalComponentStateException.java +++ b/libjava/java/awt/IllegalComponentStateException.java @@ -1,5 +1,5 @@ -/* IllegalComponentStateException.java -- Bad component state - Copyright (C) 1999 Free Software Foundation, Inc. +/* IllegalComponentStateException.java -- bad component state + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,37 +39,33 @@ exception statement from your version. */ package java.awt; /** - * This exception is thrown when the requested operation failed because - * a component was not in the proper state. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This exception is thrown when the requested operation failed because + * a component was not in the proper state. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @status updated to 1.4 + */ public class IllegalComponentStateException extends IllegalStateException { + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -1889339587208144238L; -/** - * Initializes a new instance of <code>IllegalComponentStateException</code> - * with the specified detailed error message. - * - * @param message The detailed error message. - */ -public -IllegalComponentStateException(String message) -{ - super(message); -} - -/*************************************************************************/ - -/** - * Initializes a new instance of <code>IllegalComponentStateException</code> - * with no detailed error message. - */ -public -IllegalComponentStateException() -{ - super(); -} + /** + * Create a new instance with no detailed error message. + */ + public IllegalComponentStateException() + { + } + /** + * Create a new instance with the specified detailed error message. + * + * @param message the detailed error message + */ + public IllegalComponentStateException(String message) + { + super(message); + } } // class IllegalComponentStateException - diff --git a/libjava/java/awt/Image.java b/libjava/java/awt/Image.java index fb9b404336c..d4b75b88822 100644 --- a/libjava/java/awt/Image.java +++ b/libjava/java/awt/Image.java @@ -1,5 +1,5 @@ -/* Image.java -- Java class for images - Copyright (C) 1999 Free Software Foundation, Inc. +/* Image.java -- superclass for images + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,160 +38,153 @@ exception statement from your version. */ package java.awt; -import java.awt.image.*; +import java.awt.image.AreaAveragingScaleFilter; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.image.ReplicateScaleFilter; /** - * This is the abstract superclass of all image objects in Java. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public abstract class Image -{ - -/* - * Static Variables + * This is the abstract superclass of all image objects in Java. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.0 + * @status updated to 1.4 */ - -/** - * Constant indicating that the default scaling algorithm should be used. - */ -public static final int SCALE_DEFAULT = 1; - -/** - * Constant indicating that a fast scaling algorithm should be used. - */ -public static final int SCALE_FAST = 2; - -/** - * Constant indicating that a smooth scaling algorithm should be used. - */ -public static final int SCALE_SMOOTH = 4; - -/** - * Constant indicating that the <code>ReplicateScaleFilter</code> class - * algorithm should be used for scaling. - */ -public static final int SCALE_REPLICATE = 8; - -/** - * Constant indicating that the area averaging scaling algorithm should be - * used. - */ -public static final int SCALE_AREA_AVERAGING = 16; - -/** - * This variable is returned whenever a property that is not defined - * is requested. - */ -public static final Object UndefinedProperty = Image.class; - -/*************************************************************************/ - -/* - * Constructors - */ - -/** - * A default constructor for subclasses. - */ -public -Image() +public abstract class Image { -} - -/*************************************************************************/ - -/* - * Instance Methods - */ - -/** - * Returns the width of the image, or -1 if it is unknown. If the - * image width is unknown, the observer object will be notified when - * the value is known. - * - * @param observer The image observer for this object. - */ -public abstract int -getWidth(ImageObserver observer); - -/*************************************************************************/ - -/** - * Returns the height of the image, or -1 if it is unknown. If the - * image height is unknown, the observer object will be notified when - * the value is known. - * - * @param observer The image observer for this object. - */ -public abstract int -getHeight(ImageObserver observer); - -/*************************************************************************/ - -/** - * Returns the image producer object for this object. - * - * @return The image producer for this object. - */ -public abstract ImageProducer -getSource(); - -/*************************************************************************/ - -/** - * Returns a graphics context object for drawing an off-screen object. - * This method is only valid for off-screen objects. - * - * @return A graphics context object for an off-screen object. - */ -public abstract Graphics -getGraphics(); - -/*************************************************************************/ - -/** - * This method requests a named property for an object. The value of the - * property is returned. The value <code>UndefinedProperty</code> is - * returned if there is no property with the specified name. The value - * <code>null</code> is returned if the properties for the object are - * not yet known. In this case, the specified image observer is notified - * when the properties are known. - * - * @param name The requested property name. - * @param observer The image observer for this object. - */ -public abstract Object -getProperty(String name, ImageObserver observer); - -/*************************************************************************/ - -/** - * Scales the image to the requested dimension. - * - * XXX: FIXME - * - * @param width The width of the scaled image. - * @param height The height of the scaled image. - * @param flags A value indicating the algorithm to use, which will be - * set from contants defined in this class. - * - * @return The scaled <code>Image</code> object. - */ -public Image -getScaledInstance(int width, int height, int flags) + /** + * This variable is returned whenever a property that is not defined + * is requested. + */ + // For debug purposes, this might as well be a unique string. + public static final Object UndefinedProperty + = new String("undefined property"); + + /** + * Constant indicating that the default scaling algorithm should be used. + * + * @since 1.1 + */ + public static final int SCALE_DEFAULT = 1; + + /** + * Constant indicating that a fast scaling algorithm should be used. + * + * @since 1.1 + */ + public static final int SCALE_FAST = 2; + + /** + * Constant indicating that a smooth scaling algorithm should be used. + * + * @since 1.1 + */ + public static final int SCALE_SMOOTH = 4; + + /** + * Constant indicating that the <code>ReplicateScaleFilter</code> class + * algorithm should be used for scaling. + * + * @see ReplicateScaleFilter + * @since 1.1 + */ + public static final int SCALE_REPLICATE = 8; + + /** + * Constant indicating that the area averaging scaling algorithm should be + * used. + * + * @see AreaAveragingScaleFilter + * @since 1.1 + */ + public static final int SCALE_AREA_AVERAGING = 16; + + /** + * A default constructor for subclasses. + */ + public Image() { - return null; } -/*************************************************************************/ - -/** - * Flushes (that is, destroys) any resources used for this image. This - * includes the actual image data. - */ -public abstract void -flush(); + /** + * Returns the width of the image, or -1 if it is unknown. If the + * image width is unknown, the observer object will be notified when + * the value is known. + * + * @param observer the image observer for this object + * @return the width in pixels + * @see #getHeight(ImageObserver) + */ + public abstract int getWidth(ImageObserver observer); + + /** + * Returns the height of the image, or -1 if it is unknown. If the + * image height is unknown, the observer object will be notified when + * the value is known. + * + * @param observer the image observer for this object + * @return the height in pixels + * @see #getWidth(ImageObserver) + */ + public abstract int getHeight(ImageObserver observer); + + /** + * Returns the image producer object for this object. The producer is the + * object which generates pixels for this image. + * + * @return the image producer for this object + */ + public abstract ImageProducer getSource(); + + /** + * Returns a graphics context object for drawing an off-screen object. + * This method is only valid for off-screen objects. + * + * @return a graphics context object for an off-screen object + * @see Graphics#createImage(int, int) + */ + public abstract Graphics getGraphics(); + + /** + * This method requests a named property for an object. The value of the + * property is returned. The value <code>UndefinedProperty</code> is + * returned if there is no property with the specified name. The value + * <code>null</code> is returned if the properties for the object are + * not yet known. In this case, the specified image observer is notified + * when the properties are known. + * + * @param name the requested property name + * @param observer the image observer for this object + * @return the named property, if available + * @see #UndefinedProperty + */ + public abstract Object getProperty(String name, ImageObserver observer); + + /** + * Scales the image to the requested dimension. A new Image with asynchronous + * loading will be produced according to the hints of the algorithm + * requested. If either the width or height is non-positive, it is adjusted + * to preserve the original aspect ratio. + * + * @param width the width of the scaled image + * @param height the height of the scaled image + * @param flags a value indicating the algorithm to use + * @return the scaled <code>Image</code> object + * @see #SCALE_DEFAULT + * @see #SCALE_FAST + * @see #SCALE_SMOOTH + * @see #SCALE_REPLICATE + * @see #SCALE_AREA_AVERAGING + * @since 1.1 + */ + public Image getScaledInstance(int width, int height, int flags) + { + throw new Error("not implemented"); + } + /** + * Flushes (that is, destroys) any resources used for this image. This + * includes the actual image data. + */ + public abstract void flush(); } // class Image - diff --git a/libjava/java/awt/ImageCapabilities.java b/libjava/java/awt/ImageCapabilities.java new file mode 100644 index 00000000000..4d274e2021e --- /dev/null +++ b/libjava/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/libjava/java/awt/Insets.java b/libjava/java/awt/Insets.java index fb1d46563de..573005a7689 100644 --- a/libjava/java/awt/Insets.java +++ b/libjava/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/libjava/java/awt/ItemSelectable.java b/libjava/java/awt/ItemSelectable.java index 4d1314fc3d2..ddf77aeb10a 100644 --- a/libjava/java/awt/ItemSelectable.java +++ b/libjava/java/awt/ItemSelectable.java @@ -1,5 +1,5 @@ -/* ItemSelectable.java -- Items that can be selected - Copyright (C) 1999 Free Software Foundation, Inc. +/* ItemSelectable.java -- items that can be selected + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,44 +41,35 @@ package java.awt; import java.awt.event.ItemListener; /** - * This interface is for objects that can have one or more items - * selected. For example, radio buttons. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This interface is for objects that can have one or more items selected. + * For example, radio buttons. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.0 + * @status updated to 1.4 + */ public interface ItemSelectable { - -/** - * Returns the list of objects that are selected in this component. - * - * @return The list of objects that are selected, or <code>null</code> if - * no objects are selected. - */ -public abstract Object[] -getSelectedObjects(); - -/*************************************************************************/ - -/** - * Adds an item listener to this object. It will receive - * selection events for this object. - * - * @param listener The item listener to add. - */ -public abstract void -addItemListener(ItemListener listener); - -/*************************************************************************/ - -/** - * Removes an item listener from this object. It will no longer receive - * selection change events. - * - * @param listener The item listener to remove. - */ -public abstract void -removeItemListener(ItemListener listener); - + /** + * Returns the list of objects that are selected in this component. + * + * @return the list of selected objects, or null + */ + Object[] getSelectedObjects(); + + /** + * Adds an item listener to this object. It will receive selection events + * for this object by the user (but not programatically). If listener is + * null, it is ignored. + * + * @param listener the item listener to add + */ + void addItemListener(ItemListener listener); + + /** + * Removes an item listener from this object. + * + * @param listener the item listener to remove + */ + void removeItemListener(ItemListener listener); } // interface ItemSelectable - diff --git a/libjava/java/awt/JobAttributes.java b/libjava/java/awt/JobAttributes.java new file mode 100644 index 00000000000..b64234dda5f --- /dev/null +++ b/libjava/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/libjava/java/awt/KeyEventDispatcher.java b/libjava/java/awt/KeyEventDispatcher.java new file mode 100644 index 00000000000..95aad8030d1 --- /dev/null +++ b/libjava/java/awt/KeyEventDispatcher.java @@ -0,0 +1,82 @@ +/* KeyEventDispatcher.java -- dispatches key events + 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; + +/** + * An instance of this interface coordinates with a KeyboardFocusManager to + * target and dispatch all key events. This allows retargeting, consuming, + * changing, or otherwise manipulating the key event before sending it on to + * a target. + * + * <p>By default, the KeyboardFocusManager is the sink for all key events not + * dispatched by other dispatchers. Therefore, it is unnecessary for the user + * to register the focus manager as a dispatcher. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see KeyboardFocusManager#addKeyEventDispatcher(KeyEventDispatcher) + * @see KeyboardFocusManager#removeKeyEventDispatcher(KeyEventDispatcher) + * @since 1.4 + * @status updated to 1.4 + */ +public interface KeyEventDispatcher +{ + /** + * Called by the KeyboardFocusManager to request that a key event be + * dispatched. The dispatcher is free to retarget the event, consume it, + * dispatch it, or make other changes. This is usually done to allow + * delivery of key events to objects other than the window in focus, such + * as for navigating non-focusable components. If this dispatcher chooses + * to dispatch the event itself, it should call <code>redispatchEvent</code> + * to avoid infinite recursion. + * + * <p>If the return value is false, the KeyEvent is passed to the next + * dispatcher in the chain, ending with the KeyboardFocusManager. If the + * return value is true, the event has been consumed (although it might + * have been ignored), and no further action will be taken on the event. Be + * sure to check whether the event was consumed before dispatching it + * further. + * + * @param e the key event + * @return true if the event has been consumed + * @see KeyboardFocusManager#redispatchEvent(Component, AWTEvent) + */ + boolean dispatchKeyEvent(KeyEvent e); +} // interface KeyEventDispatcher diff --git a/libjava/java/awt/KeyEventPostProcessor.java b/libjava/java/awt/KeyEventPostProcessor.java new file mode 100644 index 00000000000..5069aaf510c --- /dev/null +++ b/libjava/java/awt/KeyEventPostProcessor.java @@ -0,0 +1,81 @@ +/* KeyEventPostProcessor.java -- performs actions after a key event dispatch + 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; + +/** + * An instance of this interface coordinates with a KeyboardFocusManager to + * target and dispatch all key events that are otherwise unconsumed. This + * allows events which take place when nothing has focus to still operate, + * such as menu keyboard shortcuts. + * + * <p>By default, the KeyboardFocusManager is the sink for all key events not + * post-processed elsewhere. Therefore, it is unnecessary for the user + * to register the focus manager as a dispatcher. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see KeyboardFocusManager#addKeyEventPostProcessor(KeyEventPostProcessor) + * @see KeyboardFocusManager#removeKeyEventPostProcessor(KeyEventPostProcessor) + * @since 1.4 + * @status updated to 1.4 + */ +public interface KeyEventPostProcessor +{ + /** + * Called by the KeyboardFocusManager to request that a key event be + * post-processed. Typically, the event has already been dispatched and + * handled, unless no object has focus. Thus, this allows global event + * handling for things like menu shortcuts. If this post-processor chooses + * to dispatch the event, it should call <code>redispatchEvent</code> + * to avoid infinite recursion. + * + * <p>If the return value is false, the KeyEvent is passed to the next + * dispatcher in the chain, ending with the KeyboardFocusManager. If the + * return value is true, the event has been consumed (although it might + * have been ignored), and no further action will be taken on the event. Be + * sure to check whether the event was consumed before dispatching it + * further. + * + * @param e the key event + * @return true if the event has been consumed + * @see KeyboardFocusManager#redispatchEvent(Component, AWTEvent) + */ + boolean postProcessKeyEvent(KeyEvent e); +} // interface KeyEventPostProcessor diff --git a/libjava/java/awt/KeyboardFocusManager.java b/libjava/java/awt/KeyboardFocusManager.java new file mode 100644 index 00000000000..2680894b8df --- /dev/null +++ b/libjava/java/awt/KeyboardFocusManager.java @@ -0,0 +1,556 @@ +/* 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 + && ((Container) focusOwner).isFocusCycleRoot()) + downFocusCycle((Container) focusOwner); + } +} // class KeyboardFocusManager diff --git a/libjava/java/awt/LayoutManager.java b/libjava/java/awt/LayoutManager.java index 695755b62b2..1231c3eb62f 100644 --- a/libjava/java/awt/LayoutManager.java +++ b/libjava/java/awt/LayoutManager.java @@ -1,5 +1,5 @@ -/* LayoutManager.java -- Layout containers in a Window - Copyright (C) 1999 Free Software Foundation, Inc. +/* LayoutManager.java -- lay out elements in a Container + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,68 +39,54 @@ exception statement from your version. */ package java.awt; /** - * This interface is for laying out containers. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This interface is for laying out containers in a particular sequence. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see Container + * @since 1.0 + * @status updated to 1.4 + */ public interface LayoutManager { - -/** - * Adds the specified component to the layout group. - * - * @param name The name of the component to add. - * @param component The component to add. - */ -public abstract void -addLayoutComponent(String name, Component component); - -/*************************************************************************/ - -/** - * Removes the specified component from the layout group. - * - * @param component The component to remove. - */ -public abstract void -removeLayoutComponent(Component component); - -/*************************************************************************/ - -/** - * Calculates the preferred size for this container, taking into account - * the components in the specified parent container. - * - * @param parent The parent container. - * - * @return The preferred dimensions of this container. - */ -public abstract Dimension -preferredLayoutSize(Container parent); - -/*************************************************************************/ - -/** - * Calculates the minimum size for this container, taking into account - * the components in the specified parent container. - * - * @param parent The parent container. - * - * @return The minimum dimensions of this container. - */ -public abstract Dimension -minimumLayoutSize(Container parent); - -/*************************************************************************/ - -/** - * Lays out the components in this container on the specified parent - * container. - * - * @param parent The parent container. - */ -public abstract void -layoutContainer(Container parent); - + /** + * Adds the specified component to the layout group. + * + * @param name the name of the component to add + * @param component the component to add + */ + void addLayoutComponent(String name, Component component); + + /** + * Removes the specified component from the layout group. + * + * @param component the component to remove + */ + void removeLayoutComponent(Component component); + + /** + * Calculates the preferred size for this container, taking into account + * the components it contains. + * + * @param parent the parent container to lay out + * @return the preferred dimensions of this container + * @see #minimumLayoutSize(Container) + */ + Dimension preferredLayoutSize(Container parent); + + /** + * Calculates the minimum size for this container, taking into account + * the components it contains. + * + * @param parent the parent container to lay out + * @return the minimum dimensions of this container + * @see #preferredLayoutSize(Container) + */ + Dimension minimumLayoutSize(Container parent); + + /** + * Lays out the components in the given container. + * + * @param parent the container to lay out + */ + void layoutContainer(Container parent); } // interface LayoutManager - diff --git a/libjava/java/awt/LayoutManager2.java b/libjava/java/awt/LayoutManager2.java index 77c021d0cee..418e4d886fb 100644 --- a/libjava/java/awt/LayoutManager2.java +++ b/libjava/java/awt/LayoutManager2.java @@ -1,5 +1,5 @@ -/* LayoutManager2.java -- Enhanced layout manager. - Copyright (C) 1999 Free Software Foundation, Inc. +/* LayoutManager2.java -- enhanced layout manager + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,70 +39,62 @@ exception statement from your version. */ package java.awt; /** - * Layout manager for laying out containers based on contraints. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * Layout manager for laying out containers based on contraints. The + * constraints control how the layout will proceed. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see LayoutManager + * @see Container + * @since 1.0 + * @status updated to 1.4 + */ public interface LayoutManager2 extends LayoutManager { - -/** - * Adds the specified component to the layout, with the specified - * constraint object. - * - * @param component The component to add. - * @param constraint The constraint object. - */ -public abstract void -addLayoutComponent(Component component, Object contraint); - -/*************************************************************************/ - -/** - * Determines the minimum size of the specified target container. - * - * @param target The target container. - */ -public abstract Dimension -maximumLayoutSize(Container target); - -/*************************************************************************/ - -/** - * Returns the preferred X axis alignment for the specified target - * container. This value will range from 0 to 1 where 0 is alignment - * closest to the origin, 0.5 is centered, and 1 is aligned furthest - * from the origin. - * - * @param target The target container. - */ -public abstract float -getLayoutAlignmentX(Container target); - -/*************************************************************************/ - -/** - * Returns the preferred Y axis alignment for the specified target - * container. This value will range from 0 to 1 where 0 is alignment - * closest to the origin, 0.5 is centered, and 1 is aligned furthest - * from the origin. - * - * @param target The target container. - */ -public abstract float -getLayoutAlignmentY(Container target); - -/*************************************************************************/ - -/** - * Forces the layout manager to purge any cached information about - * the layout of the target container. This will force it to be - * recalculated. - * - * @param target The target container. - */ -public abstract void -invalidateLayout(Container target); - -} // interface LayoutManager2 - + /** + * Adds the specified component to the layout, with the specified + * constraint object. + * + * @param component the component to add + * @param constraint the constraint to satisfy + */ + void addLayoutComponent(Component component, Object contraint); + + /** + * Determines the maximum size of the specified target container. + * + * @param target the container to lay out + * @return the maximum size of the container + * @see Component#getMaximumSize() + */ + Dimension maximumLayoutSize(Container target); + + /** + * Returns the preferred X axis alignment for the specified target + * container. This value will range from 0 to 1 where 0 is alignment + * closest to the origin, 0.5 is centered, and 1 is aligned furthest + * from the origin. + * + * @param target the target container + * @return the x-axis alignment preference + */ + float getLayoutAlignmentX(Container target); + + /** + * Returns the preferred Y axis alignment for the specified target + * container. This value will range from 0 to 1 where 0 is alignment + * closest to the origin, 0.5 is centered, and 1 is aligned furthest + * from the origin. + * + * @param target the target container + * @return the y-axis alignment preference + */ + float getLayoutAlignmentY(Container target); + + /** + * Forces the layout manager to purge any cached information about the + * layout of the target container. This will force it to be recalculated. + * + * @param target the target container + */ + void invalidateLayout(Container target); +} // interface LayoutManager2 diff --git a/libjava/java/awt/MenuContainer.java b/libjava/java/awt/MenuContainer.java index 33ac07d837d..dd8b3412e2b 100644 --- a/libjava/java/awt/MenuContainer.java +++ b/libjava/java/awt/MenuContainer.java @@ -1,4 +1,4 @@ -/* MenuContainer.java -- Container for menu items. +/* MenuContainer.java -- container for menu items Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,42 +39,33 @@ exception statement from your version. */ package java.awt; /** - * This interface is a container for menu components. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This interface is a container for menu components. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.0 + * @status updated to 1.4 + */ public interface MenuContainer { + /** + * Returns the font in use by this container. + * + * @return the menu font + */ + Font getFont(); -/** - * Returns the font in use by this container. - * - * @return The font in use by this container. - */ -public abstract Font -getFont(); - -/*************************************************************************/ - -/** - * Removes the specified menu component from the menu. - * - * @param component The menu component to remove. - */ -public abstract void -remove(MenuComponent component); - -/*************************************************************************/ - -/** - * Posts and event to the listeners. This is replaced by - * <code>dispatchEvent</code>. - * - * @param event The event to dispatch. - * - * @deprecated - */ -public abstract boolean -postEvent(Event event); + /** + * Removes the specified menu component from the menu. + * + * @param component the menu component to remove + */ + void remove(MenuComponent component); + /** + * Posts an event to the listeners. + * + * @param event the event to dispatch + * @deprecated use {@link MenuComponent#dispatchEvent(AWTEvent)} instead + */ + boolean postEvent(Event event); } // interface MenuContainer diff --git a/libjava/java/awt/MenuItem.java b/libjava/java/awt/MenuItem.java index ea92f9ab8e4..ffef30ecf8c 100644 --- a/libjava/java/awt/MenuItem.java +++ b/libjava/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/libjava/java/awt/PageAttributes.java b/libjava/java/awt/PageAttributes.java new file mode 100644 index 00000000000..2501aa3eeaf --- /dev/null +++ b/libjava/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/libjava/java/awt/Paint.java b/libjava/java/awt/Paint.java index 1bba0735cf9..94c30c0ff5d 100644 --- a/libjava/java/awt/Paint.java +++ b/libjava/java/awt/Paint.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* Paint.java -- generate colors for Graphics2D operations + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,23 +38,42 @@ exception statement from your version. */ package java.awt; -/** - * @author Warren Levy <warrenl@cygnus.com> - * @date March 15, 2000. - */ +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.awt.image.ColorModel; /** - * Written using on-line Java Platform 1.2 API Specification, as well - * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). - * Status: Stubbed. + * Defines how color patterns are generated for Graphics2D operations. This + * is used to perform the <code>draw</code> and <code>fill</code> methods + * of the graphics object. Instances must be immutable, because the graphics + * object does not clone them. + * + * @author Warren Levy <warrenl@cygnus.com> + * @see PaintContext + * @see Color + * @see GradientPaint + * @see TexturePaint + * @see Graphics2D#setPaint(Paint) + * @since 1.1 + * @status updated to 1.4 */ - public interface Paint extends Transparency { - // FIXME - // public PaintContext createContext(ColorModel cm, - // Rectangle deviceBounds, - // Rectangle2D userBounds, - // AffineTransform xform, - // RenderingHints hints); -} + /** + * Create the context necessary for performing the color pattern generation. + * The color model is a hint, and may be null for Classpath implementations; + * however some legacy code may throw a NullPointerException when passed a + * null. Leaving the color model null provides the most efficiency and leeway + * in the generation of the color pattern. + * + * @param cm the color model, used as a hint + * @param deviceBounds the device space bounding box of the painted area + * @param userBounds the user space bounding box of the painted area + * @param xform the transformation from user space to device space + * @param hints any hints for choosing between rendering alternatives + * @return the context for performing the paint + */ + PaintContext createContext(ColorModel cm, Rectangle deviceBounds, + Rectangle2D userBounds, AffineTransform xform, + RenderingHints hints); +} // interface Paint diff --git a/libjava/java/awt/PaintContext.java b/libjava/java/awt/PaintContext.java index 6393118690b..fa26061f0ea 100644 --- a/libjava/java/awt/PaintContext.java +++ b/libjava/java/awt/PaintContext.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* PaintContext.java -- the environment for performing a paint operation + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,21 +38,39 @@ exception statement from your version. */ package java.awt; -/** - * @author Warren Levy <warrenl@cygnus.com> - * @date March 16, 2000. - */ +import java.awt.image.ColorModel; +import java.awt.image.Raster; /** - * Written using on-line Java Platform 1.2 API Specification, as well - * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). - * Status: Partially stubbed. + * @author Warren Levy <warrenl@cygnus.com> + * @see Paint + * @since 1.1 + * @status updated to 1.4 */ - public interface PaintContext { - public void dispose(); - // FIXME - // public ColorModel getColorModel(); - // public Raster getRaster(int x, int y, int w, int h); -} + /** + * Release the resources allocated for the paint. + */ + void dispose(); + + /** + * Return the color model of this context. It may be different from the + * hint specified during createContext, as not all contexts can generate + * color patterns in an arbitrary model. + * + * @return the context color model + */ + ColorModel getColorModel(); + + /** + * Return a raster containing the colors for the graphics operation. + * + * @param x the x-coordinate, in device space + * @param y the y-coordinate, in device space + * @param w the width, in device space + * @param h the height, in device space + * @return a raster for the given area and color + */ + Raster getRaster(int x, int y, int w, int h); +} // interface PaintContext diff --git a/libjava/java/awt/Panel.java b/libjava/java/awt/Panel.java index 06fcb3ed253..23336bc6bd6 100644 --- a/libjava/java/awt/Panel.java +++ b/libjava/java/awt/Panel.java @@ -1,4 +1,4 @@ -/* Panel.java -- Simple container object. +/* Panel.java -- Simple container object Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,59 +41,109 @@ package java.awt; import java.awt.peer.PanelPeer; import java.awt.peer.ContainerPeer; import java.awt.peer.ComponentPeer; +import java.io.Serializable; +import javax.accessibility.Accessible; +import javax.accessibility.AccessibleContext; +import javax.accessibility.AccessibleRole; /** - * A panel is a simple container class. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public class Panel extends Container implements java.io.Serializable -{ - -/* - * Constructors - */ - -/** - * Initializes a new instance of <code>Panel</code> that has a default - * layout manager of <code>FlowLayout</code>. - */ -public -Panel() -{ - this(new FlowLayout()); -} - -/*************************************************************************/ - -/** - * Initializes a new instance of <code>Panel</code> with the specified - * layout manager. - * - * @param layoutManager The layout manager for this object. - */ -public -Panel(LayoutManager layoutManager) -{ - setLayout(layoutManager); -} - -/*************************************************************************/ - -/* - * Instance Methods + * A panel is a simple container class. It's default layout is the + * <code>FlowLayout</code> manager. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @see FlowLayout + * @since 1.0 + * @status updated to 1.4 */ - -/** - * Notifies this object to create its native peer. - */ -public void -addNotify() +public class Panel extends Container implements Accessible { - if (peer == null) - peer = getToolkit().createPanel(this); - super.addNotify(); -} - + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -2728009084054400034L; + + /** The cached accessible context. */ + private transient AccessibleContext context; + + /** + * Initializes a new instance of <code>Panel</code> that has a default + * layout manager of <code>FlowLayout</code>. + */ + public Panel() + { + this(new FlowLayout()); + } + + /** + * Initializes a new instance of <code>Panel</code> with the specified + * layout manager. + * + * @param layoutManager the layout manager for this object + * @since 1.1 + */ + public Panel(LayoutManager layoutManager) + { + setLayout(layoutManager); + } + + /** + * Notifies this object to create its native peer. + * + * @see #isDisplayable() + * @see #removeNotify() + */ + public void addNotify() + { + if (peer == null) + peer = getToolkit().createPanel(this); + super.addNotify(); + } + + /** + * Gets the AccessibleContext associated with this panel, creating one if + * necessary. This always returns an instance of {@link AccessibleAWTPanel}. + * + * @return the accessibility context of this panel + * @since 1.3 + */ + public AccessibleContext getAccessibleContext() + { + if (context == null) + context = new AccessibleAWTPanel(); + return context; + } + + /** + * This class provides accessibility support for Panels, and is the + * runtime type returned by {@link #getAccessibleContext()}. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.3 + */ + protected class AccessibleAWTPanel extends AccessibleAWTContainer + { + /** + * Compatible with JDK 1.4+. + */ + private static final long serialVersionUID = -6409552226660031050L; + + /** + * The default constructor. + */ + protected AccessibleAWTPanel() + { + } + + /** + * Get the role of this accessible object, a panel. + * + * @return the role of the object + * @see AccessibleRole#PANEL + */ + public AccessibleRole getAccessibleRole() + { + return AccessibleRole.PANEL; + } + } // class AccessibleAWTPanel } // class Panel - diff --git a/libjava/java/awt/Point.java b/libjava/java/awt/Point.java index 35048d1b542..9d5126434ae 100644 --- a/libjava/java/awt/Point.java +++ b/libjava/java/awt/Point.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2002 Free Software Foundation +/* Point.java -- represents a point in 2-D space + Copyright (C) 1999, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -36,144 +37,209 @@ exception statement from your version. */ package java.awt; -import java.awt.geom.Point2D; -/* Written using "Java Class Libraries", 2nd edition, plus online - * API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct, except that neither toString - * nor hashCode have been compared with JDK output. - */ +import java.awt.geom.Point2D; +import java.io.Serializable; /** * This class represents a point on the screen using cartesian coordinates. + * Remember that in screen coordinates, increasing x values go from left to + * right, and increasing y values go from top to bottom. + * + * <p>There are some public fields; if you mess with them in an inconsistent + * manner, it is your own fault when you get invalid results. Also, this + * class is not threadsafe. * * @author Per Bothner <bothner@cygnus.com> - * @author Aaron M. Renn (arenn@urbanophile.com) - * @date February 8, 1999. + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.0 + * @status updated to 1.4 */ -public class Point extends Point2D implements java.io.Serializable +public class Point extends Point2D implements Serializable { /** - * @serial The X coordinate of the point. + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -5276940640259749850L; + + /** + * The x coordinate. + * + * @see #getLocation() + * @see #move(int, int) + * @serial the X coordinate of the point */ public int x; /** - * @serial The Y coordinate of the point. + * The y coordinate. + * + * @see #getLocation() + * @see #move(int, int) + * @serial The Y coordinate of the point */ public int y; /** * Initializes a new instance of <code>Point</code> representing the * coordiates (0,0). + * + * @since 1.1 */ - public Point () { } + public Point() + { + } /** * Initializes a new instance of <code>Point</code> with coordinates * identical to the coordinates of the specified points. * - * @param point The point to copy the coordinates from. + * @param point the point to copy the coordinates from + * @throws NullPointerException if p is null */ - public Point (Point p) { this.x = p.x; this.y = p.y; } + public Point(Point p) + { + x = p.x; + y = p.y; + } /** * Initializes a new instance of <code>Point</code> with the specified * coordinates. * - * @param x The X coordinate of this point. - * @param y The Y coordinate of this point. + * @param x the X coordinate + * @param y the Y coordinate */ - public Point (int x, int y) { this.x = x; this.y = y; } + public Point(int x, int y) + { + this.x = x; + this.y = y; + } /** - * Tests whether or not this object is equal to the specified object. - * This will be true if and only if the specified objectj: - * <p> - * <ul> - * <li>Is not <code>null</code>. - * <li>Is an instance of <code>Point</code>. - * <li>Has X and Y coordinates equal to this object's. - * </ul> + * Get the x coordinate. * - * @param obj The object to test against for equality. + * @return the value of x, as a double + */ + public double getX() + { + return x; + } + + /** + * Get the y coordinate. * - * @return <code>true</code> if the specified object is equal to this - * object, <code>false</code> otherwise. - */ - public boolean equals (Object obj) + * @return the value of y, as a double + */ + public double getY() { - if (! (obj instanceof Point)) - return false; - Point p = (Point) obj; - return this.x == p.x && this.y == p.y; + return y; } /** - * Returns a hash value for this point. + * Returns the location of this point. A pretty useless method, as this + * is already a point. * - * @param A hash value for this point. + * @return a copy of this point + * @see #setLocation(Point) + * @since 1.1 */ - public int hashCode () { return x ^ y; } + public Point getLocation() + { + return new Point(x, y); + } /** - * Returns the location of this object as a point. A pretty useless - * method. It is included to mimic the <code>getLocation</code> method - * in component. + * Sets this object's coordinates to match those of the specified point. * - * @return This point. + * @param p the point to copy the coordinates from + * @throws NullPointerException if p is null + * @since 1.1 */ - public Point getLocation () { return new Point(this); } + public void setLocation(Point p) + { + x = p.x; + y = p.y; + } /** * Sets this object's coordinates to the specified values. This method - * is identical to the <code>setLocation(int, int)</code> method. + * is identical to the <code>move()</code> method. * - * @param x The new X coordinate. - * @param y The new Y coordinate. + * @param x the new X coordinate + * @param y the new Y coordinate */ - public void move (int x, int y) { this.x = x; this.y = y; } + public void setLocation(int x, int y) + { + this.x = x; + this.y = y; + } /** * Sets this object's coordinates to the specified values. This method - * is identical to the <code>move()</code> method. + * performs normal casting from double to int, so you may lose precision. * - * @param x The new X coordinate. - * @param y The new Y coordinate. + * @param x the new X coordinate + * @param y the new Y coordinate */ - public void setLocation (int x, int y) { this.x = x; this.y = y; } + public void setLocation(double x, double y) + { + this.x = (int) x; + this.y = (int) y; + } /** - * Sets this object's coordinates to match those of the specified point. + * Sets this object's coordinates to the specified values. This method + * is identical to the <code>setLocation(int, int)</code> method. * - * @param point The point to copy the coordinates from. + * @param x the new X coordinate + * @param y the new Y coordinate */ - public void setLocation (Point pt) { this.x = pt.x; this.y = pt.y; } + public void move(int x, int y) + { + this.x = x; + this.y = y; + } /** - * Changes the coordinates of this point such that the specified + * Changes the coordinates of this point such that the specified * <code>dx</code> parameter is added to the existing X coordinate and * <code>dy</code> is added to the existing Y coordinate. * - * @param dx The amount to add to the X coordinate. - * @param dy The amount to add to the Y coordinate. + * @param dx the amount to add to the X coordinate + * @param dy the amount to add to the Y coordinate */ - public void translate (int x, int y) { this.x += x; this.y += y; } + public void translate(int dx, int dy) + { + x += dx; + y += dy; + } /** - * Returns a string representation of this object. + * Tests whether or not this object is equal to the specified object. + * This will be true if and only if the specified object is an instance + * of Point2D and has the same X and Y coordinates. * - * @return A string representation of this object. - */ - public String toString () + * @param obj the object to test against for equality + * @return true if the specified object is equal + */ + public boolean equals(Object obj) { - return getClass().getName() + "[x:"+x+",y:"+y+']'; + if (! (obj instanceof Point2D)) + return false; + Point2D p = (Point2D) obj; + return x == p.getX() && y == p.getY(); } - public double getX() { return x; } - public double getY() { return y; } - - public void setLocation (double x, double y) - { this.x = (int) x; this.y = (int) y; } - -} + /** + * Returns a string representation of this object. The format is: + * <code>getClass().getName() + "[x=" + x + ",y=" + y + ']'</code>. + * + * @return a string representation of this object + */ + public String toString() + { + return getClass().getName() + "[x=" + x + ",y=" + y + ']'; + } +} // class Point diff --git a/libjava/java/awt/Polygon.java b/libjava/java/awt/Polygon.java index ad4df2c47a0..1f51ac811d6 100644 --- a/libjava/java/awt/Polygon.java +++ b/libjava/java/awt/Polygon.java @@ -1,422 +1,751 @@ -/* Copyright (C) 2001 Free Software Foundation +/* Polygon.java -- class representing a polygon + Copyright (C) 1999, 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. */ - This file is part of libjava. - -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt; -import java.awt.geom.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; import java.io.Serializable; -import java.util.Arrays; /** - * @author Tom Tromey <tromey@redhat.com> - * @date May 10, 2001 + * This class represents a polygon, a closed, two-dimensional region in a + * coordinate space. The region is bounded by an arbitrary number of line + * segments, between (x,y) coordinate vertices. The polygon has even-odd + * winding, meaning that a point is inside the shape if it crosses the + * boundary an odd number of times on the way to infinity. + * + * <p>There are some public fields; if you mess with them in an inconsistent + * manner, it is your own fault when you get NullPointerException, + * ArrayIndexOutOfBoundsException, or invalid results. Also, this class is + * not threadsafe. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.0 + * @status updated to 1.4 */ - -/** The Polygon class represents a closed region whose boundary is - made of line segments. The Polygon is defined by its vertices. */ public class Polygon implements Shape, Serializable { - /** The bounds of the polygon. This is null until the bounds have - * been computed for the first time; then it is correctly - * maintained whenever it is modified. */ - protected Rectangle bounds; + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -6460061437900069969L; - /** The number of points in the polygon. */ + /** + * This total number of endpoints. + * + * @serial the number of endpoints, possibly less than the array sizes + */ public int npoints; - /** The x coordinates of the points. */ + /** + * The array of X coordinates of endpoints. This should not be null. + * + * @see #addPoint(int, int) + * @serial the x coordinates + */ public int[] xpoints; - /** The y coordinates of the points. */ + /** + * The array of Y coordinates of endpoints. This should not be null. + * + * @see #addPoint(int, int) + * @serial the y coordinates + */ public int[] ypoints; - /** Create a new, empty Polygon. */ - public Polygon () + /** + * The bounding box of this polygon. This is lazily created and cached, so + * it must be invalidated after changing points. + * + * @see #getBounds() + * @serial the bounding box, or null + */ + protected Rectangle bounds; + + /** + * Cached flattened version - condense points and parallel lines, so the + * result has area if there are >= 3 condensed vertices. flat[0] is the + * number of condensed points, and (flat[odd], flat[odd+1]) form the + * condensed points. + * + * @see #condense() + * @see #contains(double, double) + * @see #contains(double, double, double, double) + */ + private transient int[] condensed; + + /** + * Initializes an empty polygon. + */ + public Polygon() { - this.xpoints = new int[0]; - this.ypoints = new int[0]; - this.npoints = 0; + // Leave room for growth. + xpoints = new int[4]; + ypoints = new int[4]; } - /** Create a new Polygon from the given vertices. - * @param xpoints The x coordinates - * @param ypoints The y coordinates - * @param npoints The number of points + /** + * Create a new polygon with the specified endpoints. The arrays are copied, + * so that future modifications to the parameters do not affect the polygon. + * + * @param xpoints the array of X coordinates for this polygon + * @param ypoints the array of Y coordinates for this polygon + * @param npoints the total number of endpoints in this polygon + * @throws NegativeArraySizeException if npoints is negative + * @throws IndexOutOfBoundsException if npoints exceeds either array + * @throws NullPointerException if xpoints or ypoints is null */ - public Polygon (int[] xpoints, int[] ypoints, int npoints) + public Polygon(int[] xpoints, int[] ypoints, int npoints) { - // We make explicit copies instead of relying on clone so that we - // ensure the new arrays are the same size. this.xpoints = new int[npoints]; this.ypoints = new int[npoints]; - System.arraycopy (xpoints, 0, this.xpoints, 0, npoints); - System.arraycopy (ypoints, 0, this.ypoints, 0, npoints); + System.arraycopy(xpoints, 0, this.xpoints, 0, npoints); + System.arraycopy(ypoints, 0, this.ypoints, 0, npoints); + this.npoints = npoints; } - /** Append the specified point to this Polygon. - * @param x The x coordinate - * @param y The y coordinate + /** + * Reset the polygon to be empty. The arrays are left alone, to avoid object + * allocation, but the number of points is set to 0, and all cached data + * is discarded. If you are discarding a huge number of points, it may be + * more efficient to just create a new Polygon. + * + * @see #invalidate() + * @since 1.4 */ - public void addPoint (int x, int y) + public void reset() { - int[] newx = new int[npoints + 1]; - System.arraycopy (xpoints, 0, newx, 0, npoints); - int[] newy = new int[npoints + 1]; - System.arraycopy (ypoints, 0, newy, 0, npoints); - newx[npoints] = x; - newy[npoints] = y; - ++npoints; - xpoints = newx; - ypoints = newy; - - // It is simpler to just recompute. - if (bounds != null) - computeBoundingBox (); + npoints = 0; + invalidate(); } - /** Return true if the indicated point is inside this Polygon. - * This uses an even-odd rule to determine insideness. - * @param x The x coordinate - * @param y The y coordinate - * @returns true if the point is contained by this Polygon. + /** + * Invalidate or flush all cached data. After direct manipulation of the + * public member fields, this is necessary to avoid inconsistent results + * in methods like <code>contains</code>. + * + * @see #getBounds() + * @since 1.4 */ - public boolean contains (double x, double y) + public void invalidate() { - // What we do is look at each line segment. If the line segment - // crosses the "scan line" at y at a point x' < x, then we - // increment our counter. At the end, an even number means the - // point is outside the polygon. Instead of a number, though, we - // use a boolean. - boolean inside = false; - for (int i = 0; i < npoints; ++i) + bounds = null; + condensed = null; + } + + /** + * Translates the polygon by adding the specified values to all X and Y + * coordinates. This updates the bounding box, if it has been calculated. + * + * @param dx the amount to add to all X coordinates + * @param dy the amount to add to all Y coordinates + * @since 1.1 + */ + public void translate(int dx, int dy) + { + int i = npoints; + while (--i >= 0) { - // Handle the wrap case. - int x2 = (i == npoints) ? xpoints[0] : xpoints[i + 1]; - int y2 = (i == npoints) ? ypoints[0] : ypoints[i + 1]; - - if (ypoints[i] == y2) - { - // We ignore horizontal lines. This might give weird - // results in some situations -- ? - continue; - } - - double t = (y - ypoints[i]) / (double) (y2 - ypoints[i]); - double x3 = xpoints[i] + t * (x2 - xpoints[i]); - if (x3 < x) - inside = ! inside; + xpoints[i] += dx; + xpoints[i] += dy; } - - return inside; + if (bounds != null) + { + bounds.x += dx; + bounds.y += dy; + } + condensed = null; } - /** Return true if the indicated rectangle is entirely inside this - * Polygon. - * This uses an even-odd rule to determine insideness. - * @param x The x coordinate - * @param y The y coordinate - * @param w The width - * @param h The height - * @returns true if the rectangle is contained by this Polygon. + /** + * Adds the specified endpoint to the polygon. This updates the bounding + * box, if it has been created. + * + * @param x the X coordinate of the point to add + * @param y the Y coordiante of the point to add */ - public boolean contains (double x, double y, double w, double h) + public void addPoint(int x, int y) { - return intersectOrContains (x, y, w, h, false); + if (npoints + 1 > xpoints.length) + { + int[] newx = new int[npoints + 1]; + System.arraycopy(xpoints, 0, newx, 0, npoints); + xpoints = newx; + } + if (npoints + 1 > ypoints.length) + { + int[] newy = new int[npoints + 1]; + System.arraycopy(ypoints, 0, newy, 0, npoints); + ypoints = newy; + } + xpoints[npoints] = x; + ypoints[npoints] = y; + npoints++; + if (bounds != null) + { + if (npoints == 1) + { + bounds.x = x; + bounds.y = y; + } + else + { + if (x < bounds.x) + { + bounds.width += bounds.x - x; + bounds.x = x; + } + else if (x > bounds.x + bounds.width) + bounds.width = x - bounds.x; + if (y < bounds.y) + { + bounds.height += bounds.y - y; + bounds.y = y; + } + else if (y > bounds.y + bounds.height) + bounds.height = y - bounds.y; + } + } + condensed = null; } - /** Return true if the indicated point is inside this Polygon. - * This uses an even-odd rule to determine insideness. - * @param x The x coordinate - * @param y The y coordinate - * @returns true if the point is contained by this Polygon. + /** + * Returns the bounding box of this polygon. This is the smallest + * rectangle with sides parallel to the X axis that will contain this + * polygon. + * + * @return the bounding box for this polygon + * @see #getBounds2D() + * @since 1.1 */ - public boolean contains (int x, int y) + public Rectangle getBounds() { - return contains ((double) x, (double) y); + if (bounds == null) + { + if (npoints == 0) + return bounds = new Rectangle(); + int i = npoints - 1; + int minx = xpoints[i]; + int maxx = minx; + int miny = ypoints[i]; + int maxy = miny; + while (--i >= 0) + { + int x = xpoints[i]; + int y = ypoints[i]; + if (x < minx) + minx = x; + else if (x > maxx) + maxx = x; + if (y < miny) + miny = y; + else if (y > maxy) + maxy = y; + } + bounds = new Rectangle(minx, maxy, maxx - minx, maxy - miny); + } + return bounds; } - /** Return true if the indicated point is inside this Polygon. - * This uses an even-odd rule to determine insideness. - * @param p The point - * @returns true if the point is contained by this Polygon. + /** + * Returns the bounding box of this polygon. This is the smallest + * rectangle with sides parallel to the X axis that will contain this + * polygon. + * + * @return the bounding box for this polygon + * @see #getBounds2D() + * @deprecated use {@link #getBounds()} instead */ - public boolean contains (Point p) + public Rectangle getBoundingBox() { - return contains (p.x, p.y); + return getBounds(); } - /** Return true if the indicated point is inside this Polygon. - * This uses an even-odd rule to determine insideness. - * @param p The point - * @returns true if the point is contained by this Polygon. + /** + * Tests whether or not the specified point is inside this polygon. + * + * @param p the point to test + * @return true if the point is inside this polygon + * @throws NullPointerException if p is null + * @see #contains(double, double) */ - public boolean contains (Point2D p) + public boolean contains(Point p) { - return contains (p.getX (), p.getY ()); + return contains(p.getX(), p.getY()); } - /** Return true if the indicated rectangle is entirely inside this - * Polygon. This uses an even-odd rule to determine insideness. - * @param r The rectangle - * @returns true if the rectangle is contained by this Polygon. + /** + * Tests whether or not the specified point is inside this polygon. + * + * @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 inside this polygon + * @see #contains(double, double) + * @since 1.1 */ - public boolean contains (Rectangle2D r) + public boolean contains(int x, int y) { - return contains (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); + return contains((double) x, (double) y); } - /** Returns the bounds of this Polygon. - * @deprecated Use getBounds() instead. + /** + * Tests whether or not the specified point is inside this polygon. + * + * @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 inside this polygon + * @see #contains(double, double) + * @deprecated use {@link #contains(int, int)} instead */ - public Rectangle getBoundingBox () + public boolean inside(int x, int y) { - if (bounds == null) - computeBoundingBox (); - return bounds; + return contains((double) x, (double) y); } - /** Returns the bounds of this Polygon. */ - public Rectangle getBounds () + /** + * Returns a high-precision bounding box of this polygon. This is the + * smallest rectangle with sides parallel to the X axis that will contain + * this polygon. + * + * @return the bounding box for this polygon + * @see #getBounds() + * @since 1.2 + */ + public Rectangle2D getBounds2D() { - if (bounds == null) - computeBoundingBox (); - return bounds; + // For polygons, the integer version is exact! + return getBounds(); } - /** Returns the bounds of this Polygon. */ - public Rectangle2D getBounds2D () + /** + * Tests whether or not the specified point is inside this polygon. + * + * @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 inside this polygon + * @since 1.2 + */ + public boolean contains(double x, double y) { - if (bounds == null) - computeBoundingBox (); - return bounds; // Why not? + // First, the obvious bounds checks. + if (! condense() || ! getBounds().contains(x, y)) + return false; + // A point is contained if a ray to (-inf, y) crosses an odd number + // of segments. This must obey the semantics of Shape when the point is + // exactly on a segment or vertex: a point is inside only if the adjacent + // point in the increasing x or y direction is also inside. Note that we + // are guaranteed that the condensed polygon has area, and no consecutive + // segments with identical slope. + boolean inside = false; + int limit = condensed[0]; + int curx = condensed[(limit << 1) - 1]; + int cury = condensed[limit << 1]; + for (int i = 1; i <= limit; i++) + { + int priorx = curx; + int priory = cury; + curx = condensed[(i << 1) - 1]; + cury = condensed[i << 1]; + if ((priorx > x && curx > x) // Left of segment, or NaN. + || (priory > y && cury > y) // Below segment, or NaN. + || (priory < y && cury < y)) // Above segment. + continue; + if (priory == cury) // Horizontal segment, y == cury == priory + { + if (priorx < x && curx < x) // Right of segment. + { + inside = ! inside; + continue; + } + // Did we approach this segment from above or below? + // This mess is necessary to obey rules of Shape. + priory = condensed[((limit + i - 2) % limit) << 1]; + boolean above = priory > cury; + if ((curx == x && (curx > priorx || above)) + || (priorx == x && (curx < priorx || ! above)) + || (curx > priorx && ! above) || above) + inside = ! inside; + continue; + } + if (priorx == x && priory == y) // On prior vertex. + continue; + if (priorx == curx // Vertical segment. + || (priorx < x && curx < x)) // Right of segment. + { + inside = ! inside; + continue; + } + // The point is inside the segment's bounding box, compare slopes. + double leftx = curx > priorx ? priorx : curx; + double lefty = curx > priorx ? priory : cury; + double slopeseg = (double) (cury - priory) / (curx - priorx); + double slopepoint = (double) (y - lefty) / (x - leftx); + if ((slopeseg > 0 && slopeseg > slopepoint) + || slopeseg < slopepoint) + inside = ! inside; + } + return inside; } - /** Return an iterator for the boundary of this Polygon. - * @param at A transform to apply to the coordinates. - * @returns A path iterator for the Polygon's boundary. + /** + * Tests whether or not the specified point is inside this polygon. + * + * @param p the point to test + * @return true if the point is inside this polygon + * @throws NullPointerException if p is null + * @see #contains(double, double) + * @since 1.2 */ - public PathIterator getPathIterator (AffineTransform at) + public boolean contains(Point2D p) { - return new Iterator (at); + return contains(p.getX(), p.getY()); } - /** Return an iterator for the boundary of this Polygon. - * @param at A transform to apply to the coordinates. - * @param flatness The flatness of the result; it is ignored by - * this class. - * @returns A path iterator for the Polygon's boundary. + /** + * Test if a high-precision rectangle intersects the shape. This is true + * if any point in the rectangle is in the shape. This implementation is + * precise. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle, treated as point if negative + * @param h the height of the rectangle, treated as point if negative + * @return true if the rectangle intersects this shape + * @since 1.2 */ - public PathIterator getPathIterator (AffineTransform at, double flatness) + public boolean intersects(double x, double y, double w, double h) { - // We ignore the flatness. - return new Iterator (at); + // First, the obvious bounds checks. + if (w <= 0 || h <= 0 || npoints == 0 || + ! getBounds().intersects(x, y, w, h)) + return false; // Disjoint bounds. + if ((x <= bounds.x && x + w >= bounds.x + bounds.width + && y <= bounds.y && y + h >= bounds.y + bounds.height) + || contains(x, y)) + return true; // Rectangle contains the polygon, or one point matches. + // If any vertex is in the rectangle, the two might intersect. + int curx = 0; + int cury = 0; + for (int i = 0; i < npoints; i++) + { + curx = xpoints[i]; + cury = ypoints[i]; + if (curx >= x && curx < x + w && cury >= y && cury < y + h + && contains(curx, cury)) // Boundary check necessary. + return true; + } + // Finally, if at least one of the four bounding lines intersect any + // segment of the polygon, return true. Be careful of the semantics of + // Shape; coinciding lines do not necessarily return true. + for (int i = 0; i < npoints; i++) + { + int priorx = curx; + int priory = cury; + curx = xpoints[i]; + cury = ypoints[i]; + if (priorx == curx) // Vertical segment. + { + if (curx < x || curx >= x + w) // Outside rectangle. + continue; + if ((cury >= y + h && priory <= y) + || (cury <= y && priory >= y + h)) + return true; // Bisects rectangle. + continue; + } + if (priory == cury) // Horizontal segment. + { + if (cury < y || cury >= y + h) // Outside rectangle. + continue; + if ((curx >= x + w && priorx <= x) + || (curx <= x && priorx >= x + w)) + return true; // Bisects rectangle. + continue; + } + // Slanted segment. + double slope = (double) (cury - priory) / (curx - priorx); + double intersect = slope * (x - curx) + cury; + if (intersect > y && intersect < y + h) // Intersects left edge. + return true; + intersect = slope * (x + w - curx) + cury; + if (intersect > y && intersect < y + h) // Intersects right edge. + return true; + intersect = (y - cury) / slope + curx; + if (intersect > x && intersect < x + w) // Intersects bottom edge. + return true; + intersect = (y + h - cury) / slope + cury; + if (intersect > x && intersect < x + w) // Intersects top edge. + return true; + } + return false; } - /** @deprecated use contains(int,int). */ - public boolean inside (int x, int y) + /** + * Test if a high-precision rectangle intersects the shape. This is true + * if any point in the rectangle is in the shape. This implementation is + * precise. + * + * @param r the rectangle + * @return true if the rectangle intersects this shape + * @throws NullPointerException if r is null + * @see #intersects(double, double, double, double) + * @since 1.2 + */ + public boolean intersects(Rectangle2D r) { - return contains (x, y); + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - /** Return true if this Polygon's interior intersects the given - * rectangle's interior. - * @param x The x coordinate - * @param y The y coordinate - * @param w The width - * @param h The height + /** + * Test if a high-precision rectangle lies completely in the shape. This is + * true if all points in the rectangle are in the shape. This implementation + * is precise. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle, treated as point if negative + * @param h the height of the rectangle, treated as point if negative + * @return true if the rectangle is contained in this shape + * @since 1.2 */ - public boolean intersects (double x, double y, double w, double h) + public boolean contains(double x, double y, double w, double h) { - return intersectOrContains (x, y, w, h, true); + // First, the obvious bounds checks. + if (w <= 0 || h <= 0 || ! contains(x, y) + || ! bounds.contains(x, y, w, h)) + return false; + // Now, if any of the four bounding lines intersects a polygon segment, + // return false. The previous check had the side effect of setting + // the condensed array, which we use. Be careful of the semantics of + // Shape; coinciding lines do not necessarily return false. + int limit = condensed[0]; + int curx = condensed[(limit << 1) - 1]; + int cury = condensed[limit << 1]; + for (int i = 1; i <= limit; i++) + { + int priorx = curx; + int priory = cury; + curx = condensed[(i << 1) - 1]; + cury = condensed[i << 1]; + if (curx > x && curx < x + w && cury > y && cury < y + h) + return false; // Vertex is in rectangle. + if (priorx == curx) // Vertical segment. + { + if (curx < x || curx > x + w) // Outside rectangle. + continue; + if ((cury >= y + h && priory <= y) + || (cury <= y && priory >= y + h)) + return false; // Bisects rectangle. + continue; + } + if (priory == cury) // Horizontal segment. + { + if (cury < y || cury > y + h) // Outside rectangle. + continue; + if ((curx >= x + w && priorx <= x) + || (curx <= x && priorx >= x + w)) + return false; // Bisects rectangle. + continue; + } + // Slanted segment. + double slope = (double) (cury - priory) / (curx - priorx); + double intersect = slope * (x - curx) + cury; + if (intersect > y && intersect < y + h) // Intersects left edge. + return false; + intersect = slope * (x + w - curx) + cury; + if (intersect > y && intersect < y + h) // Intersects right edge. + return false; + intersect = (y - cury) / slope + curx; + if (intersect > x && intersect < x + w) // Intersects bottom edge. + return false; + intersect = (y + h - cury) / slope + cury; + if (intersect > x && intersect < x + w) // Intersects top edge. + return false; + } + return true; } - /** Return true if this Polygon's interior intersects the given - * rectangle's interior. - * @param r The rectangle + /** + * Test if a high-precision rectangle lies completely in the shape. This is + * true if all points in the rectangle are in the shape. This implementation + * is precise. + * + * @param r the rectangle + * @return true if the rectangle is contained in this shape + * @throws NullPointerException if r is null + * @see #contains(double, double, double, double) + * @since 1.2 */ - public boolean intersects (Rectangle2D r) + public boolean contains(Rectangle2D r) { - return intersects (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - // This tests for intersection with or containment of a rectangle, - // depending on the INTERSECT argument. - private boolean intersectOrContains (double x, double y, double w, double h, - boolean intersect) + /** + * Return an iterator along the shape boundary. If the optional transform + * is provided, the iterator is transformed accordingly. Each call returns + * a new object, independent from others in use. This class is not + * threadsafe to begin with, so the path iterator is not either. + * + * @param transform an optional transform to apply to the iterator + * @return a new iterator over the boundary + * @since 1.2 + */ + public PathIterator getPathIterator(final AffineTransform transform) { - // First compute the rectangle of possible intersection points. - Rectangle r = getBounds (); - int minx = Math.max (r.x, (int) x); - int maxx = Math.min (r.x + r.width, (int) (x + w)); - int miny = Math.max (r.y, (int) y); - int maxy = Math.min (r.y + r.height, (int) (y + h)); - - if (miny > maxy) - return false; - - double[] crosses = new double[npoints + 1]; + return new PathIterator() + { + /** The current vertex of iteration. */ + private int vertex; - for (; miny < maxy; ++miny) + public int getWindingRule() { - // First compute every place where the polygon might intersect - // the scan line at Y. - int ins = 0; - for (int i = 0; i < npoints; ++i) - { - // Handle the wrap case. - int x2 = (i == npoints) ? xpoints[0] : xpoints[i + 1]; - int y2 = (i == npoints) ? ypoints[0] : ypoints[i + 1]; - - if (ypoints[i] == y2) - { - // We ignore horizontal lines. This might give weird - // results in some situations -- ? - continue; - } - - double t = (((double) miny - ypoints[i]) - / (double) (y2 - ypoints[i])); - double x3 = xpoints[i] + t * (x2 - xpoints[i]); - crosses[ins++] = x3; - } - - // Now we can sort into increasing order and look to see if - // any point in the rectangle is in the polygon. We examine - // every other pair due to our even-odd rule. - Arrays.sort (crosses, 0, ins); - int i = intersect ? 0 : 1; - for (; i < ins - 1; i += 2) - { - // Pathological case. - if (crosses[i] == crosses[i + 1]) - continue; - - // Found a point on the inside. - if ((crosses[i] >= x && crosses[i] < x + w) - || (crosses[i + 1] >= x && crosses[i + 1] < x + w)) - { - // If we're checking containment then we just lost. - // But if we're checking intersection then we just - // won. - return intersect; - } - } + return WIND_EVEN_ODD; } - return false; - } - - /** Translates all the vertices of the polygon via a given vector. - * @param deltaX The X offset - * @param deltaY The Y offset - */ - public void translate (int deltaX, int deltaY) - { - for (int i = 0; i < npoints; ++i) + public boolean isDone() { - xpoints[i] += deltaX; - ypoints[i] += deltaY; + return vertex > npoints; } - if (bounds != null) + public void next() { - bounds.x += deltaX; - bounds.y += deltaY; + vertex++; } - } - // This computes the bounding box if required. - private void computeBoundingBox () - { - if (npoints == 0) + public int currentSegment(float[] coords) { - // This is wrong if the user adds a new point, but we - // account for that in addPoint(). - bounds = new Rectangle (0, 0, 0, 0); + if (vertex >= npoints) + return SEG_CLOSE; + coords[0] = xpoints[vertex]; + coords[1] = ypoints[vertex]; + if (transform != null) + transform.transform(coords, 0, coords, 0, 1); + return vertex == 0 ? SEG_MOVETO : SEG_LINETO; } - else + + public int currentSegment(double[] coords) { - int maxx = xpoints[0]; - int minx = xpoints[0]; - int maxy = ypoints[0]; - int miny = ypoints[0]; - - for (int i = 1; i < npoints; ++i) - { - maxx = Math.max (maxx, xpoints[i]); - minx = Math.min (minx, xpoints[i]); - maxy = Math.max (maxy, ypoints[i]); - miny = Math.min (miny, ypoints[i]); - } - - bounds = new Rectangle (minx, miny, maxx - minx, maxy - miny); + if (vertex >= npoints) + return SEG_CLOSE; + coords[0] = xpoints[vertex]; + coords[1] = ypoints[vertex]; + if (transform != null) + transform.transform(coords, 0, coords, 0, 1); + return vertex == 0 ? SEG_MOVETO : SEG_LINETO; } + }; } - private class Iterator implements PathIterator + /** + * Return an iterator along the flattened version of the shape boundary. + * Since polygons are already flat, the flatness parameter is ignored, and + * the resulting iterator only has SEG_MOVETO, SEG_LINETO and SEG_CLOSE + * points. If the optional transform is provided, the iterator is + * transformed accordingly. Each call returns a new object, independent + * from others in use. This class is not threadsafe to begin with, so the + * path iterator is not either. + * + * @param transform an optional transform to apply to the iterator + * @param double the maximum distance for deviation from the real boundary + * @return a new iterator over the boundary + * @since 1.2 + */ + public PathIterator getPathIterator(AffineTransform transform, + double flatness) { - public AffineTransform xform; - public int where; - - public Iterator (AffineTransform xform) - { - this.xform = xform; - where = 0; - } - - public int currentSegment (double[] coords) - { - int r; - - if (where < npoints) - { - coords[0] = xpoints[where]; - coords[1] = ypoints[where]; - r = (where == 0) ? SEG_MOVETO : SEG_LINETO; - xform.transform (coords, 0, coords, 0, 1); - ++where; - } - else - r = SEG_CLOSE; - - return r; - } - - public int currentSegment (float[] coords) - { - int r; - - if (where < npoints) - { - coords[0] = xpoints[where]; - coords[1] = ypoints[where]; - r = (where == 0) ? SEG_MOVETO : SEG_LINETO; - xform.transform (coords, 0, coords, 0, 1); - } - else - r = SEG_CLOSE; - - return r; - } - - public int getWindingRule () - { - return WIND_EVEN_ODD; - } - - public boolean isDone () - { - return where == npoints + 1; - } + return getPathIterator(transform); + } - public void next () - { - ++where; - } + /** + * Helper for contains, which caches a condensed version of the polygon. + * This condenses all colinear points, so that consecutive segments in + * the condensed version always have different slope. + * + * @return true if the condensed polygon has area + * @see #condensed + * @see #contains(double, double) + */ + private boolean condense() + { + if (npoints <= 2) + return false; + if (condensed != null) + return condensed[0] > 2; + condensed = new int[npoints * 2 + 1]; + int curx = xpoints[npoints - 1]; + int cury = ypoints[npoints - 1]; + double curslope = Double.NaN; + int count = 0; + outer: + for (int i = 0; i < npoints; i++) + { + int priorx = curx; + int priory = cury; + double priorslope = curslope; + curx = xpoints[i]; + cury = ypoints[i]; + while (curx == priorx && cury == priory) + { + if (++i == npoints) + break outer; + curx = xpoints[i]; + cury = ypoints[i]; + } + curslope = (curx == priorx ? Double.POSITIVE_INFINITY + : (double) (cury - priory) / (curx - priorx)); + if (priorslope == curslope) + { + if (count > 1 && condensed[(count << 1) - 3] == curx + && condensed[(count << 1) - 2] == cury) + { + count--; + continue; + } + } + else + count++; + condensed[(count << 1) - 1] = curx; + condensed[count << 1] = cury; + } + condensed[0] = count; + return count > 2; } -} +} // class Polygon diff --git a/libjava/java/awt/PrintGraphics.java b/libjava/java/awt/PrintGraphics.java index 3d1ee632682..4a65fcec510 100644 --- a/libjava/java/awt/PrintGraphics.java +++ b/libjava/java/awt/PrintGraphics.java @@ -1,5 +1,5 @@ -/* PrintGraphics.java -- A print graphics context. - Copyright (C) 1999 Free Software Foundation, Inc. +/* PrintGraphics.java -- a print graphics context + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,21 +39,19 @@ exception statement from your version. */ package java.awt; /** - * This interface allows the originating print job to be obtained. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This interface allows the originating print job to be obtained. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.0 + * @status updated to 1.4 + */ public interface PrintGraphics { - -/** - * Returns the <code>PrintJob</code> that this object is being - * managed by. - * - * @return The print job for this object. - */ -public abstract PrintJob -getPrintJob(); - + /** + * Returns the <code>PrintJob</code> that this object is being + * managed by. + * + * @return the print job for this object + */ + PrintJob getPrintJob(); } // interface PrintGraphics - diff --git a/libjava/java/awt/PrintJob.java b/libjava/java/awt/PrintJob.java index 4e6ae29ff7b..9cf95f21495 100644 --- a/libjava/java/awt/PrintJob.java +++ b/libjava/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/libjava/java/awt/Rectangle.java b/libjava/java/awt/Rectangle.java index 6c04b48168f..451f116e6ce 100644 --- a/libjava/java/awt/Rectangle.java +++ b/libjava/java/awt/Rectangle.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation +/* Rectangle.java -- represents a graphics rectangle + Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,41 +38,73 @@ exception statement from your version. */ package java.awt; -import java.awt.geom.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; import java.io.Serializable; -/* Status: Mostly complete. Some of the Java2D stuff is commented out. */ - /** * This class represents a rectangle and all the interesting things you * might want to do with it. Note that the coordinate system uses * the origin (0,0) as the top left of the screen, with the x and y * values increasing as they move to the right and down respectively. * + * <p>It is valid for a rectangle to have negative width or height; but it + * is considered to have no area or internal points. Therefore, the behavior + * in methods like <code>contains</code> or <code>intersects</code> is + * undefined unless the rectangle has positive width and height. + * + * <p>There are some public fields; if you mess with them in an inconsistent + * manner, it is your own fault when you get NullPointerException, + * ArrayIndexOutOfBoundsException, or invalid results. Also, this class is + * not threadsafe. + * * @author Warren Levy <warrenl@cygnus.com> - * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.0 + * @status updated to 1.4 */ -public class Rectangle extends Rectangle2D - implements Cloneable, Shape, Serializable +public class Rectangle extends Rectangle2D implements Shape, Serializable { /** - * The X coordinate of the top-left corner of the rectangle. - */ + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = -4345857070255674764L; + + /** + * The X coordinate of the top-left corner of the rectangle. + * + * @see #setLocation(int, int) + * @see #getLocation() + * @serial the x coordinate + */ public int x; /** - * The Y coordinate of the top-left corner of the rectangle; - */ + * The Y coordinate of the top-left corner of the rectangle. + * + * @see #setLocation(int, int) + * @see #getLocation() + * @serial the y coordinate + */ public int y; /** - * The width of the rectangle - */ + * The width of the rectangle. + * + * @see #setSize(int, int) + * @see #getSize() + * @serial + */ public int width; /** - * The height of the rectangle - */ + * The height of the rectangle. + * + * @see #setSize(int, int) + * @see #getSize() + * @serial + */ public int height; /** @@ -80,17 +113,15 @@ public class Rectangle extends Rectangle2D */ public Rectangle() { - x = 0; - y = 0; - width = 0; - height = 0; } /** * Initializes a new instance of <code>Rectangle</code> from the * coordinates of the specified rectangle. * - * @param rect The rectangle to copy from. + * @param r the rectangle to copy from + * @throws NullPointerException if r is null + * @since 1.1 */ public Rectangle(Rectangle r) { @@ -104,10 +135,10 @@ public class Rectangle extends Rectangle2D * Initializes a new instance of <code>Rectangle</code> from the specified * inputs. * - * @param x The X coordinate of the top left corner of the rectangle. - * @param y The Y coordinate of the top 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 top left corner + * @param y the Y coordinate of the top left corner + * @param width the width of the rectangle + * @param height the height of the rectangle */ public Rectangle(int x, int y, int width, int height) { @@ -119,16 +150,14 @@ public class Rectangle extends Rectangle2D /** * Initializes a new instance of <code>Rectangle</code> with the specified - * width and height. The upper left corner of the rectangle will be at + * width and height. The upper left corner of the rectangle will be at * the origin (0,0). * - * @param width The width of the rectangle. - * @param height the height of the rectange. + * @param width the width of the rectangle + * @param height the height of the rectange */ public Rectangle(int width, int height) { - x = 0; - y = 0; this.width = width; this.height = height; } @@ -138,8 +167,9 @@ public class Rectangle extends Rectangle2D * corner represented by the specified point and the width and height * represented by the specified dimension. * - * @param point The upper left corner of the rectangle. - * @param dim The width and height of the rectangle. + * @param p the upper left corner of the rectangle + * @param d the width and height of the rectangle + * @throws NullPointerException if p or d is null */ public Rectangle(Point p, Dimension d) { @@ -153,14 +183,12 @@ public class Rectangle extends Rectangle2D * Initializes a new instance of <code>Rectangle</code> with a top left * corner at the specified point and a width and height of zero. * - * @param poin The upper left corner of the rectangle. + * @param p the upper left corner of the rectangle */ public Rectangle(Point p) { x = p.x; y = p.y; - width = 0; - height = 0; } /** @@ -168,151 +196,154 @@ public class Rectangle extends Rectangle2D * upper left corner at the origin (0,0) and a width and height represented * by the specified dimension. * - * @param dim The width and height of the rectangle. + * @param d the width and height of the rectangle */ public Rectangle(Dimension d) { - x = 0; - y = 0; width = d.width; height = d.height; } /** - * Returns the bounding rectangle for this rectangle, which is simply - * this rectange itself. + * Get the X coordinate of the upper-left corner. * - * @return This rectangle. + * @return the value of x, as a double */ - public Rectangle getBounds () + public double getX() { - return (Rectangle) this.clone(); + return x; } /** - * Modifies this rectangle so that it represents the smallest rectangle - * that contains both the existing rectangle and the specified point. + * Get the Y coordinate of the upper-left corner. * - * @param x The X coordinate of the point to add to this rectangle. - * @param y The Y coordinate of the point to add to this rectangle. + * @return the value of y, as a double */ - public void add(int newx, int newy) + public double getY() { - int x = this.x > newx ? newx : this.x; - int y = this.y > newy ? newy : this.y; - width = (this.x + width > newx ? this.x + width : newx) - x; - height = (this.y + height > newy ? this.y + height : newy) - y; - this.x = x; - this.y = y; + return y; } /** - * Modifies this rectangle so that it represents the smallest rectangle - * that contains both the existing rectangle and the specified point. + * Get the width of the rectangle. * - * @param point The point to add to this rectangle. + * @return the value of width, as a double */ - public void add(Point pt) + public double getWidth() { - add (pt.x, pt.y); + return width; } /** - * Modifies this rectangle so that it represents the smallest rectangle - * that contains both the existing rectangle and the specified rectangle. + * Get the height of the rectangle. * - * @param rect The rectangle to add to this rectangle. + * @return the value of height, as a double */ - public void add(Rectangle r) + public double getHeight() { - int x = this.x > r.x ? r.x : this.x; - int y = this.y > r.y ? r.y : this.y; - width = (this.x + width > r.x + r.width ? - this.x + width : r.x + r.width) - x; - height = (this.y + height > r.y + r.height ? - this.y + height : r.y + r.height) - y; - this.x = x; - this.y = y; + return height; } /** - * Tests whether or not the specified point is inside this rectangle. + * Returns the bounds of this rectangle. A pretty useless method, as this + * is already a rectangle; it is included to mimic the + * <code>getBounds</code> method in Component. * - * @param x The X coordinate of the point to test. - * @param y The Y coordinate of the point to test. - * - * @return <code>true</code> if the point is inside the rectangle, - * <code>false</code> otherwise. + * @return a copy of this rectangle + * @see #setBounds(Rectangle) + * @since 1.1 */ - public boolean contains(int x, int y) + public Rectangle getBounds() { - return (x >= this.x && x <= this.x + this.width - && y >= this.y && y <= this.y + this.height); - } + return new Rectangle(this); + } - public boolean contains(int x, int y, int w, int h) + /** + * Returns the high-precision bounds of this rectangle. A pretty useless + * method, as this is already a rectangle. + * + * @return a copy of this rectangle + * @see #setBounds(Rectangle) + * @since 1.2 + */ + public Rectangle2D getBounds2D() { - return (x >= this.x && x + w <= this.x + this.width - && y >= this.y && y + h <= this.y + this.height); + return new Rectangle(x, y, width, height); } /** - * Tests whether or not the specified point is inside this rectangle. - * - * @param point The point to test. + * Updates this rectangle to match the dimensions of the specified + * rectangle. * - * @return <code>true</code> if the point is inside the rectangle, - * <code>false</code> otherwise. + * @param r the rectangle to update from + * @throws NullPointerException if r is null + * @see #setBounds(int, int, int, int) + * @since 1.1 */ - public boolean contains(Point p) + public void setBounds(Rectangle r) { - return contains(p.x, p.y); + x = r.x; + y = r.y; + width = r.width; + height = r.height; } - public boolean contains(Rectangle r) + /** + * Updates this rectangle to have the specified dimensions. + * + * @param x the new X coordinate of the upper left hand corner + * @param y the new Y coordinate of the upper left hand corner + * @param width the new width of this rectangle + * @param height the new height of this rectangle + * @since 1.1 + */ + public void setBounds(int x, int y, int width, int height) { - return contains(r.x, r.y, r.width, r.height); + this.x = x; + this.y = y; + this.width = width; + this.height = height; } /** - * Tests this rectangle for equality against the specified object. This - * will be true if an only if the specified object: - * <p> - * <ul> - * <li>Is not <code>null</code>. - * <li>Is an instance of <code>Rectangle</code>. - * <li>Has X and Y coordinates identical to this rectangle. - * <li>Has a width and height identical to this rectangle. - * </ul> - * - * @param obj The object to test against for equality. + * Updates this rectangle to have the specified dimensions, as rounded to + * integers. * - * @return <code>true</code> if the specified object is equal to this one, - * <code>false</code> otherwise. + * @param x the new X coordinate of the upper left hand corner + * @param y the new Y coordinate of the upper left hand corner + * @param width the new width of this rectangle + * @param height the new height of this rectangle + * @since 1.2 */ - public boolean equals(Object obj) + public void setRect(double x, double y, double width, double height) { - if (obj instanceof Rectangle) - { - Rectangle r = (Rectangle) obj; - return (r.x == x - && r.y == y - && r.width == width - && r.height == height); - } - return false; + this.x = (int) x; + this.y = (int) y; + this.width = (int) width; + this.height = (int) height; } - public double getHeight() + /** + * Updates this rectangle to have the specified dimensions. + * + * @param x the new X coordinate of the upper left hand corner + * @param y the new Y coordinate of the upper left hand corner + * @param width the new width of this rectangle + * @param height the new height of this rectangle + * @deprecated use {@link #setBounds(int, int, int, int)} instead + */ + public void reshape(int x, int y, int width, int height) { - return (double) this.height; + setBounds(x, y, width, height); } /** * Returns the location of this rectangle, which is the coordinates of * its upper left corner. * - * @return The point where this rectangle is located. + * @return the point where this rectangle is located + * @see setLocation(Point) + * @since 1.1 */ public Point getLocation() { @@ -320,326 +351,409 @@ public class Rectangle extends Rectangle2D } /** - * Returns the size of this rectangle. + * Moves the location of this rectangle by setting its upper left + * corner to the specified point. * - * @return The size of this rectangle. + * @param p the point to move the rectangle to + * @throws NullPointerException if p is null + * @see #getLocation() + * @since 1.1 */ - public Dimension getSize() + public void setLocation(Point p) { - return new Dimension(width, height); + this.x = p.x; + this.y = p.y; } - public double getWidth() + /** + * Moves the location of this rectangle by setting its upper left + * corner to the specified coordinates. + * + * @param x the new X coordinate for this rectangle + * @param y the new Y coordinate for this rectangle + * @since 1.1 + */ + public void setLocation(int x, int y) { - return (double) this.width; + this.x = x; + this.y = y; } - public double getX() + /** + * Moves the location of this rectangle by setting its upper left + * corner to the specified coordinates. + * + * @param x the new X coordinate for this rectangle + * @param y the new Y coordinate for this rectangle + * @deprecated use {@link #setLocation(int, int)} instead + */ + public void move(int x, int y) { - return (double) x; + setLocation(x, y); } - public double getY() + /** + * Translate the location of this rectangle by the given amounts. + * + * @param dx the x distance to move by + * @param dy the y distance to move by + * @see #setLocation(int, int) + */ + public void translate(int dx, int dy) { - return (double) y; + x += dx; + y += dy; } /** - * Expands the rectangle by the specified amount. The horizontal - * and vertical expansion values are applied both to the X,Y coordinate - * of this rectangle, and its width and height. Thus the width and - * height will increase by 2h and 2v accordingly. + * Returns the size of this rectangle. * - * @param h The horizontal expansion value. - * @param v The vertical expansion value. + * @return the size of this rectangle + * @see #setSize(Dimension) + * @since 1.1 */ - public void grow(int h, int v) + public Dimension getSize() { - width += h; - height += v; + return new Dimension(width, height); } /** - * Tests whether or not the specified point is inside this rectangle. - * - * @param x The X coordinate of the point to test. - * @param y The Y coordinate of the point to test. - * - * @return <code>true</code> if the point is inside the rectangle, - * <code>false</code> otherwise. + * Sets the size of this rectangle based on the specified dimensions. * - * @deprecated This method is deprecated in favor of - * <code>contains(int, int)</code>. + * @param d the new dimensions of the rectangle + * @throws NullPointerException if d is null + * @see #getSize() + * @since 1.1 */ - public boolean inside(int x, int y) + public void setSize(Dimension d) { - return contains(x, y); + width = d.width; + height = d.height; } /** - * Determines the rectange which is formed by the intersection of this - * rectangle with the specified rectangle. - * - * @param rect The rectange to calculate the intersection with. - * - * @return The rectangle bounding the intersection. + * Sets the size of this rectangle based on the specified dimensions. * - * @specnote If there is no intersection, an empty rectangle at 0,0 - * is returned. + * @param width the new width of the rectangle + * @param height the new height of the rectangle + * @since 1.1 */ - public Rectangle intersection(Rectangle r) + public void setSize(int width, int height) { - int newx = x < r.x ? r.x : x; - int newy = y < r.y ? r.y : y; - int neww = (x + width < r.x + r.width ? - x + width : r.x + r.width) - newx; - int newh = (y + height < r.y + r.height ? - y + height : r.y + r.height) - newy; - if (neww >= 0 && newh >= 0) - return new Rectangle(newx, newy, neww, newh); - else - return new Rectangle(0, 0, 0, 0); + this.width = width; + this.height = height; } /** - * Tests whether or not the specified rectangle intersects this rectangle. - * - * @param rect The rectangle to test against. - * - * @return <code>true</code> if the specified rectangle intersects this - * one, <code>false</code> otherwise. + * Sets the size of this rectangle based on the specified dimensions. * - * @specnote If the intersection is at an edge or corner only (an empty - * intersection with a non-zero location), false is returned. + * @param width the new width of the rectangle + * @param height the new height of the rectangle + * @deprecated use {@link #setSize(int, int)} instead */ - public boolean intersects(Rectangle r) + public void resize(int width, int height) { - int neww = (x + width < r.x + r.width ? - x + width : r.x + r.width) - (x < r.x ? r.x : x); - int newh = (y + height < r.y + r.height ? - y + height : r.y + r.height) - (y < r.y ? r.y : y); - return (neww > 0 && newh > 0); + setSize(width, height); } /** - * Tests whether or not this rectangle is empty. An empty rectangle - * has a width or height of zero. + * Tests whether or not the specified point is inside this rectangle. + * According to the contract of Shape, a point on the border is in only if + * it has an adjacent point inside the rectangle in either the increasing + * x or y direction. * - * @return <code>true</code> if the rectangle is empty, <code>false</code> - * otherwise. + * @param p the point to test + * @return true if the point is inside the rectangle + * @throws NullPointerException if p is null + * @see #contains(int, int) + * @since 1.1 */ - public boolean isEmpty() + public boolean contains(Point p) { - return !(width > 0 && height > 0); + return width > 0 && height > 0 + && p.x >= x && p.x < x + width + && p.y >= y && p.y < y + height; } /** - * Moves the location of this rectangle by setting its upper left - * corner to the specified coordinates. - * // FIXME: Is this true? - * - * @param x The new X coordinate for this rectangle. - * @param y The new Y coordinate for this rectangle. + * Tests whether or not the specified point is inside this rectangle. + * According to the contract of Shape, a point on the border is in only if + * it has an adjacent point inside the rectangle in either the increasing + * x or y direction. * - * @deprecated This method is deprecated in favor of - * <code>setLocation(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 inside the rectangle + * @since 1.1 */ - public void move(int x, int y) + public boolean contains(int x, int y) { - setLocation(x, y); + return width > 0 && height > 0 + && x >= this.x && x < this.x + width + && y >= this.y && y < this.y + height; } - public int outcode(double x, double y) + /** + * Checks whether all points in the given rectangle are contained in this + * rectangle. + * + * @param r the rectangle to check + * @return true if r is contained in this rectangle + * @throws NullPointerException if r is null + * @see #contains(int, int, int, int) + * @since 1.1 + */ + public boolean contains(Rectangle r) { - // FIXME - return 0; + return width > 0 && height > 0 && r.width > 0 && r.height > 0 + && r.x >= x && r.x + r.width <= x + width + && r.y >= y && r.y + r.height <= y + height; } /** - * Updates this rectangle to have the specified dimensions. - * - * @param x The new X coordinate of the upper left hand corner. - * @param y The new Y coordinate of the upper left hand corner. - * @param width The new width of this rectangle. - * @param height The new height of this rectangle. + * Checks whether all points in the given rectangle are contained in this + * rectangle. * - * @deprecated This method is deprecated in favor of - * <code>setBounds(int, int, int, int)</code>. + * @param x the x coordinate of the rectangle to check + * @param y the y coordinate of the rectangle to check + * @param w the width of the rectangle to check + * @param h the height of the rectangle to check + * @return true if the parameters are contained in this rectangle + * @since 1.1 */ - public void reshape(int x, int y, int width, int height) + public boolean contains(int x, int y, int w, int h) { - setBounds(x, y, width, height); + return width > 0 && height > 0 && w > 0 && h > 0 + && x >= this.x && x + w <= this.x + this.width + && y >= this.y && y + h <= this.y + this.height; } /** - * Sets the size of this rectangle based on the specified dimensions. - * - * @param width The new width of the rectangle. - * @param height The new height of the rectangle. + * Tests whether or not the specified point is inside this rectangle. * - * @deprecated This method is deprecated in favor of - * <code>setSize(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 inside the rectangle + * @deprecated use {@link #contains(int, int)} instead */ - public void resize(int width, int height) + public boolean inside(int x, int y) { - setSize(width, height); + return contains(x, y); } /** - * Updates this rectangle to have the specified dimensions. + * Tests whether or not the specified rectangle intersects this rectangle. + * This means the two rectangles share at least one internal point. * - * @param x The new X coordinate of the upper left hand corner. - * @param y The new Y coordinate of the upper left hand corner. - * @param width The new width of this rectangle. - * @param height The new height of this rectangle. + * @param r the rectangle to test against + * @return true if the specified rectangle intersects this one + * @throws NullPointerException if r is null + * @since 1.2 */ - public void setBounds(int x, int y, int width, int height) + public boolean intersects(Rectangle r) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; + return width > 0 && height > 0 && r.width > 0 && r.height > 0 + && r.x < x + width && r.x + r.width > x + && r.y < y + height && r.y + r.height > y; } /** - * Updates this rectangle to match the dimensions of the specified - * rectangle. + * Determines the rectangle which is formed by the intersection of this + * rectangle with the specified rectangle. If the two do not intersect, + * an empty rectangle will be returned (meaning the width and/or height + * will be non-positive). * - * @param rect The rectangle to update from. + * @param r the rectange to calculate the intersection with + * @return a new rectangle bounding the intersection + * @throws NullPointerException if r is null */ - public void setBounds(Rectangle r) + public Rectangle intersection(Rectangle r) { - this.x = r.x; - this.y = r.y; - this.width = r.width; - this.height = r.height; + Rectangle res = new Rectangle(); + intersect(this, r, res); + return res; } /** - * Moves the location of this rectangle by setting its upper left - * corner to the specified coordinates. - * // FIXME: Is this true? + * Returns the smallest rectangle that contains both this rectangle + * and the specified rectangle. * - * @param x The new X coordinate for this rectangle. - * @param y The new Y coordinate for this rectangle. + * @param r the rectangle to compute the union with + * @return the smallest rectangle containing both rectangles + * @throws NullPointerException if r is null */ - public void setLocation(int x, int y) + public Rectangle union(Rectangle r) { - this.x = x; - this.y = y; + Rectangle res = new Rectangle(); + union(this, r, res); + return res; } /** - * Moves the location of this rectangle by setting its upper left - * corner to the specified point. - * // FIXME: Is this true? + * Modifies this rectangle so that it represents the smallest rectangle + * that contains both the existing rectangle and the specified point. + * However, if the point falls on one of the two borders which are not + * inside the rectangle, a subsequent call to <code>contains</code> may + * return false. * - * @param point The point to move the rectange to. + * @param x the X coordinate of the point to add to this rectangle + * @param y the Y coordinate of the point to add to this rectangle */ - public void setLocation(Point p) + public void add(int x, int y) { - this.x = p.x; - this.y = p.y; + add((double) x, (double) y); } - public void setRect(double x, double y, double width, double height) + /** + * Modifies this rectangle so that it represents the smallest rectangle + * that contains both the existing rectangle and the specified point. + * However, if the point falls on one of the two borders which are not + * inside the rectangle, a subsequent call to <code>contains</code> may + * return false. + * + * @param p the point to add to this rectangle + * @throws NullPointerException if p is null + */ + public void add(Point p) { - this.x = (int) x; - this.y = (int) y; - this.width = (int) width; - this.height = (int) height; + add((double) p.x, (double) p.y); } /** - * Sets the size of this rectangle based on the specified dimensions. + * Modifies this rectangle so that it represents the smallest rectangle + * that contains both the existing rectangle and the specified rectangle. * - * @param dim The new dimensions of the rectangle. + * @param r the rectangle to add to this rectangle + * @throws NullPointerException if r is null + * @see #union(Rectangle) */ - public void setSize(Dimension d) + public void add(Rectangle r) { - this.width = d.width; - this.height = d.height; + union(this, r, this); } /** - * Sets the size of this rectangle based on the specified dimensions. + * Expands the rectangle by the specified amount. The horizontal + * and vertical expansion values are applied both to the X,Y coordinate + * of this rectangle, and its width and height. Thus the width and + * height will increase by 2h and 2v accordingly. * - * @param width The new width of the rectangle. - * @param height The new height of the rectangle. + * @param h the horizontal expansion value + * @param v the vertical expansion value */ - public void setSize(int width, int height) + public void grow(int h, int v) { - this.width = width; - this.height = height; + x -= h; + y -= v; + width += h + h; + height += v + v; } - public void translate(int x, int y) + /** + * Tests whether or not this rectangle is empty. An empty rectangle + * has a non-positive width or height. + * + * @return true if the rectangle is empty + */ + public boolean isEmpty() { - x += x; - y += y; + return width <= 0 || height <= 0; } /** - * Returns the smallest rectangle that contains both this rectangle - * and the specified rectangle. + * Determine where the point lies with respect to this rectangle. The + * result will be the binary OR of the appropriate bit masks. * - * @param rect The rectangle to compute the union with. - * - * @return The smallest rectangle containing both rectangles. + * @param x the x coordinate to check + * @param y the y coordinate to check + * @return the binary OR of the result + * @see #OUT_LEFT + * @see #OUT_TOP + * @see #OUT_RIGHT + * @see #OUT_BOTTOM + * @since 1.2 */ - public Rectangle union(Rectangle r) + public int outcode(double x, double y) { - int newx = x > r.x ? r.x : x; - int newy = y > r.y ? r.y : y; - int neww = (this.x + width > r.x + r.width ? - this.x + width : r.x + r.width) - newx; - int newh = (this.y + height > r.y + r.height ? - this.y + height : r.y + r.height) - newy; - return new Rectangle(newx, newy, neww, newh); - } - - // Commented out until we have Rectangle2D + int result = 0; + if (width <= 0) + result |= OUT_LEFT | OUT_RIGHT; + else if (x < this.x) + result |= OUT_LEFT; + else if (x > this.x + width) + result |= OUT_RIGHT; + if (height <= 0) + result |= OUT_BOTTOM | OUT_TOP; + else if (y < this.y) // Remember that +y heads top-to-bottom. + result |= OUT_TOP; + else if (y > this.y + height) + result |= OUT_BOTTOM; + return result; + } + + /** + * Determines the rectangle which is formed by the intersection of this + * rectangle with the specified rectangle. If the two do not intersect, + * an empty rectangle will be returned (meaning the width and/or height + * will be non-positive). + * + * @param r the rectange to calculate the intersection with + * @return a new rectangle bounding the intersection + * @throws NullPointerException if r is null + * @since 1.2 + */ public Rectangle2D createIntersection(Rectangle2D r) { - // FIXME: maybe we should consider returning a Rectangle or - // Rectangle2D.Float depending on type of R. - Rectangle2D.Double res = new Rectangle2D.Double (); - intersect (this, r, res); + // Favor runtime type of other rectangle. + Rectangle2D res = r.getBounds2D(); + intersect(this, r, res); return res; } + /** + * Returns the smallest rectangle that contains both this rectangle + * and the specified rectangle. + * + * @param r the rectangle to compute the union with + * @return the smallest rectangle containing both rectangles + * @throws NullPointerException if r is null + * @since 1.2 + */ public Rectangle2D createUnion(Rectangle2D r) { - // FIXME: maybe we should consider returning a Rectangle or - // Rectangle2D.Float depending on type of R. - Rectangle2D.Double res = new Rectangle2D.Double (); - union (this, r, res); + // Favor runtime type of other rectangle. + Rectangle2D res = r.getBounds2D(); + union(this, r, res); return res; } - public Rectangle2D getBounds2D() - { - return new Rectangle (x, y, width, height); - } - /** - * Returns a string representation of this rectangle. + * Tests this rectangle for equality against the specified object. This + * will be true if an only if the specified object is an instance of + * Rectangle2D with the same coordinates and dimensions. * - * @return A string representation of this rectangle. + * @param obj the object to test against for equality + * @return true if the specified object is equal to this one */ - public String toString() + public boolean equals(Object obj) { - return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + - ",height=" + height + "]"; + if (! (obj instanceof Rectangle2D)) + return false; + Rectangle2D r = (Rectangle2D) obj; + return r.getX() == x && r.getY() == y + && r.getWidth() == width && r.getHeight() == height; } /** - * Returns a hash value for this object. + * Returns a string representation of this rectangle. This is in the form + * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + * + ",height=" + height + ']'</code>. * - * @return A hash value for this object. + * @return a string representation of this rectangle */ - public int hashCode() + public String toString() { - return x * y * width * height * 37; + return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + + ",height=" + height + ']'; } -} +} // class Rectangle diff --git a/libjava/java/awt/RenderingHints.java b/libjava/java/awt/RenderingHints.java index 9bdbd547ac5..9dc6d5f6419 100644 --- a/libjava/java/awt/RenderingHints.java +++ b/libjava/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/libjava/java/awt/Robot.java b/libjava/java/awt/Robot.java new file mode 100644 index 00000000000..1de5f3f3706 --- /dev/null +++ b/libjava/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/libjava/java/awt/ScrollPane.java b/libjava/java/awt/ScrollPane.java index dd657ac1996..546f8e64d17 100644 --- a/libjava/java/awt/ScrollPane.java +++ b/libjava/java/awt/ScrollPane.java @@ -1,340 +1,466 @@ -/* Copyright (C) 2000 Free Software Foundation +/* ScrollPane.java -- Scrolling window + Copyright (C) 1999 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. */ - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.awt; -import java.awt.event.AdjustmentListener; import java.awt.peer.ScrollPanePeer; +import java.awt.peer.ContainerPeer; +import java.awt.peer.ComponentPeer; + +/** + * This widget provides a scrollable region that allows a single + * subcomponent to be viewed through a smaller window. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class ScrollPane extends Container implements java.io.Serializable +{ + +/* + * Static Variables + */ + +/** + * Constant indicating that scrollbars are created as needed in this + * windows. + */ +public static final int SCROLLBARS_AS_NEEDED = 0; + +/** + * Constant indicating that scrollbars are always displayed in this + * window. + */ +public static final int SCROLLBARS_ALWAYS = 1; + +/** + * Constant indicating that scrollbars are never displayed in this window. + */ +public static final int SCROLLBARS_NEVER = 2; -/** A ScrollPane is a component that has vertical and horizontal - * scrollbars as well as a single child which is scrolled by them. - * @author Tom Tromey <tromey@redhat.com> - * @date December 31, 2000 +// Serialization constant +private static final long serialVersionUID = 7956609840827222915L; + +/*************************************************************************/ + +/* + * Instance Variables + */ + +/** + * @serial The horizontal scrollbar for this window. The methods + * <code>setMinimum()</code>, <code>setMaximum</code>, and + * <code>setVisibleAmount</code> must not be called on this scrollbar. + */ +private ScrollPaneAdjustable hAdjustable; + +/** + * @serial The vertical scrollbar for this window. The methods + * <code>setMinimum()</code>, <code>setMaximum</code>, and + * <code>setVisibleAmount</code> must not be called on this scrollbar. + */ +private ScrollPaneAdjustable vAdjustable; + +/** + * @serial Indicates when scrollbars are displayed in this window, will + * be one of the constants from this class. + */ +private int scrollbarDisplayPolicy; + +// Current scroll position +private Point scrollPosition = new Point(0, 0); + +/*************************************************************************/ + +/* + * Constructors */ -public class ScrollPane extends Container + +/** + * Initializes a new instance of <code>ScrollPane</code> with a default + * scrollbar policy of <code>SCROLLBARS_AS_NEEDED</code>. + */ +public +ScrollPane() { - /** This indicates that scrollbars should only be displayed when - * needed. */ - public static final int SCROLLBARS_AS_NEEDED = 0; - /** This indicates that scrollbars should always be displayed. */ - public static final int SCROLLBARS_ALWAYS = 1; - /** This indicates that scrollbars should never be displayed. */ - public static final int SCROLLBARS_NEVER = 2; - - /** Create a new ScrollPane object using the indicated scrollbar - * display policy. If the policy is not specified it defaults to - * SCROLLBARS_AS_NEEDED. The default size of this component is - * 100x100. - * @param policy The scrollbar display policy - */ - public ScrollPane () - { - this (SCROLLBARS_AS_NEEDED); - } - - public ScrollPane (int policy) - { - if (policy != SCROLLBARS_AS_NEEDED - && policy != SCROLLBARS_ALWAYS - && policy != SCROLLBARS_NEVER) - throw new IllegalArgumentException ("invalid value for policy"); - - this.policy = policy; - setSize (100, 100); - } - - /** Add a component to this ScrollPane. - * @param comp The component to add - * @param constraints Constraints. This is ignored. - * @param pos Position. This must be <= 0, but is otherwise ignored. - */ - protected final void addImpl (Component comp, Object constraints, - int pos) - { - if (pos > 0) - throw new IllegalArgumentException ("pos must be <= 0"); - - if (ncomponents > 0) - remove (component[0]); - - if (comp.isLightweight ()) - { - Panel p = new Panel (); - p.add (comp); - comp = p; - } - - super.addImpl (comp, constraints, pos); - } - - /** This creates the component's peer. */ - public void addNotify () - { - if (peer == null) - peer = getToolkit ().createScrollPane (this); - super.addNotify (); - } - - /** Lays out the components in this container. */ - public void doLayout () - { - ScrollPanePeer spp = (ScrollPanePeer) peer; - Dimension c = component[0].getPreferredSize (); - component[0].setSize (c.width, c.height); - spp.childResized (c.width, c.height); - // Update the scrollbar position to the closest valid value. - setScrollPosition (hscroll.getValue (), vscroll.getValue ()); - } - - /** Returns an Adjustable representing the horizontal scrollbar. - * The methods setMaximum, setMinimum, and setVisibleAmount should - * not be called on this Adjustable. They will throw AWTError if - * called. - */ - public Adjustable getHAdjustable () - { - return hscroll; - } - - /** Returns the height of the horizontal scrollbar. */ - public int getHScrollbarHeight () - { - if (peer == null) - return 0; - ScrollPanePeer spp = (ScrollPanePeer) peer; - return spp.getHScrollbarHeight (); - } - - /** Returns the scrollbar display policy. */ - public int getScrollbarDisplayPolicy () - { - return policy; - } - - /** Returns the viewport's scroll position. */ - public Point getScrollPosition () - { - return new Point (hscroll.getValue (), vscroll.getValue ()); - } - - /** Returns an Adjustable representing the vertical scrollbar. - * The methods setMaximum, setMinimum, and setVisibleAmount should - * not be called on this Adjustable. They will throw AWTError if - * called. - */ - public Adjustable getVAdjustable () - { - return vscroll; - } - - /** Returns the size of the viewport. */ - public Dimension getViewportSize () - { - // Note: according to the online docs, the Insets are - // automatically updated by the peer to include the scrollbar - // sizes. - Insets ins = getInsets (); - int myw = width - ins.left - ins.right; - int myh = height - ins.top - ins.bottom; - - Dimension cs; - if (ncomponents > 0) - cs = component[0].getPreferredSize (); - else - cs = new Dimension (myw, myh); - - // A little optimization -- reuse the Dimension. - cs.setSize (myw, myh); - return cs; - } - - /** Returns the width of the vertical scrollbar. */ - public int getVScrollbarWidth () - { - if (peer == null) - return 0; - ScrollPanePeer spp = (ScrollPanePeer) peer; - return spp.getVScrollbarWidth (); - } - - /** Generates a String representation of this ScrollPane's state. */ - public String paramString () - { - return ("[" + getClass ().getName () - + ": " + ((ncomponents > 0) ? component[0].paramString () : "") - + "]"); - } - - /** Set the layout manager for this component. ScrollPane has its - * own layout manager and overrides this method so that the layout - * manager cannot be changed. - * @param m The new layout manager (ignored) - */ - public final void setLayout (LayoutManager m) - { - // Nothing. - } - - /** Sets the scroll position for this ScrollPane. If the point if - * out of range it is silently moved within range. - * @param x The x coordinate - * @param y The y coordinate - */ - public void setScrollPosition (int x, int y) - { - // According to the JCL we throw a NullPointerException if there - // is no child. - if (ncomponents == 0) - throw new NullPointerException ("no child in ScrollPane"); - - Dimension child_d = component[0].getPreferredSize (); - Dimension our_d = getViewportSize (); - - int xmax = Math.max (0, child_d.width - our_d.width); - int ymax = Math.max (0, child_d.height - our_d.height); - - if (x < 0) - x = 0; - else if (x > xmax) - x = xmax; - if (y < 0) - y = 0; - else if (y > ymax) - y = ymax; - - ScrollPanePeer spp = (ScrollPanePeer) peer; - spp.setScrollPosition (x, y); - } - - /** Sets the scroll position for this ScrollPane. If the point if - * out of range it is silently moved within range. - * @param p The new point - */ - public void setScrollPosition (Point p) - { - setScrollPosition (p.x, p.y); - } - - // This implements the Adjustable for each scrollbar. The - // expectation is that the peer will look at these objects directly - // and modify the values in them when the user manipulates the - // scrollbars. This has to be done from CNI to bypass Java - // protection rules. The peer should also take care of calling the - // adjustment listeners. - class ScrollPaneAdjustable implements Adjustable - { - AdjustmentListener listeners; - int orient; - int unit; - int block; - int value; - - public ScrollPaneAdjustable (int orient) - { - this.orient = orient; - } + this(SCROLLBARS_AS_NEEDED); +} - public void addAdjustmentListener (AdjustmentListener l) - { - listeners = AWTEventMulticaster.add (listeners, l); - } +/*************************************************************************/ + +/** + * Initializes a new instance of <code>ScrollPane</code> with the + * specified scrollbar policy. + * + * @param scrollbarDisplayPolicy When to display scrollbars, which must + * be one of the constants defined in this class. + */ +public +ScrollPane(int scrollbarDisplayPolicy) +{ + this.scrollbarDisplayPolicy = scrollbarDisplayPolicy; - public int getBlockIncrement () + if ((scrollbarDisplayPolicy != SCROLLBARS_ALWAYS) || + (scrollbarDisplayPolicy != SCROLLBARS_AS_NEEDED) || + (scrollbarDisplayPolicy != SCROLLBARS_NEVER)) + throw new IllegalArgumentException("Bad scrollbarDisplayPolicy: " + + scrollbarDisplayPolicy); + + if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) { - return block; + hAdjustable = new ScrollPaneAdjustable(Scrollbar.HORIZONTAL); + vAdjustable = new ScrollPaneAdjustable(Scrollbar.VERTICAL); } +} - public int getMaximum () - { - Dimension child_d = component[0].getPreferredSize (); - Dimension our_d = getViewportSize (); +/*************************************************************************/ - int xmax = Math.max (0, child_d.width - our_d.width); - int ymax = Math.max (0, child_d.height - our_d.height); +/* + * Instance Variables + */ - return (orient == Adjustable.HORIZONTAL) ? xmax : ymax; - } +/** + * Returns the current scrollbar display policy. + * + * @return The current scrollbar display policy. + */ +public int +getScrollbarDisplayPolicy() +{ + return(scrollbarDisplayPolicy); +} - public int getMinimum () - { - return 0; - } +/*************************************************************************/ + +/** + * Returns the horizontal scrollbar for this object. If the scrollbar + * display policy is set to <code>SCROLLBARS_NEVER</code> then this + * will be <code>null</code>. + * + * @return The horizontal scrollbar for this window. + */ +public Adjustable +getHAdjustable() +{ + return(hAdjustable); +} - public int getOrientation () - { - return orient; - } +/*************************************************************************/ + +/** + * Returns the vertical scrollbar for this object. If the scrollbar + * display policy is set to <code>SCROLLBARS_NEVER</code> then this + * will be <code>null</code>. + * + * @return The horizontal scrollbar for this window. + */ +public Adjustable +getVAdjustable() +{ + return(vAdjustable); +} - public int getUnitIncrement () - { - return unit; - } +/*************************************************************************/ - public int getValue () - { - return value; - } +/** + * Returns the current viewport size. The viewport is the region of + * this object's window where the child is actually displayed. + * + * @return The viewport size. + */ +public Dimension +getViewportSize() +{ + Dimension viewsize = getSize(); + Insets insets = getInsets(); + viewsize.width = viewsize.width - (insets.left + insets.right); + viewsize.height = viewsize.height - (insets.top + insets.bottom); - public int getVisibleAmount () - { - Dimension d = getViewportSize (); - return (orient == Adjustable.HORIZONTAL) ? d.width : d.height; - } + ScrollPaneAdjustable v = (ScrollPaneAdjustable)getVAdjustable(); + ScrollPaneAdjustable h = (ScrollPaneAdjustable)getHAdjustable(); - public void removeAdjustmentListener (AdjustmentListener l) - { - listeners = AWTEventMulticaster.remove (listeners, l); - } + if ((v != null) && v.isVisible()) + viewsize.width = viewsize.width - v.getSize().width; + if ((h != null) && h.isVisible()) + viewsize.height = viewsize.height - v.getSize().height; - public void setBlockIncrement (int b) - { - throw new AWTError ("can't use setBlockIncrement on this Adjustable"); - } + return(viewsize); +} - public void setMaximum (int max) - { - throw new AWTError ("can't use setMaximum on this Adjustable"); - } +/*************************************************************************/ - public void setMinimum (int min) - { - throw new AWTError ("can't use setMinimum on this Adjustable"); - } +/** + * Returns the height of a horizontal scrollbar. + * + * @return The height of a horizontal scrollbar. + */ +public int +getHScrollbarHeight() +{ + ScrollPanePeer spp = (ScrollPanePeer)getPeer(); + if (spp != null) + return(spp.getHScrollbarHeight()); + else + return(0); // FIXME: What to do here? +} - public void setUnitIncrement (int u) - { - unit = u; - if (peer != null) - { - ScrollPanePeer spp = (ScrollPanePeer) peer; - spp.setUnitIncrement (this, u); - } - } +/*************************************************************************/ - public void setValue (int v) - { - value = v; - if (peer != null) - { - ScrollPanePeer spp = (ScrollPanePeer) peer; - spp.setValue (this, v); - } - } +/** + * Returns the width of a vertical scrollbar. + * + * @return The width of a vertical scrollbar. + */ +public int +getVScrollbarWidth() +{ + ScrollPanePeer spp = (ScrollPanePeer)getPeer(); + if (spp != null) + return(spp.getVScrollbarWidth()); + else + return(0); // FIXME: What to do here? +} + +/*************************************************************************/ + +/** + * Returns the current scroll position of the viewport. + * + * @return The current scroll position of the viewport. + */ +public Point +getScrollPosition() +{ + int x = 0; + int y = 0; + + Adjustable v = getVAdjustable(); + Adjustable h = getHAdjustable(); + + if (v != null) + y = v.getValue(); + if (h != null) + x = h.getValue(); + + return(new Point(x, y)); +} + +/*************************************************************************/ + +/** + * Sets the scroll position to the specified value. + * + * @param scrollPosition The new scrollPosition. + * + * @exception IllegalArgumentException If the specified value is outside + * the legal scrolling range. + */ +public void +setScrollPosition(Point scrollPosition) throws IllegalArgumentException +{ + setScrollPosition(scrollPosition.x, scrollPosition.y); +} + +/*************************************************************************/ + +/** + * Sets the scroll position to the specified value. + * + * @param x The new X coordinate of the scroll position. + * @param y The new Y coordinate of the scroll position. + * + * @exception IllegalArgumentException If the specified value is outside + * the legal scrolling range. + */ +public void +setScrollPosition(int x, int y) +{ + Adjustable h = getHAdjustable(); + Adjustable v = getVAdjustable(); + + if (h != null) + h.setValue(x); + if (v != null) + v.setValue(y); + + ScrollPanePeer spp = (ScrollPanePeer)getPeer(); + if (spp != null) + spp.setScrollPosition(x, y); +} + +/*************************************************************************/ + +/** + * Notifies this object that it should create its native peer. + */ +public void +addNotify() +{ + if (getPeer() == null) + return; + + setPeer((ComponentPeer)getToolkit().createScrollPane(this)); + + if (hAdjustable != null) + hAdjustable.addNotify(); + if (vAdjustable != null) + vAdjustable.removeNotify(); +} + +/*************************************************************************/ + +/** + * Notifies this object that it should destroy its native peers. + */ +public void +removeNotify() +{ + if (hAdjustable != null) + hAdjustable.removeNotify(); + if (vAdjustable != null) + vAdjustable.removeNotify(); - public void setVisibleAmount (int v) + super.removeNotify(); +} + +/*************************************************************************/ + +/** + * Adds the specified child component to this container. A + * <code>ScrollPane</code> can have at most one child, so if a second + * one is added, then first one is removed. + * + * @param component The component to add to this container. + * @param constraints A list of layout constraints for this object. + * @param index The index at which to add the child, which is ignored + * in this implementation. + */ +public final void +addImpl(Component component, Object constraints, int index) +{ + Component[] list = getComponents(); + if ((list != null) && (list.length > 0)) + remove(list[0]); + + super.addImpl(component, constraints, -1); + + doLayout(); +} + +/*************************************************************************/ + +/** + * Lays out this component. This consists of resizing the sole child + * component to its perferred size. + */ +public void +doLayout() +{ + Component[] list = getComponents(); + if ((list != null) && (list.length > 0)) { - throw new AWTError ("can't use setVisibleAmount on this Adjustable"); + Dimension dim = list[0].getPreferredSize(); + list[0].resize(dim); + + Point p = getScrollPosition(); + if (p.x > dim.width) + p.x = dim.width; + if (p.y > dim.height) + p.y = dim.height; + + setScrollPosition(p); } - } +} + +/*************************************************************************/ + +/** + * Lays out this component. This consists of resizing the sole child + * component to its perferred size. + * + * @deprecated This method is deprecated in favor of + * <code>doLayout()</code>. + */ +public void +layout() +{ + doLayout(); +} - ScrollPaneAdjustable hscroll - = new ScrollPaneAdjustable (Adjustable.HORIZONTAL); - ScrollPaneAdjustable vscroll - = new ScrollPaneAdjustable (Adjustable.VERTICAL); - int policy; +/*************************************************************************/ + +/** + * This method overrides its superclass method to ensure no layout + * manager is set for this container. <code>ScrollPane</code>'s do + * not have layout managers. + * + * @param layoutManager Ignored + */ +public final void +setLayout(LayoutManager layoutManager) +{ + return; +} + +/*************************************************************************/ + +/** + * Prints all of the components in this container. + * + * @param graphics The desired graphics context for printing. + */ +public void +printComponents(Graphics graphics) +{ + super.printComponents(graphics); } + +/*************************************************************************/ + +/** + * Returns a debug string for this object. + * + * @return A debug string for this object. + */ +public String +paramString() +{ + return(getClass().getName()); +} + +} // class ScrollPane + diff --git a/libjava/java/awt/ScrollPaneAdjustable.java b/libjava/java/awt/ScrollPaneAdjustable.java new file mode 100644 index 00000000000..62cfefc1f9a --- /dev/null +++ b/libjava/java/awt/ScrollPaneAdjustable.java @@ -0,0 +1,72 @@ +/* ScrollPaneAdjustable.java -- Scrollbars for a ScrollPane + Copyright (C) 1999 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; + +/** + * Need this class since the serialization spec for ScrollPane + * uses it. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +class ScrollPaneAdjustable extends Scrollbar +{ + +public +ScrollPaneAdjustable(int orientation) +{ + super(orientation); +} + +public void +setMaximum(int maximum) +{ +} + +public void +setMinimum(int minimum) +{ +} + +public void +setVisibleAmount(int visibleAmount) +{ +} + +} // class ScrollPaneAdjustable + diff --git a/libjava/java/awt/Shape.java b/libjava/java/awt/Shape.java index 7f2fda02d8f..8d61c4a9a88 100644 --- a/libjava/java/awt/Shape.java +++ b/libjava/java/awt/Shape.java @@ -1,5 +1,5 @@ -/* Shape.java -- Interface for shape abstractions. - Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. +/* Shape.java -- the classic Object-Oriented shape interface + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,38 +38,166 @@ exception statement from your version. */ package java.awt; -import java.awt.geom.*; - -/* Written using "Java Class Libraries", 2nd edition. - * Status: Believed complete and correct to JDK 1.2. - */ +import java.awt.geom.AffineTransform; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; /** - * This interface represents an abstract shape. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - * @author Per Bothner <bothner@cygnus.com> - */ + * This interface represents an abstract shape. The shape is described by + * a {@link PathIterator}, and has callbacks for determining bounding box, + * where points and rectangles lie in relation to the shape, and tracing + * the trajectory. + * + * <p>A point is inside if it is completely inside, or on the boundary and + * adjacent points in the increasing x or y direction are completely inside. + * Unclosed shapes are considered as implicitly closed when performing + * <code>contains</code> or <code>intersects</code>. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see PathIterator + * @see AffineTransform + * @see FlatteningPathIterator + * @see GeneralPath + * @since 1.0 + * @status updated to 1.4 + */ public interface Shape { + /** + * Returns a <code>Rectange</code> that bounds the shape. There is no + * guarantee that this is the minimum bounding box, particularly if + * the shape overflows the finite integer range of a bound. Generally, + * <code>getBounds2D</code> returns a tighter bound. + * + * @return the shape's bounding box + * @see #getBounds2D() + */ + Rectangle getBounds(); -/** - * Returns a <code>Rectange</code> that bounds the shape. - * - * @return A <code>Rectange</code> that bounds the shape. - */ -public abstract Rectangle -getBounds(); - - public boolean contains (double x, double y); - public boolean contains (double x, double y, double w, double h); - public boolean contains (Point2D p); - public boolean contains (Rectangle2D r); - public Rectangle2D getBounds2D (); - public PathIterator getPathIterator (AffineTransform at); - public PathIterator getPathIterator (AffineTransform at, double flatness); - public boolean intersects (double x, double y, double w, double h); - public boolean intersects (Rectangle2D r); + /** + * Returns a high precision bounding box of the shape. There is no guarantee + * that this is the minimum bounding box, but at least it never overflows. + * + * @return the shape's bounding box + * @see #getBounds() + * @since 1.2 + */ + Rectangle2D getBounds2D(); -} // interface Shape + /** + * Test if the coordinates lie in the shape. + * + * @param x the x coordinate + * @param y the y coordinate + * @return true if (x,y) lies inside the shape + * @since 1.2 + */ + boolean contains(double x, double y); + + /** + * Test if the point lie in the shape. + * + * @param p the high-precision point + * @return true if p lies inside the shape + * @throws NullPointerException if p is null + * @since 1.2 + */ + boolean contains(Point2D p); + /** + * Test if a high-precision rectangle intersects the shape. This is true + * if any point in the rectangle is in the shape, with the caveat that the + * operation may include high probability estimates when the actual + * calculation is prohibitively expensive. The {@link Area} class can + * be used for more precise answers. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle, undefined results if negative + * @param h the height of the rectangle, undefined results if negative + * @return true if the rectangle intersects this shape + * @see Area + * @since 1.2 + */ + boolean intersects(double x, double y, double w, double h); + + /** + * Test if a high-precision rectangle intersects the shape. This is true + * if any point in the rectangle is in the shape, with the caveat that the + * operation may include high probability estimates when the actual + * calculation is prohibitively expensive. The {@link Area} class can + * be used for more precise answers. + * + * @param r the rectangle + * @return true if the rectangle intersects this shape + * @throws NullPointerException if r is null + * @see #intersects(double, double, double, double) + * @since 1.2 + */ + boolean intersects(Rectangle2D r); + + /** + * Test if a high-precision rectangle lies completely in the shape. This is + * true if all points in the rectangle are in the shape, with the caveat + * that the operation may include high probability estimates when the actual + * calculation is prohibitively expensive. The {@link Area} class can + * be used for more precise answers. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param w the width of the rectangle, undefined results if negative + * @param h the height of the rectangle, undefined results if negative + * @return true if the rectangle is contained in this shape + * @see Area + * @since 1.2 + */ + boolean contains(double x, double y, double w, double h); + + /** + * Test if a high-precision rectangle lies completely in the shape. This is + * true if all points in the rectangle are in the shape, with the caveat + * that the operation may include high probability estimates when the actual + * calculation is prohibitively expensive. The {@link Area} class can + * be used for more precise answers. + * + * @param r the rectangle + * @return true if the rectangle is contained in this shape + * @throws NullPointerException if r is null + * @see #contains(double, double, double, double) + * @since 1.2 + */ + boolean contains(Rectangle2D r); + + /** + * Return an iterator along the shape boundary. If the optional transform + * is provided, the iterator is transformed accordingly. Each call returns + * a new object, independent from others in use. It is recommended, but + * not required, that the Shape isolate iterations from future changes to + * the boundary, and document this fact. + * + * @param transform an optional transform to apply to the iterator + * @return a new iterator over the boundary + * @since 1.2 + */ + PathIterator getPathIterator(AffineTransform transform); + + /** + * Return an iterator along the flattened version of the shape boundary. + * Only SEG_MOVETO, SEG_LINETO, and SEG_CLOSE points are returned in the + * iterator. The flatness paramter controls how far points are allowed to + * differ from the real curve; although a limit on accuracy may cause this + * parameter to be enlarged if needed. + * + * <p>If the optional transform is provided, the iterator is transformed + * accordingly. Each call returns a new object, independent from others in + * use. It is recommended, but not required, that the Shape isolate + * iterations from future changes to the boundary, and document this fact. + * + * @param transform an optional transform to apply to the iterator + * @param double the maximum distance for deviation from the real boundary + * @return a new iterator over the boundary + * @since 1.2 + */ + PathIterator getPathIterator(AffineTransform transform, double flatness); +} // interface Shape diff --git a/libjava/java/awt/Stroke.java b/libjava/java/awt/Stroke.java new file mode 100644 index 00000000000..8b9b7fc777f --- /dev/null +++ b/libjava/java/awt/Stroke.java @@ -0,0 +1,65 @@ +/* Stroke.java -- a stroked outline of a shape + 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 interface allows a Graphics2D to grab the outline of a shape, as if + * stroked by a marking pen of appropriate size and shape. The area inked + * by the pen is the area of this stroke. Anything in the graphic which + * traces an outline will use this stroke, such as <code>drawLine</code>. + * Strokes must be immutable, because the graphics object does not clone + * them. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see BasicStroke + * @see Graphics2D#setStroke(Stroke) + * @since 1.1 + * @status updated to 1.4 + */ +public interface Stroke +{ + /** + * Returns a shape which outlines the boundary of the given shape, in + * effect converting the infinitely thin line into a new shape. + * + * @param s the shape to stroke + * @return the stroked outline shape + */ + Shape createStrokedShape(Shape s); +} // interface Stroke diff --git a/libjava/java/awt/SystemColor.java b/libjava/java/awt/SystemColor.java index f518a89a825..c6bffe2101a 100644 --- a/libjava/java/awt/SystemColor.java +++ b/libjava/java/awt/SystemColor.java @@ -1,5 +1,5 @@ -/* SystemColor.java -- Class to access system color values. - Copyright (C) 1999 Free Software Foundation, Inc. +/* SystemColor.java -- access dynamic system color values + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,393 +38,425 @@ exception statement from your version. */ package java.awt; -/** - * This class contains the various "system colors" in use by the - * native windowing system. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public final class SystemColor extends Color implements java.io.Serializable -{ - -/* - * Static Variables - */ - -/** - * Array index of the desktop color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int DESKTOP = 0; - -/** - * Array index of the active caption color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int ACTIVE_CAPTION = 1; - -/** - * Array index of the active caption text color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int ACTIVE_CAPTION_TEXT = 2; - -/** - * Array index of the active caption border color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int ACTIVE_CAPTION_BORDER = 3; - -/** - * Array index of the inactive caption color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int INACTIVE_CAPTION = 4; - -/** - * Array index of the inactive caption text color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int INACTIVE_CAPTION_TEXT = 5; - -/** - * Array index of the inactive caption border color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int INACTIVE_CAPTION_BORDER = 6; - -/** - * Array index of the window background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int WINDOW = 7; - -/** - * Array index of the window border color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int WINDOW_BORDER = 8; - -/** - * Array index of the window text color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int WINDOW_TEXT = 9; - -/** - * Array index of the menu background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int MENU = 10; - -/** - * Array index of the menu text color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int MENU_TEXT = 11; - -/** - * Array index of the text background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int TEXT = 12; - -/** - * Array index of the text foreground color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int TEXT_TEXT = 13; - -/** - * Array index of the highlighted text background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int TEXT_HIGHLIGHT = 14; - -/** - * Array index of the highlighted text foreground color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int TEXT_HIGHLIGHT_TEXT = 15; - -/** - * Array index of the inactive text foreground color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int TEXT_INACTIVE_TEXT = 16; - -/** - * Array index of the control background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int CONTROL = 17; - -/** - * Array index of the control text color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int CONTROL_TEXT = 18; - -/** - * Array index of the highlighted control background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int CONTROL_HIGHLIGHT = 19; - -/** - * Array index of the lightly highlighted control background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int CONTROL_LT_HIGHLIGHT = 20; - -/** - * Array index of the shadowed control background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int CONTROL_SHADOW = 21; - -/** - * Array index of the darkly shadowed control background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int CONTROL_DK_SHADOW = 22; - -/** - * Array index of the scrollbar background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int SCROLLBAR = 23; - -/** - * Array index of the info background color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int INFO = 24; - -/** - * Array index of the info text color. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int INFO_TEXT = 25; - -/** - * The number of system colors. Used by - * <code>Toolkit.loadSystemColors()</code>. - */ -public static final int NUM_COLORS = 26; - -/** - * The desktop color. - */ -public static final SystemColor desktop; - -/** - * The active caption background color. - */ -public static final SystemColor activeCaption; - -/** - * The active caption text color. - */ -public static final SystemColor activeCaptionText; - -/** - * The active caption border color. - */ -public static final SystemColor activeCaptionBorder; - -/** - * The inactive caption background color. - */ -public static final SystemColor inactiveCaption; - -/** - * The inactive caption text color. - */ -public static final SystemColor inactiveCaptionText; - -/** - * The inactive caption border color. - */ -public static final SystemColor inactiveCaptionBorder; - -/** - * The window background color. - */ -public static final SystemColor window; - -/** - * The window border color. - */ -public static final SystemColor windowBorder; - -/** - * The window text color. - */ -public static final SystemColor windowText; - -/** - * The menu background color. - */ -public static final SystemColor menu; - -/** - * The menu text color. - */ -public static final SystemColor menuText; - -/** - * The text background color. - */ -public static final SystemColor text; - -/** - * The text foreground color. - */ -public static final SystemColor textText; - -/** - * The highlighted text background color. - */ -public static final SystemColor textHighlight; - -/** - * The highlighted text foreground color. - */ -public static final SystemColor textHighlightText; - -/** - * The inactive text color. - */ -public static final SystemColor textInactiveText; - -/** - * The control background color. - */ -public static final SystemColor control; - -/** - * The control text color. - */ -public static final SystemColor controlText; - -/** - * The control highlight color. - */ -public static final SystemColor controlHighlight; - -/** - * The control light highlight color. - */ -public static final SystemColor controlLtHighlight; - -/** - * The control shadow color. - */ -public static final SystemColor controlShadow; - -/** - * The control dark shadow color. - */ -public static final SystemColor controlDkShadow; - -/** - * The scrollbar color. - */ -public static final SystemColor scrollbar; - -/** - * The info text background color. - */ -public static final SystemColor info; - -/** - * The info text foreground color. - */ -public static final SystemColor infoText; - -// Serialization version constant -private static final long serialVersionUID = 4503142729533789064L; - -static -{ - int[] sys_color_rgbs = new int[NUM_COLORS]; - Toolkit.getDefaultToolkit().loadSystemColors(sys_color_rgbs); - - desktop = new SystemColor(sys_color_rgbs[DESKTOP]); - activeCaption= new SystemColor(sys_color_rgbs[ACTIVE_CAPTION]); - activeCaptionText= new SystemColor(sys_color_rgbs[ACTIVE_CAPTION_TEXT]); - activeCaptionBorder = new SystemColor(sys_color_rgbs[ACTIVE_CAPTION_BORDER]); - inactiveCaption = new SystemColor(sys_color_rgbs[INACTIVE_CAPTION]); - inactiveCaptionText = new SystemColor(sys_color_rgbs[INACTIVE_CAPTION_TEXT]); - inactiveCaptionBorder = - new SystemColor(sys_color_rgbs[INACTIVE_CAPTION_BORDER]); - window = new SystemColor(sys_color_rgbs[WINDOW]); - windowBorder = new SystemColor(sys_color_rgbs[WINDOW_BORDER]); - windowText = new SystemColor(sys_color_rgbs[WINDOW_TEXT]); - menu = new SystemColor(sys_color_rgbs[MENU]); - menuText = new SystemColor(sys_color_rgbs[MENU_TEXT]); - text = new SystemColor(sys_color_rgbs[TEXT]); - textText = new SystemColor(sys_color_rgbs[TEXT_TEXT]); - textHighlight = new SystemColor(sys_color_rgbs[TEXT_HIGHLIGHT]); - textHighlightText = new SystemColor(sys_color_rgbs[TEXT_HIGHLIGHT_TEXT]); - textInactiveText = new SystemColor(sys_color_rgbs[TEXT_INACTIVE_TEXT]); - control = new SystemColor(sys_color_rgbs[CONTROL]); - controlText = new SystemColor(sys_color_rgbs[CONTROL_TEXT]); - controlHighlight = new SystemColor(sys_color_rgbs[CONTROL_HIGHLIGHT]); - controlLtHighlight = new SystemColor(sys_color_rgbs[CONTROL_LT_HIGHLIGHT]); - controlShadow = new SystemColor(sys_color_rgbs[CONTROL_SHADOW]); - controlDkShadow = new SystemColor(sys_color_rgbs[CONTROL_DK_SHADOW]); - scrollbar = new SystemColor(sys_color_rgbs[SCROLLBAR]); - info = new SystemColor(sys_color_rgbs[INFO]); - infoText = new SystemColor(sys_color_rgbs[INFO_TEXT]); -} - -/*************************************************************************/ - -/* - * Constructors - */ - -private -SystemColor(int rgb) -{ - super(rgb); -} - -/*************************************************************************/ - -/* - * Instance Methods +import java.awt.image.ColorModel; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; +import java.io.Serializable; + +/** + * This class contains the various "system colors" in use by the native + * windowing system. The <code>getRGB()</code> method is dynamic on systems + * which support dynamic system color changes, and most methods in the + * superclass are written to use this dynamic value when reporting colors. + * However, the <code>equals()</code> method is not dynamic, and does not + * track the actual color of instances in this class. This means that equals + * may give surprising results; you are better off relying on getRGB. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.1 + * @status updated to 1.4 */ - -/** - * Returns the RGB value for this color as an <code>int</code>. The first - * byte is the blue value, the second the green value, the third the - * red value and the fourth is set to 0xFF. - * - * @return The RGB value. - */ -public int -getRGB() +public final class SystemColor extends Color implements Serializable { - // Override only to be spec consistent. - return(super.getRGB()); -} - -/*************************************************************************/ - -/** - * Returns a string describing this color. - * - * @return A string describing this color. - */ -public String -toString() -{ - return("SystemColor(R=" + getRed() + ",G=" + getGreen() + ",B=" + - getBlue() + ")"); -} - -} // class SystemColor - + // Implementation note: To be serial compatible with JDK, this class must + // violate the semantic meaning of super.value to be one of the + // NUM_COLORS constants instead of the actual RGB value. Hence there are + // a lot of ugly workarounds in Color and in this class. I would have + // designed it MUCH differently, making a separate id field in this class. + + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = 4503142729533789064L; + + /** + * Array index of the desktop color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #desktop + */ + public static final int DESKTOP = 0; + + /** + * Array index of the active caption color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #activeCaption + */ + public static final int ACTIVE_CAPTION = 1; + + /** + * Array index of the active caption text color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #activeCaptionText + */ + public static final int ACTIVE_CAPTION_TEXT = 2; + + /** + * Array index of the active caption border color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #activeCaptionBorder + */ + public static final int ACTIVE_CAPTION_BORDER = 3; + + /** + * Array index of the inactive caption color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #inactiveCaption + */ + public static final int INACTIVE_CAPTION = 4; + + /** + * Array index of the inactive caption text color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #inactiveCaptionText + */ + public static final int INACTIVE_CAPTION_TEXT = 5; + + /** + * Array index of the inactive caption border color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #inactiveCaptionBorder + */ + public static final int INACTIVE_CAPTION_BORDER = 6; + + /** + * Array index of the window background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #window + */ + public static final int WINDOW = 7; + + /** + * Array index of the window border color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #windowBorder + */ + public static final int WINDOW_BORDER = 8; + + /** + * Array index of the window text color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #windowText + */ + public static final int WINDOW_TEXT = 9; + + /** + * Array index of the menu background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #menu + */ + public static final int MENU = 10; + + /** + * Array index of the menu text color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #menuText + */ + public static final int MENU_TEXT = 11; + + /** + * Array index of the text background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #text + */ + public static final int TEXT = 12; + + /** + * Array index of the text foreground color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #textText + */ + public static final int TEXT_TEXT = 13; + + /** + * Array index of the highlighted text background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #textHighlight + */ + public static final int TEXT_HIGHLIGHT = 14; + + /** + * Array index of the highlighted text foreground color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #textHighlightText + */ + public static final int TEXT_HIGHLIGHT_TEXT = 15; + + /** + * Array index of the inactive text foreground color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #textInactiveText + */ + public static final int TEXT_INACTIVE_TEXT = 16; + + /** + * Array index of the control background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #control + */ + public static final int CONTROL = 17; + + /** + * Array index of the control text color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #controlText + */ + public static final int CONTROL_TEXT = 18; + + /** + * Array index of the highlighted control background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #controlHighlight + */ + public static final int CONTROL_HIGHLIGHT = 19; + + /** + * Array index of the lightly highlighted control background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #controlLtHighlight + */ + public static final int CONTROL_LT_HIGHLIGHT = 20; + + /** + * Array index of the shadowed control background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #controlShadow + */ + public static final int CONTROL_SHADOW = 21; + + /** + * Array index of the darkly shadowed control background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #controlDkShadow + */ + public static final int CONTROL_DK_SHADOW = 22; + + /** + * Array index of the scrollbar background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #scrollbar + */ + public static final int SCROLLBAR = 23; + + /** + * Array index of the info background color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #info + */ + public static final int INFO = 24; + + /** + * Array index of the info text color. Used by + * {@link Toolkit#loadSystemColors()}. + * + * @see #infoText + */ + public static final int INFO_TEXT = 25; + + /** + * The number of system colors. Used by + * {@link Toolkit#loadSystemColors()}. + */ + public static final int NUM_COLORS = 26; + + /** + * The internal array used to dynamically update <code>getRGB()</code>. + */ + private static final int[] colors = new int[NUM_COLORS]; + + /** The desktop color. */ + public static final SystemColor desktop + = new SystemColor(DESKTOP); + + /** The active caption background color. */ + public static final SystemColor activeCaption + = new SystemColor(ACTIVE_CAPTION); + + /** The active caption text color. */ + public static final SystemColor activeCaptionText + = new SystemColor(ACTIVE_CAPTION_TEXT); + + /** The active caption border color. */ + public static final SystemColor activeCaptionBorder + = new SystemColor(ACTIVE_CAPTION_BORDER); + + /** The inactive caption background color. */ + public static final SystemColor inactiveCaption + = new SystemColor(INACTIVE_CAPTION); + + /** The inactive caption text color. */ + public static final SystemColor inactiveCaptionText + = new SystemColor(INACTIVE_CAPTION_TEXT); + + /** The inactive caption border color. */ + public static final SystemColor inactiveCaptionBorder + = new SystemColor(INACTIVE_CAPTION_BORDER); + + /** The window background color. */ + public static final SystemColor window + = new SystemColor(WINDOW); + + /** The window border color. */ + public static final SystemColor windowBorder + = new SystemColor(WINDOW_BORDER); + + /** The window text color. */ + public static final SystemColor windowText + = new SystemColor(WINDOW_TEXT); + + /** The menu background color. */ + public static final SystemColor menu + = new SystemColor(MENU); + + /** The menu text color. */ + public static final SystemColor menuText + = new SystemColor(MENU_TEXT); + + /** The text background color. */ + public static final SystemColor text + = new SystemColor(TEXT); + + /** The text foreground color. */ + public static final SystemColor textText + = new SystemColor(TEXT_TEXT); + + /** The highlighted text background color. */ + public static final SystemColor textHighlight + = new SystemColor(TEXT_HIGHLIGHT); + + /** The highlighted text foreground color. */ + public static final SystemColor textHighlightText + = new SystemColor(TEXT_HIGHLIGHT_TEXT); + + /** The inactive text color. */ + public static final SystemColor textInactiveText + = new SystemColor(TEXT_INACTIVE_TEXT); + + /** The control background color. */ + public static final SystemColor control + = new SystemColor(CONTROL); + + /** The control text color. */ + public static final SystemColor controlText + = new SystemColor(CONTROL_TEXT); + + /** The control highlight color. */ + public static final SystemColor controlHighlight + = new SystemColor(CONTROL_HIGHLIGHT); + + /** The control light highlight color. */ + public static final SystemColor controlLtHighlight + = new SystemColor(CONTROL_LT_HIGHLIGHT); + + /** The control shadow color. */ + public static final SystemColor controlShadow + = new SystemColor(CONTROL_SHADOW); + + /** The control dark shadow color. */ + public static final SystemColor controlDkShadow + = new SystemColor(CONTROL_DK_SHADOW); + + /** The scrollbar color. */ + public static final SystemColor scrollbar + = new SystemColor(SCROLLBAR); + + /** The info text background color. */ + public static final SystemColor info + = new SystemColor(INFO); + + /** The info text foreground color. */ + public static final SystemColor infoText + = new SystemColor(INFO_TEXT); + + /** + * Construct a system color which is dynamically updated. + * + * @param id the color id + */ + private SystemColor(int id) + { + // Note: See Color#Color(int, boolean) to explain why we use this + // particular constructor. + super(id, true); + } + + /** + * Returns the RGB value for this color, in the sRGB color space. The blue + * value will be in bits 0-7, green in 8-15, red in 6-23, and the alpha + * value (bits 24-31) is 0xff. This is dynamically updated, so it may not + * match the results of <code>getRed()</code>, <code>getGreen()</code>, or + * <code>getBlue()</code>. + * + * @return the current RGB value + */ + public int getRGB() + { + Toolkit.getDefaultToolkit().loadSystemColors(colors); + return colors[value] | ALPHA_MASK; + } + + /** + * Returns a paint context, used for filling areas of a raster scan with + * the current value of this system color. Since the system colors may be + * dynamically updated, the returned value may not always be the same; but + * as the system color is solid, the context does not need any of the + * passed parameters to do its job. + * + * @param cm the requested color model, ignored + * @param deviceBounds the bounding box in device coordinates, ignored + * @param userBounds the bounding box in user coordinates, ignored + * @param xform the bounds transformation, ignored + * @param hints any rendering hints, ignored + * @return a context for painting this solid color + */ + public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, + Rectangle2D userBounds, + AffineTransform xform, + RenderingHints hints) + { + Toolkit.getDefaultToolkit().loadSystemColors(colors); + int color = colors[value] | ALPHA_MASK; + if (context == null || color != context.color) + context = new ColorPaintContext(color); + return context; + } + + /** + * Returns a string describing this color. This is in the format + * "java.awt.SystemColor[i=" + index + ']', where index is one of the + * integer constants of this class. Unfortunately, this description + * does not describe the current value of the color; for that you should + * use <code>new Color(syscolor.getRGB()).toString()</code>. + * + * @return a string describing this color + */ + public String toString() + { + return "java.awt.SystemColor[i=" + value + ']'; + } +} // class SystemColor diff --git a/libjava/java/awt/TexturePaint.java b/libjava/java/awt/TexturePaint.java new file mode 100644 index 00000000000..5ff0b57ecdd --- /dev/null +++ b/libjava/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/libjava/java/awt/Toolkit.java b/libjava/java/awt/Toolkit.java index 4c59138fc6b..7caec22dca9 100644 --- a/libjava/java/awt/Toolkit.java +++ b/libjava/java/awt/Toolkit.java @@ -38,788 +38,727 @@ exception statement from your version. */ package java.awt; -import java.awt.event.*; -import java.awt.peer.*; -import java.awt.image.*; import java.awt.datatransfer.Clipboard; -import java.util.Properties; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.awt.event.AWTEventListener; +import java.awt.event.KeyEvent; +import java.awt.im.InputMethodHighlight; +import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.awt.peer.ButtonPeer; +import java.awt.peer.CanvasPeer; +import java.awt.peer.CheckboxPeer; +import java.awt.peer.CheckboxMenuItemPeer; +import java.awt.peer.ChoicePeer; +import java.awt.peer.DialogPeer; +import java.awt.peer.FileDialogPeer; +import java.awt.peer.FontPeer; +import java.awt.peer.FramePeer; +import java.awt.peer.LabelPeer; +import java.awt.peer.LightweightPeer; +import java.awt.peer.ListPeer; +import java.awt.peer.MenuPeer; +import java.awt.peer.MenuBarPeer; +import java.awt.peer.MenuItemPeer; +import java.awt.peer.PanelPeer; +import java.awt.peer.PopupMenuPeer; +import java.awt.peer.ScrollbarPeer; +import java.awt.peer.ScrollPanePeer; +import java.awt.peer.TextAreaPeer; +import java.awt.peer.TextFieldPeer; +import java.awt.peer.WindowPeer; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.net.URL; -import java.beans.*; - -/** - * The AWT system uses a set of native peer objects to implement its - * widgets. These peers are provided by a peer toolkit, that is accessed - * via a subclass of this superclass. The system toolkit is retrieved - * by the static methods <code>getDefaultToolkit</code>. This method - * determines the system toolkit by examining the system property - * <code>awt.toolkit</code>. That property is set to the name of the - * <code>Toolkit</code> subclass for the specified peer set. If the - * <code>awt.toolkit</code> property is not set, then the default - * toolkit <code>gnu.java.awt.peer.gtk.GtkToolkit</code> is used. This - * toolkit creates its peers using the GTK+ toolkit. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public abstract class Toolkit -{ - -/* - * Static Variables - */ - -// The default toolkit name. -private static String default_toolkit_name = - "gnu.java.awt.peer.gtk.GtkToolkit"; - -// The toolkit in use. Once we load it, we don't ever change it -// if the awt.toolkit propert is set. -private static Toolkit toolkit; - -// The toolkit properties -private static Properties props = new Properties(); - -private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); - -private Properties desktopProperties = new Properties(); - -/*************************************************************************/ - -/* - * Static Methods - */ - -/** - * Returns an instance of the default toolkit. The default toolkit is - * the subclass of <code>Toolkit</code> specified in the system property - * <code>awt.toolkit</code>, or <code>gnu.java.awt.peer.gtk.GtkToolkit</code> - * if the property is not set. - * - * @return An instance of the system default toolkit. - * - * @error AWTError If the toolkit cannot be loaded. - */ -public static Toolkit -getDefaultToolkit() -{ - if (toolkit != null) - return(toolkit); - - String toolkit_name = System.getProperty("awt.toolkit", - default_toolkit_name); - - try - { - Class cls = Class.forName(toolkit_name); - Object obj = cls.newInstance(); - - if (!(obj instanceof Toolkit)) - throw new AWTError(toolkit_name + " is not a subclass of " + - "java.awt.Toolkit"); - - toolkit = (Toolkit)obj; - return(toolkit); - } - catch(Exception e) - { - throw new AWTError("Cannot load AWT toolkit: " + e.getMessage()); - } -} - -/*************************************************************************/ - -/** - * Returns the value of the property with the specified name, or the - * default value if the property does not exist. - * - * @param key The name of the property to retrieve. - * @param defThe default value of the property. - */ -public static String -getProperty(String key, String def) -{ - return(props.getProperty(key, def)); -} - -/*************************************************************************/ - -/** - * Returns the native container object of the specified component. This - * method is necessary because the parent component might be a lightweight - * component. - * - * @param component The component to fetch the native container for. - * - * @return The native container object for this component. - */ -protected static Container -getNativeContainer(Component component) -{ - component = component.getParent(); - - for(;;) - { - if (component == null) - return(null); - - if (!(component instanceof Container)) - { - component = component.getParent(); - continue; - } - - if (component.getPeer() instanceof LightweightPeer) - { - component = component.getParent(); - continue; - } - - return((Container)component); - } -} - -/*************************************************************************/ - -/* - * Constructors - */ +import java.util.Map; +import java.util.Properties; /** - * Default constructor for subclasses. - */ -public -Toolkit() -{ -} - -/*************************************************************************/ - -/* - * Instance Methods + * The AWT system uses a set of native peer objects to implement its + * widgets. These peers are provided by a peer toolkit, that is accessed + * via a subclass of this superclass. The system toolkit is retrieved + * by the static methods <code>getDefaultToolkit</code>. This method + * determines the system toolkit by examining the system property + * <code>awt.toolkit</code>. That property is set to the name of the + * <code>Toolkit</code> subclass for the specified peer set. If the + * <code>awt.toolkit</code> property is not set, then the default + * toolkit <code>gnu.java.awt.peer.gtk.GtkToolkit</code> is used. This + * toolkit creates its peers using the GTK+ toolkit. + * + * @author Aaron M. Renn <arenn@urbanophile.com> */ - -/** - * Creates a peer object for the specified <code>Button</code>. - * - * @param target The <code>Button</code> to create the peer for. - * - * @return The peer for the specified <code>Button</code> object. - */ -protected abstract ButtonPeer -createButton(Button target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>TextField</code>. - * - * @param target The <code>TextField</code> to create the peer for. - * - * @return The peer for the specified <code>TextField</code> object. - */ -protected abstract TextFieldPeer -createTextField(TextField target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Label</code>. - * - * @param target The <code>Label</code> to create the peer for. - * - * @return The peer for the specified <code>Label</code> object. - */ -protected abstract LabelPeer -createLabel(Label target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>List</code>. - * - * @param target The <code>List</code> to create the peer for. - * - * @return The peer for the specified <code>List</code> object. - */ -protected abstract ListPeer -createList(List target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Checkbox</code>. - * - * @param target The <code>Checkbox</code> to create the peer for. - * - * @return The peer for the specified <code>Checkbox</code> object. - */ -protected abstract CheckboxPeer -createCheckbox(Checkbox target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Scrollbar</code>. - * - * @param target The <code>Scrollbar</code> to create the peer for. - * - * @return The peer for the specified <code>Scrollbar</code> object. - */ -protected abstract ScrollbarPeer -createScrollbar(Scrollbar target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>ScrollPane</code>. - * - * @param target The <code>ScrollPane</code> to create the peer for. - * - * @return The peer for the specified <code>ScrollPane</code> object. - */ -protected abstract ScrollPanePeer -createScrollPane(ScrollPane target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>TextArea</code>. - * - * @param target The <code>TextArea</code> to create the peer for. - * - * @return The peer for the specified <code>TextArea</code> object. - */ -protected abstract TextAreaPeer -createTextArea(TextArea target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Choice</code>. - * - * @param target The <code>Choice</code> to create the peer for. - * - * @return The peer for the specified <code>Choice</code> object. - */ -protected abstract ChoicePeer -createChoice(Choice target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Frame</code>. - * - * @param target The <code>Frame</code> to create the peer for. - * - * @return The peer for the specified <code>Frame</code> object. - */ -protected abstract FramePeer -createFrame(Frame target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Canvas</code>. - * - * @param target The <code>Canvas</code> to create the peer for. - * - * @return The peer for the specified <code>Canvas</code> object. - */ -protected abstract CanvasPeer -createCanvas(Canvas target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Panel</code>. - * - * @param target The <code>Panel</code> to create the peer for. - * - * @return The peer for the specified <code>Panel</code> object. - */ -protected abstract PanelPeer -createPanel(Panel target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Window</code>. - * - * @param target The <code>Window</code> to create the peer for. - * - * @return The peer for the specified <code>Window</code> object. - */ -protected abstract WindowPeer -createWindow(Window target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Dialog</code>. - * - * @param target The dialog to create the peer for - * - * @return The peer for the specified font name. - */ -protected abstract DialogPeer -createDialog(Dialog target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>MenuBar</code>. - * - * @param target The <code>MenuBar</code> to create the peer for. - * - * @return The peer for the specified <code>MenuBar</code> object. - */ -protected abstract MenuBarPeer -createMenuBar(MenuBar target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Menu</code>. - * - * @param target The <code>Menu</code> to create the peer for. - * - * @return The peer for the specified <code>Menu</code> object. - */ -protected abstract MenuPeer -createMenu(Menu target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>PopupMenu</code>. - * - * @param target The <code>PopupMenu</code> to create the peer for. - * - * @return The peer for the specified <code>PopupMenu</code> object. - */ -protected abstract PopupMenuPeer -createPopupMenu(PopupMenu target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>MenuItem</code>. - * - * @param target The <code>MenuItem</code> to create the peer for. - * - * @return The peer for the specified <code>MenuItem</code> object. - */ -protected abstract MenuItemPeer -createMenuItem(MenuItem target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>FileDialog</code>. - * - * @param target The <code>FileDialog</code> to create the peer for. - * - * @return The peer for the specified <code>FileDialog</code> object. - */ -protected abstract FileDialogPeer -createFileDialog(FileDialog target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>CheckboxMenuItem</code>. - * - * @param target The <code>CheckboxMenuItem</code> to create the peer for. - * - * @return The peer for the specified <code>CheckboxMenuItem</code> object. - */ -protected abstract CheckboxMenuItemPeer -createCheckboxMenuItem(CheckboxMenuItem target); - -/*************************************************************************/ - -/** - * Creates a peer object for the specified <code>Component</code>. The - * peer returned by this method is not a native windowing system peer - * with its own native window. Instead, this method allows the component - * to draw on its parent window as a "lightweight" widget. - * - * XXX: FIXME - * - * @param target The <code>Component</code> to create the peer for. - * - * @return The peer for the specified <code>Component</code> object. - */ -protected LightweightPeer -createComponent(Component target) -{ - return null; -} - -/*************************************************************************/ - -/** - * Creates a peer object for the specified font name. - * - * @param name The font to create the peer for. - * @param style The font style to create the peer for. - * - * @return The peer for the specified font name. - */ -protected abstract FontPeer -getFontPeer(String name, int style); - -/*************************************************************************/ - -/** - * Copies the current system colors into the specified array. This is - * the interface used by the <code>SystemColors</code> class. - * - * @param colors The array to copy the system colors into. - */ -protected void -loadSystemColors(int systemColors[]) -{ -} - -/*************************************************************************/ - -/** - * Returns the dimensions of the screen in pixels. - * - * @return The dimensions of the screen in pixels. - */ -public abstract Dimension -getScreenSize(); - -/*************************************************************************/ - -/** - * Returns the screen resolution in dots per square inch. - * - * @return The screen resolution in dots per square inch. - */ -public abstract int -getScreenResolution(); - -/*************************************************************************/ - -/** - * Returns the color model of the screen. - * - * @return The color model of the screen. - */ -public abstract ColorModel -getColorModel(); - -/*************************************************************************/ - -/** - * Returns the names of the available fonts. - * - * @return The names of the available fonts. - */ -public abstract String[] -getFontList(); - -/*************************************************************************/ - -/** - * Return the font metrics for the specified font - * - * @param name The name of the font to return metrics for. - * - * @return The requested font metrics. - */ -public abstract FontMetrics -getFontMetrics(Font name); - -/*************************************************************************/ - -/** - * Flushes any buffered data to the screen so that it is in sync with - * what the AWT system has drawn to it. - */ -public abstract void -sync(); - -/*************************************************************************/ - -/** - * Returns an image from the specified file, which must be in a - * recognized format. Supported formats vary from toolkit to toolkit. - * - * @return name The name of the file to read the image from. - */ -public abstract Image -getImage(String name); - -/*************************************************************************/ - -/** - * Returns an image from the specified URL, which must be in a - * recognized format. Supported formats vary from toolkit to toolkit. - * - * @return url The URl to read the image from. - */ -public abstract Image -getImage(URL url); - -/*************************************************************************/ - -/** - * Readies an image to be rendered on the screen. The width and height - * values can be set to the default sizes for the image by passing -1 - * in those parameters. - * - * @param image The image to prepare for rendering. - * @param width The width of the image. - * @param height The height of the image. - * @param observer The observer to receive events about the preparation - * process. - * - * @return <code>true</code> if the image is already prepared for rendering, - * <code>false</code> otherwise. - */ -public abstract boolean -prepareImage(Image image, int width, int height, ImageObserver observer); - -/*************************************************************************/ - -/** - * Checks the status of specified image as it is being readied for - * rendering. - * - * @param image The image to prepare for rendering. - * @param width The width of the image. - * @param height The height of the image. - * @param observer The observer to receive events about the preparation - * process. - * - * @return A union of the bitmasks from - * <code>java.awt.image.ImageObserver</code> that indicates the current - * state of the imaging readying process. - */ -public abstract int -checkImage(Image image, int width, int height, ImageObserver observer); - -/*************************************************************************/ - -/** - * Creates an image using the specified <code>ImageProducer</code> - * - * @param producer The <code>ImageProducer</code> to create the image from. - * - * @return The created image. - */ -public abstract Image -createImage(ImageProducer producer); - -/*************************************************************************/ - -/** - * Creates an image from the specified portion of the byte array passed. - * The array must be in a recognized format. Supported formats vary from - * toolkit to toolkit. - * - * @param data The raw image data. - * @param offset The offset into the data where the image data starts. - * @param len The length of the image data. - * - * @return The created image. - */ -public abstract Image -createImage(byte[] data, int offset, int len); - -/*************************************************************************/ - -/** - * Creates an image from the specified byte array. The array must be in - * a recognized format. Supported formats vary from toolkit to toolkit. - * - * @param data The raw image data. - * - * @return The created image. - */ -public Image -createImage(byte[] data) -{ - return(createImage(data, 0, data.length)); -} - -public abstract Image -createImage(String filename); - -public abstract Image -createImage(URL url); - - -/*************************************************************************/ - -/** - * Returns a instance of <code>PrintJob</code> for the specified - * arguments. - * - * @param frame The window initiating the print job. - * @param title The print job title. - * @param props The print job properties. - * - * @return The requested print job, or <code>null</code> if the job - * was cancelled. - */ -public abstract PrintJob -getPrintJob(Frame frame, String title, Properties props); - -/*************************************************************************/ - -/** - * Returns the system clipboard. - * - * @return THe system clipboard. - */ -public abstract Clipboard -getSystemClipboard(); - -/*************************************************************************/ - -/** - * Returns the accelerator key mask for menu shortcuts. The default is - * <code>Event.CTRL_MASK</code>. A toolkit must override this method - * to change the default. - * - * @return The key mask for the menu accelerator key. - */ -public int -getMenuShortcutKeyMask() -{ - return Event.CTRL_MASK; -} - -public boolean -getLockingKeyState(int keyCode) -{ - if (keyCode != KeyEvent.VK_CAPS_LOCK - && keyCode != KeyEvent.VK_NUM_LOCK - && keyCode != KeyEvent.VK_SCROLL_LOCK) - throw new IllegalArgumentException(); - - throw new UnsupportedOperationException(); -} - -public void -setLockingKeyState(int keyCode, boolean on) -{ - if (keyCode != KeyEvent.VK_CAPS_LOCK - && keyCode != KeyEvent.VK_NUM_LOCK - && keyCode != KeyEvent.VK_SCROLL_LOCK) - throw new IllegalArgumentException(); - - throw new UnsupportedOperationException(); -} - -/*************************************************************************/ - -/** - * Returns the event queue for the applet. Despite the word "System" - * in the name of this method, there is no guarantee that the same queue - * is shared system wide. - * - * @return The event queue for this applet (or application) - */ -public final EventQueue -getSystemEventQueue() -{ - return(getSystemEventQueueImpl()); -} - -/*************************************************************************/ - -/** - * // FIXME: What does this do? - */ -protected abstract EventQueue -getSystemEventQueueImpl(); - -/*************************************************************************/ - -/** - * Causes a "beep" tone to be generated. - */ -public abstract void -beep(); - -public Cursor -createCustomCursor(Image cursor, Point hotSpot, String name) - throws IndexOutOfBoundsException -{ - // Presumably the only reason this isn't abstract is for backwards - // compatibility? FIXME? - return null; -} - -public Dimension -getBestCursorSize(int preferredWidth, int preferredHeight) -{ - return new Dimension (0,0); -} - -public int -getMaximumCursorColors() -{ - return 0; -} - -public final Object -getDesktopProperty(String propertyName) -{ - return desktopProperties.get(propertyName); -} - -protected final void -setDesktopProperty(String name, Object newValue) -{ - Object oldValue = getDesktopProperty(name); - desktopProperties.put(name, newValue); - changeSupport.firePropertyChange(name, oldValue, newValue); -} -protected Object -lazilyLoadDesktopProperty(String name) -{ - // FIXME - what is this?? - return null; -} - -protected void -initializeDesktopProperties() -{ - // Overridden by toolkit implementation? -} - -public void -addPropertyChangeListener(String name, PropertyChangeListener pcl) -{ - changeSupport.addPropertyChangeListener(name, pcl); -} - -public void -removePropertyChangeListener(String name, PropertyChangeListener pcl) -{ - changeSupport.removePropertyChangeListener(name, pcl); -} - -public void -addAWTEventListener(AWTEventListener listener, long eventMask) -{ - // SecurityManager s = System.getSecurityManager(); - // if (s != null) - // s.checkPermission(AWTPermission("listenToAllAWTEvents")); - - // FIXME -} - -public void -removeAWTEventListener(AWTEventListener listener) +public abstract class Toolkit { - // FIXME -} - + /** The default toolkit name. */ + private static String default_toolkit_name + = "gnu.java.awt.peer.gtk.GtkToolkit"; + + /** + * The toolkit in use. Once we load it, we don't ever change it + * if the awt.toolkit propert is set. + */ + private static Toolkit toolkit; + + /** The toolkit properties. */ + private static Properties props = new Properties(); + + protected final Map desktopProperties = new Properties(); + + protected final PropertyChangeSupport desktopPropsSupport + = new PropertyChangeSupport(this); + + /** + * Default constructor for subclasses. + */ + public Toolkit() + { + } + + /** + * Creates a peer object for the specified <code>Button</code>. + * + * @param target The <code>Button</code> to create the peer for. + * @return The peer for the specified <code>Button</code> object. + */ + protected abstract ButtonPeer createButton(Button target); + + /** + * Creates a peer object for the specified <code>TextField</code>. + * + * @param target The <code>TextField</code> to create the peer for. + * @return The peer for the specified <code>TextField</code> object. + */ + protected abstract TextFieldPeer createTextField(TextField target); + + /** + * Creates a peer object for the specified <code>Label</code>. + * + * @param target The <code>Label</code> to create the peer for. + * @return The peer for the specified <code>Label</code> object. + */ + protected abstract LabelPeer createLabel(Label target); + + /** + * Creates a peer object for the specified <code>List</code>. + * + * @param target The <code>List</code> to create the peer for. + * @return The peer for the specified <code>List</code> object. + */ + protected abstract ListPeer createList(List target); + + /** + * Creates a peer object for the specified <code>Checkbox</code>. + * + * @param target The <code>Checkbox</code> to create the peer for. + * @return The peer for the specified <code>Checkbox</code> object. + */ + protected abstract CheckboxPeer createCheckbox(Checkbox target); + + /** + * Creates a peer object for the specified <code>Scrollbar</code>. + * + * @param target The <code>Scrollbar</code> to create the peer for. + * @return The peer for the specified <code>Scrollbar</code> object. + */ + protected abstract ScrollbarPeer createScrollbar(Scrollbar target); + + /** + * Creates a peer object for the specified <code>ScrollPane</code>. + * + * @param target The <code>ScrollPane</code> to create the peer for. + * @return The peer for the specified <code>ScrollPane</code> object. + */ + protected abstract ScrollPanePeer createScrollPane(ScrollPane target); + + /** + * Creates a peer object for the specified <code>TextArea</code>. + * + * @param target The <code>TextArea</code> to create the peer for. + * @return The peer for the specified <code>TextArea</code> object. + */ + protected abstract TextAreaPeer createTextArea(TextArea target); + + /** + * Creates a peer object for the specified <code>Choice</code>. + * + * @param target The <code>Choice</code> to create the peer for. + * @return The peer for the specified <code>Choice</code> object. + */ + protected abstract ChoicePeer createChoice(Choice target); + + /** + * Creates a peer object for the specified <code>Frame</code>. + * + * @param target The <code>Frame</code> to create the peer for. + * @return The peer for the specified <code>Frame</code> object. + */ + protected abstract FramePeer createFrame(Frame target); + + /** + * Creates a peer object for the specified <code>Canvas</code>. + * + * @param target The <code>Canvas</code> to create the peer for. + * @return The peer for the specified <code>Canvas</code> object. + */ + protected abstract CanvasPeer createCanvas(Canvas target); + + /** + * Creates a peer object for the specified <code>Panel</code>. + * + * @param target The <code>Panel</code> to create the peer for. + * @return The peer for the specified <code>Panel</code> object. + */ + protected abstract PanelPeer createPanel(Panel target); + + /** + * Creates a peer object for the specified <code>Window</code>. + * + * @param target The <code>Window</code> to create the peer for. + * @return The peer for the specified <code>Window</code> object. + */ + protected abstract WindowPeer createWindow(Window target); + + /** + * Creates a peer object for the specified <code>Dialog</code>. + * + * @param target The dialog to create the peer for + * @return The peer for the specified font name. + */ + protected abstract DialogPeer createDialog(Dialog target); + + /** + * Creates a peer object for the specified <code>MenuBar</code>. + * + * @param target The <code>MenuBar</code> to create the peer for. + * @return The peer for the specified <code>MenuBar</code> object. + */ + protected abstract MenuBarPeer createMenuBar(MenuBar target); + + /** + * Creates a peer object for the specified <code>Menu</code>. + * + * @param target The <code>Menu</code> to create the peer for. + * @return The peer for the specified <code>Menu</code> object. + */ + protected abstract MenuPeer createMenu(Menu target); + + /** + * Creates a peer object for the specified <code>PopupMenu</code>. + * + * @param target The <code>PopupMenu</code> to create the peer for. + * @return The peer for the specified <code>PopupMenu</code> object. + */ + protected abstract PopupMenuPeer createPopupMenu(PopupMenu target); + + /** + * Creates a peer object for the specified <code>MenuItem</code>. + * + * @param target The <code>MenuItem</code> to create the peer for. + * @return The peer for the specified <code>MenuItem</code> object. + */ + protected abstract MenuItemPeer createMenuItem(MenuItem target); + + /** + * Creates a peer object for the specified <code>FileDialog</code>. + * + * @param target The <code>FileDialog</code> to create the peer for. + * @return The peer for the specified <code>FileDialog</code> object. + */ + protected abstract FileDialogPeer createFileDialog(FileDialog target); + + /** + * Creates a peer object for the specified <code>CheckboxMenuItem</code>. + * + * @param target The <code>CheckboxMenuItem</code> to create the peer for. + * @return The peer for the specified <code>CheckboxMenuItem</code> object. + */ + protected abstract CheckboxMenuItemPeer + createCheckboxMenuItem(CheckboxMenuItem target); + + /** + * Creates a peer object for the specified <code>Component</code>. The + * peer returned by this method is not a native windowing system peer + * with its own native window. Instead, this method allows the component + * to draw on its parent window as a "lightweight" widget. + * + * XXX: FIXME + * + * @param target The <code>Component</code> to create the peer for. + * @return The peer for the specified <code>Component</code> object. + */ + protected LightweightPeer createComponent(Component target) + { + return null; + } + + /** + * Creates a peer object for the specified font name. + * + * @param name The font to create the peer for. + * @param style The font style to create the peer for. + * @return The peer for the specified font name. + */ + protected abstract FontPeer getFontPeer(String name, int style); + + /** + * Copies the current system colors into the specified array. This is + * the interface used by the <code>SystemColors</code> class. + * + * @param colors The array to copy the system colors into. + */ + protected void loadSystemColors(int systemColors[]) + { + // XXX Implement. + } + + /** + * @since 1.4 + */ + public void setDynamicLayout(boolean dynamic) + { + } + + /** + * @since 1.4 + */ + protected boolean isDynamicLayoutSet() + { + return false; + } + + /** + * @since 1.4 + */ + public boolean isDynamicLayoutActive() + { + return false; + } + + /** + * Returns the dimensions of the screen in pixels. + * + * @return The dimensions of the screen in pixels. + */ + public abstract Dimension getScreenSize(); + + /** + * Returns the screen resolution in dots per square inch. + * + * @return The screen resolution in dots per square inch. + */ + public abstract int getScreenResolution(); + + /** + * @since 1.4 + */ + public Insets getScreenInsets(GraphicsConfiguration gc) + { + return null; + } + + /** + * Returns the color model of the screen. + * + * @return The color model of the screen. + */ + public abstract ColorModel getColorModel(); + + /** + * Returns the names of the available fonts. + * + * @return The names of the available fonts. + */ + public abstract String[] getFontList(); + + /** + * Return the font metrics for the specified font + * + * @param name The name of the font to return metrics for. + * @return The requested font metrics. + */ + public abstract FontMetrics getFontMetrics(Font name); + + /** + * Flushes any buffered data to the screen so that it is in sync with + * what the AWT system has drawn to it. + */ + public abstract void sync(); + + /** + * Returns an instance of the default toolkit. The default toolkit is + * the subclass of <code>Toolkit</code> specified in the system property + * <code>awt.toolkit</code>, or <code>gnu.java.awt.peer.gtk.GtkToolkit</code> + * if the property is not set. + * + * @return An instance of the system default toolkit. + * @throws AWTError If the toolkit cannot be loaded. + */ + public static Toolkit getDefaultToolkit() + { + if (toolkit != null) + return toolkit; + String toolkit_name = System.getProperty("awt.toolkit", + default_toolkit_name); + try + { + Class cls = Class.forName(toolkit_name); + Object obj = cls.newInstance(); + if (!(obj instanceof Toolkit)) + throw new AWTError(toolkit_name + " is not a subclass of " + + "java.awt.Toolkit"); + toolkit = (Toolkit) obj; + return toolkit; + } + catch (Exception e) + { + throw new AWTError("Cannot load AWT toolkit: " + e.getMessage()); + } + } + + /** + * Returns an image from the specified file, which must be in a + * recognized format. Supported formats vary from toolkit to toolkit. + * + * @return name The name of the file to read the image from. + */ + public abstract Image getImage(String name); + + /** + * Returns an image from the specified URL, which must be in a + * recognized format. Supported formats vary from toolkit to toolkit. + * + * @return url The URl to read the image from. + */ + public abstract Image getImage(URL url); + + public abstract Image createImage(String filename); + + public abstract Image createImage(URL url); + + /** + * Readies an image to be rendered on the screen. The width and height + * values can be set to the default sizes for the image by passing -1 + * in those parameters. + * + * @param image The image to prepare for rendering. + * @param width The width of the image. + * @param height The height of the image. + * @param observer The observer to receive events about the preparation + * process. + * @return <code>true</code> if the image is already prepared for rendering, + * <code>false</code> otherwise. + */ + public abstract boolean prepareImage(Image image, int width, int height, + ImageObserver observer); + + /** + * Checks the status of specified image as it is being readied for + * rendering. + * + * @param image The image to prepare for rendering. + * @param width The width of the image. + * @param height The height of the image. + * @param observer The observer to receive events about the preparation + * process. + * @return A union of the bitmasks from + * <code>java.awt.image.ImageObserver</code> that indicates the current + * state of the imaging readying process. + */ + public abstract int checkImage(Image image, int width, int height, + ImageObserver observer); + + /** + * Creates an image using the specified <code>ImageProducer</code> + * + * @param producer The <code>ImageProducer</code> to create the image from. + * @return The created image. + */ + public abstract Image createImage(ImageProducer producer); + + /** + * Creates an image from the specified byte array. The array must be in + * a recognized format. Supported formats vary from toolkit to toolkit. + * + * @param data The raw image data. + * @return The created image. + */ + public Image createImage(byte[] data) + { + return createImage(data, 0, data.length); + } + + /** + * Creates an image from the specified portion of the byte array passed. + * The array must be in a recognized format. Supported formats vary from + * toolkit to toolkit. + * + * @param data The raw image data. + * @param offset The offset into the data where the image data starts. + * @param len The length of the image data. + * @return The created image. + */ + public abstract Image createImage(byte[] data, int offset, int len); + + /** + * Returns a instance of <code>PrintJob</code> for the specified + * arguments. + * + * @param frame The window initiating the print job. + * @param title The print job title. + * @param props The print job properties. + * @return The requested print job, or <code>null</code> if the job + * was cancelled. + */ + public abstract PrintJob getPrintJob(Frame frame, String title, + Properties props); + + + /** + * @since 1.3 + */ + public PrintJob getPrintJob(Frame frame, String title, + JobAttributes jobAttr, PageAttributes pageAttr) + { + return null; + } + + /** + * Causes a "beep" tone to be generated. + */ + public abstract void beep(); + + /** + * Returns the system clipboard. + * + * @return THe system clipboard. + */ + public abstract Clipboard getSystemClipboard(); + + /** + * @since 1.4 + */ + public Clipboard getSystemSelection() + { + return null; + } + + /** + * Returns the accelerator key mask for menu shortcuts. The default is + * <code>Event.CTRL_MASK</code>. A toolkit must override this method + * to change the default. + * + * @return The key mask for the menu accelerator key. + */ + public int getMenuShortcutKeyMask() + { + return Event.CTRL_MASK; + } + + public boolean getLockingKeyState(int keyCode) + { + if (keyCode != KeyEvent.VK_CAPS_LOCK + && keyCode != KeyEvent.VK_NUM_LOCK + && keyCode != KeyEvent.VK_SCROLL_LOCK) + throw new IllegalArgumentException(); + throw new UnsupportedOperationException(); + } + + public void setLockingKeyState(int keyCode, boolean on) + { + if (keyCode != KeyEvent.VK_CAPS_LOCK + && keyCode != KeyEvent.VK_NUM_LOCK + && keyCode != KeyEvent.VK_SCROLL_LOCK) + throw new IllegalArgumentException(); + throw new UnsupportedOperationException(); + } + + /** + * Returns the native container object of the specified component. This + * method is necessary because the parent component might be a lightweight + * component. + * + * @param component The component to fetch the native container for. + * @return The native container object for this component. + */ + protected static Container getNativeContainer(Component component) + { + component = component.getParent(); + while (true) + { + if (component == null) + return null; + if (! (component instanceof Container)) + { + component = component.getParent(); + continue; + } + if (component.getPeer() instanceof LightweightPeer) + { + component = component.getParent(); + continue; + } + return (Container) component; + } + } + + public Cursor createCustomCursor(Image cursor, Point hotSpot, String name) + { + // Presumably the only reason this isn't abstract is for backwards + // compatibility? FIXME? + return null; + } + + public Dimension getBestCursorSize(int preferredWidth, int preferredHeight) + { + return new Dimension (0,0); + } + + public int getMaximumCursorColors() + { + return 0; + } + + /** + * @since 1.4 + */ + public boolean isFrameStateSupported(int state) + { + return false; + } + + /** + * Returns the value of the property with the specified name, or the + * default value if the property does not exist. + * + * @param key The name of the property to retrieve. + * @param defThe default value of the property. + */ + public static String getProperty(String key, String def) + { + return props.getProperty(key, def); + } + + /** + * Returns the event queue for the applet. Despite the word "System" + * in the name of this method, there is no guarantee that the same queue + * is shared system wide. + * + * @return The event queue for this applet (or application) + */ + public final EventQueue getSystemEventQueue() + { + return getSystemEventQueueImpl(); + } + + /** + * // FIXME: What does this do? + */ + protected abstract EventQueue getSystemEventQueueImpl(); + + /** + * @since 1.3 + */ + public abstract DragSourceContextPeer + createDragSourceContextPeer(DragGestureEvent e); + + /** + * @since 1.3 + */ + public DragGestureRecognizer + createDragGestureRecognizer(Class recognizer, DragSource ds, + Component comp, int actions, + DragGestureListener l) + { + return null; + } + + public final Object getDesktopProperty(String propertyName) + { + return desktopProperties.get(propertyName); + } + + protected final void setDesktopProperty(String name, Object newValue) + { + Object oldValue = getDesktopProperty(name); + desktopProperties.put(name, newValue); + desktopPropsSupport.firePropertyChange(name, oldValue, newValue); + } + + protected Object lazilyLoadDesktopProperty(String name) + { + // FIXME - what is this?? + return null; + } + + protected void initializeDesktopProperties() + { + // Overridden by toolkit implementation? + } + + public void addPropertyChangeListener(String name, + PropertyChangeListener pcl) + { + desktopPropsSupport.addPropertyChangeListener(name, pcl); + } + + public void removePropertyChangeListener(String name, + PropertyChangeListener pcl) + { + desktopPropsSupport.removePropertyChangeListener(name, pcl); + } + + /** + * @since 1.4 + */ + public PropertyChangeListener[] getPropertyChangeListeners() + { + return desktopPropsSupport.getPropertyChangeListeners(); + } + + /** + * @since 1.4 + */ + public PropertyChangeListener[] getPropertyChangeListeners(String name) + { + return desktopPropsSupport.getPropertyChangeListeners(name); + } + + public void addAWTEventListener(AWTEventListener listener, long eventMask) + { + // SecurityManager s = System.getSecurityManager(); + // if (s != null) + // s.checkPermission(AWTPermission("listenToAllAWTEvents")); + // FIXME + } + + public void removeAWTEventListener(AWTEventListener listener) + { + // FIXME + } + + /** + * @since 1.4 + */ + public AWTEventListener[] getAWTEventListeners() + { + return null; + } + + /** + * @since 1.4 + */ + public AWTEventListener[] getAWTEventListeners(long mask) + { + return null; + } + + /** + * @since 1.3 + */ + public abstract Map mapInputMethodHighlight(InputMethodHighlight highlight); } // class Toolkit diff --git a/libjava/java/awt/Transparency.java b/libjava/java/awt/Transparency.java index 6a8aeaece6d..fc01f583955 100644 --- a/libjava/java/awt/Transparency.java +++ b/libjava/java/awt/Transparency.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* Transparency.java -- common transparency modes in graphics + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,21 +38,30 @@ exception statement from your version. */ package java.awt; /** + * A common transparency mode for layering graphics. + * * @author Warren Levy <warrenl@cygnus.com> - * @date March 15, 2000. + * @since 1.1 + * @status updated to 1.4 */ - -/** - * Written using on-line Java Platform 1.2 API Specification, as well - * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). - * Status: Believed complete and correct. - */ - public interface Transparency { - public static final int OPAQUE = 1; - public static final int BITMASK = 2; - public static final int TRANSLUCENT = 3; + /** Image data which is completely opaque, for an alpha value of 1.0. */ + int OPAQUE = 1; + + /** + * Image data which is either completely opaque or transparent, for an + * exact integer alpha value. + */ + int BITMASK = 2; + + /** Image data which is translucent, for a non-integer alpha value. */ + int TRANSLUCENT = 3; - public int getTransparency(); -} + /** + * Return the transparency type. + * + * @return One of {@see #OPAQUE}, {@see #BITMASK}, or {@see #TRANSLUCENT}. + */ + int getTransparency(); +} // interface Transparency diff --git a/libjava/java/awt/Window.java b/libjava/java/awt/Window.java index 6af7c345008..7064511b2b6 100644 --- a/libjava/java/awt/Window.java +++ b/libjava/java/awt/Window.java @@ -1,6 +1,5 @@ -/* Copyright (C) 1999, 2000, 2002 Free Software Foundation - - Copyright (C) 1999 Free Software Foundation, Inc. +/* Window.java -- + Copyright (C) 1999, 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -36,7 +35,9 @@ 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.WindowEvent; import java.awt.event.WindowListener; import java.awt.peer.WindowPeer; @@ -145,8 +146,8 @@ public class Window extends Container public void addNotify() { if (peer == null) - peer = getToolkit ().createWindow (this); - super.addNotify (); + peer = getToolkit().createWindow(this); + super.addNotify(); } /** @@ -171,7 +172,7 @@ public class Window extends Container /** * Makes this window visible and brings it to the front. */ - public void show () + public void show() { if (peer == null) addNotify(); @@ -206,12 +207,12 @@ public class Window extends Container * Sends this window to the back so that all other windows display in * front of it. */ - public void toBack () + public void toBack() { if (peer != null) { WindowPeer wp = (WindowPeer) peer; - wp.toBack (); + wp.toBack(); } } @@ -219,12 +220,12 @@ public class Window extends Container * Brings this window to the front so that it displays in front of * any other windows. */ - public void toFront () + public void toFront() { if (peer != null) { WindowPeer wp = (WindowPeer) peer; - wp.toFront (); + wp.toFront(); } } @@ -238,7 +239,7 @@ public class Window extends Container */ public Toolkit getToolkit() { - return Toolkit.getDefaultToolkit (); + return Toolkit.getDefaultToolkit(); } /** @@ -270,9 +271,9 @@ public class Window extends Container * * @return The locale this window is configured for. */ - public Locale getLocale () + public Locale getLocale() { - return locale == null ? Locale.getDefault () : locale; + return locale == null ? Locale.getDefault() : locale; } /* @@ -312,9 +313,9 @@ public class Window extends Container * * @param listener The <code>WindowListener</code> to add. */ - public synchronized void addWindowListener (WindowListener listener) + public synchronized void addWindowListener(WindowListener listener) { - windowListener = AWTEventMulticaster.add (windowListener, listener); + windowListener = AWTEventMulticaster.add(windowListener, listener); } /** @@ -323,17 +324,24 @@ public class Window extends Container * * @param listener The <code>WindowListener</code> to remove. */ - public synchronized void removeWindowListener (WindowListener listener) + public synchronized void removeWindowListener(WindowListener listener) + { + windowListener = AWTEventMulticaster.remove(windowListener, listener); + } + + public synchronized WindowListener[] getWindowListeners() { - windowListener = AWTEventMulticaster.remove (windowListener, listener); + 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) @@ -356,12 +364,12 @@ public class Window extends Container * * @param event The event to process. */ - protected void processEvent (AWTEvent evt) + protected void processEvent(AWTEvent evt) { if (evt instanceof WindowEvent) - processWindowEvent ((WindowEvent) evt); + processWindowEvent((WindowEvent) evt); else - super.processEvent (evt); + super.processEvent(evt); } /** @@ -372,32 +380,32 @@ public class Window extends Container * * @param event The event to process. */ - protected void processWindowEvent (WindowEvent evt) + protected void processWindowEvent(WindowEvent evt) { if (windowListener != null) { - switch (evt.getID ()) + switch (evt.getID()) { case WindowEvent.WINDOW_ACTIVATED: - windowListener.windowActivated (evt); + windowListener.windowActivated(evt); break; case WindowEvent.WINDOW_CLOSED: - windowListener.windowClosed (evt); + windowListener.windowClosed(evt); break; case WindowEvent.WINDOW_CLOSING: - windowListener.windowClosing (evt); + windowListener.windowClosing(evt); break; case WindowEvent.WINDOW_DEACTIVATED: - windowListener.windowDeactivated (evt); + windowListener.windowDeactivated(evt); break; case WindowEvent.WINDOW_DEICONIFIED: - windowListener.windowDeiconified (evt); + windowListener.windowDeiconified(evt); break; case WindowEvent.WINDOW_ICONIFIED: - windowListener.windowIconified (evt); + windowListener.windowIconified(evt); break; case WindowEvent.WINDOW_OPENED: - windowListener.windowOpened (evt); + windowListener.windowOpened(evt); break; } } diff --git a/libjava/java/awt/color/CMMException.java b/libjava/java/awt/color/CMMException.java new file mode 100644 index 00000000000..0d146e6c6eb --- /dev/null +++ b/libjava/java/awt/color/CMMException.java @@ -0,0 +1,63 @@ +/* CMMException.java -- error in the native CMM + 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.color; + +/** + * Thrown when there is an error in the native CMM. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @status updated to 1.4 + */ +public class CMMException extends Exception +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 5775558044142994965L; + + /** + * Create a new instance with a specified detailed error message. + * + * @param message the message + */ + public CMMException(String message) + { + super(message); + } +} // class CMMException diff --git a/libjava/java/awt/color/ProfileDataException.java b/libjava/java/awt/color/ProfileDataException.java new file mode 100644 index 00000000000..130781faf9b --- /dev/null +++ b/libjava/java/awt/color/ProfileDataException.java @@ -0,0 +1,64 @@ +/* ProfileDataException.java -- error in processing an ICC_Profile + 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.color; + +/** + * Thrown when there is an error accessing or processing an + * <code>ICC_Profile</code>. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @status updated to 1.4 + */ +public class ProfileDataException extends Exception +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 7286140888240322498L; + + /** + * Create a new instance with a specified detailed error message. + * + * @param message the message + */ + public ProfileDataException(String message) + { + super(message); + } +} // class ProfileDataException diff --git a/libjava/java/awt/datatransfer/FlavorTable.java b/libjava/java/awt/datatransfer/FlavorTable.java new file mode 100644 index 00000000000..23fa9fa1fc1 --- /dev/null +++ b/libjava/java/awt/datatransfer/FlavorTable.java @@ -0,0 +1,73 @@ +/* FlavorTable.java -- A relaxed mapping between flavors + 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.datatransfer; + +import java.util.List; + +/** + * A FlavorMap which no longer requires a 1-to-1 mapping between flavors. Any + * native can map to multiple flavors, and any flavor can map to multiple + * natives; although the mappings are usually symmetric. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.4 + * @status updated to 1.4 + */ +public interface FlavorTable extends FlavorMap +{ + /** + * Returns a list of String natives corresponding to the given flavor. The + * list should be sorted from best to worst. The list must be modifiable + * without affecting this table. + * + * @param flavor the flavor to look up, or null to return all natives + * @return the sorted list of natives + */ + List getNativesForFlavor(DataFlavor flavor); + + /** + * Returns a list of flavors corresponding to the given String native. The + * list should be sorted from best to worst. The list must be modifiable + * without affecting this table. + * + * @param native the native to look up, or null to return all flavors + * @return the sorted list of flavors + */ + List getFlavorsForNative(String name); +} // interface FlavorTable diff --git a/libjava/java/awt/datatransfer/MimeTypeParseException.java b/libjava/java/awt/datatransfer/MimeTypeParseException.java index 32bc8850b31..42aecac0528 100644 --- a/libjava/java/awt/datatransfer/MimeTypeParseException.java +++ b/libjava/java/awt/datatransfer/MimeTypeParseException.java @@ -1,5 +1,5 @@ -/* MimeTypeParseException.java -- Thrown when MIME string couldn't be parsed. - Copyright (C) 2001 Free Software Foundation, Inc. +/* MimeTypeParseException.java -- thrown when MIME string couldn't be parsed + Copyright (C) 2001, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,30 +41,30 @@ package java.awt.datatransfer; /** * MIME string couldn't be parsed correctly. * - * @author Mark Wielaard (mark@klomp.org) + * @author Mark Wielaard <mark@klomp.org> + * @status updated to 1.4 */ -public class MimeTypeParseException extends Exception +public class MimeTypeParseException extends Exception { + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = -5604407764691570741L; -/** - * Initializes a new instance of <code>MimeTypeParseException</code> - * without any message. - */ -public -MimeTypeParseException() -{ - super(); -} - -/** - * Initializes a new instance of <code>MimeTypeParseException</code> - * with a specified detailed error message. - */ -public -MimeTypeParseException(String message) -{ - super(message); -} + /** + * Create a new instance without any message. + */ + public MimeTypeParseException() + { + } + /** + * Create a new instance with a specified detailed error message. + * + * @param message the message + */ + public MimeTypeParseException(String message) + { + super(message); + } } // class MimeTypeParseException - diff --git a/libjava/java/awt/datatransfer/Transferable.java b/libjava/java/awt/datatransfer/Transferable.java index 52dac691e5b..ad957ed0868 100644 --- a/libjava/java/awt/datatransfer/Transferable.java +++ b/libjava/java/awt/datatransfer/Transferable.java @@ -1,5 +1,5 @@ /* Transferable.java -- Data transfer source - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,52 +41,41 @@ package java.awt.datatransfer; import java.io.IOException; /** - * This interface is implemented by classes that can transfer data. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ + * This interface is implemented by classes that can transfer data. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.1 + * @status updated to 1.4 + */ public interface Transferable { - -/** - * Returns the data in the specified <code>DataFlavor</code> - * - * @param flavor The data flavor to return. - * - * @return The data in the appropriate flavor. - * - * @exception UnsupportedFlavorException If the flavor is not supported. - * @exception IOException If the data is not available. - */ -public abstract Object -getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, - IOException; - -/*************************************************************************/ - -/** - * This method returns a list of available data flavors for the - * data being transferred. The array returned will be sorted from most - * preferred flavor at the beginning to least preferred at the end. - * - * @return A list of data flavors for this data. - */ -public abstract DataFlavor[] -getTransferDataFlavors(); - -/*************************************************************************/ - -/** - * Tests whether or not this data can be delivered in the specified - * data flavor. - * - * @param flavor The data flavor to test. - * - * @return <code>true</code> if the data flavor is supported, - * <code>false</code> otherwise. - */ -public abstract boolean -isDataFlavorSupported(DataFlavor flavor); - + /** + * This method returns a list of available data flavors for the data being + * transferred. The array returned will be sorted from most preferred + * flavor at the beginning to least preferred at the end. + * + * @return adA list of data flavors for this data + */ + public abstract DataFlavor[] getTransferDataFlavors(); + + /** + * Tests whether or not this data can be delivered in the specified data + * flavor. + * + * @param flavor the data flavor to test + * @return true if the data flavor is supported + */ + public abstract boolean isDataFlavorSupported(DataFlavor flavor); + + /** + * Returns the data in the specified <code>DataFlavor</code>. + * + * @param flavor the data flavor to return + * @return the data in the appropriate flavor + * @throws UnsupportedFlavorException if the flavor is not supported + * @throws IOException if the data is not available + * @see DataFlavor#getRepresentationClass + */ + public abstract Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException; } // interface Transferable - diff --git a/libjava/java/awt/datatransfer/UnsupportedFlavorException.java b/libjava/java/awt/datatransfer/UnsupportedFlavorException.java index a31059ef23a..620452be6f8 100644 --- a/libjava/java/awt/datatransfer/UnsupportedFlavorException.java +++ b/libjava/java/awt/datatransfer/UnsupportedFlavorException.java @@ -1,5 +1,5 @@ -/* UnsupportedFlavorException.java -- Data flavor is not valid. - Copyright (C) 1999 Free Software Foundation, Inc. +/* UnsupportedFlavorException.java -- ata flavor is not valid + Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,24 +39,27 @@ exception statement from your version. */ package java.awt.datatransfer; /** - * The data flavor requested is not supported for the transfer data. - * - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public class UnsupportedFlavorException extends Exception + * The data flavor requested is not supported for the transfer data. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see Transferable#getTransferData(DataFlavor) + * @status updated to 1.4 + */ +public class UnsupportedFlavorException extends Exception { + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = 5383814944251665601L; -/** - * Initializes a new instance of <code>UnsupportedDataFlavor</code> - * for the specified data flavor. - * - * @param flavor The data flavor that is not supported. - */ -public -UnsupportedFlavorException(DataFlavor flavor) -{ - super(flavor.getHumanPresentableName()); -} - + /** + * Initializes a new instance of <code>UnsupportedDataFlavor</code> + * for the specified data flavor. + * + * @param flavor the data flavor that is not supported + */ + public UnsupportedFlavorException(DataFlavor flavor) + { + super(flavor == null ? null : flavor.getHumanPresentableName()); + } } // class UnsupportedFlavorException - diff --git a/libjava/java/awt/dnd/DnDConstants.java b/libjava/java/awt/dnd/DnDConstants.java new file mode 100644 index 00000000000..3e78121a57a --- /dev/null +++ b/libjava/java/awt/dnd/DnDConstants.java @@ -0,0 +1,72 @@ +/* DnDConstants.java -- constants for drag-and-drop operations + 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.dnd; + +/** + * This class contains various constants used in drag-and-drop operations. + * Why it is not an interface is beyond me. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ +public final class DnDConstants +{ + /** No action takes place. */ + public static final int ACTION_NONE = 0; + + /** The copy action. */ + public static final int ACTION_COPY = 1; + + /** The move action. */ + public static final int ACTION_MOVE = 2; + + /** Either a copy or a move. */ + public static final int ACTION_COPY_OR_MOVE = 3; + + /** + * A link action. This does not copy or move, but creates a reference back + * to the original. However, since platforms differ on how a reference should + * behave, this action is not recommended for common use. + */ + public static final int ACTION_LINK = 1073741824; + + /** A synonym for {@link #ACTION_LINK}. */ + public static final int ACTION_REFERENCE = ACTION_LINK; +} // class DnDConstants diff --git a/libjava/java/awt/dnd/DragGestureEvent.java b/libjava/java/awt/dnd/DragGestureEvent.java new file mode 100644 index 00000000000..84fa1cbb901 --- /dev/null +++ b/libjava/java/awt/dnd/DragGestureEvent.java @@ -0,0 +1,129 @@ +/* DragGestureEvent.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.dnd; + +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Image; +import java.awt.Point; +import java.awt.datatransfer.Transferable; +import java.awt.event.InputEvent; +import java.util.EventObject; +import java.util.Iterator; +import java.util.List; + +/** + * STUBBED + * @see DragGestureRecognizer + * @see DragGestureListener + * @see DragSource + * @since 1.2 + */ +public class DragGestureEvent extends EventObject +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 9080172649166731306L; + + private DragSource dragSource; + private Component component; + private final Point origin; + private final int action; + + public DragGestureEvent(DragGestureRecognizer dgr, int action, Point origin, + List events) + { + super(dgr); + if (origin == null || events == null) + throw new IllegalArgumentException(); + this.origin = origin; + this.action = action; + } + + public DragGestureRecognizer getSourceAsDragGestureRecognizer() + { + return (DragGestureRecognizer) source; + } + public Component getComponent() + { + return null; + } + public DragSource getDragSource() + { + return null; + } + public Point getDragOrigin() + { + return origin; + } + public Iterator iterator() + { + return null; + } + public Object[] toArray() + { + return null; + } + public Object[] toArray(Object[] array) + { + return array; + } + public int getDragAction() + { + return 0; + } + public InputEvent getTriggerEvent() + { + return null; + } + public void startDrag(Cursor dragCursor, Transferable trans) + { + startDrag(dragCursor, null, null, trans, null); + } + public void startDrag(Cursor dragCursor, Transferable trans, + DragSourceListener l) + { + startDrag(dragCursor, null, null, trans, l); + } + public void startDrag(Cursor dragCursor, Image dragImage, Point imageOffset, + Transferable trans, DragSourceListener l) + { + } +} // class DragGestureEvent diff --git a/libjava/java/awt/dnd/DragGestureListener.java b/libjava/java/awt/dnd/DragGestureListener.java new file mode 100644 index 00000000000..2673d0d5d1f --- /dev/null +++ b/libjava/java/awt/dnd/DragGestureListener.java @@ -0,0 +1,63 @@ +/* DragGestureListener.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.dnd; + +import java.util.EventListener; + +/** + * This is a listener for starting a drag-and-drop gesture. Upon receiving + * notification, the implementor then starts the drag operation. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see DragGestureRecognizer + * @see DragGestureEvent + * @see DragSource + * @since 1.2 + * @status updated to 1.4 + */ +public interface DragGestureListener extends EventListener +{ + /** + * Called when the native platform notifies the virtual machine that a + * drag-and-drop has been initiated. + * + * @param e the event + */ + void dragGestureRecognized(DragGestureEvent e); +} // interface DragGestureListener diff --git a/libjava/java/awt/dnd/DragGestureRecognizer.java b/libjava/java/awt/dnd/DragGestureRecognizer.java new file mode 100644 index 00000000000..674e26e8a3b --- /dev/null +++ b/libjava/java/awt/dnd/DragGestureRecognizer.java @@ -0,0 +1,173 @@ +/* DragGestureRecognizer.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.dnd; + +import java.awt.Component; +import java.awt.Point; +import java.awt.event.InputEvent; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.TooManyListenersException; + +/** + * STUBBED + * @since 1.2 + */ +public abstract class DragGestureRecognizer implements Serializable +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 8996673345831063337L; + + protected DragSource dragSource; + protected Component component; + protected transient DragGestureListener dragGestureListener; + protected int sourceActions; + protected ArrayList events = new ArrayList(); + + protected DragGestureRecognizer(DragSource ds, Component c, int sa, + DragGestureListener dgl) + { + if (ds == null) + throw new IllegalArgumentException(); + dragSource = ds; + component = c; + sourceActions = sa; + dragGestureListener = dgl; + } + + protected DragGestureRecognizer(DragSource ds, Component c, int sa) + { + this(ds, c, sa, null); + } + + protected DragGestureRecognizer(DragSource ds, Component c) + { + this(ds, c, 0, null); + } + + protected DragGestureRecognizer(DragSource ds) + { + this(ds, null, 0, null); + } + + protected abstract void registerListeners(); + + protected abstract void unregisterListeners(); + + public DragSource getDragSource() + { + return dragSource; + } + + public Component getComponent() + { + return component; + } + + public void setComponent(Component c) + { + component = c; + } + + public int getSourceActions() + { + return sourceActions; + } + + public void setSourceActions(int sa) + { + sourceActions = sa; + } + + public InputEvent getTriggerEvent() + { + return events.size() > 0 ? (InputEvent) events.get(0) : null; + } + + public void resetRecognizer() + { + throw new Error("not implemented"); + } + + public void addDragGestureListener(DragGestureListener dgl) + throws TooManyListenersException + { + if (dragGestureListener != null) + throw new TooManyListenersException(); + dragGestureListener = dgl; + } + + public void removeDragGestureListener(DragGestureListener dgl) + { + if (dragGestureListener != dgl) + throw new IllegalArgumentException(); + dragGestureListener = null; + } + + protected void fireDragGestureRecognized(int dragAction, Point p) + { + throw new Error("not implemented"); + } + + protected void appendEvent(InputEvent e) + { + if (e == null) + return; + events.add(e); + } + + private void readObject(ObjectInputStream s) + throws ClassNotFoundException, IOException + { + s.defaultReadObject(); + dragGestureListener = (DragGestureListener) s.readObject(); + } + + private void writeObject(ObjectOutputStream s) throws IOException + { + s.defaultWriteObject(); + s.writeObject(dragGestureListener instanceof Serializable + ? dragGestureListener : null); + } +} // class DragGestureRecognizer diff --git a/libjava/java/awt/dnd/DragSource.java b/libjava/java/awt/dnd/DragSource.java new file mode 100644 index 00000000000..01cae00a3cf --- /dev/null +++ b/libjava/java/awt/dnd/DragSource.java @@ -0,0 +1,163 @@ +/* DragSource.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.dnd; + +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Image; +import java.awt.Point; +import java.awt.datatransfer.FlavorMap; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.io.Serializable; +import java.util.EventListener; + +public class DragSource implements Serializable +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 6236096958971414066L; + + public static final Cursor DefaultCopyDrop = null; + public static final Cursor DefaultMoveDrop = null; + public static final Cursor DefaultLinkDrop = null; + public static final Cursor DefaultCopyNoDrop = null; + public static final Cursor DefaultMoveNoDrop = null; + public static final Cursor DefaultLinkNoDrop = null; + + public DragSource() + { + } + + public static DragSource getDefaultDragSource() + { + return null; + } + + public static boolean isDragImageSupported() + { + return false; + } + + public void startDrag(DragGestureEvent trigger, Cursor dragCursor, + Image dragImage, Point imageOffset, + Transferable trans, DragSourceListener dsl, + FlavorMap map) + { + } + + public void startDrag(DragGestureEvent trigger, Cursor dragCursor, + Transferable trans, DragSourceListener dsl, + FlavorMap map) + { + startDrag(trigger, dragCursor, null, null, trans, dsl, map); + } + + public void startDrag(DragGestureEvent trigger, Cursor dragCursor, + Image dragImage, Point imageOffset, + Transferable trans, DragSourceListener dsl) + { + startDrag(trigger, dragCursor, dragImage, imageOffset, trans, dsl, null); + } + + public void startDrag(DragGestureEvent trigger, Cursor dragCursor, + Transferable trans, DragSourceListener dsl) + { + startDrag(trigger, dragCursor, null, null, trans, dsl, null); + } + + protected DragSourceContext + createDragSourceContext(DragSourceContextPeer peer, DragGestureEvent dge, + Cursor cursor, Image image, Point offset, + Transferable t, DragSourceListener dsl) + { + return null; + } + + public FlavorMap getFlavorMap() + { + return null; + } + + public DragGestureRecognizer + createDragGestureRecognizer(Class recognizer, Component c, int actions, + DragGestureListener dgl) + { + return null; + } + + public DragGestureRecognizer + createDefaultDragGestureRecognizer(Component c, int actions, + DragGestureListener dgl) + { + return null; + } + + public void addDragSourceListener(DragSourceListener l) + { + } + + public void removeDragSourceListener(DragSourceListener l) + { + } + + public DragSourceListener[] getDragSourceListeners() + { + return null; + } + + public void addDragSourceMotionListener(DragSourceMotionListener l) + { + } + + public void removeDragSourceMotionListener(DragSourceMotionListener l) + { + } + + public DragSourceMotionListener[] getDragSourceMotionListeners() + { + return null; + } + + public EventListener[] getListeners(Class type) + { + return null; + } +} // class DragSource diff --git a/libjava/java/awt/dnd/DragSourceAdapter.java b/libjava/java/awt/dnd/DragSourceAdapter.java new file mode 100644 index 00000000000..55daf41b257 --- /dev/null +++ b/libjava/java/awt/dnd/DragSourceAdapter.java @@ -0,0 +1,126 @@ +/* DragSourceAdapter.java -- drag-and-drop listener adapter + 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.dnd; + +/** + * This class implements <code>DragSourceListener</code> and + * <code>DragSourceMotionListener</code>, and implements all methods + * with empty bodies. This allows a listener interested in implementing only + * a subset of these interfaces to extend this class and override only the + * desired methods. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see DragSourceEvent + * @see DragSourceListener + * @see DragSourceMotionListener + * @since 1.4 + * @status updated to 1.4 + */ +public abstract class DragSourceAdapter + implements DragSourceListener, DragSourceMotionListener +{ + /** + * Default constructor. + */ + public DragSourceAdapter() + { + } + + /** + * Called when the cursor hotspot enters a drop site which will accept the + * drag. + * + * @param e the event + */ + public void dragEnter(DragSourceDragEvent e) + { + } + + /** + * Called when the cursor hotspot moves inside of a drop site which will + * accept the drag. + * + * @param e the event + */ + public void dragOver(DragSourceDragEvent e) + { + } + + /** + * Called whenever the mouse is moved during a drag-and-drop operation. + * + * @param e the event + */ + public void dragMouseMoved(DragSourceDragEvent e) + { + } + + /** + * Called when the user modifies the drop gesture. This is often the case + * when additional mouse or key events are received during the drag. + * + * @param e the event + */ + public void dropActionChanged(DragSourceDragEvent e) + { + } + + /** + * Called when the cursor hotspot moves outside of a drop site which will + * accept the drag. This could also happen if the drop site is no longer + * active, or no longer accepts the drag. + * + * @param e the event + */ + public void dragExit(DragSourceDragEvent e) + { + } + + /** + * Called when the drag and drop operation is complete. After this event, + * <code>getDropSuccess</code> of the event is valid, and + * <code>getDropAction</code> holds the action requested by the drop site. + * Furthermore, the <code>DragSourceContext</code> is invalidated. + * + * @param e the event + */ + public void dragDropEnd(DragSourceDragEvent e) + { + } +} // class DragSourceAdapter diff --git a/libjava/java/awt/dnd/DragSourceContext.java b/libjava/java/awt/dnd/DragSourceContext.java new file mode 100644 index 00000000000..ff7e88257e9 --- /dev/null +++ b/libjava/java/awt/dnd/DragSourceContext.java @@ -0,0 +1,138 @@ +/* DragSourceContext.java -- + 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.dnd; + +import java.awt.Component; +import java.awt.Cursor; +import java.awt.Image; +import java.awt.Point; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.peer.DragSourceContextPeer; +import java.io.Serializable; +import java.util.TooManyListenersException; + +public class DragSourceContext + implements DragSourceListener, DragSourceMotionListener, Serializable +{ + protected static final int DEFAULT = 0; + protected static final int ENTER = 1; + protected static final int OVER = 2; + protected static final int CHANGED = 3; + + public DragSourceContext(DragSourceContextPeer peer, DragGestureEvent dge, + Cursor cursor, Image image, Point offset, + Transferable trans, DragSourceListener dsl) + { + } + + public DragSource getDragSource() + { + return null; + } + + public Component getComponent() + { + return null; + } + + public DragGestureEvent getTrigger() + { + return null; + } + + public int getSourceActions() + { + return 0; + } + + public void setCursor(Cursor c) + { + } + + public Cursor getCursor() + { + return null; + } + + public void addDragSourceListener(DragSourceListener l) + throws TooManyListenersException + { + } + + public void removeDragSourceListener(DragSourceListener l) + { + } + + public void transferablesFlavorsChanged() + { + } + + public void dragEnter(DragSourceDragEvent e) + { + } + + public void dragOver(DragSourceDragEvent e) + { + } + + public void dragExit(DragSourceDragEvent e) + { + } + + public void dropActionChanged(DragSourceDragEvent e) + { + } + + public void dragDropEnd(DragSourceDragEvent e) + { + } + + public void dragMouseMoved(DragSourceDragEvent e) + { + } + + public Transferable getTransferable() + { + return null; + } + + protected void updateCurrentCursor(int dropOp, int targetAct, int status) + { + } +} // class DragSourceContext diff --git a/libjava/java/awt/dnd/DragSourceDragEvent.java b/libjava/java/awt/dnd/DragSourceDragEvent.java new file mode 100644 index 00000000000..0a1d759e986 --- /dev/null +++ b/libjava/java/awt/dnd/DragSourceDragEvent.java @@ -0,0 +1,95 @@ +/* DragSourceDragEvent.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.dnd; + +import gnu.java.awt.EventModifier; + +/** + * STUBBED + */ +public class DragSourceDragEvent extends DragSourceEvent +{ + private final int dropAction; + private final int targetActions; + private final int gestureModifiers; + + public DragSourceDragEvent(DragSourceContext context, int dropAction, + int actions, int modifiers) + { + super(context); + this.dropAction = dropAction; + targetActions = actions; + gestureModifiers = EventModifier.extend(modifiers); + } + + public DragSourceDragEvent(DragSourceContext context, int dropAction, + int actions, int modifiers, int x, int y) + { + super(context, x, y); + this.dropAction = dropAction; + targetActions = actions; + gestureModifiers = EventModifier.extend(modifiers); + } + + public int getTargetActions() + { + return targetActions; + } + + public int getGestureModifiers() + { + return EventModifier.revert(gestureModifiers); + } + + public int getGestureModifiersEx() + { + return gestureModifiers; + } + + public int getUserAction() + { + return dropAction; + } + + public int getDropAction() + { + return dropAction & targetActions + & ((DragSourceContext) source).getSourceActions(); + } +} // class DragSourceDragEvent diff --git a/libjava/java/awt/dnd/DragSourceEvent.java b/libjava/java/awt/dnd/DragSourceEvent.java new file mode 100644 index 00000000000..9d5b00bf9eb --- /dev/null +++ b/libjava/java/awt/dnd/DragSourceEvent.java @@ -0,0 +1,85 @@ +/* DragSourceEvent.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.dnd; + +import java.awt.Point; +import java.util.EventObject; + +public class DragSourceEvent extends EventObject +{ + private final boolean locationSpecified; + private final int x; + private final int y; + + public DragSourceEvent(DragSourceContext context) + { + super(context); + locationSpecified = false; + x = 0; + y = 0; + } + + public DragSourceEvent(DragSourceContext context, int x, int y) + { + super(context); + locationSpecified = true; + this.x = x; + this.y = y; + } + + public DragSourceContext getDragSourceContext() + { + return (DragSourceContext) source; + } + + public Point getLocation() + { + return locationSpecified ? new Point(x, y) : null; + } + + public int getX() + { + return x; + } + + public int getY() + { + return y; + } +} // class DragSourceEvent diff --git a/libjava/java/awt/dnd/DragSourceListener.java b/libjava/java/awt/dnd/DragSourceListener.java new file mode 100644 index 00000000000..46326418fb9 --- /dev/null +++ b/libjava/java/awt/dnd/DragSourceListener.java @@ -0,0 +1,97 @@ +/* DragSourceListener.java -- listen to events during the drag + 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.dnd; + +import java.util.EventListener; + +/** + * This class allows an object to listen for drag and drop events. It can + * be used to provide appropriate feedback for "drag over" actions. You can + * also use a <code>DragSourceAdapter</code> to filter the events you are + * interested in. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ +public interface DragSourceListener extends EventListener +{ + /** + * Called when the cursor hotspot enters a drop site which will accept the + * drag. + * + * @param e the drag source drag event + */ + void dragEnter(DragSourceDragEvent e); + + /** + * Called when the cursor hotspot moves inside of a drop site which will + * accept the drag. + * + * @param e the drag source drag event + */ + void dragOver(DragSourceDragEvent e); + + /** + * Called when the user modifies the drop gesture. This is often the case + * when additional mouse or key events are received during the drag. + * + * @param e the drag source drag event + */ + void dropActionChanged(DragSourceDragEvent e); + + /** + * Called when the cursor hotspot moves outside of a drop site which will + * accept the drag. This could also happen if the drop site is no longer + * active, or no longer accepts the drag. + * + * @param e the drag source drag event + */ + void dragExit(DragSourceDragEvent e); + + /** + * Called when the drag and drop operation is complete. After this event, + * <code>getDropSuccess</code> of the event is valid, and + * <code>getDropAction</code> holds the action requested by the drop site. + * Furthermore, the <code>DragSourceContext</code> is invalidated. + * + * @param e the drag source drag event + */ + void dragDropEnd(DragSourceDragEvent e); +} // interface DragSourceListener diff --git a/libjava/java/awt/dnd/DragSourceMotionListener.java b/libjava/java/awt/dnd/DragSourceMotionListener.java new file mode 100644 index 00000000000..38d025c3a06 --- /dev/null +++ b/libjava/java/awt/dnd/DragSourceMotionListener.java @@ -0,0 +1,64 @@ +/* DragSourceMotionListener.java -- tracks motion in the drag source + 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.dnd; + +import java.util.EventListener; + +/** + * This is a listener for mouse motion in the drag source before the drop + * event occurs. You can also use a <code>DragSourceAdapter</code> to filter + * the events you are interested in. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see DragSourceDragEvent + * @see DragSource + * @see DragSourceListener + * @see DragSourceAdapter + * @since 1.4 + * @status updated to 1.4 + */ +public interface DragSourceMotionListener extends EventListener +{ + /** + * Called whenever the mouse is moved during a drag-and-drop operation. + * + * @param e the event + */ + void dragMouseMoved(DragSourceDragEvent e); +} // interface DragSourceMotionListener diff --git a/libjava/java/awt/dnd/DropTarget.java b/libjava/java/awt/dnd/DropTarget.java new file mode 100644 index 00000000000..9ae423438ec --- /dev/null +++ b/libjava/java/awt/dnd/DropTarget.java @@ -0,0 +1,40 @@ +/* DropTarget.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.dnd; +/** STUB CLASS ONLY */ +public class DropTarget {} diff --git a/libjava/java/awt/dnd/InvalidDnDOperationException.java b/libjava/java/awt/dnd/InvalidDnDOperationException.java new file mode 100644 index 00000000000..927ab140627 --- /dev/null +++ b/libjava/java/awt/dnd/InvalidDnDOperationException.java @@ -0,0 +1,73 @@ +/* InvalidDnDOperationException.java -- thrown when drag-and-drop fails + 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.dnd; + +/** + * Thrown when a method in the java.awt.dnd package is unable to perform a + * requested operation, usually because the underlying DnD system is in the + * wrong state. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ +public class InvalidDnDOperationException extends IllegalStateException +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = -6062568741193956678L; + + /** + * Create an exception without a message. + */ + public InvalidDnDOperationException() + { + } + + /** + * Create an exception with a message. + * + * @param s the message + */ + public InvalidDnDOperationException(String s) + { + super(s); + } +} // class InvalidDnDOperationException diff --git a/libjava/java/awt/dnd/peer/DragSourceContextPeer.java b/libjava/java/awt/dnd/peer/DragSourceContextPeer.java new file mode 100644 index 00000000000..da9e09833fd --- /dev/null +++ b/libjava/java/awt/dnd/peer/DragSourceContextPeer.java @@ -0,0 +1,55 @@ +/* DragSourceContextPeer.java -- interface for drag-and-drop peers + 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.dnd.peer; + +import java.awt.Cursor; +import java.awt.Image; +import java.awt.Point; +import java.awt.dnd.DragSourceContext; + +/** + * STUBBED + */ +public interface DragSourceContextPeer +{ + void startDrag(DragSourceContext context, Cursor c, Image i, Point p); + Cursor getCursor(); + void setCursor(Cursor c); + void transferablesFlavorsChanged(); +} // interface DragSourceContextPeer diff --git a/libjava/java/awt/event/AWTEventListener.java b/libjava/java/awt/event/AWTEventListener.java index ec9e4ffa27d..b735ce1197b 100644 --- a/libjava/java/awt/event/AWTEventListener.java +++ b/libjava/java/awt/event/AWTEventListener.java @@ -1,22 +1,64 @@ -/* Copyright (C) 2000 Free Software Foundation +/* AWTEventListener.java -- listen for all events in the AWT system + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.AWTEvent; +import java.util.EventListener; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This listener is for classes that need to listen to all events in the AWT + * system. In general, this should not be used except for classes like + * javax.accessibility or by event recorders. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see AWTEvent + * @see Toolkit#addAWTEventListener(AWTEventListener, long) + * @see Toolkit#removeAWTEventListener(AWTEventListener) + * @since 1.2 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - -public interface AWTEventListener extends java.util.EventListener +public interface AWTEventListener extends EventListener { - public void eventDispatched (AWTEvent e); -} + /** + * This method is called when any event in the AWT system is dispatched. + * + * @param event the AWTEvent that was dispatched + */ + void eventDispatched(AWTEvent event); +} // interface AWTEventListener diff --git a/libjava/java/awt/event/AWTEventListenerProxy.java b/libjava/java/awt/event/AWTEventListenerProxy.java new file mode 100644 index 00000000000..7572e701a65 --- /dev/null +++ b/libjava/java/awt/event/AWTEventListenerProxy.java @@ -0,0 +1,154 @@ +/* AWTEventListenerProxy.java -- wrapper/filter for AWTEventListener + 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.event; + +import java.awt.AWTEvent; +import java.util.EventListenerProxy; + +/** + * This class allows adding an AWTEventListener which only pays attention to + * a specific event mask. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Toolkit + * @see EventListenerProxy + * @since 1.4 + * @status updated to 1.4 + */ +public class AWTEventListenerProxy extends EventListenerProxy + implements AWTEventListener +{ + /** The event mask. */ + private final long mask; + + /** + * Construct an AWT Event Listener which only listens to events in the given + * mask, passing the work on to the real listener. + * + * @param eventMask the mask of events to listen to + * @param listener the wrapped listener + */ + public AWTEventListenerProxy(long eventMask, AWTEventListener listener) + { + super(listener); + mask = eventMask; + } + + /** + * Forwards events on to the delegate if they meet the event mask. + * + * @param event the property change event to filter + * @throws NullPointerException if the delegate this was created with is null + */ + public void eventDispatched(AWTEvent event) + { + int id = event == null ? 0 : event.getID(); + if (((mask & AWTEvent.ACTION_EVENT_MASK) != 0 + && event instanceof ActionEvent) + || ((mask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0 + && event instanceof AdjustmentEvent) + || ((mask & AWTEvent.COMPONENT_EVENT_MASK) != 0 + && event instanceof ComponentEvent + && (id >= ComponentEvent.COMPONENT_FIRST + && id <= ComponentEvent.COMPONENT_LAST)) + || ((mask & AWTEvent.CONTAINER_EVENT_MASK) != 0 + && event instanceof ContainerEvent) + || ((mask & AWTEvent.FOCUS_EVENT_MASK) != 0 + && event instanceof FocusEvent) + || ((mask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0 + && event instanceof HierarchyEvent + && (id == HierarchyEvent.ANCESTOR_MOVED + || id == HierarchyEvent.ANCESTOR_RESIZED)) + || ((mask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 + && event instanceof HierarchyEvent + && id == HierarchyEvent.HIERARCHY_CHANGED) + || ((mask & AWTEvent.INPUT_METHOD_EVENT_MASK) != 0 + && event instanceof InputMethodEvent) + || ((mask & AWTEvent.INVOCATION_EVENT_MASK) != 0 + && event instanceof InvocationEvent) + || ((mask & AWTEvent.ITEM_EVENT_MASK) != 0 + && event instanceof ItemEvent) + || ((mask & AWTEvent.KEY_EVENT_MASK) != 0 + && event instanceof KeyEvent) + || ((mask & AWTEvent.MOUSE_EVENT_MASK) != 0 + && event instanceof MouseEvent + && (id == MouseEvent.MOUSE_PRESSED + || id == MouseEvent.MOUSE_RELEASED + || id == MouseEvent.MOUSE_CLICKED + || id == MouseEvent.MOUSE_ENTERED + || id == MouseEvent.MOUSE_EXITED)) + || ((mask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0 + && event instanceof MouseEvent + && (id == MouseEvent.MOUSE_MOVED + || id == MouseEvent.MOUSE_DRAGGED)) + || ((mask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0 + && event instanceof MouseWheelEvent) + || ((mask & AWTEvent.PAINT_EVENT_MASK) != 0 + && event instanceof PaintEvent) + || ((mask & AWTEvent.TEXT_EVENT_MASK) != 0 + && event instanceof TextEvent) + || ((mask & AWTEvent.WINDOW_EVENT_MASK) != 0 + && event instanceof WindowEvent + && (id == WindowEvent.WINDOW_OPENED + || id == WindowEvent.WINDOW_CLOSING + || id == WindowEvent.WINDOW_CLOSED + || id == WindowEvent.WINDOW_ICONIFIED + || id == WindowEvent.WINDOW_DEICONIFIED + || id == WindowEvent.WINDOW_ACTIVATED + || id == WindowEvent.WINDOW_DEACTIVATED)) + || ((mask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0 + && event instanceof WindowEvent + && (id == WindowEvent.WINDOW_GAINED_FOCUS + || id == WindowEvent.WINDOW_LOST_FOCUS)) + || ((mask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0 + && event instanceof WindowEvent + && id == WindowEvent.WINDOW_STATE_CHANGED)) + ((AWTEventListener) getListener()).eventDispatched(event); + } + + /** + * This returns the event mask associated with this listener. + * + * @return the event mask + */ + public long getEventMask() + { + return mask; + } +} // class AWTEventListenerProxy diff --git a/libjava/java/awt/event/ActionEvent.java b/libjava/java/awt/event/ActionEvent.java index 891b6bd4e51..4f77fe06eea 100644 --- a/libjava/java/awt/event/ActionEvent.java +++ b/libjava/java/awt/event/ActionEvent.java @@ -1,66 +1,226 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* ActionEvent.java -- an action has been triggered + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; -/* Status: Believed complete and correct to JDK 1.2. */ +import java.awt.AWTEvent; +import java.awt.EventQueue; +/** + * This event is generated when an action on a component (such as a + * button press) occurs. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ActionListener + * @since 1.1 + * @status updated to 1.4 + */ public class ActionEvent extends AWTEvent { + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = -7671078796273832149L; + + /** Bit mask indicating the shift key was pressed. */ + public static final int SHIFT_MASK = InputEvent.SHIFT_MASK; + + /** Bit mask indicating the control key was pressed. */ + public static final int CTRL_MASK = InputEvent.CTRL_MASK; + + /** Bit mask indicating the that meta key was pressed. */ + public static final int META_MASK = InputEvent.META_MASK; + + /** Bit mask indicating that the alt key was pressed. */ + public static final int ALT_MASK = InputEvent.ALT_MASK; + + /** The first id number in the range of action id's. */ public static final int ACTION_FIRST = 1001; + + /** The last id number in the range of action id's. */ public static final int ACTION_LAST = 1001; + + /** An event id indicating that an action has occurred. */ public static final int ACTION_PERFORMED = 1001; - public static final int ALT_MASK = 8; - public static final int CTRL_MASK = 2; - public static final int META_MASK = 4; - public static final int SHIFT_MASK = 1; - String cmd; - int modifiers; + /** + * A nonlocalized string that gives more specific details of the event cause. + * + * @see #getActionCommand() + * @serial the command for this event + */ + private final String actionCommand; + + /** + * The bitmask of the modifiers that were pressed during the action. + * + * @see #getModifiers() + * @serial modifiers for this event + */ + private final int modifiers; + + /** + * The timestamp of this event; usually the same as the underlying input + * event. + * + * @see #getWhen() + * @serial the timestamp of the event + * @since 1.4 + */ + private final long when; - public ActionEvent (Object source, int id, String command) + /** + * Initializes a new instance of <code>ActionEvent</code> with the + * specified source, id, and command. Note that an invalid id leads to + * unspecified results. + * + * @param source the event source + * @param id the event id + * @param command the command string for this action + * @throws IllegalArgumentException if source is null + */ + public ActionEvent(Object source, int id, String command) { - super(source, id); - cmd = command; + this(source, id, command, EventQueue.getMostRecentEventTime(), 0); + } + + /** + * Initializes a new instance of <code>ActionEvent</code> with the + * specified source, id, command, and modifiers. Note that an invalid id + * leads to unspecified results. + * + * @param source the event source + * @param id the event id + * @param command the command string for this action + * @param modifiers the bitwise or of modifier keys down during the action + * @throws IllegalArgumentException if source is null + */ + public ActionEvent(Object source, int id, String command, int modifiers) + { + this(source, id, command, EventQueue.getMostRecentEventTime(), modifiers); } - public ActionEvent (Object source, int id, String command, int modifiers) + /** + * Initializes a new instance of <code>ActionEvent</code> with the + * specified source, id, command, and modifiers, and timestamp. Note that + * an invalid id leads to unspecified results. + * + * @param source the event source + * @param id the event id + * @param command the command string for this action + * @param when the timestamp of the event + * @param modifiers the bitwise or of modifier keys down during the action + * @throws IllegalArgumentException if source is null + * @since 1.4 + */ + public ActionEvent(Object source, int id, String command, long when, + int modifiers) { super(source, id); - cmd = command; + actionCommand = command; + this.when = when; this.modifiers = modifiers; } - public String getActionCommand () + /** + * Returns the command string associated with this action. + * + * @return the command string associated with this action + */ + public String getActionCommand() + { + return actionCommand; + } + + /** + * Gets the timestamp of when this action took place. Usually, this + * corresponds to the timestamp of the underlying InputEvent. + * + * @return the timestamp of this action + * @since 1.4 + */ + public long getWhen() { - return cmd; + return when; } - public int getModifiers () + /** + * Returns the keys held down during the action. This value will be a + * combination of the bit mask constants defined in this class, or 0 if no + * modifiers were pressed. + * + * @return the modifier bits + */ + public int getModifiers() { return modifiers; } - public String paramString () + /** + * Returns a string that identifies the action event. This is in the format + * <code>"ACTION_PERFORMED,cmd=" + getActionCommand() + ",when=" + getWhen() + * + ",modifiers=" + <modifier string></code>, where the modifier + * string is in the order "Meta", "Ctrl", "Alt", "Shift", "Alt Graph", and + * "Button1", separated by '+', according to the bits set in getModifiers(). + * + * @return a string identifying the event + */ + public String paramString() { - String r; - switch (id) - { - case ACTION_PERFORMED: - r = "ACTION_PERFORMED"; - break; - default: - r = "unknown type"; - break; - } - - r += ",cmd=" + cmd; - return r; + StringBuffer s = new StringBuffer(id == ACTION_PERFORMED + ? "ACTION_PERFORMED,cmd=" + : "unknown type,cmd="); + s.append(actionCommand).append(",when=").append(when).append("modifiers"); + int len = s.length(); + s.setLength(len + 1); + if ((modifiers & META_MASK) != 0) + s.append("+Meta"); + if ((modifiers & CTRL_MASK) != 0) + s.append("+Ctrl"); + if ((modifiers & ALT_MASK) != 0) + s.append("+Alt"); + if ((modifiers & SHIFT_MASK) != 0) + s.append("+Shift"); + if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) + s.append("+Alt Graph"); + if ((modifiers & InputEvent.BUTTON1_MASK) != 0) + s.append("+Button1"); + s.setCharAt(len, '='); + return s.toString(); } -} +} // class ActionEvent diff --git a/libjava/java/awt/event/ActionListener.java b/libjava/java/awt/event/ActionListener.java index 7fb359ff076..40112080e53 100644 --- a/libjava/java/awt/event/ActionListener.java +++ b/libjava/java/awt/event/ActionListener.java @@ -1,21 +1,59 @@ -/* Copyright (C) 1999 Free Software Foundation +/* ActionListener.java -- listens for action events + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Per Bothner <bothner@cygnus.com> - * @date Fenruary, 1999. + * This interface is for classes that listen for action events. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ActionEvent + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct. */ - -public interface ActionListener extends java.util.EventListener +public interface ActionListener extends EventListener { - public void actionPerformed (ActionEvent e); -} + /** + * This method is invoked when an action occurs. + * + * @param event the <code>ActionEvent</code> that occurred + */ + void actionPerformed(ActionEvent e); +} // interface ActionListener diff --git a/libjava/java/awt/event/AdjustmentEvent.java b/libjava/java/awt/event/AdjustmentEvent.java index 9da9993a794..48b208b5d86 100644 --- a/libjava/java/awt/event/AdjustmentEvent.java +++ b/libjava/java/awt/event/AdjustmentEvent.java @@ -1,95 +1,222 @@ -/* Copyright (C) 2000 Free Software Foundation +/* AdjustmentEvent.java -- an adjustable value was changed + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.Adjustable; +import java.awt.AWTEvent; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class represents an event that is generated when an adjustable + * value is changed. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see Adjustable + * @see AdjustmentListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public class AdjustmentEvent extends AWTEvent { + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = 5700290645205279921L; + + /** This is the first id in the range of ids used by adjustment events. */ public static final int ADJUSTMENT_FIRST = 601; + + /** This is the last id in the range of ids used by adjustment events. */ public static final int ADJUSTMENT_LAST = 601; + + /** This is the id indicating an adjustment value changed. */ public static final int ADJUSTMENT_VALUE_CHANGED = 601; + + /** Adjustment type for unit increments. */ + public static final int UNIT_INCREMENT = 1; + + /** Adjustment type for unit decrements. */ + public static final int UNIT_DECREMENT = 2; + + /** Adjustment type for block decrements. */ public static final int BLOCK_DECREMENT = 3; + + /** Adjustment type for block increments. */ public static final int BLOCK_INCREMENT = 4; + + /** Adjustment type for tracking adjustments. */ public static final int TRACK = 5; - public static final int UNIT_DECREMENT = 2; - public static final int UNIT_INCREMENT = 1; - public AdjustmentEvent (Adjustable source, int id, int type, int value) + /** + * The adjustable object that caused the event. + * + * @see #getAdjustable() + * @serial the cause + */ + private final Adjustable adjustable; + + /** + * The type of adjustment, one of {@link #UNIT_INCREMENT}, + * {@link #UNIT_DECREMENT}, {@link #BLOCK_INCREMENT}, + * {@link #BLOCK_DECREMENT}, or {@link #TRACK}. + * + * @see #getAdjustmentType() + * @serial the adjustment type + */ + private final int adjustmentType; + + /** + * The new value of the adjustable; it should be in the range of the + * adjustable cause. + * + * @see #getValue() + * @serial the adjustment value + */ + private final int value; + + /** + * True if this is in a series of multiple adjustment events. + * + * @see #getValueIsAdjusting() + * @serial true if this is not the last adjustment + * @since 1.4 + */ + private final boolean isAdjusting; + + /** + * Initializes an instance of <code>AdjustmentEvent</code> with the + * specified source, id, type, and value. Note that an invalid id leads to + * unspecified results. + * + * @param source the source of the event + * @param id the event id + * @param type the event type, one of the constants of this class + * @param value the value of the adjustment + * @throws IllegalArgumentException if source is null + */ + public AdjustmentEvent(Adjustable source, int id, int type, int value) { - super (source, id); - this.adjType = type; - this.value = value; + this(source, id, type, value, false); } - public Adjustable getAdjustable () + /** + * Initializes an instance of <code>AdjustmentEvent</code> with the + * specified source, id, type, and value. Note that an invalid id leads to + * unspecified results. + * + * @param source the source of the event + * @param id the event id + * @param type the event type, one of the constants of this class + * @param value the value of the adjustment + * @param isAdjusting if this event is in a chain of adjustments + * @throws IllegalArgumentException if source is null + * @since 1.4 + */ + public AdjustmentEvent(Adjustable source, int id, int type, int value, + boolean isAdjusting) { - return (Adjustable) source; + super(source, id); + this.adjustmentType = type; + this.value = value; + adjustable = source; + this.isAdjusting = isAdjusting; } - public int getAdjustmentType () + /** + * This method returns the source of the event as an <code>Adjustable</code>. + * + * @return the <code>Adjustable</code> source of the event + */ + public Adjustable getAdjustable() { - return adjType; + return adjustable; } - public int getValue () + /** + * Returns the new value of the adjustable object. + * + * @return the value of the event + */ + public int getValue() { return value; } - public String paramString () + /** + * Returns the type of the event, which will be one of + * {@link #UNIT_INCREMENT}, {@link #UNIT_DECREMENT}, + * {@link #BLOCK_INCREMENT}, {@link #BLOCK_DECREMENT}, or {@link #TRACK}. + * + * @return the type of the event + */ + public int getAdjustmentType() { - String r; - switch (id) - { - case ADJUSTMENT_VALUE_CHANGED: - r = "ADJUSTMENT_VALUE_CHANGED"; - break; - default: - r = "unknown id"; - break; - } - - r += ",adjType="; - - switch (adjType) - { - case BLOCK_DECREMENT: - r += "BLOCK_DECREMENT"; - break; - case BLOCK_INCREMENT: - r += "BLOCK_INCREMENT"; - break; - case TRACK: - r += "TRACK"; - break; - case UNIT_DECREMENT: - r += "UNIT_DECREMENT"; - break; - case UNIT_INCREMENT: - r += "UNIT_INCREMENT"; - break; - default: - r += "unknown type"; - break; - } - - r += ",value=" + value; - return r; + return adjustmentType; } - private int adjType; - private int value; -} + /** + * Test if this event is part of a sequence of multiple adjustements. + * + * @return true if this is not the last adjustment + * @since 1.4 + */ + public boolean getValueIsAdjusting() + { + return isAdjusting; + } + + /** + * Returns a string that describes the event. This is in the format + * <code>"ADJUSTMENT_VALUE_CHANGED,adjType=" + <type> + ",value=" + * + getValue() + ",isAdjusting=" + getValueIsAdjusting()</code>, where + * type is the name of the constant returned by getAdjustmentType(). + * + * @return a string that describes the event + */ + public String paramString() + { + return (id == ADJUSTMENT_VALUE_CHANGED + ? "ADJUSTMENT_VALUE_CHANGED,adjType=" : "unknown type,adjType=") + + (adjustmentType == UNIT_INCREMENT ? "UNIT_INCREMENT,value=" + : adjustmentType == UNIT_DECREMENT ? "UNIT_DECREMENT,value=" + : adjustmentType == BLOCK_INCREMENT ? "BLOCK_INCREMENT,value=" + : adjustmentType == BLOCK_DECREMENT ? "BLOCK_DECREMENT,value=" + : adjustmentType == TRACK ? "TRACK,value=" : "unknown type,value=") + + value + ",isAdjusting=" + isAdjusting; + } +} // class AdjustmentEvent diff --git a/libjava/java/awt/event/AdjustmentListener.java b/libjava/java/awt/event/AdjustmentListener.java index 1d103328c63..050528b00c9 100644 --- a/libjava/java/awt/event/AdjustmentListener.java +++ b/libjava/java/awt/event/AdjustmentListener.java @@ -1,21 +1,58 @@ -/* Copyright (C) 2000 Free Software Foundation +/* AdjustmentListener.java -- listen for adjustment events + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * Interface for classes that listen for adjustment events. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - -public interface AdjustmentListener extends java.util.EventListener +public interface AdjustmentListener extends EventListener { - public void adjustmentValueChanged (AdjustmentEvent e); -} + /** + * This method is called when an adjustable value changes. + * + * @param event the <code>AdjustmentEvent</code> that occurred + */ + void adjustmentValueChanged(AdjustmentEvent event); +} // interface AdjustmentListener diff --git a/libjava/java/awt/event/ComponentAdapter.java b/libjava/java/awt/event/ComponentAdapter.java index 0faba3d6eff..a8d6044fa2e 100644 --- a/libjava/java/awt/event/ComponentAdapter.java +++ b/libjava/java/awt/event/ComponentAdapter.java @@ -1,35 +1,97 @@ -/* Copyright (C) 2000 Free Software Foundation +/* ComponentAdapter.java -- convenience class for writing component listeners + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class implements <code>ComponentListener</code> and implements + * all methods with empty bodies. This allows a listener interested in + * implementing only a subset of the <code>ComponentListener</code> + * interface to extend this class and override only the desired methods. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ComponentEvent + * @see ComponentListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public abstract class ComponentAdapter implements ComponentListener { - public void componentHidden (ComponentEvent e) + /** + * Do nothing default constructor for subclasses. + */ + public ComponentAdapter() + { + } + + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void componentResized(ComponentEvent event) { } - public void componentMoved (ComponentEvent e) + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void componentMoved(ComponentEvent event) { } - public void componentResized (ComponentEvent e) + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void componentShown(ComponentEvent event) { } - public void componentShown (ComponentEvent e) + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void componentHidden(ComponentEvent event) { } -} +} // class ComponentAdapter diff --git a/libjava/java/awt/event/ComponentEvent.java b/libjava/java/awt/event/ComponentEvent.java index bdf80ce2f35..0f208151d3c 100644 --- a/libjava/java/awt/event/ComponentEvent.java +++ b/libjava/java/awt/event/ComponentEvent.java @@ -1,61 +1,137 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* ComponentEvent.java -- notification of events for components + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.AWTEvent; +import java.awt.Component; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class is for events generated when a component is moved, resized, + * hidden, or shown. These events normally do not need to be handled by the + * application, since the AWT system automatically takes care of them. This + * is also the superclass for other events on components, but + * ComponentListeners ignore such subclasses. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ComponentAdapter + * @see ComponentListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public class ComponentEvent extends AWTEvent { + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = 8101406823902992965L; + + /** This is the first id in the range of ids used by this class. */ public static final int COMPONENT_FIRST = 100; - public static final int COMPONENT_HIDDEN = 103; + + /** This is the last id in the range of ids used by this class. */ public static final int COMPONENT_LAST = 103; + + /** This id indicates that a component was moved. */ public static final int COMPONENT_MOVED = 100; + + /** This id indicates that a component was resized. */ public static final int COMPONENT_RESIZED = 101; + + /** This id indicates that a component was shown. */ public static final int COMPONENT_SHOWN = 102; - public ComponentEvent (Component source, int id) + /** This id indicates that a component was hidden. */ + public static final int COMPONENT_HIDDEN = 103; + + /** + * Initializes a new instance of <code>ComponentEvent</code> with the + * specified source and id. Note that an invalid id leads to unspecified + * results. + * + * @param source the source of the event + * @param id the event id + * @throws IllegalArgumentException if source is null + */ + public ComponentEvent(Component source, int id) { super(source, id); } - public Component getComponent () + /** + * This method returns the event source as a <code>Component</code>. If the + * source has subsequently been modified to a non-Component, this returns + * null. + * + * @return the event source as a <code>Component</code>, or null + */ + public Component getComponent() { - return (Component) source; + return source instanceof Component ? (Component) source : null; } - public String paramString () + /** + * This method returns a string identifying this event. This is the field + * name of the id type, and for COMPONENT_MOVED or COMPONENT_RESIZED, the + * new bounding box of the component. + * + * @return a string identifying this event + */ + public String paramString() { - String r; + // Unlike Sun, we don't throw NullPointerException or ClassCastException + // when source was illegally changed. switch (id) { - case COMPONENT_HIDDEN: - r = "COMPONENT_HIDDEN"; - break; - case COMPONENT_MOVED: - r = "COMPONENT_MOVED"; - break; - case COMPONENT_RESIZED: - r = "COMPONENT_RESIZED"; - break; - case COMPONENT_SHOWN: - r = "COMPONENT_SHOWN"; - break; - default: - r = "unknown id"; - break; - } - return r; + case COMPONENT_MOVED: + return "COMPONENT_MOVED " + + (source instanceof Component + ? ((Component) source).getBounds() : (Object) ""); + case COMPONENT_RESIZED: + return "COMPONENT_RESIZED " + + (source instanceof Component + ? ((Component) source).getBounds() : (Object) ""); + case COMPONENT_SHOWN: + return "COMPONENT_SHOWN"; + case COMPONENT_HIDDEN: + return "COMPONENT_HIDDEN"; + default: + return "unknown type"; + } } -} +} // class ComponentEvent diff --git a/libjava/java/awt/event/ComponentListener.java b/libjava/java/awt/event/ComponentListener.java index 3302cf2a713..fbfc3335cf9 100644 --- a/libjava/java/awt/event/ComponentListener.java +++ b/libjava/java/awt/event/ComponentListener.java @@ -1,24 +1,84 @@ -/* Copyright (C) 2000 Free Software Foundation +/* ComponentListener.java -- receive all events for a component + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This interface is for classes that receive all events from a component. + * Normally it is not necessary to process these events since the AWT + * handles them internally, taking all appropriate actions. To watch a subset + * of these events, use a ComponentAdapter. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ComponentAdapter + * @see ComponentEvent + * @since 1.1 + * @status updated to 1.4 */ +public interface ComponentListener extends EventListener +{ + /** + * This method is called when the component is resized. + * + * @param event the <code>ComponentEvent</code> indicating the resize + */ + void componentResized(ComponentEvent event); -/* Status: Believed complete and correct to JDK 1.2. */ + /** + * This method is called when the component is moved. + * + * @param event the <code>ComponentEvent</code> indicating the move + */ + void componentMoved(ComponentEvent event); -public interface ComponentListener extends java.util.EventListener -{ - public void componentHidden (ComponentEvent e); - public void componentMoved (ComponentEvent e); - public void componentResized (ComponentEvent e); - public void componentShown (ComponentEvent e); -} + /** + * This method is called when the component is made visible. + * + * @param event the <code>ComponentEvent</code> indicating the visibility + */ + void componentShown(ComponentEvent event); + + /** + * This method is called when the component is hidden. + * + * @param event the <code>ComponentEvent</code> indicating the visibility + */ + void componentHidden(ComponentEvent event); +} // interface ComponentListener diff --git a/libjava/java/awt/event/ContainerAdapter.java b/libjava/java/awt/event/ContainerAdapter.java index 18c12a5f19b..b4c97be47b0 100644 --- a/libjava/java/awt/event/ContainerAdapter.java +++ b/libjava/java/awt/event/ContainerAdapter.java @@ -1,27 +1,79 @@ -/* Copyright (C) 2000 Free Software Foundation +/* ContainerAdapter.java -- convenience class for writing container listeners + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class implements <code>ContainerListener</code> and implements + * all methods with empty bodies. This allows a listener interested in + * implementing only a subset of the <code>ContainerListener</code> + * interface to extend this class and override only the desired methods. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ContainerEvent + * @see ContainerListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public abstract class ContainerAdapter implements ContainerListener { - public void componentAdded (ContainerEvent e) + /** + * Do nothing default constructor for subclasses. + */ + public ContainerAdapter() + { + } + + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void componentAdded(ContainerEvent event) { } - public void componentRemoved (ContainerEvent e) + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void componentRemoved(ContainerEvent event) { } -} +} // class ContainerAdapter diff --git a/libjava/java/awt/event/ContainerEvent.java b/libjava/java/awt/event/ContainerEvent.java index 99964141857..fe087d2e507 100644 --- a/libjava/java/awt/event/ContainerEvent.java +++ b/libjava/java/awt/event/ContainerEvent.java @@ -1,64 +1,135 @@ -/* Copyright (C) 2000, 2001 Free Software Foundation +/* ContainerEvent.java -- components added/removed from a container + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.Component; +import java.awt.Container; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This event is generated when a component is added or removed from a + * container. Applications do not ordinarily need to handle these events + * since the AWT system handles them internally. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ContainerAdapter + * @see ContainerListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public class ContainerEvent extends ComponentEvent { - public static final int COMPONENT_ADDED = 300; - public static final int COMPONENT_REMOVED = 301; + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = -4114942250539772041L; + + /** This is the first id in the id range used by this class. */ public static final int CONTAINER_FIRST = 300; + + /** This is the last id in the id range used by this class. */ public static final int CONTAINER_LAST = 301; - /** @specnote In JDK1.2 and 1.3, source is a Component. */ - public ContainerEvent (Component source, int id, Component child) + /** This id indicates a component was added to the container. */ + public static final int COMPONENT_ADDED = 300; + + /** This id indicates a component was removed from the container. */ + public static final int COMPONENT_REMOVED = 301; + + /** + * The non-null child component that was added or removed. + * + * @serial the child component that changed + */ + private final Component child; + + /** + * Initializes a new instance of <code>ContainerEvent</code> with the + * specified source and id. Additionally, the affected child component + * is also passed as a parameter. Note that an invalid id leads to + * unspecified results. + * + * @param source the source container of the event + * @param id the event id + * @param child the child component affected by this event + * @throws IllegalArgumentException if source is null + */ + public ContainerEvent(Component source, int id, Component child) { - super (source, id); + super(source, id); this.child = child; } - public Component getChild () + /** + * Returns the source of this event as a <code>Container</code>. + * + * @return the source of the event + * @throws ClassCastException if the source is changed to a non-Container + */ + public Container getContainer() { - return child; + return (Container) source; } - public Container getContainer () + /** + * This method returns the child object that was added or removed from + * the container. + * + * @return the child object added or removed + */ + public Component getChild() { - return (Container) source; + return child; } - public String paramString () + /** + * This method returns a string identifying this event. It is formatted as: + * <code>(getID() == COMPONENT_ADDED ? "COMPONENT_ADDED" + * : "COMPONENT_REMOVED") + ",child=" + getChild().getName()</code>. + * + * @return a string identifying this event + */ + public String paramString() { - String r; - switch (id) - { - case COMPONENT_ADDED: - r = "COMPONENT_ADDED"; - break; - case COMPONENT_REMOVED: - r = "COMPONENT_REMOVED"; - break; - default: - r = "unknown id"; - break; - - } - r += ",child=" + child; - return r; + // Unlike Sun, we don't throw NullPointerException if child is illegally + // null. + return (id == COMPONENT_ADDED ? "COMPONENT_ADDED,child=" + : id == COMPONENT_REMOVED ? "COMPONENT_REMOVED,child=" + : "unknown type,child=") + (child == null ? "" : child.getName()); } - - private Component child; -} +} // class ContainerEvent diff --git a/libjava/java/awt/event/ContainerListener.java b/libjava/java/awt/event/ContainerListener.java index 65acba4a756..a937e1550aa 100644 --- a/libjava/java/awt/event/ContainerListener.java +++ b/libjava/java/awt/event/ContainerListener.java @@ -1,22 +1,70 @@ -/* Copyright (C) 2000 Free Software Foundation +/* ContainerListener.java -- listen for container events + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This interface is for classes that wish to listen for all events from + * container objects. This is normally not necessary since the AWT system + * listens for and processes these events. To watch a subset of these events, + * use a ContainerAdapter. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ContainerAdapter + * @see ContainerEvent + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - -public interface ContainerListener extends java.util.EventListener +public interface ContainerListener extends EventListener { - public void componentAdded (ContainerEvent e); - public void componentRemoved (ContainerEvent e); -} + /** + * This method is called when a component is added to the container. + * + * @param event the <code>ContainerEvent</code> indicating component addition + */ + void componentAdded(ContainerEvent event); + + /** + * This method is called when a component is removed from the container. + * + * @param event the <code>ContainerEvent</code> indicating component removal + */ + void componentRemoved(ContainerEvent event); +} // interface ContainerListener diff --git a/libjava/java/awt/event/FocusAdapter.java b/libjava/java/awt/event/FocusAdapter.java index f8419d92efa..721878efccb 100644 --- a/libjava/java/awt/event/FocusAdapter.java +++ b/libjava/java/awt/event/FocusAdapter.java @@ -1,27 +1,79 @@ -/* Copyright (C) 2000 Free Software Foundation +/* FocusAdapter.java -- convenience class for writing focus listeners + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class implements <code>FocusListener</code> and implements all + * methods with empty bodies. This allows a listener interested in + * implementing only a subset of the <code>FocusListener</code> interface to + * extend this class and override only the desired methods. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see FocusEvent + * @see FocusListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public abstract class FocusAdapter implements FocusListener { - public void focusGained (FocusEvent e) + /** + * Do nothing default constructor for subclasses. + */ + public FocusAdapter() + { + } + + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void focusGained(FocusEvent event) { } - public void focusLost (FocusEvent e) + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void focusLost(FocusEvent event) { } -} +} // class FocusAdapter diff --git a/libjava/java/awt/event/FocusEvent.java b/libjava/java/awt/event/FocusEvent.java index d4759275a62..9f2b98f762a 100644 --- a/libjava/java/awt/event/FocusEvent.java +++ b/libjava/java/awt/event/FocusEvent.java @@ -1,63 +1,181 @@ -/* Copyright (C) 2000 Free Software Foundation +/* FocusEvent.java -- generated for a focus change + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.Component; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class represents an event generated when a focus change occurs for a + * component. There are both temporary changes, such as when focus is stolen + * during a sroll then returned, and permanent changes, such as when the user + * TABs through focusable components. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see FocusAdapter + * @see FocusListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public class FocusEvent extends ComponentEvent { + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = 523753786457416396L; + + /** This is the first id in the range of ids used by this class. */ public static final int FOCUS_FIRST = 1004; - public static final int FOCUS_GAINED = 1004; + + /** This is the last id in the range of ids used by this class. */ public static final int FOCUS_LAST = 1005; + + /** This is the event id for a focus gained event. */ + public static final int FOCUS_GAINED = 1004; + + /** This is the event id for a focus lost event. */ public static final int FOCUS_LOST = 1005; - public FocusEvent (Component source, int id) + /** + * Indicates whether or not the focus change is temporary. + * + * @see #isTemporary() + * @serial true if the focus change is temporary + */ + private final boolean temporary; + + /** + * The other component which is giving up or stealing focus from this + * component, if known. + * + * @see #getOppositeComponent() + * @serial the component with the opposite focus event, or null + * @since 1.4 + */ + private final Component opposite; + + /** + * Initializes a new instance of <code>FocusEvent</code> with the + * specified source, id, temporary status, and opposite counterpart. Note + * that an invalid id leads to unspecified results. + * + * @param source the component that is gaining or losing focus + * @param id the event id + * @param temporary true if the focus change is temporary + * @param opposite the component receiving the opposite focus event, or null + * @throws IllegalArgumentException if source is null + */ + public FocusEvent(Component source, int id, boolean temporary, + Component opposite) { - super (source, id); - this.temporary = false; + super(source, id); + this.temporary = temporary; + this.opposite = opposite; } - public FocusEvent (Component source, int id, boolean temporary) + /** + * Initializes a new instance of <code>FocusEvent</code> with the + * specified source, id, and temporary status. Note that an invalid id + * leads to unspecified results. + * + * @param source the component that is gaining or losing focus + * @param id the event id + * @param temporary true if the focus change is temporary + * @throws IllegalArgumentException if source is null + */ + public FocusEvent(Component source, int id, boolean temporary) { - super (source, id); - this.temporary = temporary; + this(source, id, temporary, null); } - public boolean isTemporary () + /** + * Initializes a new instance of <code>FocusEvent</code> with the + * specified source and id. Note that an invalid id leads to unspecified + * results. + * + * @param source the component that is gaining or losing focus + * @param id the event id + * @throws IllegalArgumentException if source is null + */ + public FocusEvent(Component source, int id) + { + this(source, id, false, null); + } + + /** + * This method tests whether or not the focus change is temporary or + * permanent. + * + * @return true if the focus change is temporary + */ + public boolean isTemporary() { return temporary; } - public String paramString () + /** + * Returns the component which received the opposite focus event. If this + * component gained focus, the opposite lost focus; likewise if this + * component is giving up focus, the opposite is gaining it. If this + * information is unknown, perhaps because the opposite is a native + * application, this returns null. + * + * @return the component with the focus opposite, or null + * @since 1.4 + */ + public Component getOppositeComponent() { - String r = ""; - switch (id) - { - case FOCUS_GAINED: - r += "FOCUS_GAINED"; - break; - case FOCUS_LOST: - r += "FOCUS_LOST"; - break; - default: - r += "unknown id"; - break; - } - r += (temporary ? "temporary" : "permanent"); - return r; + return opposite; } - private boolean temporary; -} + /** + * Returns a string identifying this event. This is formatted as: + * <code>(getID() == FOCUS_GAINED ? "FOCUS_GAINED" : "FOCUS_LOST") + * + (isTemporary() ? ",temporary," : ",permanent,") + "opposite=" + * + getOppositeComponent()</code>. + * + * @return a string identifying this event + */ + public String paramString() + { + return (id == FOCUS_GAINED ? "FOCUS_GAINED" + : id == FOCUS_LOST ? "FOCUS_LOST" : "unknown type") + + (temporary ? ",temporary,opposite=" : ",permanent,opposite=") + + opposite; + } +} // class FocusEvent diff --git a/libjava/java/awt/event/FocusListener.java b/libjava/java/awt/event/FocusListener.java index f4167de6c01..e372843cb2a 100644 --- a/libjava/java/awt/event/FocusListener.java +++ b/libjava/java/awt/event/FocusListener.java @@ -1,22 +1,69 @@ -/* Copyright (C) 2000 Free Software Foundation +/* FocusListener.java -- listen for focus changes + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This interface is for classes that wish to be notified of changes of + * keyboard focus for a component. To watch a subset of these events, use a + * FocusAdapter. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see FocusAdapter + * @see FocusEvent + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - -public interface FocusListener extends java.util.EventListener +public interface FocusListener extends EventListener { - public void focusGained (FocusEvent e); - public void focusLost (FocusEvent e); -} + /** + * This method is called when a component gains the keyboard focus. + * + * @param event the <code>FocusEvent</code> indicating that focus was gained + */ + void focusGained(FocusEvent event); + + /** + * This method is invoked when a component loses the keyboard focus. + * + * @param event the <code>FocusEvent</code> indicating that focus was lost + */ + void focusLost(FocusEvent event); +} // interface FocusListener diff --git a/libjava/java/awt/event/HierarchyBoundsAdapter.java b/libjava/java/awt/event/HierarchyBoundsAdapter.java index d9cfbbabef9..5f807b38c9e 100644 --- a/libjava/java/awt/event/HierarchyBoundsAdapter.java +++ b/libjava/java/awt/event/HierarchyBoundsAdapter.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* HierarchyBoundsAdapter.java -- convenience class for writing listeners + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,19 +38,41 @@ exception statement from your version. */ package java.awt.event; /** - * @since 1.3 + * This class implements <code>HierarchyBoundsListener</code> and implements + * all methods with empty bodies. This allows a listener interested in + * implementing only a subset of the <code>HierarchyBoundsListener</code> + * interface to extend this class and override only the desired methods. + * * @author Bryce McKinlay + * @see HierarchyBoundsListener + * @see HierarchyEvent + * @since 1.3 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct. */ - public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener { + /** + * Do nothing default constructor for subclasses. + */ + public HierarchyBoundsAdapter() + { + } + + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ public void ancestorMoved(HierarchyEvent e) { } - + + /** + * Implements this method from the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ public void ancestorResized(HierarchyEvent e) { } -} +} // class HierarchyBoundsAdapter diff --git a/libjava/java/awt/event/HierarchyBoundsListener.java b/libjava/java/awt/event/HierarchyBoundsListener.java index b45423ceded..4d74f0d8d34 100644 --- a/libjava/java/awt/event/HierarchyBoundsListener.java +++ b/libjava/java/awt/event/HierarchyBoundsListener.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* HierarchyBoundsListener.java -- listens to bounds changes of parents + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,17 +35,36 @@ 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.event; +import java.util.EventListener; + /** - * @since 1.3 + * This listens for changes in an ancestors size or location. Normally it is + * not necessary to process these events since the AWT handles them + * internally, taking all appropriate actions. To watch a subset of these + * events, use a HierarchyBoundsAdapter. + * * @author Bryce McKinlay + * @see HierarchyBoundsAdapter + * @see HierarchyEvent + * @since 1.3 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct. */ - -public interface HierarchyBoundsListener extends java.util.EventListener +public interface HierarchyBoundsListener extends EventListener { - public void ancestorMoved(HierarchyEvent e); - public void ancestorResized(HierarchyEvent e); -} + /** + * Called when an ancestor component of the source is moved. + * + * @param e the event describing the ancestor's motion + */ + void ancestorMoved(HierarchyEvent e); + + /** + * Called when an ancestor component is resized. + * + * @param e the event describing the ancestor's resizing + */ + void ancestorResized(HierarchyEvent e); +} // interface HierarchyBoundsListener diff --git a/libjava/java/awt/event/HierarchyEvent.java b/libjava/java/awt/event/HierarchyEvent.java index 6858989e237..fcb7db951d2 100644 --- a/libjava/java/awt/event/HierarchyEvent.java +++ b/libjava/java/awt/event/HierarchyEvent.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* HierarchyEvent.java -- generated for a change in hierarchy + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -38,87 +39,211 @@ package java.awt.event; import java.awt.*; /** - * @since 1.3 + * This class represents an event generated for an ancestor component which + * may affect this component. These events normally do not need to be handled + * by the application, since the AWT system automatically takes care of them. + * + * <p>There are two types of hierarchy events. The first type is handled by + * HierarchyListener, and includes addition or removal of an ancestor, or + * an ancestor changing its on-screen status (visible and/or displayble). The + * second type is handled by HierarchyBoundsListener, and includes resizing + * or moving of an ancestor. + * * @author Bryce McKinlay + * @see HierarchyListener + * @see HierarchyBoundsAdapter + * @see HierarchyBoundsListener + * @since 1.3 + * @status updated to 1.4 */ - -/* Status: thought to be complete and correct. */ - public class HierarchyEvent extends AWTEvent { - public static final int PARENT_CHANGED = 1 << 0, - DISPLAYABILITY_CHANGED = 1 << 1, - SHOWING_CHANGED = 1 << 2, - HIERARCHY_FIRST = 1400, - HIERARCHY_CHANGED = 1400, - ANCESTOR_MOVED = 1401, - ANCESTOR_RESIZED = 1402, - HIERARCHY_LAST = 1402; - - /* Serialized fields from the serialization spec. */ - Component changed; - Container changedParent; - long changeFlags = 0; - + /** + * Compatible with JDK 1.3+. + */ + private static final long serialVersionUID = -5337576970038043990L; + + /** This is the first id in the range of ids used by this class. */ + public static final int HIERARCHY_FIRST = 1400; + + /** This id indicates that the hierarchy tree changed. */ + public static final int HIERARCHY_CHANGED = 1400; + + /** This id indicates that an ancestor was moved. */ + public static final int ANCESTOR_MOVED = 1401; + + /** This id indicates that an ancestor was resized. */ + public static final int ANCESTOR_RESIZED = 1402; + + /** This is the last id in the range of ids used by this class. */ + public static final int HIERARCHY_LAST = 1402; + + /** This indicates that the HIERARCHY_CHANGED is a changed parent. */ + public static final int PARENT_CHANGED = 1; + + /** + * This indicates that the HIERARCHY_CHANGED is caused by a change in + * displayability. + * + * @see Component#isDisplayable() + * @see Component#addNotify() + * @see Component#removeNotify() + */ + public static final int DISPLAYABILITY_CHANGED = 2; + + /** + * This indicates that the HIERARCHY_CHANGED is a changed visibility. + * + * @see Component#isShowing() + * @see Component#addNotify() + * @see Component#removeNotify() + * @see Component#show() + * @see Component#hide() + */ + public static final int SHOWING_CHANGED = 4; + + /** + * The component at the top of the changed hierarchy. + * + * @serial the top component changed + */ + private final Component changed; + + /** + * The parent of this component, either before or after the change depending + * on the type of change. + * + * @serial the parent component changed + */ + private final Container changedParent; + + /** + * The bitmask of HIERARCHY_CHANGED event types. + * + * @serial the change flags + */ + private final long changeFlags; + + /** + * Initializes a new instance of <code>HierarchyEvent</code> with the + * specified parameters. Note that an invalid id leads to unspecified + * results. + * + * @param source the component whose hierarchy changed + * @param id the event id + * @param changed the top component in the tree of changed hierarchy + * @param changedParent the updated parent of this object + * @throws IllegalArgumentException if source is null + */ public HierarchyEvent(Component source, int id, Component changed, - Container changedParent) + Container changedParent) { - super(source, id); - this.changed = changed; - this.changedParent = changedParent; + this(source, id, changed, changedParent, 0); } - - public HierarchyEvent(Component source, int id, Component changed, + + /** + * Initializes a new instance of <code>HierarchyEvent</code> with the + * specified parameters. Note that an invalid id leads to unspecified + * results. + * + * @param source the component whose hierarchy changed + * @param id the event id + * @param changed the top component in the tree of changed hierarchy + * @param changedParent the updated parent of this object + * @param changeFlags the bitmask of specific HIERARCHY_CHANGED events + * @throws IllegalArgumentException if source is null + */ + public HierarchyEvent(Component source, int id, Component changed, Container changedParent, long changeFlags) { - super(source,id); + super(source, id); this.changed = changed; this.changedParent = changedParent; this.changeFlags = changeFlags; } - + + /** + * This method returns the event source as a <code>Component</code>. If the + * source has subsequently been modified to a non-Component, this returns + * null. + * + * @return the event source as a <code>Component</code>, or null + */ public Component getComponent() { - return (Component) source; + return source instanceof Component ? (Component) source : null; } - + + /** + * Returns the component at the top of the hierarchy which changed. + * + * @return the top changed component + */ public Component getChanged() { return changed; } - + + /** + * Returns the parent of the component listed in <code>getChanged()</code>. + * If the cause of this event was <code>Container.add</code>, this is the + * new parent; if the cause was <code>Container.remove</code>, this is the + * old parent; otherwise it is the unchanged parent. + * + * @return the parent container of the changed component + */ public Container getChangedParent() { return changedParent; } - + + /** + * If this is a HIERARCHY_CHANGED event, this returns a bitmask of the + * types of changes that took place. + * + * @return the bitwise or of hierarchy change types, or 0 + * @see #PARENT_CHANGED + * @see #DISPLAYABILITY_CHANGED + * @see #SHOWING_CHANGED + */ public long getChangeFlags() { return changeFlags; } - + + /** + * This method returns a string identifying this event. This is the field + * name of the id type, followed by a parenthesized listing of the changed + * component and its parent container. In addition, if the type is + * HIERARCHY_CHANGED, the flags preceed the changed component, in the + * order PARENT_CHANGED, DISPLAYABILITY_CHANGED, and SHOWING_CHANGED. + * + * @return a string identifying this event + */ public String paramString() { - String r; + StringBuffer r = new StringBuffer(); switch (id) { - case HIERARCHY_CHANGED: - r = "HIERARCHY_CHANGED"; - break; - - case ANCESTOR_MOVED: - r = "ANCESTOR_MOVED"; - break; - - case ANCESTOR_RESIZED: - r = "ANCESTOR_RESIZED"; - break; - - default: - return "unknown type"; + case HIERARCHY_CHANGED: + r.append("HIERARCHY_CHANGED ("); + if ((changeFlags & PARENT_CHANGED) != 0) + r.append("PARENT_CHANGED,"); + if ((changeFlags & DISPLAYABILITY_CHANGED) != 0) + r.append("DISPLAYABILITY_CHANGED,"); + if ((changeFlags & SHOWING_CHANGED) != 0) + r.append("SHOWING_CHANGED,"); + break; + case ANCESTOR_MOVED: + r.append("ANCESTOR_MOVED ("); + break; + case ANCESTOR_RESIZED: + r.append("ANCESTOR_RESIZED ("); + break; + default: + return "unknown type"; } - - r += "(" + changed + "," + changedParent + ")"; - return r; + r.append(changed).append(',').append(changedParent).append(')'); + return r.toString(); } -} +} // class HierarchyEvent diff --git a/libjava/java/awt/event/HierarchyListener.java b/libjava/java/awt/event/HierarchyListener.java index 791e5bbaf05..4fdbdff977b 100644 --- a/libjava/java/awt/event/HierarchyListener.java +++ b/libjava/java/awt/event/HierarchyListener.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* HierarchyListener.java -- listens to changes in the component hierarchy + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,16 +35,28 @@ 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.event; +import java.util.EventListener; + /** - * @since 1.3 + * This listens for changes in the hierarchy tree of components. Normally it is + * not necessary to process these events since the AWT handles them + * internally, taking all appropriate actions. + * * @author Bryce McKinlay + * @see HierarchyEvent + * @since 1.3 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct. */ - -public interface HierarchyListener extends java.util.EventListener +public interface HierarchyListener extends EventListener { - public void hierarchyChanged(HierarchyEvent e); -} + /** + * Called when the hierarchy of this component changes. Use + * <code>getChangeFlags()</code> on the event to see what exactly changed. + * + * @param e the event describing the change + */ + void hierarchyChanged(HierarchyEvent e); +} // interface HierarchyListener diff --git a/libjava/java/awt/event/InputEvent.java b/libjava/java/awt/event/InputEvent.java index e5e18d28549..1689e51143d 100644 --- a/libjava/java/awt/event/InputEvent.java +++ b/libjava/java/awt/event/InputEvent.java @@ -1,78 +1,379 @@ -/* Copyright (C) 1999, 2000, 2002 Free Software Foundation +/* InputEvent.java -- common superclass of component input events + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; -/* Status: Believed complete and correct to JDK 1.2. */ +import java.awt.Component; +import gnu.java.awt.EventModifier; +/** + * This is the common superclass for all component input classes. These are + * passed to listeners before the component, so that listeners can consume + * the event before it does its default behavior. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see KeyEvent + * @see KeyAdapter + * @see MouseEvent + * @see MouseAdapter + * @see MouseMotionAdapter + * @see MouseWheelEvent + * @since 1.1 + * @status updated to 1.4 + */ public abstract class InputEvent extends ComponentEvent { - public static final int ALT_GRAPH_MASK = 32; + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = -2482525981698309786L; + + /** + * This is the bit mask which indicates the shift key is down. It is + * recommended that SHIFT_DOWN_MASK be used instead. + * + * @see #SHIFT_DOWN_MASK + */ + public static final int SHIFT_MASK = 1; + + /** + * This is the bit mask which indicates the control key is down. It is + * recommended that CTRL_DOWN_MASK be used instead. + * + * @see #CTRL_DOWN_MASK + */ + public static final int CTRL_MASK = 2; + + /** + * This is the bit mask which indicates the meta key is down. It is + * recommended that META_DOWN_MASK be used instead. + * + * @see #META_DOWN_MASK + */ + public static final int META_MASK = 4; + + /** + * This is the bit mask which indicates the alt key is down. It is + * recommended that ALT_DOWN_MASK be used instead. + * + * @see #ALT_DOWN_MASK + */ public static final int ALT_MASK = 8; - public static final int BUTTON1_MASK = 16; + + /** + * This is the bit mask which indicates the alt-graph modifier is in effect. + * It is recommended that ALT_GRAPH_DOWN_MASK be used instead. + * + * @see #ALT_GRAPH_DOWN_MASK + */ + public static final int ALT_GRAPH_MASK = 0x20; + + /** + * This bit mask indicates mouse button one is down. It is recommended that + * BUTTON1_DOWN_MASK be used instead. + * + * @see #BUTTON1_DOWN_MASK + */ + public static final int BUTTON1_MASK = 0x10; + + /** + * This bit mask indicates mouse button two is down. It is recommended that + * BUTTON2_DOWN_MASK be used instead. + * + * @see #BUTTON2_DOWN_MASK + */ public static final int BUTTON2_MASK = 8; + + /** + * This bit mask indicates mouse button three is down. It is recommended + * that BUTTON3_DOWN_MASK be used instead. + * + * @see #BUTTON3_DOWN_MASK + */ public static final int BUTTON3_MASK = 4; - public static final int CTRL_MASK = 2; - public static final int META_MASK = 4; - public static final int SHIFT_MASK = 1; - InputEvent (Component source, int id) // Not public + /** + * The SHIFT key extended modifier. + * + * @since 1.4 + */ + public static final int SHIFT_DOWN_MASK = 0x0040; + + /** + * The CTRL key extended modifier. + * + * @since 1.4 + */ + public static final int CTRL_DOWN_MASK = 0x0080; + + /** + * The META key extended modifier. + * + * @since 1.4 + */ + public static final int META_DOWN_MASK = 0x0100; + + /** + * The ALT key extended modifier. + * + * @since 1.4 + */ + public static final int ALT_DOWN_MASK = 0x0200; + + /** + * The mouse button1 key extended modifier. + * + * @since 1.4 + */ + public static final int BUTTON1_DOWN_MASK = 0x0400; + + /** + * The mouse button2 extended modifier. + * + * @since 1.4 + */ + public static final int BUTTON2_DOWN_MASK = 0x0800; + + /** + * The mouse button3 extended modifier. + * + * @since 1.4 + */ + public static final int BUTTON3_DOWN_MASK = 0x1000; + + /** + * The ALT_GRAPH key extended modifier. + * + * @since 1.4 + */ + public static final int ALT_GRAPH_DOWN_MASK = 0x2000; + + /** The mask to convert new to old, package visible for use in subclasses. */ + static final int CONVERT_MASK + = EventModifier.NEW_MASK & ~(BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK); + + /** + * The timestamp when this event occurred. + * + * @see #getWhen() + * @serial the timestamp + */ + private final long when; + + /** + * The modifiers in effect for this event. Package visible for use by + * subclasses. The old style (bitmask 0x3f) should not be mixed with the + * new style (bitmasks 0xffffffc0). + * + * @see #getModifiers() + * @see MouseEvent + * @serial the modifier state, stored in the new style + */ + int modifiers; + + /** + * Initializes a new instance of <code>InputEvent</code> with the specified + * source, id, timestamp, and modifiers. Note that an invalid id leads to + * unspecified results. + * + * @param source the source of the event + * @param id the event id + * @param when the timestamp when the event occurred + * @param modifiers the modifiers in effect for this event, old or new style + * @throws IllegalArgumentException if source is null + */ + InputEvent(Component source, int id, long when, int modifiers) { super(source, id); + this.when = when; + this.modifiers = EventModifier.extend(modifiers); } - public boolean isShiftDown () + /** + * This method tests whether or not the shift key was down during the event. + * + * @return true if the shift key is down + */ + public boolean isShiftDown() { - return (modifiers & SHIFT_MASK) != 0; + return (modifiers & SHIFT_DOWN_MASK) != 0; } - public boolean isControlDown () + /** + * This method tests whether or not the control key was down during the + * event. + * + * @return true if the control key is down + */ + public boolean isControlDown() { - return (modifiers & CTRL_MASK) != 0; + return (modifiers & CTRL_DOWN_MASK) != 0; } - public boolean isMetaDown () + /** + * This method tests whether or not the meta key was down during the event. + * + * @return true if the meta key is down + */ + public boolean isMetaDown() { - return (modifiers & META_MASK) != 0; + return (modifiers & META_DOWN_MASK) != 0; } - public boolean isAltDown () + /** + * This method tests whether or not the alt key was down during the event. + * + * @return true if the alt key is down + */ + public boolean isAltDown() { - return (modifiers & ALT_MASK) != 0; + return (modifiers & ALT_DOWN_MASK) != 0; } - public boolean isAltGraphDown () + /** + * This method tests whether or not the alt-graph modifier was in effect + * during the event. + * + * @return true if the alt-graph modifier is down + */ + public boolean isAltGraphDown() { - return (modifiers & ALT_GRAPH_MASK) != 0; + return (modifiers & ALT_GRAPH_DOWN_MASK) != 0; } - public long getWhen () + /** + * This method returns the timestamp when this event occurred. + * + * @return the timestamp when this event occurred + */ + public long getWhen() { return when; } - public int getModifiers () + /** + * This method returns the old-style modifiers in effect for this event. + * Note that this is ambiguous between button2 and alt, and between + * button3 and meta. Also, code which generated these modifiers tends to + * only list the modifier that just changed, even if others were down at + * the time. Consider using getModifiersEx instead. This will be a union + * of the bit masks defined in this class that are applicable to the event. + * + * @return the modifiers in effect for this event + * @see #getModifiersEx() + */ + public int getModifiers() { - return modifiers; + return EventModifier.revert(modifiers); } - public boolean isConsumed () + /** + * Returns the extended modifiers (new-style) for this event. This represents + * the state of all modal keys and mouse buttons at the time of the event, + * and does not suffer from the problems mentioned in getModifiers. + * + * <p>For an example of checking multiple modifiers, this code will return + * true only if SHIFT and BUTTON1 were pressed and CTRL was not: + * <pre> + * int onmask = InputEvent.SHIFT_DOWN_MASK | InputEvent.BUTTON1_DOWN_MASK; + * int offmask = InputEvent.CTRL_DOWN_MASK; + * return (event.getModifiersEx() & (onmask | offmask)) == onmask; + * </pre> + * + * @return the bitwise or of all modifiers pressed during the event + * @since 1.4 + */ + public int getModifiersEx() { - return consumed; + return modifiers; } - public void consume () + /** + * Consumes this event. A consumed event is not processed further by the AWT + * system. + */ + public void consume() { - /* FIXME */ consumed = true; } - long when; - int modifiers; -} + /** + * This method tests whether or not this event has been consumed. + * + * @return true if this event has been consumed + */ + public boolean isConsumed() + { + return consumed; + } + + /** + * Convert the extended modifier bitmask into a String, such as "Shift" or + * "Ctrl+Button1". + * + * XXX Sun claims this can be localized via the awt.properties file - how + * do we implement that? + * + * @return a string representation of the modifiers in this bitmask + * @since 1.4 + */ + public static String getModifiersExText(int modifiers) + { + modifiers &= EventModifier.NEW_MASK; + if (modifiers == 0) + return ""; + StringBuffer s = new StringBuffer(); + if ((modifiers & META_DOWN_MASK) != 0) + s.append("Meta+"); + if ((modifiers & CTRL_DOWN_MASK) != 0) + s.append("Ctrl+"); + if ((modifiers & ALT_DOWN_MASK) != 0) + s.append("Alt+"); + if ((modifiers & SHIFT_DOWN_MASK) != 0) + s.append("Shift+"); + if ((modifiers & ALT_GRAPH_DOWN_MASK) != 0) + s.append("Alt Graph+"); + if ((modifiers & BUTTON1_DOWN_MASK) != 0) + s.append("Button1+"); + if ((modifiers & BUTTON2_DOWN_MASK) != 0) + s.append("Button2+"); + if ((modifiers & BUTTON3_DOWN_MASK) != 0) + s.append("Button3+"); + return s.substring(0, s.length() - 1); + } +} // class InputEvent diff --git a/libjava/java/awt/event/InputMethodEvent.java b/libjava/java/awt/event/InputMethodEvent.java index 3cafd3508a3..880025b0a9f 100644 --- a/libjava/java/awt/event/InputMethodEvent.java +++ b/libjava/java/awt/event/InputMethodEvent.java @@ -1,68 +1,303 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* InputMethodEvent.java -- events from a text input method + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; -/* A very incomplete placeholder. */ +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.font.TextHitInfo; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.text.AttributedCharacterIterator; +/** + * This class is for event generated by change in a text input method. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see InputMethodListener + * @since 1.2 + * @status updated to 1.4 + */ public class InputMethodEvent extends AWTEvent { - public static final int CARET_POSITION_CHANGED = 1101; + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 4727190874778922661L; + + /** This is the first id in the range of event ids used by this class. */ public static final int INPUT_METHOD_FIRST = 1100; - public static final int INPUT_METHOD_LAST = 1101; + + /** This event id indicates that the text in the input method has changed. */ public static final int INPUT_METHOD_TEXT_CHANGED = 1100; - /* - public InputMethodEvent (Component source, int id, - AttributedCharacterIterator text, - int committedCharacterCount, TextHitInfo caret, - TextHitInfo visiblePosition) + /** This event id indicates that the input method curor point has changed. */ + public static final int CARET_POSITION_CHANGED = 1101; + + /** This is the last id in the range of event ids used by this class. */ + public static final int INPUT_METHOD_LAST = 1101; + + /** + * The timestamp when this event was created. + * + * @serial the timestamp + * @since 1.4 + */ + private long when; + + /** The input method text. */ + private final transient AttributedCharacterIterator text; + + /** The number of committed characters in the text. */ + private final transient int committedCharacterCount; + + /** The caret. */ + private final transient TextHitInfo caret; + + /** The most important position to be visible. */ + private final transient TextHitInfo visiblePosition; + + /** + * Initializes a new instance of <code>InputMethodEvent</code> with the + * specified source, id, timestamp, text, char count, caret, and visible + * position. + * + * @param source the source that generated the event + * @param id the event id + * @param when the timestamp of the event + * @param text the input text + * @param committedCharacterCount the number of committed characters + * @param caret the caret position + * @param visiblePosition the position most important to make visible + * @throws IllegalArgumentException if source is null, id is invalid, id is + * CARET_POSITION_CHANGED and text is non-null, or if + * committedCharacterCount is out of range + * @since 1.4 + */ + public InputMethodEvent(Component source, int id, long when, + AttributedCharacterIterator text, + int committedCharacterCount, TextHitInfo caret, + TextHitInfo visiblePosition) { - if (id < INPUT_METHOD_FIRST - || id > INPUT_METHOD_LAST - || (id == CARET_POSITION_CHANGED && text != null) - || committedCharacterCount < 0 - || (committedCharacterCount - > text.getEndIndex () - text.getBeginIndex ())) - throw new IllegalArgumentException (); + super(source, id); + this.when = when; + this.text = text; + this.committedCharacterCount = committedCharacterCount; + this.caret = caret; + this.visiblePosition = visiblePosition; + if (id < INPUT_METHOD_FIRST || id > INPUT_METHOD_LAST + || (id == CARET_POSITION_CHANGED && text != null) + || committedCharacterCount < 0 + || (committedCharacterCount + > (text == null ? 0 : text.getEndIndex() - text.getBeginIndex()))) + throw new IllegalArgumentException(); } - public InputMethodEvent (Component source, int id, TextHitInfo caret, - TextHitInfo visiblePosition); + /** + * Initializes a new instance of <code>InputMethodEvent</code> with the + * specified source, id, text, char count, caret, and visible position. + * + * @param source the source that generated the event + * @param id the event id + * @param text the input text + * @param committedCharacterCount the number of committed characters + * @param caret the caret position + * @param visiblePosition the position most important to make visible + * @throws IllegalArgumentException if source is null, id is invalid, id is + * CARET_POSITION_CHANGED and text is non-null, or if + * committedCharacterCount is out of range + * @since 1.4 + */ + public InputMethodEvent(Component source, int id, + AttributedCharacterIterator text, + int committedCharacterCount, TextHitInfo caret, + TextHitInfo visiblePosition) + { + this(source, id, EventQueue.getMostRecentEventTime(), text, + committedCharacterCount, caret, visiblePosition); + } - public void consume (); - public TextHitInfo getCaret (); - public int getCommittedCharacterCount (); - public AttributedCharacterIterator getText (); - public TextHitInfo getVisiblePosition (); - public boolean isConsumed (); + /** + * Initializes a new instance of <code>InputMethodEvent</code> with the + * specified source, id, caret, and visible position, and with a null + * text and char count. + * + * @param source the source that generated the event + * @param id the event id + * @param caret the caret position + * @param visiblePosition the position most important to make visible + * @throws IllegalArgumentException if source is null or id is invalid + * @since 1.4 + */ + public InputMethodEvent(Component source, int id, TextHitInfo caret, + TextHitInfo visiblePosition) + { + this(source, id, EventQueue.getMostRecentEventTime(), null, 0, caret, + visiblePosition); + } + + /** + * This method returns the input method text. This can be <code>null</code>, + * and will always be null for <code>CARET_POSITION_CHANGED</code> events. + * Characters from 0 to <code>getCommittedCharacterCount()-1</code> have + * been committed, the remaining characters are composed text. + * + * @return the input method text, or null + */ + public AttributedCharacterIterator getText() + { + return text; + } + + /** + * Returns the number of committed characters in the input method text. + * + * @return the number of committed characters in the input method text + */ + public int getCommittedCharacterCount() + { + return committedCharacterCount; + } + + /** + * Returns the caret position. The caret offset is relative to the composed + * text of the most recent <code>INPUT_METHOD_TEXT_CHANGED</code> event. + * + * @return the caret position, or null + */ + public TextHitInfo getCaret() + { + return caret; + } + + /** + * Returns the position that is most important to be visible, or null if + * such a hint is not necessary. The caret offset is relative to the composed + * text of the most recent <code>INPUT_METHOD_TEXT_CHANGED</code> event. + * + * @return the position that is most important to be visible + */ + public TextHitInfo getVisiblePosition() + { + return visiblePosition; + } + + /** + * This method consumes the event. A consumed event is not processed + * in the default manner by the component that generated it. + */ + public void consume() + { + consumed = true; + } + + /** + * This method tests whether or not this event has been consumed. + * + * @return true if the event has been consumed + */ + public boolean isConsumed() + { + return consumed; + } + + /** + * Return the timestamp of this event. + * + * @return the timestamp + * @since 1.4 + */ + public long getWhen() + { + return when; + } - public String paramString () + /** + * This method returns a string identifying the event. This contains the + * event ID, the committed and composed characters separated by '+', the + * number of committed characters, the caret, and the visible position. + * + * @return a string identifying the event + */ + public String paramString() { - String r; - switch (id) + StringBuffer s + = new StringBuffer(80 + (text == null ? 0 + : text.getEndIndex() - text.getBeginIndex())); + s.append(id == INPUT_METHOD_TEXT_CHANGED ? "INPUT_METHOD_TEXT_CHANGED, " + : "CARET_POSITION_CHANGED, "); + if (text == null) + s.append("no text, 0 characters committed, caret: "); + else { - case CARET_POSITION_CHANGED: - r = "CARET_POSITION_CHANGED"; - break; - case INPUT_METHOD_TEXT_CHANGED: - r = "INPUT_METHOD_TEXT_CHANGED"; - break; + s.append('"'); + int i = text.getBeginIndex(); + int j = committedCharacterCount; + while (--j >= 0) + s.append(text.setIndex(i++)); + s.append("\" + \""); + j = text.getEndIndex() - i; + while (--j >= 0) + s.append(text.setIndex(i++)); + s.append("\", ").append(committedCharacterCount) + .append(" characters committed, caret: "); } - r += ""; // FIXME - return r; + s.append(caret == null ? (Object) "no caret" : caret).append(", ") + .append(visiblePosition == null ? (Object) "no visible position" + : visiblePosition); + return s.toString(); } - */ - // FIXME: this is just to let it compile. - private InputMethodEvent () + /** + * Reads in the object from a serial stream, updating when to + * {@link EventQueue#getMostRecentEventTime()} if necessary. + * + * @param s the stream to read from + * @throws IOException if deserialization fails + * @throws ClassNotFoundException if deserialization fails + * @serialData default, except for updating when + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { - super (null, -1); + s.defaultReadObject(); + if (when == 0) + when = EventQueue.getMostRecentEventTime(); } -} +} // class InputMethodEvent diff --git a/libjava/java/awt/event/InputMethodListener.java b/libjava/java/awt/event/InputMethodListener.java index 0712404af39..bf09ed89336 100644 --- a/libjava/java/awt/event/InputMethodListener.java +++ b/libjava/java/awt/event/InputMethodListener.java @@ -1,22 +1,69 @@ -/* Copyright (C) 2000 Free Software Foundation +/* InputMethodListener.java -- listen for input method events + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This interface is for classes that wish to receive events from an input + * method. For a text component to use input methods, it must also install + * an InputMethodRequests handler. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see InputMethodEvent + * @see InputMethodRequests + * @since 1.2 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - -public interface InputMethodListener extends java.util.EventListener +public interface InputMethodListener extends EventListener { - public void caretPositionChanged (InputMethodEvent e); - public void inputMethodTextChanged (InputMethodEvent e); -} + /** + * This method is called when the text is changed. + * + * @param event the <code>InputMethodEvent</code> indicating the text change + */ + void inputMethodTextChanged(InputMethodEvent event); + + /** + * This method is called when the cursor position within the text is changed. + * + * @param event the <code>InputMethodEvent</code> indicating the change + */ + void caretPositionChanged(InputMethodEvent event); +} // interface InputMethodListener diff --git a/libjava/java/awt/event/InvocationEvent.java b/libjava/java/awt/event/InvocationEvent.java index 6ee6300e7fc..fbf7b5e9379 100644 --- a/libjava/java/awt/event/InvocationEvent.java +++ b/libjava/java/awt/event/InvocationEvent.java @@ -1,96 +1,232 @@ -/* Copyright (C) 2000 Free Software Foundation +/* InvocationEvent.java -- call a runnable when dispatched + Copyright (C) 1999, 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. */ - This file is part of libjava. - -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.ActiveEvent; +import java.awt.AWTEvent; +import java.awt.EventQueue; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This event executes {@link Runnable#run()} of a target object when it is + * dispatched. This class is used by calls to <code>invokeLater</code> and + * <code>invokeAndWait</code>, so client code can use this fact to avoid + * writing special-casing AWTEventListener objects. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ActiveEvent + * @see EventQueue#invokeLater(Runnable) + * @see EventQueue#invokeAndWait(Runnable) + * @see AWTEventListener + * @since 1.2 + * @status updated to 1.4 */ - -/* Status: Believed to be complete and correct. */ - public class InvocationEvent extends AWTEvent implements ActiveEvent { - public static final int INVOCATION_DEFAULT = 1200; + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 436056344909459450L; + + /** This is the first id in the range of event ids used by this class. */ public static final int INVOCATION_FIRST = 1200; + + /** This is the default id for this event type. */ + public static final int INVOCATION_DEFAULT = 1200; + + /** This is the last id in the range of event ids used by this class. */ public static final int INVOCATION_LAST = 1200; - protected InvocationEvent (Object source, int id, Runnable runnable, - Object notifier, boolean catchExceptions) + /** + * This is the <code>Runnable</code> object to call when dispatched. + * + * @serial the runnable to execute + */ + protected Runnable runnable; + + /** + * This is the object to call <code>notifyAll()</code> on when + * the call to <code>run()</code> returns, or <code>null</code> if no + * object is to be notified. + * + * @serial the object to notify + */ + protected Object notifier; + + /** + * This variable is set to <code>true</code> if exceptions are caught + * and stored in a variable during the call to <code>run()</code>, otherwise + * exceptions are ignored and propagate up. + * + * @serial true to catch exceptions + */ + protected boolean catchExceptions; + + /** + * This is the caught exception thrown in the <code>run()</code> method. It + * is null if exceptions are ignored, the run method hasn't completed, or + * there were no exceptions. + * + * @serial the caught exception, if any + */ + private Exception exception; + + /** + * The timestamp when this event was created. + * + * @see #getWhen() + * @serial the timestamp + * @since 1.4 + */ + private final long when = EventQueue.getMostRecentEventTime(); + + /** + * Initializes a new instance of <code>InvocationEvent</code> with the + * specified source and runnable. + * + * @param source the source of the event + * @param runnable the <code>Runnable</code> object to invoke + * @throws IllegalArgumentException if source is null + */ + public InvocationEvent(Object source, Runnable runnable) { - super (source, id); - this.runnable = runnable; - this.notifier = notifier; - this.catchExceptions = catchExceptions; + this(source, INVOCATION_DEFAULT, runnable, null, false); } - public InvocationEvent (Object source, Runnable runnable) + /** + * Initializes a new instance of <code>InvocationEvent</code> with the + * specified source, runnable, and notifier. It will also catch exceptions + * if specified. If notifier is non-null, this will call notifyAll() on + * the object when the runnable is complete. If catchExceptions is true, + * this traps any exception in the runnable, otherwise it lets the exception + * propagate up the Event Dispatch thread. + * + * @param source the source of the event + * @param runnable the <code>Runnable</code> object to invoke + * @param notifier the object to notify, or null + * @param catchExceptions true to catch exceptions from the runnable + */ + public InvocationEvent(Object source, Runnable runnable, Object notifier, + boolean catchExceptions) { - super (source, INVOCATION_DEFAULT); - this.runnable = runnable; + this(source, INVOCATION_DEFAULT, runnable, notifier, catchExceptions); } - public InvocationEvent(Object source, Runnable runnable, Object notifier, - boolean catchExceptions) + /** + * Initializes a new instance of <code>InvocationEvent</code> with the + * specified source, runnable, and notifier. It will also catch exceptions + * if specified. If notifier is non-null, this will call notifyAll() on + * the object when the runnable is complete. If catchExceptions is true, + * this traps any exception in the runnable, otherwise it lets the exception + * propagate up the Event Dispatch thread. Note that an invalid id leads to + * unspecified results. + * + * @param source the source of the event + * @param id the event id + * @param runnable the <code>Runnable</code> object to invoke + * @param notifier the object to notify, or null + * @param catchExceptions true to catch exceptions from the runnable + */ + protected InvocationEvent(Object source, int id, Runnable runnable, + Object notifier, boolean catchExceptions) { - super (source, INVOCATION_DEFAULT); + super(source, id); this.runnable = runnable; this.notifier = notifier; this.catchExceptions = catchExceptions; } - public void dispatch () + /** + * This method calls the <code>run()</code> method of the runnable, traps + * exceptions if instructed to do so, and calls <code>notifyAll()</code> + * on any notifier if all worked successfully. + */ + public void dispatch() { - Exception e = null; if (catchExceptions) try - { - runnable.run (); - } - catch (Exception x) - { - exception = x; - } + { + runnable.run(); + } + catch (Exception e) + { + exception = e; + } else - runnable.run (); - + runnable.run(); if (notifier != null) - { - synchronized (notifier) - { - notifier.notifyAll (); - } - } + notifier.notifyAll(); } - public Exception getException () + /** + * This method returns the exception that occurred during the execution of + * the runnable, or <code>null</code> if not exception was thrown or + * exceptions were not caught. + * + * @return the exception thrown by the runnable + */ + public Exception getException() { return exception; } - public String paramString () + /** + * Gets the timestamp of when this event was created. + * + * @return the timestamp of this event + * @since 1.4 + */ + public long getWhen() { - String r; - if (id == INVOCATION_DEFAULT) - r = "INVOCATION_DEFAULT"; - else - r = "unknown type"; - - r += ",runnable=" + runnable + ",notifier=" + notifier + - ",catchExceptions=" + catchExceptions; - return r; + return when; } - protected boolean catchExceptions; - protected Object notifier; - protected Runnable runnable; - - private Exception exception; -} + /** + * This method returns a string identifying this event. This is formatted as: + * <code>"INVOCATION_DEFAULT,runnable=" + runnable + ",notifier=" + notifier + * + ",catchExceptions=" + catchExceptions + ",when=" + getWhen()</code>. + * + * @return a string identifying this event + */ + public String paramString() + { + return (id == INVOCATION_DEFAULT ? "INVOCATION_DEFAULT,runnable=" + : "unknown type,runnable=") + runnable + ",notifier=" + notifier + + ",catchExceptions=" + catchExceptions + ",when=" + when; + } +} // class InvocationEvent diff --git a/libjava/java/awt/event/ItemEvent.java b/libjava/java/awt/event/ItemEvent.java index 3d2e502655a..43784a86504 100644 --- a/libjava/java/awt/event/ItemEvent.java +++ b/libjava/java/awt/event/ItemEvent.java @@ -1,81 +1,155 @@ -/* Copyright (C) 2000 Free Software Foundation +/* ItemEvent.java -- event for item state changes + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.AWTEvent; +import java.awt.ItemSelectable; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This event is generated when a selection item changes state. This is an + * abstraction that distills a large number of individual mouse or keyboard + * events into a simpler "item selected" and "item deselected" events. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ItemSelectable + * @see ItemListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public class ItemEvent extends AWTEvent { - public static final int DESELECTED = 2; + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = -608708132447206933L; + + /** This is the first id in the event id range used by this class. */ public static final int ITEM_FIRST = 701; + + /** This is the last id in the event id range used by this class. */ public static final int ITEM_LAST = 701; + + /** This event id indicates a state change occurred. */ public static final int ITEM_STATE_CHANGED = 701; + + /** This type indicates that the item was selected. */ public static final int SELECTED = 1; - public ItemEvent (ItemSelectable source, int id, Object item, int sc) + /** This type indicates that the item was deselected. */ + public static final int DESELECTED = 2; + + /** + * The item affected by this event. + * + * @serial the item of the selection + */ + private final Object item; + + /** + * The state change direction, one of {@link #SELECTED} or + * {@link #DESELECTED}. + * + * @serial the selection state + */ + private final int stateChange; + + /** + * Initializes a new instance of <code>ItemEvent</code> with the specified + * source, id, and state change constant. Note that an invalid id leads to + * unspecified results. + * + * @param source the source of the event + * @param id the event id + * @param item the item affected by the state change + * @param stateChange one of {@link #SELECTED} or {@link #DESELECTED} + */ + public ItemEvent(ItemSelectable source, int id, Object item, int stateChange) { - super (source, id); + super(source, id); this.item = item; - this.stateChange = sc; + this.stateChange = stateChange; } - public Object getItem () + /** + * This method returns the event source as an <code>ItemSelectable</code>. + * + * @return the event source as an <code>ItemSelected</code> + * @throws ClassCastException if source is changed to a non-ItemSelectable + */ + public ItemSelectable getItemSelectable() { - return item; + return (ItemSelectable) source; } - public ItemSelectable getItemSelectable () + /** + * Returns the item affected by this state change. + * + * @return the item affected by this state change + */ + public Object getItem() { - return (ItemSelectable) source; + return item; } - public int getStateChange () + /** + * Returns the type of state change, either {@link #SELECTED} or + * {@link #DESELECTED}. + * + * @return the type of state change + */ + public int getStateChange() { return stateChange; } - public String paramString () + /** + * Returns a string identifying this event. This is in the format: + * <code>"ITEM_STATE_CHANGED,item=" + item + ",stateChange=" + * + (getStateChange() == DESELECTED ? "DESELECTED" : "SELECTED")</code>. + * + * @return a string identifying this event + */ + public String paramString() { - String r; - switch (id) - { - case ITEM_STATE_CHANGED: - r = "ITEM_STATE_CHANGED"; - break; - default: - r = "unknown id"; - break; - } - - r += ",item=" + item + ",stateChange="; - switch (stateChange) - { - case SELECTED: - r += "SELECTED"; - break; - case DESELECTED: - r += "DESELECTED"; - break; - default: - r += "unknown"; - break; - } - - return r; + return (id == ITEM_STATE_CHANGED ? "ITEM_STATE_CHANGED,item=" + : "unknown type,item=") + item + ",stateChange=" + + (stateChange == SELECTED ? "SELECTED" + : stateChange == DESELECTED ? "DESELECTED" : "unknown type"); } - - private Object item; - private int stateChange; -} +} // class ItemEvent diff --git a/libjava/java/awt/event/ItemListener.java b/libjava/java/awt/event/ItemListener.java index 30bfcac3cab..5c67357851b 100644 --- a/libjava/java/awt/event/ItemListener.java +++ b/libjava/java/awt/event/ItemListener.java @@ -1,21 +1,61 @@ -/* Copyright (C) 2000 Free Software Foundation +/* ItemListener.java -- listen for item events + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This interface is for classes that wish to receive events when an + * item's selection state changes. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ItemSelectable + * @see ItemEvent + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - -public interface ItemListener extends java.util.EventListener +public interface ItemListener extends EventListener { - public void itemStateChanged (ItemEvent e); -} + /** + * This method is called when an item's state is changed. + * + * @param event the <code>ItemEvent</code> indicating the change + */ + void itemStateChanged(ItemEvent event); +} // interface ItemListener diff --git a/libjava/java/awt/event/KeyAdapter.java b/libjava/java/awt/event/KeyAdapter.java index 0e1297eb80d..c60fd52e245 100644 --- a/libjava/java/awt/event/KeyAdapter.java +++ b/libjava/java/awt/event/KeyAdapter.java @@ -1,31 +1,88 @@ -/* Copyright (C) 2000 Free Software Foundation +/* KeyAdapter.java -- convenience class for writing key listeners + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class implements <code>KeyListener</code> and implements all methods + * with empty bodies. This allows a listener interested in implementing only + * a subset of the <code>KeyListener</code> interface to extend this class + * and override only the desired methods. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see KeyEvent + * @see KeyListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public abstract class KeyAdapter implements KeyListener { - public void keyPressed (KeyEvent w) + /** + * Do nothing default constructor for subclasses. + */ + public KeyAdapter() + { + } + + /** + * Implements this method in the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void keyTyped(KeyEvent event) { } - public void keyReleased (KeyEvent w) + /** + * Implements this method in the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void keyPressed(KeyEvent event) { } - public void keyTyped (KeyEvent w) + /** + * Implements this method in the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void keyReleased(KeyEvent event) { } -} +} // class KeyAdapter diff --git a/libjava/java/awt/event/KeyEvent.java b/libjava/java/awt/event/KeyEvent.java index caca0d4e716..33390e48f42 100644 --- a/libjava/java/awt/event/KeyEvent.java +++ b/libjava/java/awt/event/KeyEvent.java @@ -1,275 +1,1733 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* KeyEvent.java -- event for key presses + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; -/* Status: still incomplete. */ +import java.awt.Component; +import java.io.IOException; +import java.io.ObjectInputStream; +import gnu.java.awt.EventModifier; +/** + * This event is generated when a key is pressed or released. There are two + * categories of key events: + * + * <p><em>"Key typed" events</em> are higher-level, and have already + * compensated for modifiers and keyboard layout to generate a single Unicode + * character. It may take several key press events to generate one key typed. + * The <code>getKeyCode</code> method will return <code>VK_UNDEFINED</code>, + * and <code>getKeyChar</code> will return a valid Unicode character or + * <code>CHAR_UNDEFINED</code>. + * + * <p><em>"Key pressed" and "key released" events</em> are lower-level, and + * are platform and keyboard dependent. They correspond to the actaul motion + * on a keyboard, and return a virtual key code which labels the key that was + * pressed. The <code>getKeyCode</code> method will return one of the + * <code>VK_*</code> constants (except VK_UNDEFINED), and the + * <code>getKeyChar</code> method is undefined. + * + * <p>Some keys do not generate key typed events, such as the F1 or HELP keys. + * Not all keyboards can generate all virtual keys, and no attempt is made to + * simulate the ones that can't be typed. Virtual keys correspond to the + * keyboard layout, so for example, VK_Q in English is VK_A in French. Also, + * there are some additional virtual keys to ease handling of actions, such + * as VK_ALL_CANDIDATES in place of ALT+VK_CONVERT. Do not rely on the value + * of the VK_* constants, except for VK_ENTER, VK_BACK_SPACE, and VK_TAB. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @see KeyAdapter + * @see KeyListener + * @since 1.1 + * @status updated to 1.4 + */ public class KeyEvent extends InputEvent { - public static final char CHAR_UNDEFINED = 0;; + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = -2352130953028126954L; + + /** This is the first id in the range of event ids used by this class. */ public static final int KEY_FIRST = 400; + + /** This is the last id in the range of event ids used by this class. */ public static final int KEY_LAST = 402; + + /** + * This event id indicates a key was typed, which is a key press followed + * by a key release to generate an actual Unicode character. It may take + * several key presses to generate one key typed event, and some action + * keys have no corresponding key typed. + */ + public static final int KEY_TYPED = 400; + + /** This event id indicates a key was pressed. */ public static final int KEY_PRESSED = 401; + + /** This event it indicates a key was released. */ public static final int KEY_RELEASED = 402; - public static final int KEY_TYPED = 400; - public static final int VK_0 = 48; - public static final int VK_1 = 49; - public static final int VK_2 = 50; - public static final int VK_3 = 51; - public static final int VK_4 = 52; - public static final int VK_5 = 53; - public static final int VK_6 = 54; - public static final int VK_7 = 55; - public static final int VK_8 = 56; - public static final int VK_9 = 57; - public static final int VK_A = 65; - public static final int VK_ACCEPT = 30; - public static final int VK_ADD = 107; - public static final int VK_AGAIN = 65481; - public static final int VK_ALL_CANDIDATES = 256; - public static final int VK_ALPHANUMERIC = 240; - public static final int VK_ALT = 18; - public static final int VK_ALT_GRAPH = 65406; - public static final int VK_AMPERSAND = 150; - public static final int VK_ASTERISK = 151; - public static final int VK_AT = 512; - public static final int VK_B = 66; - public static final int VK_BACK_QUOTE = 192; - public static final int VK_BACK_SLASH = 92; - public static final int VK_BACK_SPACE = 8; - public static final int VK_BRACELEFT = 161; - public static final int VK_BRACERIGHT = 162; - public static final int VK_C = 67; + + /** The virtual key Enter, which will always map to '\n'. */ + public static final int VK_ENTER = '\n'; + + /** The virtual key Backspace, which will always map to '\b'. */ + public static final int VK_BACK_SPACE = '\b'; + + /** The virtual key Tab, which will always map to '\t'. */ + public static final int VK_TAB = '\t'; + + /** The virtual key Cancel. */ public static final int VK_CANCEL = 3; - public static final int VK_CAPS_LOCK = 20; - public static final int VK_CIRCUMFLEX = 514; + + /** The virtual key VK_CLEAR. */ public static final int VK_CLEAR = 12; - public static final int VK_CLOSE_BRACKET = 93; - public static final int VK_CODE_INPUT = 258; - public static final int VK_COLON = 513; - public static final int VK_COMMA = 44; - public static final int VK_COMPOSE = 65312; + + /** The virtual key VK_SHIFT. */ + public static final int VK_SHIFT = 16; + + /** The virtual key VK_CONTROL. */ public static final int VK_CONTROL = 17; - public static final int VK_CONVERT = 28; - public static final int VK_COPY = 65485; - public static final int VK_CUT = 65489; - public static final int VK_D = 68; - public static final int VK_DEAD_ABOVEDOT = 134; - public static final int VK_DEAD_ABOVERING = 136; - public static final int VK_DEAD_ACUTE = 129; - public static final int VK_DEAD_BREVE = 133; - public static final int VK_DEAD_CARON = 138; - public static final int VK_DEAD_CEDILLA = 139; - public static final int VK_DEAD_CIRCUMFLEX = 130; - public static final int VK_DEAD_DIAERESIS = 135; - public static final int VK_DEAD_DOUBLEACUTE = 137; - public static final int VK_DEAD_GRAVE = 128; - public static final int VK_DEAD_IOTA = 141; - public static final int VK_DEAD_MACRON = 132; - public static final int VK_DEAD_OGONEK = 140; - public static final int VK_DEAD_SEMIVOICED_SOUND = 143; - public static final int VK_DEAD_TILDE = 131; - public static final int VK_DEAD_VOICED_SOUND = 142; + + /** The virtual key VK_ALT. */ + public static final int VK_ALT = 18; + + /** The virtual key VK_PAUSE. */ + public static final int VK_PAUSE = 19; + + /** The virtual key VK_CAPS_LOCK. */ + public static final int VK_CAPS_LOCK = 20; + + /** The virtual key VK_ESCAPE. */ + public static final int VK_ESCAPE = 27; + + /** The virtual key VK_SPACE. */ + public static final int VK_SPACE = ' '; + + /** The virtual key VK_PAGE_UP. */ + public static final int VK_PAGE_UP = 33; + + /** The virtual key VK_PAGE_DOWN. */ + public static final int VK_PAGE_DOWN = 34; + + /** The virtual key VK_END. */ + public static final int VK_END = 35; + + /** The virtual key VK_HOME. */ + public static final int VK_HOME = 36; + + /** + * The virtual key for the non-numpad VK_LEFT. + * + * @see #VK_KP_LEFT + */ + public static final int VK_LEFT = 37; + + /** + * The virtual key for the non-numpad VK_UP. + * + * @see #VK_KP_UP + */ + public static final int VK_UP = 38; + + /** + * The virtual key for the non-numpad VK_RIGHT. + * + * @see #VK_KP_RIGHT + */ + public static final int VK_RIGHT = 39; + + /** + * The virtual key for the non-numpad VK_DOWN. + * + * @see #VK_KP_DOWN + */ + public static final int VK_DOWN = 40; + + /** The virtual key VK_COMMA. */ + public static final int VK_COMMA = ','; + + /** + * The virtual key VK_MINUS. + * + * @since 1.2 + */ + public static final int VK_MINUS = '-'; + + /** The virtual key VK_PERIOD. */ + public static final int VK_PERIOD = '.'; + + /** The virtual key VK_SLASH. */ + public static final int VK_SLASH = '/'; + + /** The virtual key VK_0. */ + public static final int VK_0 = '0'; + + /** The virtual key VK_1. */ + public static final int VK_1 = '1'; + + /** The virtual key VK_2. */ + public static final int VK_2 = '2'; + + /** The virtual key VK_3. */ + public static final int VK_3 = '3'; + + /** The virtual key VK_4. */ + public static final int VK_4 = '4'; + + /** The virtual key VK_5. */ + public static final int VK_5 = '5'; + + /** The virtual key VK_6. */ + public static final int VK_6 = '6'; + + /** The virtual key VK_7. */ + public static final int VK_7 = '7'; + + /** The virtual key VK_8. */ + public static final int VK_8 = '8'; + + /** The virtual key VK_9. */ + public static final int VK_9 = '9'; + + /** The virtual key VK_SEMICOLON. */ + public static final int VK_SEMICOLON = ';'; + + /** The virtual key VK_EQUALS. */ + public static final int VK_EQUALS = '='; + + /** The virtual key VK_A. */ + public static final int VK_A = 'A'; + + /** The virtual key VK_B. */ + public static final int VK_B = 'B'; + + /** The virtual key VK_C. */ + public static final int VK_C = 'C'; + + /** The virtual key VK_D. */ + public static final int VK_D = 'D'; + + /** The virtual key VK_E. */ + public static final int VK_E = 'E'; + + /** The virtual key VK_F. */ + public static final int VK_F = 'F'; + + /** The virtual key VK_G. */ + public static final int VK_G = 'G'; + + /** The virtual key VK_H. */ + public static final int VK_H = 'H'; + + /** The virtual key VK_I. */ + public static final int VK_I = 'I'; + + /** The virtual key VK_J. */ + public static final int VK_J = 'J'; + + /** The virtual key VK_K. */ + public static final int VK_K = 'K'; + + /** The virtual key VK_L. */ + public static final int VK_L = 'L'; + + /** The virtual key VK_M. */ + public static final int VK_M = 'M'; + + /** The virtual key VK_N. */ + public static final int VK_N = 'N'; + + /** The virtual key VK_O. */ + public static final int VK_O = 'O'; + + /** The virtual key VK_P. */ + public static final int VK_P = 'P'; + + /** The virtual key VK_Q. */ + public static final int VK_Q = 'Q'; + + /** The virtual key VK_R. */ + public static final int VK_R = 'R'; + + /** The virtual key VK_S. */ + public static final int VK_S = 'S'; + + /** The virtual key VK_T. */ + public static final int VK_T = 'T'; + + /** The virtual key VK_U. */ + public static final int VK_U = 'U'; + + /** The virtual key VK_V. */ + public static final int VK_V = 'V'; + + /** The virtual key VK_W. */ + public static final int VK_W = 'W'; + + /** The virtual key VK_X. */ + public static final int VK_X = 'X'; + + /** The virtual key VK_Y. */ + public static final int VK_Y = 'Y'; + + /** The virtual key VK_Z. */ + public static final int VK_Z = 'Z'; + + /** The virtual key VK_OPEN_BRACKET. */ + public static final int VK_OPEN_BRACKET = '['; + + /** The virtual key VK_BACK_SLASH. */ + public static final int VK_BACK_SLASH = '\\'; + + /** The virtual key VK_CLOSE_BRACKET. */ + public static final int VK_CLOSE_BRACKET = ']'; + + /** The virtual key VK_NUMPAD0. */ + public static final int VK_NUMPAD0 = 96; + + /** The virtual key VK_NUMPAD1. */ + public static final int VK_NUMPAD1 = 97; + + /** The virtual key VK_NUMPAD2. */ + public static final int VK_NUMPAD2 = 98; + + /** The virtual key VK_NUMPAD3. */ + public static final int VK_NUMPAD3 = 99; + + /** The virtual key VK_NUMPAD4. */ + public static final int VK_NUMPAD4 = 100; + + /** The virtual key VK_NUMPAD5. */ + public static final int VK_NUMPAD5 = 101; + + /** The virtual key VK_NUMPAD6. */ + public static final int VK_NUMPAD6 = 102; + + /** The virtual key VK_NUMPAD7. */ + public static final int VK_NUMPAD7 = 103; + + /** The virtual key VK_NUMPAD8. */ + public static final int VK_NUMPAD8 = 104; + + /** The virtual key VK_NUMPAD9. */ + public static final int VK_NUMPAD9 = 105; + + /** The virtual key VK_MULTIPLY. */ + public static final int VK_MULTIPLY = 106; + + /** The virtual key VK_ADD. */ + public static final int VK_ADD = 107; + + /** + * The virtual key VK_SEPARATOR, handily mispelled for those who can't + * figure it out. + * + * @deprecated use {@link #VK_SEPARATOR} + */ + public static final int VK_SEPARATER = 108; + + /** + * The virtual key VK_SEPARATOR. + * + * @since 1.4 + */ + public static final int VK_SEPARATOR = 108; + + /** The virtual key VK_SUBTRACT. */ + public static final int VK_SUBTRACT = 109; + + /** The virtual key VK_DECIMAL. */ public static final int VK_DECIMAL = 110; - public static final int VK_DELETE = 127; + + /** The virtual key VK_DIVIDE. */ public static final int VK_DIVIDE = 111; - public static final int VK_DOLLAR = 515; - public static final int VK_DOWN = 40; - public static final int VK_E = 69; - public static final int VK_END = 35; - public static final int VK_ENTER = 10; - public static final int VK_EQUALS = 61; - public static final int VK_ESCAPE = 27; - public static final int VK_EURO_SIGN = 516; - public static final int VK_EXCLAMATION_MARK = 517; - public static final int VK_F = 70; + + /** The virtual key VK_DELETE. */ + public static final int VK_DELETE = 127; + + /** The virtual key VK_NUM_LOCK. */ + public static final int VK_NUM_LOCK = 144; + + /** The virtual key VK_SCROLL_LOCK. */ + public static final int VK_SCROLL_LOCK = 145; + + /** The virtual key VK_F1. */ public static final int VK_F1 = 112; + + /** The virtual key VK_F2. */ + public static final int VK_F2 = 113; + + /** The virtual key VK_F3. */ + public static final int VK_F3 = 114; + + /** The virtual key VK_F4. */ + public static final int VK_F4 = 115; + + /** The virtual key VK_F5. */ + public static final int VK_F5 = 116; + + /** The virtual key VK_F6. */ + public static final int VK_F6 = 117; + + /** The virtual key VK_F7. */ + public static final int VK_F7 = 118; + + /** The virtual key VK_F8. */ + public static final int VK_F8 = 119; + + /** The virtual key VK_F9. */ + public static final int VK_F9 = 120; + + /** The virtual key VK_F10. */ public static final int VK_F10 = 121; + + /** The virtual key VK_F11. */ public static final int VK_F11 = 122; + + /** The virtual key VK_F12. */ public static final int VK_F12 = 123; + + /** + * The virtual key VK_F13. + * + * @since 1.2 + */ public static final int VK_F13 = 61440; + + /** + * The virtual key VK_F14. + * + * @since 1.2 + */ public static final int VK_F14 = 61441; + + /** + * The virtual key VK_F15. + * + * @since 1.2 + */ public static final int VK_F15 = 61442; + + /** + * The virtual key VK_F16. + * + * @since 1.2 + */ public static final int VK_F16 = 61443; + + /** + * The virtual key VK_F17. + * + * @since 1.2 + */ public static final int VK_F17 = 61444; + + /** + * The virtual key VK_F18. + * + * @since 1.2 + */ public static final int VK_F18 = 61445; + + /** + * The virtual key VK_F19. + * + * @since 1.2 + */ public static final int VK_F19 = 61446; - public static final int VK_F2 = 113; + + /** + * The virtual key VK_F20. + * + * @since 1.2 + */ public static final int VK_F20 = 61447; + + /** + * The virtual key VK_F21. + * + * @since 1.2 + */ public static final int VK_F21 = 61448; + + /** + * The virtual key VK_F22. + * + * @since 1.2 + */ public static final int VK_F22 = 61449; + + /** + * The virtual key VK_F23. + * + * @since 1.2 + */ public static final int VK_F23 = 61450; + + /** + * The virtual key VK_F24. + * + * @since 1.2 + */ public static final int VK_F24 = 61451; - public static final int VK_F3 = 114; - public static final int VK_F4 = 115; - public static final int VK_F5 = 116; - public static final int VK_F6 = 117; - public static final int VK_F7 = 118; - public static final int VK_F8 = 119; - public static final int VK_F9 = 120; - public static final int VK_FINAL = 24; - public static final int VK_FIND = 65488; - public static final int VK_FULL_WIDTH = 243; - public static final int VK_G = 71; - public static final int VK_GREATER = 160; - public static final int VK_H = 72; - public static final int VK_HALF_WIDTH = 244; - public static final int VK_HELP = 156; - public static final int VK_HIRAGANA = 242; - public static final int VK_HOME = 36; - public static final int VK_I = 73; + + /** The virtual key VK_PRINTSCREEN. */ + public static final int VK_PRINTSCREEN = 154; + + /** The virtual key VK_INSERT. */ public static final int VK_INSERT = 155; - public static final int VK_INVERTED_EXCLAMATION_MARK = 518; - public static final int VK_J = 74; - public static final int VK_JAPANESE_HIRAGANA = 260; - public static final int VK_JAPANESE_KATAKANA = 259; - public static final int VK_JAPANESE_ROMAN = 261; - public static final int VK_K = 75; - public static final int VK_KANA = 21; - public static final int VK_KANJI = 25; - public static final int VK_KATAKANA = 241; + + /** The virtual key VK_HELP. */ + public static final int VK_HELP = 156; + + /** The virtual key VK_META. */ + public static final int VK_META = 157; + + /** The virtual key VK_BACK_QUOTE. */ + public static final int VK_BACK_QUOTE = 192; + + /** The virtual key VK_QUOTE. */ + public static final int VK_QUOTE = 222; + + /** + * The virtual key for the numpad VK_KP_UP. + * + * @see #VK_UP + * @since 1.2 + */ + public static final int VK_KP_UP = 224; + + /** + * The virtual key for the numpad VK_KP_DOWN. + * + * @see #VK_DOWN + * @since 1.2 + */ public static final int VK_KP_DOWN = 225; + + /** + * The virtual key for the numpad VK_KP_LEFT. + * + * @see #VK_LEFT + * @since 1.2 + */ public static final int VK_KP_LEFT = 226; + + /** + * The virtual key for the numpad VK_KP_RIGHT. + * + * @see #VK_RIGHT + * @since 1.2 + */ public static final int VK_KP_RIGHT = 227; - public static final int VK_KP_UP = 224; - public static final int VK_L = 76; - public static final int VK_LEFT = 37; - public static final int VK_LEFT_PARENTHESIS = 519; + + /** + * The virtual key VK_DEAD_GRAVE. + * + * @since 1.2 + */ + public static final int VK_DEAD_GRAVE = 128; + + /** + * The virtual key VK_DEAD_ACUTE. + * + * @since 1.2 + */ + public static final int VK_DEAD_ACUTE = 129; + + /** + * The virtual key VK_DEAD_CIRCUMFLEX. + * + * @since 1.2 + */ + public static final int VK_DEAD_CIRCUMFLEX = 130; + + /** + * The virtual key VK_DEAD_TILDE. + * + * @since 1.2 + */ + public static final int VK_DEAD_TILDE = 131; + + /** + * The virtual key VK_DEAD_MACRON. + * + * @since 1.2 + */ + public static final int VK_DEAD_MACRON = 132; + + /** + * The virtual key VK_DEAD_BREVE. + * + * @since 1.2 + */ + public static final int VK_DEAD_BREVE = 133; + + /** + * The virtual key VK_DEAD_ABOVEDOT. + * + * @since 1.2 + */ + public static final int VK_DEAD_ABOVEDOT = 134; + + /** + * The virtual key VK_DEAD_DIAERESIS. + * + * @since 1.2 + */ + public static final int VK_DEAD_DIAERESIS = 135; + + /** + * The virtual key VK_DEAD_ABOVERING. + * + * @since 1.2 + */ + public static final int VK_DEAD_ABOVERING = 136; + + /** + * The virtual key VK_DEAD_DOUBLEACUTE. + * + * @since 1.2 + */ + public static final int VK_DEAD_DOUBLEACUTE = 137; + + /** + * The virtual key VK_DEAD_CARON. + * + * @since 1.2 + */ + public static final int VK_DEAD_CARON = 138; + + /** + * The virtual key VK_DEAD_CEDILLA. + * + * @since 1.2 + */ + public static final int VK_DEAD_CEDILLA = 139; + + /** + * The virtual key VK_DEAD_OGONEK. + * + * @since 1.2 + */ + public static final int VK_DEAD_OGONEK = 140; + + /** + * The virtual key VK_DEAD_IOTA. + * + * @since 1.2 + */ + public static final int VK_DEAD_IOTA = 141; + + /** + * The virtual key VK_DEAD_VOICED_SOUND. + * + * @since 1.2 + */ + public static final int VK_DEAD_VOICED_SOUND = 142; + + /** + * The virtual key VK_DEAD_SEMIVOICED_SOUND. + * + * @since 1.2 + */ + public static final int VK_DEAD_SEMIVOICED_SOUND = 143; + + /** + * The virtual key VK_AMPERSAND. + * + * @since 1.2 + */ + public static final int VK_AMPERSAND = 150; + + /** + * The virtual key VK_ASTERISK. + * + * @since 1.2 + */ + public static final int VK_ASTERISK = 151; + + /** + * The virtual key VK_QUOTEDBL. + * + * @since 1.2 + */ + public static final int VK_QUOTEDBL = 152; + + /** + * The virtual key VK_LESS. + * + * @since 1.2 + */ public static final int VK_LESS = 153; - public static final int VK_M = 77; - public static final int VK_META = 157; - public static final int VK_MINUS = 45; - public static final int VK_MODECHANGE = 31; - public static final int VK_MULTIPLY = 106; - public static final int VK_N = 78; - public static final int VK_NONCONVERT = 29; - public static final int VK_NUM_LOCK = 144; + + /** + * The virtual key VK_GREATER. + * + * @since 1.2 + */ + public static final int VK_GREATER = 160; + + /** + * The virtual key VK_BRACELEFT. + * + * @since 1.2 + */ + public static final int VK_BRACELEFT = 161; + + /** + * The virtual key VK_BRACERIGHT. + * + * @since 1.2 + */ + public static final int VK_BRACERIGHT = 162; + + /** + * The virtual key VK_AT. + * + * @since 1.2 + */ + public static final int VK_AT = 512; + + /** + * The virtual key VK_COLON. + * + * @since 1.2 + */ + public static final int VK_COLON = 513; + + /** + * The virtual key VK_CIRCUMFLEX. + * + * @since 1.2 + */ + public static final int VK_CIRCUMFLEX = 514; + + /** + * The virtual key VK_DOLLAR. + * + * @since 1.2 + */ + public static final int VK_DOLLAR = 515; + + /** + * The virtual key VK_EURO_SIGN. + * + * @since 1.2 + */ + public static final int VK_EURO_SIGN = 516; + + /** + * The virtual key VK_EXCLAMATION_POINT. + * + * @since 1.2 + */ + public static final int VK_EXCLAMATION_POINT = 517; + + /** + * The virtual key VK_INVERTED_EXCLAMATION_POINT. + * + * @since 1.2 + */ + public static final int VK_INVERTED_EXCLAMATION_POINT = 518; + + /** + * The virtual key VK_LEFT_PARENTHESIS. + * + * @since 1.2 + */ + public static final int VK_LEFT_PARENTHESIS = 519; + + /** + * The virtual key VK_NUMBER_SIGN. + * + * @since 1.2 + */ public static final int VK_NUMBER_SIGN = 520; - public static final int VK_NUMPAD0 = 96; - public static final int VK_NUMPAD1 = 97; - public static final int VK_NUMPAD2 = 98; - public static final int VK_NUMPAD3 = 99; - public static final int VK_NUMPAD4 = 100; - public static final int VK_NUMPAD5 = 101; - public static final int VK_NUMPAD6 = 102; - public static final int VK_NUMPAD7 = 103; - public static final int VK_NUMPAD8 = 104; - public static final int VK_NUMPAD9 = 105; - public static final int VK_O = 79; - public static final int VK_OPEN_BRACKET = 91; - public static final int VK_P = 80; - public static final int VK_PAGE_DOWN = 34; - public static final int VK_PAGE_UP = 33; - public static final int VK_PASTE = 65487; - public static final int VK_PAUSE = 19; - public static final int VK_PERIOD = 46; + + /** + * The virtual key VK_PLUS. + * + * @since 1.2 + */ public static final int VK_PLUS = 521; - public static final int VK_PREVIOUS_CANDIDATE = 257; - public static final int VK_PRINTSCREEN = 154; - public static final int VK_PROPS = 65482; - public static final int VK_Q = 81; - public static final int VK_QUOTE = 222; - public static final int VK_QUOTEDBL = 152; - public static final int VK_R = 82; - public static final int VK_RIGHT = 39; + + /** + * The virtual key VK_RIGHT_PARENTHESIS. + * + * @since 1.2 + */ public static final int VK_RIGHT_PARENTHESIS = 522; + + /** + * The virtual key VK_UNDERSCORE. + * + * @since 1.2 + */ + public static final int VK_UNDERSCORE = 523; + + /** The virtual key VK_FINAL. */ + public static final int VK_FINAL = 24; + + /** The virtual key VK_CONVERT. */ + public static final int VK_CONVERT = 28; + + /** The virtual key VK_NONCONVERT. */ + public static final int VK_NONCONVERT = 29; + + /** The virtual key VK_ACCEPT. */ + public static final int VK_ACCEPT = 30; + + /** The virtual key VK_MODECHANGE. */ + public static final int VK_MODECHANGE = 31; + + /** The virtual key VK_KANA. */ + public static final int VK_KANA = 21; + + /** The virtual key VK_KANJI. */ + public static final int VK_KANJI = 25; + + /** + * The virtual key VK_ALPHANUMERIC. + * + * @since 1.2 + */ + public static final int VK_ALPHANUMERIC = 240; + + /** + * The virtual key VK_KATAKANA. + * + * @since 1.2 + */ + public static final int VK_KATAKANA = 241; + + /** + * The virtual key VK_HIRAGANA. + * + * @since 1.2 + */ + public static final int VK_HIRAGANA = 242; + + /** + * The virtual key VK_FULL_WIDTH. + * + * @since 1.2 + */ + public static final int VK_FULL_WIDTH = 243; + + /** + * The virtual key VK_HALF_WIDTH. + * + * @since 1.2 + */ + public static final int VK_HALF_WIDTH = 244; + + /** + * The virtual key VK_ROMAN_CHARACTERS. + * + * @since 1.2 + */ public static final int VK_ROMAN_CHARACTERS = 245; - public static final int VK_S = 83; - public static final int VK_SCROLL_LOCK = 145; - public static final int VK_SEMICOLON = 59; - public static final int VK_SEPARATER = 108; - public static final int VK_SHIFT = 16; - public static final int VK_SLASH = 47; - public static final int VK_SPACE = 32; + + /** + * The virtual key VK_ALL_CANDIDATES. + * + * @since 1.2 + */ + public static final int VK_ALL_CANDIDATES = 256; + + /** + * The virtual key VK_PREVIOUS_CANDIDATE. + * + * @since 1.2 + */ + public static final int VK_PREVIOUS_CANDIDATE = 257; + + /** + * The virtual key VK_CODE_INPUT. + * + * @since 1.2 + */ + public static final int VK_CODE_INPUT = 258; + + /** + * The virtual key VK_JAPANESE_KATAKANA. + * + * @since 1.2 + */ + public static final int VK_JAPANESE_KATAKANA = 259; + + /** + * The virtual key VK_JAPANESE_HIRAGANA. + * + * @since 1.2 + */ + public static final int VK_JAPANESE_HIRAGANA = 260; + + /** + * The virtual key VK_JAPANESE_ROMAN. + * + * @since 1.2 + */ + public static final int VK_JAPANESE_ROMAN = 261; + + /** + * The virtual key VK_KANA_LOCK. + * + * @since 1.3 + */ + public static final int VK_KANA_LOCK = 262; + + /** + * The virtual key VK_INPUT_METHOD_ON_OFF. + * + * @since 1.3 + */ + public static final int VK_INPUT_METHOD_ON_OFF = 263; + + /** + * The virtual key VK_CUT. + * + * @since 1.2 + */ + public static final int VK_CUT = 65489; + + /** + * The virtual key VK_COPY. + * + * @since 1.2 + */ + public static final int VK_COPY = 65485; + + /** + * The virtual key VK_PASTE. + * + * @since 1.2 + */ + public static final int VK_PASTE = 65487; + + /** + * The virtual key VK_UNDO. + * + * @since 1.2 + */ + public static final int VK_UNDO = 65483; + + /** + * The virtual key VK_AGAIN. + * + * @since 1.2 + */ + public static final int VK_AGAIN = 65481; + + /** + * The virtual key VK_FIND. + * + * @since 1.2 + */ + public static final int VK_FIND = 65488; + + /** + * The virtual key VK_PROPS. + * + * @since 1.2 + */ + public static final int VK_PROPS = 65482; + + /** + * The virtual key VK_STOP. + * + * @since 1.2 + */ public static final int VK_STOP = 65480; - public static final int VK_SUBTRACT = 109; - public static final int VK_T = 84; - public static final int VK_TAB = 9; - public static final int VK_U = 85; + + /** + * The virtual key VK_COMPOSE. + * + * @since 1.2 + */ + public static final int VK_COMPOSE = 65312; + + /** + * The virtual key VK_ALT_GRAPH. + * + * @since 1.2 + */ + public static final int VK_ALT_GRAPH = 65406; + + /** + * The virtual key VK_UNDEFINED. This is used for key typed events, which + * do not have a virtual key. + */ public static final int VK_UNDEFINED = 0; - public static final int VK_UNDERSCORE = 523; - public static final int VK_UNDO = 65483; - public static final int VK_UP = 38; - public static final int VK_V = 86; - public static final int VK_W = 87; - public static final int VK_X = 88; - public static final int VK_Y = 89; - public static final int VK_Z = 90; - - public KeyEvent (Component source, int id, long when, - int modifiers, int keyCode, char keyChar) + + /** + * The only char with no valid Unicode interpretation. This is used for + * key pressed and key released events which do not have a valid keyChar. + */ + public static final char CHAR_UNDEFINED = '\uffff'; + + /** + * Indicates unknown or irrelavent key location. This is also used for + * key typed events, which do not need a location. + * + * @since 1.4 + */ + public static final int KEY_LOCATION_UNKNOWN = 0; + + /** + * Indicates a standard key location, with no left/right variants and not + * on the numeric pad. + * + * @since 1.4 + */ + public static final int KEY_LOCATION_STANDARD = 1; + + /** + * Indicates the key is on the left side of the keyboard, such as the left + * shift. + * + * @since 1.4 + */ + public static final int KEY_LOCATION_LEFT = 2; + + /** + * Indicates the key is on the right side of the keyboard, such as the right + * shift. + * + * @since 1.4 + */ + public static final int KEY_LOCATION_RIGHT = 3; + + /** + * Indicates the key is on the numeric pad, such as the numpad 0. + * + * @since 1.4 + */ + public static final int KEY_LOCATION_NUMPAD = 4; + + /** + * The code assigned to the physical keyboard location (as adjusted by the + * keyboard layout). Use the symbolic VK_* names instead of numbers. + * + * @see #getKeyCode() + * @serial the VK_ code for this key + */ + private int keyCode; + + /** + * The Unicode character produced by the key type event. This has no meaning + * for key pressed and key released events. + * + * @see #getKeyChar() + * @serial the Unicode value for this key + */ + private char keyChar; + + /** + * The keyboard location of the key. One of {@link #KEY_LOCATION_UNKNOWN}, + * {@link #KEY_LOCATION_STANDARD}, {@link #KEY_LOCATION_LEFT}, + * {@link #KEY_LOCATION_RIGHT}, or {@link #KEY_LOCATION_NUMPAD}. + * + * @see #getKeyLocation() + * @serial the key location + * @since 1.4 + */ + private final int keyLocation; + + /** + * Stores the state of the native event dispatching system, to correctly + * dispatch in Component#dispatchEventImpl when a proxy is active. + * + * XXX Does this matter in Classpath? + * + * @serial whether the proxy is active + */ + private boolean isProxyActive; + + + /** + * Initializes a new instance of <code>KeyEvent</code> with the specified + * information. Note that an invalid id leads to unspecified results. + * + * @param source the component that generated this event + * @param id the event id + * @param when the timestamp when the even occurred + * @param modifiers the modifier keys during the event, in old or new style + * @param keyCode the integer constant for the virtual key type + * @param keyChar the Unicode value of the key + * @param keyLocation the location of the key + * @throws IllegalArgumentException if source is null, if keyLocation is + * invalid, or if (id == KEY_TYPED && (keyCode != VK_UNDEFINED + * || keyChar == CHAR_UNDEFINED)) + */ + public KeyEvent(Component source, int id, long when, int modifiers, + int keyCode, char keyChar, int keyLocation) { - super (source, id); + super(source, id, when, modifiers); this.keyCode = keyCode; this.keyChar = keyChar; - this.modifiers = modifiers; + this.keyLocation = keyLocation; + if ((id == KEY_TYPED && (keyCode != VK_UNDEFINED + || keyChar == CHAR_UNDEFINED)) + || keyLocation < KEY_LOCATION_UNKNOWN + || keyLocation > KEY_LOCATION_NUMPAD) + throw new IllegalArgumentException(); } - public KeyEvent (Component source, int id, long when, - int modifiers, int keyCode) + /** + * Initializes a new instance of <code>KeyEvent</code> with the specified + * information. Note that an invalid id leads to unspecified results. + * + * @param source the component that generated this event + * @param id the event id + * @param when the timestamp when the even occurred + * @param modifiers the modifier keys during the event, in old or new style + * @param keyCode the integer constant for the virtual key type + * @param keyChar the Unicode value of the key + * @throws IllegalArgumentException if source is null, or if + * (id == KEY_TYPED && (keyCode != VK_UNDEFINED + * || keyChar == CHAR_UNDEFINED)) + */ + public KeyEvent(Component source, int id, long when, int modifiers, + int keyCode, char keyChar) { - super (source, id); - this.keyCode = keyCode; - this.keyChar = CHAR_UNDEFINED; // FIXME? - this.modifiers = modifiers; + this(source, id, when, modifiers, keyCode, keyChar, KEY_LOCATION_UNKNOWN); } - public int getKeyCode () { return keyCode; } + /** + * Initializes a new instance of <code>KeyEvent</code> with the specified + * information. Note that an invalid id leads to unspecified results. + * + * @param source the component that generated this event + * @param id the event id + * @param when the timestamp when the even occurred + * @param modifiers the modifier keys during the event, in old or new style + * @param keyCode the integer constant for the virtual key type + * @throws IllegalArgumentException if source is null, or if + * id == KEY_TYPED but keyCode != VK_UNDEFINED + */ + public KeyEvent(Component source, int id, long when, int modifiers, + int keyCode) + { + this(source, id, when, modifiers, keyCode, '\0', KEY_LOCATION_UNKNOWN); + } - public char getKeyChar () { return keyChar; } + /** + * Returns the key code for the event key. This will be one of the + * <code>VK_*</code> constants defined in this class. If the event type is + * KEY_TYPED, the result will be VK_UNDEFINED. + * + * @return the key code for this event + */ + public int getKeyCode() + { + return keyCode; + } - public void setKeyCode (int keyCode) { this.keyCode = keyCode; } + /** + * Sets the key code for this event. This must be one of the + * <code>VK_*</code> constants defined in this class. + * + * @param keyCode the new key code for this event + */ + public void setKeyCode(int keyCode) + { + this.keyCode = keyCode; + } - public void setKeyChar (char keyChar) { this.keyChar = keyChar; } + /** + * Returns the Unicode value for the event key. This will be + * <code>CHAR_UNDEFINED</code> if there is no Unicode equivalent for + * this key, usually when this is a KEY_PRESSED or KEY_RELEASED event. + * + * @return the Unicode character for this event + */ + public char getKeyChar() + { + return keyChar; + } - public void setModifiers (int modifiers) { this.modifiers = modifiers; } + /** + * Sets the Unicode character for this event to the specified value. + * + * @param keyChar the new Unicode character for this event + */ + public void setKeyChar(char keyChar) + { + this.keyChar = keyChar; + } - public static String getKeyText (int keyCode) + /** + * Sets the modifier keys to the specified value. This should be a union + * of the bit mask constants from <code>InputEvent</code>. The use of this + * method is not recommended, particularly for KEY_TYPED events, which do + * not check if the modifiers were changed. + * + * @param modifiers the new modifier value, in either old or new style + * @see InputEvent + */ + public void setModifiers(int modifiers) { - // FIXME - throw new InternalError ("unimplemented"); + this.modifiers = EventModifier.extend(modifiers); } - public static String getKeyModifiersText (int modifiers) + /** + * Returns the keyboard location of the key that generated this event. This + * provides a way to distinguish between keys like left and right shift + * which share a common key code. The result will be one of + * {@link #KEY_LOCATION_UNKNOWN}, {@link #KEY_LOCATION_STANDARD}, + * {@link #KEY_LOCATION_LEFT}, {@link #KEY_LOCATION_RIGHT}, or + * {@link #KEY_LOCATION_NUMPAD}. + * + * @return the key location + * @since 1.4 + */ + public int getKeyLocation() { - // FIXME - throw new InternalError ("unimplemented"); + return keyLocation; } - public boolean isActionKey () + /** + * Returns the text name of key code, such as "HOME", "F1", or "A". + * + * XXX Sun claims this can be localized via the awt.properties file - how + * do we implement that? + * + * @return the text name of the key code + */ + public static String getKeyText(int keyCode) { - // FIXME - return false; + switch (keyCode) + { + case VK_CANCEL: + return "Cancel"; + case VK_BACK_SPACE: + return "Backspace"; + case VK_TAB: + return "Tab"; + case VK_ENTER: + return "Enter"; + case VK_CLEAR: + return "Clear"; + case VK_SHIFT: + return "Shift"; + case VK_CONTROL: + return "Ctrl"; + case VK_ALT: + return "Alt"; + case VK_PAUSE: + return "Pause"; + case VK_CAPS_LOCK: + return "Caps Lock"; + case VK_KANA: + return "Kana"; + case VK_FINAL: + return "Final"; + case VK_KANJI: + return "Kanji"; + case VK_ESCAPE: + return "Escape"; + case VK_CONVERT: + return "Convert"; + case VK_NONCONVERT: + return "No Convert"; + case VK_ACCEPT: + return "Accept"; + case VK_MODECHANGE: + return "Mode Change"; + case VK_SPACE: + return "Space"; + case VK_PAGE_UP: + return "Page Up"; + case VK_PAGE_DOWN: + return "Page Down"; + case VK_END: + return "End"; + case VK_HOME: + return "Home"; + case VK_LEFT: + case VK_KP_LEFT: + return "Left"; + case VK_UP: + case VK_KP_UP: + return "Up"; + case VK_RIGHT: + case VK_KP_RIGHT: + return "Right"; + case VK_DOWN: + case VK_KP_DOWN: + return "Down"; + case VK_MINUS: + return "Minus"; + case VK_MULTIPLY: + return "NumPad *"; + case VK_ADD: + return "NumPad +"; + case VK_SEPARATOR: + return "NumPad ,"; + case VK_SUBTRACT: + return "NumPad -"; + case VK_DECIMAL: + return "NumPad ."; + case VK_DIVIDE: + return "NumPad /"; + case VK_DELETE: + return "Delete"; + case VK_DEAD_GRAVE: + return "Dead Grave"; + case VK_DEAD_ACUTE: + return "Dead Acute"; + case VK_DEAD_CIRCUMFLEX: + return "Dead Circumflex"; + case VK_DEAD_TILDE: + return "Dead Tilde"; + case VK_DEAD_MACRON: + return "Dead Macron"; + case VK_DEAD_BREVE: + return "Dead Breve"; + case VK_DEAD_ABOVEDOT: + return "Dead Above Dot"; + case VK_DEAD_DIAERESIS: + return "Dead Diaeresis"; + case VK_DEAD_ABOVERING: + return "Dead Above Ring"; + case VK_DEAD_DOUBLEACUTE: + return "Dead Double Acute"; + case VK_DEAD_CARON: + return "Dead Caron"; + case VK_DEAD_CEDILLA: + return "Dead Cedilla"; + case VK_DEAD_OGONEK: + return "Dead Ogonek"; + case VK_DEAD_IOTA: + return "Dead Iota"; + case VK_DEAD_VOICED_SOUND: + return "Dead Voiced Sound"; + case VK_DEAD_SEMIVOICED_SOUND: + return "Dead Semivoiced Sound"; + case VK_NUM_LOCK: + return "Num Lock"; + case VK_SCROLL_LOCK: + return "Scroll Lock"; + case VK_AMPERSAND: + return "Ampersand"; + case VK_ASTERISK: + return "Asterisk"; + case VK_QUOTEDBL: + return "Double Quote"; + case VK_LESS: + return "Less"; + case VK_PRINTSCREEN: + return "Print Screen"; + case VK_INSERT: + return "Insert"; + case VK_HELP: + return "Help"; + case VK_META: + return "Meta"; + case VK_GREATER: + return "Greater"; + case VK_BRACELEFT: + return "Left Brace"; + case VK_BRACERIGHT: + return "Right Brace"; + case VK_BACK_QUOTE: + return "Back Quote"; + case VK_QUOTE: + return "Quote"; + case VK_ALPHANUMERIC: + return "Alphanumeric"; + case VK_KATAKANA: + return "Katakana"; + case VK_HIRAGANA: + return "Hiragana"; + case VK_FULL_WIDTH: + return "Full-Width"; + case VK_HALF_WIDTH: + return "Half-Width"; + case VK_ROMAN_CHARACTERS: + return "Roman Characters"; + case VK_ALL_CANDIDATES: + return "All Candidates"; + case VK_PREVIOUS_CANDIDATE: + return "Previous Candidate"; + case VK_CODE_INPUT: + return "Code Input"; + case VK_JAPANESE_KATAKANA: + return "Japanese Katakana"; + case VK_JAPANESE_HIRAGANA: + return "Japanese Hiragana"; + case VK_JAPANESE_ROMAN: + return "Japanese Roman"; + case VK_KANA_LOCK: + return "Kana Lock"; + case VK_INPUT_METHOD_ON_OFF: + return "Input Method On/Off"; + case VK_AT: + return "At"; + case VK_COLON: + return "Colon"; + case VK_CIRCUMFLEX: + return "Circumflex"; + case VK_DOLLAR: + return "Dollar"; + case VK_EURO_SIGN: + return "Euro"; + case VK_EXCLAMATION_POINT: + return "Exclamation Mark"; + case VK_INVERTED_EXCLAMATION_POINT: + return "Inverted Exclamation Mark"; + case VK_LEFT_PARENTHESIS: + return "Left Parenthesis"; + case VK_NUMBER_SIGN: + return "Number Sign"; + case VK_PLUS: + return "Plus"; + case VK_RIGHT_PARENTHESIS: + return "Right Parenthesis"; + case VK_UNDERSCORE: + return "Underscore"; + case VK_COMPOSE: + return "Compose"; + case VK_ALT_GRAPH: + return "Alt Graph"; + case VK_STOP: + return "Stop"; + case VK_AGAIN: + return "Again"; + case VK_PROPS: + return "Props"; + case VK_UNDO: + return "Undo"; + case VK_COPY: + return "Copy"; + case VK_PASTE: + return "Paste"; + case VK_FIND: + return "Find"; + case VK_CUT: + return "Cut"; + case VK_COMMA: + case VK_PERIOD: + case VK_SLASH: + case VK_0: + case VK_1: + case VK_2: + case VK_3: + case VK_4: + case VK_5: + case VK_6: + case VK_7: + case VK_8: + case VK_9: + case VK_SEMICOLON: + case VK_EQUALS: + case VK_A: + case VK_B: + case VK_C: + case VK_D: + case VK_E: + case VK_F: + case VK_G: + case VK_H: + case VK_I: + case VK_J: + case VK_K: + case VK_L: + case VK_M: + case VK_N: + case VK_O: + case VK_P: + case VK_Q: + case VK_R: + case VK_S: + case VK_T: + case VK_U: + case VK_V: + case VK_W: + case VK_X: + case VK_Y: + case VK_Z: + case VK_OPEN_BRACKET: + case VK_BACK_SLASH: + case VK_CLOSE_BRACKET: + return "" + (char) keyCode; + case VK_NUMPAD0: + case VK_NUMPAD1: + case VK_NUMPAD2: + case VK_NUMPAD3: + case VK_NUMPAD4: + case VK_NUMPAD5: + case VK_NUMPAD6: + case VK_NUMPAD7: + case VK_NUMPAD8: + case VK_NUMPAD9: + return "NumPad-" + (char) (keyCode - VK_NUMPAD0); + case VK_F1: + case VK_F2: + case VK_F3: + case VK_F4: + case VK_F5: + case VK_F6: + case VK_F7: + case VK_F8: + case VK_F9: + case VK_F10: + case VK_F11: + case VK_F12: + return "F" + (keyCode - (VK_F1 - 1)); + case VK_F13: + case VK_F14: + case VK_F15: + case VK_F16: + case VK_F17: + case VK_F18: + case VK_F19: + case VK_F20: + case VK_F21: + case VK_F22: + case VK_F23: + case VK_F24: + return "F" + (keyCode - (VK_F13 - 13)); + default: + // This is funky on negative numbers, but that's Sun's fault. + return "Unknown keyCode: 0x" + (keyCode < 0 ? "-" : "") + + Integer.toHexString(Math.abs(keyCode)); + } } - public String paramString () + /** + * Returns a string describing the modifiers, such as "Shift" or + * "Ctrl+Button1". + * + * XXX Sun claims this can be localized via the awt.properties file - how + * do we implement that? + * + * @param modifiers the old-style modifiers to convert to text + * @return a string representation of the modifiers in this bitmask + */ + public static String getKeyModifiersText(int modifiers) { - String r = ""; + return getModifiersExText(EventModifier.extend(modifiers + & EventModifier.OLD_MASK)); + } + + /** + * Tests whether or not this key is an action key. An action key typically + * does not fire a KEY_TYPED event, and is not a modifier. + * + * @return true if this is an action key + */ + public boolean isActionKey() + { + switch (keyCode) + { + case VK_PAUSE: + case VK_CAPS_LOCK: + case VK_KANA: + case VK_FINAL: + case VK_KANJI: + case VK_CONVERT: + case VK_NONCONVERT: + case VK_ACCEPT: + case VK_MODECHANGE: + case VK_PAGE_UP: + case VK_PAGE_DOWN: + case VK_END: + case VK_HOME: + case VK_LEFT: + case VK_UP: + case VK_RIGHT: + case VK_DOWN: + case VK_F1: + case VK_F2: + case VK_F3: + case VK_F4: + case VK_F5: + case VK_F6: + case VK_F7: + case VK_F8: + case VK_F9: + case VK_F10: + case VK_F11: + case VK_F12: + case VK_NUM_LOCK: + case VK_SCROLL_LOCK: + case VK_PRINTSCREEN: + case VK_INSERT: + case VK_HELP: + case VK_KP_UP: + case VK_KP_DOWN: + case VK_KP_LEFT: + case VK_KP_RIGHT: + case VK_ALPHANUMERIC: + case VK_KATAKANA: + case VK_HIRAGANA: + case VK_FULL_WIDTH: + case VK_HALF_WIDTH: + case VK_ROMAN_CHARACTERS: + case VK_ALL_CANDIDATES: + case VK_PREVIOUS_CANDIDATE: + case VK_CODE_INPUT: + case VK_JAPANESE_KATAKANA: + case VK_JAPANESE_HIRAGANA: + case VK_JAPANESE_ROMAN: + case VK_KANA_LOCK: + case VK_INPUT_METHOD_ON_OFF: + case VK_F13: + case VK_F14: + case VK_F15: + case VK_F16: + case VK_F17: + case VK_F18: + case VK_F19: + case VK_F20: + case VK_F21: + case VK_F22: + case VK_F23: + case VK_F24: + case VK_STOP: + case VK_AGAIN: + case VK_PROPS: + case VK_UNDO: + case VK_COPY: + case VK_PASTE: + case VK_FIND: + case VK_CUT: + return true; + default: + return false; + } + } + + /** + * Returns a string identifying the event. This is formatted as the field + * name of the id type, followed by the keyCode, then the keyChar (if + * available), modifiers (if any), extModifiers (if any), and keyLocation. + * The keyChar is available unless the keyCode is Backspace, Tab, Enter, + * Escape, Numpad-[0-9], Delete, or a keyCode which is an action. + * + * @return a string identifying the event + */ + public String paramString() + { + StringBuffer s = new StringBuffer(); switch (id) { - case KEY_PRESSED: - r = "KEY_PRESSED"; - break; - case KEY_RELEASED: - r = "KEY_RELEASED"; - break; - case KEY_TYPED: - r = "KEY_TYPED"; - break; - } - r += ",keyCode=" + keyCode + "," + getKeyText(keyCode) + ",modifiers=" + - getKeyModifiersText(modifiers); - return r; + case KEY_PRESSED: + s.append("KEY_PRESSED,keyCode="); + break; + case KEY_RELEASED: + s.append("KEY_RELEASED,keyCode="); + break; + case KEY_TYPED: + s.append("KEY_TYPED,keyCode="); + break; + default: + s.append("unknown type,keyCode="); + } + s.append(keyCode); + switch (keyCode) + { + default: + if (! isActionKey()) + { + s.append(",keyChar='").append(keyChar).append('\''); + break; + } + // Fallthrough. + case VK_BACK_SPACE: + case VK_TAB: + case VK_ENTER: + case VK_ESCAPE: + case VK_NUMPAD0: + case VK_NUMPAD1: + case VK_NUMPAD2: + case VK_NUMPAD3: + case VK_NUMPAD4: + case VK_NUMPAD5: + case VK_NUMPAD6: + case VK_NUMPAD7: + case VK_NUMPAD8: + case VK_NUMPAD9: + case VK_DELETE: + s.append(',').append(getKeyText(keyCode)); + } + if ((modifiers & CONVERT_MASK) != 0) + s.append(",modifiers=").append(getModifiersExText(modifiers + & CONVERT_MASK)); + if (modifiers != 0) + s.append(",extModifiers=").append(getModifiersExText(modifiers)); + s.append(",keyLocation=KEY_LOCATION_"); + switch (keyLocation) + { + case KEY_LOCATION_UNKNOWN: + s.append("UNKNOWN"); + break; + case KEY_LOCATION_STANDARD: + s.append("STANDARD"); + break; + case KEY_LOCATION_LEFT: + s.append("LEFT"); + break; + case KEY_LOCATION_RIGHT: + s.append("RIGHT"); + break; + case KEY_LOCATION_NUMPAD: + s.append("NUMPAD"); + } + return s.toString(); } - private int keyCode; - private char keyChar; - private int modifiers; -} + /** + * Reads in the object from a serial stream. + * + * @param s the stream to read from + * @throws IOException if deserialization fails + * @throws ClassNotFoundException if deserialization fails + * @serialData default, except that the modifiers are converted to new style + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + modifiers = EventModifier.extend(modifiers); + } +} // class KeyEvent diff --git a/libjava/java/awt/event/KeyListener.java b/libjava/java/awt/event/KeyListener.java index e08d67e214e..7443eedd8fb 100644 --- a/libjava/java/awt/event/KeyListener.java +++ b/libjava/java/awt/event/KeyListener.java @@ -1,23 +1,77 @@ -/* Copyright (C) 1999 Free Software Foundation +/* KeyListener.java -- listen for keyboard presses + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Per Bothner <bothner@cygnus.com> - * @date Fenruary, 1999. + * This interface is for classes that wish to receive keyboard events. To + * watch a subset of these events, use a KeyAdapter. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see KeyAdapter + * @see KeyEvent + * @since 1.1 + * @status updated to 1.4 */ +public interface KeyListener extends EventListener +{ + /** + * This method is called when a key is typed. A key is considered typed + * when it and all modifiers have been pressed and released, mapping to + * a single virtual key. + * + * @param event the <code>KeyEvent</code> indicating that a key was typed + */ + void keyTyped(KeyEvent event); -/* Status: Believed complete and correct. */ + /** + * This method is called when a key is pressed. + * + * @param event the <code>KeyEvent</code> indicating the key press + */ + void keyPressed(KeyEvent event); -public interface KeyListener extends java.util.EventListener -{ - public void keyPressed (KeyEvent w); - public void keyReleased (KeyEvent w); - public void keyTyped (KeyEvent w); -} + /** + * This method is called when a key is released. + * + * @param event the <code>KeyEvent</code> indicating the key release + */ + void keyReleased(KeyEvent event); +} // interface KeyListener diff --git a/libjava/java/awt/event/MouseAdapter.java b/libjava/java/awt/event/MouseAdapter.java index 65189385738..2518d365576 100644 --- a/libjava/java/awt/event/MouseAdapter.java +++ b/libjava/java/awt/event/MouseAdapter.java @@ -1,39 +1,106 @@ -/* Copyright (C) 2000 Free Software Foundation +/* MouseAdapter.java -- convenience class for writing mouse listeners + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class implements <code>MouseListener</code> and implements all methods + * with empty bodies. This allows a listener interested in implementing only + * a subset of the <code>MouseListener</code> interface to extend this class + * and override only the desired methods. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see MouseEvent + * @see MouseListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public abstract class MouseAdapter implements MouseListener { - public void mouseClicked (MouseEvent e) + /** + * Do nothing default constructor for subclasses. + */ + public MouseAdapter() + { + } + + /** + * Implements this method in the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void mouseClicked(MouseEvent event) { } - public void mouseEntered (MouseEvent e) + /** + * Implements this method in the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void mousePressed(MouseEvent event) { } - public void mouseExited (MouseEvent e) + /** + * Implements this method in the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void mouseReleased(MouseEvent event) { } - public void mousePressed (MouseEvent e) + /** + * Implements this method in the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void mouseEntered(MouseEvent event) { } - public void mouseReleased (MouseEvent e) + /** + * Implements this method in the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void mouseExited(MouseEvent event) { } -} +} // class MouseAdapter diff --git a/libjava/java/awt/event/MouseEvent.java b/libjava/java/awt/event/MouseEvent.java index b978f10b5fc..5010eb9d920 100644 --- a/libjava/java/awt/event/MouseEvent.java +++ b/libjava/java/awt/event/MouseEvent.java @@ -1,113 +1,431 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* MouseEvent.java -- a mouse event + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.Component; +import java.awt.Point; +import java.io.IOException; +import java.io.ObjectInputStream; +import gnu.java.awt.EventModifier; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This event is generated for a mouse event. There are three main categories + * of mouse events: Regular events include pressing, releasing, and clicking + * buttons, as well as moving over the boundary of the unobscured portion of + * a component. Motion events include movement and dragging. Wheel events are + * covered separately by the subclass MouseWheelEvent. + * + * <p>A mouse event is tied to the unobstructed visible component that the + * mouse cursor was over at the time of the action. The button that was + * most recently pressed is the only one that shows up in + * <code>getModifiers</code>, and is returned by <code>getButton</code>, + * while all buttons that are down show up in <code>getModifiersEx</code>. + * + * <p>Drag events may be cut short if native drag-and-drop operations steal + * the event. Likewise, if a mouse drag exceeds the bounds of a window or + * virtual device, some platforms may clip the path to fit in the bounds of + * the component. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @see MouseAdapter + * @see MouseListener + * @see MouseMotionAdapter + * @see MouseMotionListener + * @see MouseWheelListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public class MouseEvent extends InputEvent { - public static final int MOUSE_CLICKED = 500; - public static final int MOUSE_DRAGGED = 506; - public static final int MOUSE_ENTERED = 504; - public static final int MOUSE_EXITED = 505; + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = -991214153494842848L; + + /** This is the first id in the range of event ids used by this class. */ public static final int MOUSE_FIRST = 500; - public static final int MOUSE_LAST = 506; - public static final int MOUSE_MOVED = 503; + + /** This is the last id in the range of event ids used by this class. */ + public static final int MOUSE_LAST = 507; + + /** This event id indicates that the mouse was clicked. */ + public static final int MOUSE_CLICKED = 500; + + /** This event id indicates that the mouse was pressed. */ public static final int MOUSE_PRESSED = 501; + + /** This event id indicates that the mouse was released. */ public static final int MOUSE_RELEASED = 502; - public MouseEvent (Component source, int id, long when, int modifiers, - int x, int y, int clickCount, boolean popupTrigger) + /** This event id indicates that the mouse was moved. */ + public static final int MOUSE_MOVED = 503; + + /** This event id indicates that the mouse entered a component. */ + public static final int MOUSE_ENTERED = 504; + + /** This event id indicates that the mouse exited a component. */ + public static final int MOUSE_EXITED = 505; + + /** + * This indicates that no button changed state. + * + * @see #getButton() + * @since 1.4 + */ + public static final int NOBUTTON = 0; + + /** + * This indicates that button 1 changed state. + * + * @see #getButton() + * @since 1.4 + */ + public static final int BUTTON1 = 1; + + /** + * This indicates that button 2 changed state. + * + * @see #getButton() + * @since 1.4 + */ + public static final int BUTTON2 = 2; + + /** + * This indicates that button 3 changed state. + * + * @see #getButton() + * @since 1.4 + */ + public static final int BUTTON3 = 3; + + /** This event id indicates that the mouse was dragged over a component. */ + public static final int MOUSE_DRAGGED = 506; + + /** + * This event id indicates that the mouse wheel was rotated. + * + * @since 1.4 + */ + public static final int MOUSE_WHEEL = 507; + + /** + * The X coordinate of the mouse cursor at the time of the event. + * + * @see #getX() + * @serial the x coordinate + */ + private int x; + + /** + * The Y coordinate of the mouse cursor at the time of the event. + * + * @see #getY() + * @serial the y coordinate + */ + private int y; + + /** + * The number of clicks that took place. For MOUSE_CLICKED, MOUSE_PRESSED, + * and MOUSE_RELEASED, this will be at least 1; otherwise it is 0. + * + * see #getClickCount() + * @serial the number of clicks + */ + private final int clickCount; + + /** + * Indicates which mouse button changed state. Can only be one of + * {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or + * {@link #BUTTON3}. + * + * @see #getButton() + * @since 1.4 + */ + private int button; + + /** + * Whether or not this event should trigger a popup menu. + * + * @see PopupMenu + * @see #isPopupTrigger() + * @serial true if this is a popup trigger + */ + private final boolean popupTrigger; + + /** + * Initializes a new instance of <code>MouseEvent</code> with the specified + * information. Note that an invalid id leads to unspecified results. + * + * @param source the source of the event + * @param id the event id + * @param when the timestamp of when the event occurred + * @param modifiers the modifier keys during the event, in old or new style + * @param x the X coordinate of the mouse point + * @param y the Y coordinate of the mouse point + * @param clickCount the number of mouse clicks for this event + * @param popupTrigger true if this event triggers a popup menu + * @param button the most recent mouse button to change state + * @throws IllegalArgumentException if source is null or button is invalid + * @since 1.4 + */ + public MouseEvent(Component source, int id, long when, int modifiers, + int x, int y, int clickCount, boolean popupTrigger, + int button) { - super (source, id); - this.when = when; - this.modifiers = modifiers; + super(source, id, when, modifiers); this.x = x; this.y = y; this.clickCount = clickCount; this.popupTrigger = popupTrigger; + this.button = button; + if (button < NOBUTTON || button > BUTTON3) + throw new IllegalArgumentException(); + if ((modifiers & EventModifier.OLD_MASK) != 0) + { + if ((modifiers & BUTTON1_MASK) != 0) + button = BUTTON1; + else if ((modifiers & BUTTON2_MASK) != 0) + button = BUTTON2; + else if ((modifiers & BUTTON3_MASK) != 0) + button = BUTTON3; + } } - public int getClickCount () + /** + * Initializes a new instance of <code>MouseEvent</code> with the specified + * information. Note that an invalid id leads to unspecified results. + * + * @param source the source of the event + * @param id the event id + * @param when the timestamp of when the event occurred + * @param modifiers the modifier keys during the event, in old or new style + * @param x the X coordinate of the mouse point + * @param y the Y coordinate of the mouse point + * @param clickCount the number of mouse clicks for this event + * @param popupTrigger true if this event triggers a popup menu + * @throws IllegalArgumentException if source is null + */ + public MouseEvent(Component source, int id, long when, int modifiers, + int x, int y, int clickCount, boolean popupTrigger) { - return clickCount; + this(source, id, when, modifiers, x, y, clickCount, popupTrigger, + NOBUTTON); } - public Point getPoint () + /** + * This method returns the X coordinate of the mouse position. This is + * relative to the source component. + * + * @return the x coordinate + */ + public int getX() { - return new Point (x, y); + return x; } - public int getX () + /** + * This method returns the Y coordinate of the mouse position. This is + * relative to the source component. + * + * @return the y coordinate + */ + public int getY() { - return x; + return y; } - public int getY () + /** + * This method returns a <code>Point</code> for the x,y position of + * the mouse pointer. This is relative to the source component. + * + * @return a <code>Point</code> for the event position + */ + public Point getPoint() { - return y; + return new Point(x, y); } - public boolean isPopupTrigger () + /** + * Translates the event coordinates by the specified x and y offsets. + * + * @param dx the value to add to the X coordinate of this event + * @param dy the value to add to the Y coordiante of this event + */ + public void translatePoint(int dx, int dy) + { + x += dx; + y += dy; + } + + /** + * This method returns the number of mouse clicks associated with this + * event. + * + * @return the number of mouse clicks for this event + */ + public int getClickCount() + { + return clickCount; + } + + /** + * Returns which button, if any, was the most recent to change state. This + * will be one of {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or + * {@link #BUTTON3}. + * + * @return the button that changed state + * @since 1.4 + */ + public int getButton() + { + return button; + } + + /** + * This method tests whether or not the event is a popup menu trigger. This + * should be checked in both MousePressed and MouseReleased to be + * cross-platform compatible, as different systems have different popup + * triggers. + * + * @return true if the event is a popup menu trigger + */ + public boolean isPopupTrigger() { return popupTrigger; } - public String paramString () + /** + * Returns a string describing the modifiers, such as "Shift" or + * "Ctrl+Button1". + * + * XXX Sun claims this can be localized via the awt.properties file - how + * do we implement that? + * + * @param modifiers the old-style modifiers to convert to text + * @return a string representation of the modifiers in this bitmask + */ + public static String getMouseModifiersText(int modifiers) + { + modifiers &= EventModifier.OLD_MASK; + if ((modifiers & BUTTON2_MASK) != 0) + modifiers |= BUTTON2_DOWN_MASK; + if ((modifiers & BUTTON3_MASK) != 0) + modifiers |= BUTTON3_DOWN_MASK; + return getModifiersExText(EventModifier.extend(modifiers)); + } + + /** + * Returns a string identifying this event. This is formatted as the field + * name of the id type, followed by the (x,y) point, the most recent button + * changed, modifiers (if any), extModifiers (if any), and clickCount. + * + * @return a string identifying this event + */ + public String paramString() { - String r; + StringBuffer s = new StringBuffer(); switch (id) { - case MOUSE_CLICKED: - r = "MOUSE_CLICKED"; - break; - case MOUSE_DRAGGED: - r = "MOUSE_DRAGGED"; - break; - case MOUSE_ENTERED: - r = "MOUSE_ENTERED"; - break; - case MOUSE_EXITED: - r = "MOUSE_EXITED"; - break; - case MOUSE_MOVED: - r = "MOUSE_MOVED"; - break; - case MOUSE_PRESSED: - r = "MOUSE_PRESSED"; - break; - case MOUSE_RELEASED: - r = "MOUSE_RELEASED"; - break; - default: - r = "unknown id"; - break; + case MOUSE_CLICKED: + s.append("MOUSE_CLICKED,("); + break; + case MOUSE_PRESSED: + s.append("MOUSE_PRESSED,("); + break; + case MOUSE_RELEASED: + s.append("MOUSE_RELEASED,("); + break; + case MOUSE_MOVED: + s.append("MOUSE_MOVED,("); + break; + case MOUSE_ENTERED: + s.append("MOUSE_ENTERED,("); + break; + case MOUSE_EXITED: + s.append("MOUSE_EXITED,("); + break; + case MOUSE_DRAGGED: + s.append("MOUSE_DRAGGED,("); + break; + case MOUSE_WHEEL: + s.append("MOUSE_WHEEL,("); + break; + default: + s.append("unknown type,("); + } + s.append(x).append(',').append(y).append("),button=").append(button); + if ((modifiers & EventModifier.NEW_MASK) != 0) + { + int mod = modifiers; + if ((mod & (ALT_DOWN_MASK | BUTTON2_DOWN_MASK)) != 0) + mod |= ALT_DOWN_MASK | BUTTON2_DOWN_MASK; + if ((mod & (META_DOWN_MASK | BUTTON3_DOWN_MASK)) != 0) + mod |= META_DOWN_MASK | BUTTON3_DOWN_MASK; + s.append(",modifiers=").append(getModifiersExText(mod)); } - r += ",(" + x + "," + y + "),modifiers=" + modifiers + ",clickCount=" + - clickCount; - return r; + if (modifiers != 0) + s.append(",extModifiers=").append(getModifiersExText(modifiers)); + return s.append(",clickCount=").append(clickCount).toString(); } - public void translatePoint (int x, int y) + /** + * Reads in the object from a serial stream. + * + * @param s the stream to read from + * @throws IOException if deserialization fails + * @throws ClassNotFoundException if deserialization fails + * @serialData default, except that the modifiers are converted to new style + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { - this.x += x; - this.y += y; + s.defaultReadObject(); + if ((modifiers & EventModifier.OLD_MASK) != 0) + { + if ((modifiers & BUTTON1_MASK) != 0) + button = BUTTON1; + else if ((modifiers & BUTTON2_MASK) != 0) + button = BUTTON2; + else if ((modifiers & BUTTON3_MASK) != 0) + button = BUTTON3; + modifiers = EventModifier.extend(modifiers); + } } - - private int x; - private int y; - private int clickCount; - private boolean popupTrigger; -} +} // class MouseEvent diff --git a/libjava/java/awt/event/MouseListener.java b/libjava/java/awt/event/MouseListener.java index 0f1b8243d8c..6162b089769 100644 --- a/libjava/java/awt/event/MouseListener.java +++ b/libjava/java/awt/event/MouseListener.java @@ -1,25 +1,94 @@ -/* Copyright (C) 2000 Free Software Foundation +/* MouseListener.java -- listen for mouse clicks and crossing component edges + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This interface is for classes that wish to receive mouse events other than + * simple motion events. This includes clicks (but not mouse wheel events), + * and crossing component boundaries without change in button status. To + * track moves and drags, use MouseMotionListener, and to track wheel events, + * use MouseWheelListener. To watch a subset of these events, use a + * MouseAdapter. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see MouseAdapter + * @see MouseEvent + * @since 1.1 + * @status updated to 1.4 */ +public interface MouseListener extends EventListener +{ + /** + * This method is called when the mouse is clicked (pressed and released + * in short succession) on a component. + * + * @param event the <code>MouseEvent</code> indicating the click + */ + void mouseClicked(MouseEvent event); -/* Status: Believed complete and correct to JDK 1.2. */ + /** + * This method is called when the mouse is pressed over a component. + * + * @param event the <code>MouseEvent</code> for the press + */ + void mousePressed(MouseEvent event); -public interface MouseListener extends java.util.EventListener -{ - public void mouseClicked (MouseEvent e); - public void mouseEntered (MouseEvent e); - public void mouseExited (MouseEvent e); - public void mousePressed (MouseEvent e); - public void mouseReleased (MouseEvent e); -} + /** + * This method is called when the mouse is released over a component. + * + * @param event the <code>MouseEvent</code> for the release + */ + void mouseReleased(MouseEvent event); + + /** + * This method is called when the mouse enters a component. + * + * @param event the <code>MouseEvent</code> for the entry + */ + void mouseEntered(MouseEvent event); + + /** + * This method is called when the mouse exits a component. + * + * @param event the <code>MouseEvent</code> for the exit + */ + void mouseExited(MouseEvent event); +} // interface MouseListener diff --git a/libjava/java/awt/event/MouseMotionAdapter.java b/libjava/java/awt/event/MouseMotionAdapter.java index ce30d2eb5c3..cc7498820c7 100644 --- a/libjava/java/awt/event/MouseMotionAdapter.java +++ b/libjava/java/awt/event/MouseMotionAdapter.java @@ -1,27 +1,79 @@ -/* Copyright (C) 2000 Free Software Foundation +/* MouseMotionAdapter.java -- convenience class for mouse motion listeners + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This class implements <code>MouseMotionListener</code> and implements all + * methods with empty bodies. This allows a listener interested in + * implementing only a subset of the <code>MouseMotionListener</code> + * interface to extend this class and override only the desired methods. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see MouseEvent + * @see MouseMotionListener + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public abstract class MouseMotionAdapter implements MouseMotionListener { - public void mouseDragged (MouseEvent e) + /** + * Do nothing default constructor for subclasses. + */ + public MouseMotionAdapter() + { + } + + /** + * Implement this method in the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void mouseDragged(MouseEvent event) { } - public void mouseMoved (MouseEvent e) + /** + * Implement this method in the interface with an empty body. + * + * @param event the event, ignored in this implementation + */ + public void mouseMoved(MouseEvent event) { } -} +} // class MouseMotionAdapter diff --git a/libjava/java/awt/event/MouseMotionListener.java b/libjava/java/awt/event/MouseMotionListener.java index 6b12da5da3e..16ced33c1f4 100644 --- a/libjava/java/awt/event/MouseMotionListener.java +++ b/libjava/java/awt/event/MouseMotionListener.java @@ -1,22 +1,72 @@ -/* Copyright (C) 2000 Free Software Foundation +/* MouseMotionListener.java -- listen to mouse motion events + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This interface is for classes that wish to be notified of mouse movements. + * This includes moves and drags, but not crossing component boundaries. To + * track other mouse events, use MouseListener or MouseWheelListener. To + * watch a subset of these events, use a MouseMotionAdapter. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see MouseMotionAdapter + * @see MouseEvent + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - -public interface MouseMotionListener extends java.util.EventListener +public interface MouseMotionListener extends EventListener { - public void mouseDragged (MouseEvent e); - public void mouseMoved (MouseEvent e); -} + /** + * This method is called when the mouse is moved over a component + * while a button has been pressed. + * + * @param event the <code>MouseEvent</code> indicating the motion + */ + void mouseDragged(MouseEvent event); + + /** + * This method is called when the mouse is moved over a component + * while no button is pressed. + * + * @param event the <code>MouseEvent</code> indicating the motion + */ + void mouseMoved(MouseEvent event); +} // interface MouseMotionListener diff --git a/libjava/java/awt/event/MouseWheelEvent.java b/libjava/java/awt/event/MouseWheelEvent.java new file mode 100644 index 00000000000..be2366a19ee --- /dev/null +++ b/libjava/java/awt/event/MouseWheelEvent.java @@ -0,0 +1,227 @@ +/* MouseWheelEvent.java -- a mouse wheel event + 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.event; + +import java.awt.Component; +import java.awt.Point; + +/** + * This event is generated for a mouse wheel rotation. The wheel (the middle + * mouse button on most modern mice) can be rotated towards or away from the + * user, and is ofteh used for scrolling. + * + * <p>Because of the special use for scrolling components, MouseWheelEvents + * often affect a different component than the one located at the point of + * the event. If the component under the mouse cursor does not accept wheel + * events, the event is passed to the first ancestor container which does. This + * is often a ScrollPane, which knows how to scroll. If an AWT component is + * built from a native widget that knows how to use mouse wheel events, that + * component will consume the event. + * + * <p>The two most common scroll types are "units" (lines at a time) or + * "blocks" (pages at a time). The initial setting is taken from the platform, + * although the user can adjust the setting at any time. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see MouseWheelListener + * @see ScrollPane + * @see ScrollPane#setWheelScrollingEnabled(boolean) + * @see JScrollPane + * @see JScrollPane#setWheelScrollingEnabled(boolean) + * @since 1.4 + * @status updated to 1.4 + */ +public class MouseWheelEvent extends MouseEvent +{ + /** + * Compatible with JDK 1.4+. + */ + private static final long serialVersionUID = 6459879390515399677L; + + /** + * Indicates scrolling by units (lines). + * + * @see #getScrollType() + */ + public static final int WHEEL_UNIT_SCROLL = 0; + + /** + * Indicates scrolling by blocks (pages). + * + * @see #getScrollType() + */ + public static final int WHEEL_BLOCK_SCROLL = 1; + + /** + * Indicates what scroll type should take place. This should be limited + * to {@link #WHEEL_UNIT_SCROLL} and {@link #WHEEL_BLOCK_SCROLL}. + * + * @serial the scroll type + */ + private final int scrollType; + + /** + * Indicates the scroll amount. This is only meaningful if scrollType is + * WHEEL_UNIT_SCROLL. + * + * @serial the number of lines to scroll + */ + private final int scrollAmount; + + /** + * Indicates how far the mouse wheel was rotated. + * + * @serial the rotation amount + */ + private final int wheelRotation; + + /** + * Initializes a new instance of <code>MouseWheelEvent</code> with the + * specified information. Note that an invalid id leads to unspecified + * results. + * + * @param source the source of the event + * @param id the event id + * @param when the timestamp of when the event occurred + * @param modifiers any modifier bits for this event + * @param x the X coordinate of the mouse point + * @param y the Y coordinate of the mouse point + * @param clickCount the number of mouse clicks for this event + * @param popupTrigger true if this event triggers a popup menu + * @param scrollType one of {@link #WHEEL_UNIT_SCROLL}, + * {@link #WHEEL_BLOCK_SCROLL} + * @param scrollAmount the number of units to scroll, ignored for block type + * @param wheelRotation the number of rotation "clicks" + * @throws IllegalArgumentException if source is null + * @see MouseEvent#MouseEvent(Component, int, long, int, int, int, int, + * boolean) + */ + public MouseWheelEvent(Component source, int id, long when, int modifiers, + int x, int y, int clickCount, boolean popupTrigger, + int scrollType, int scrollAmount, int wheelRotation) + { + super(source, id, when, modifiers, x, y, clickCount, popupTrigger); + this.scrollType = scrollType; + this.scrollAmount = scrollAmount; + this.wheelRotation = wheelRotation; + } + + /** + * This method returns the scrolling pattern this event requests. Legal + * values are WHEEL_UNIT_SCROLL and WHEEL_BLOCK_SCROLL. + * + * @return the scroll type + * @see Adjustable#getUnitIncrement() + * @see Adjustable#getBlockIncrement() + * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int) + * @see Scrollable#getScrollableBlockIncrement(Rectangle, int, int) + */ + public int getScrollType() + { + return scrollType; + } + + /** + * Returns the number of units to scroll in response to this event. This + * only makes sense when the scroll type is WHEEL_UNIT_SCROLL. + * + * @return the number of scroll units, if defined + * @see #getScrollType() + */ + public int getScrollAmount() + { + return scrollAmount; + } + + /** + * Gets the number of "clicks" the wheel was rotated. Negative values move + * up (away) from the user, positive values move down (towards) the user. + * + * @return the number of rotation clicks + */ + public int getWheelRotation() + { + return wheelRotation; + } + + /** + * This is a convenience method which aids in a common listener for scrolling + * a scrollpane (although this is already built into ScrollPane and + * JScrollPane). This method only makes sense when getScrollType() returns + * WHEEL_UNIT_SCROLL. + * + * <p>This accounts for direction of scroll and amount of wheel movement, as + * interpreted by the platform settings. + * + * @return the number of units to scroll + * @see #getScrollType() + * @see #getScrollAmount() + * @see MouseWheelListener + * @see Adjustable + * @see Adjustable#getUnitIncrement() + * @see Scrollable + * @see Scrollable#getScrollableUnitIncrement(Rectangle, int, int) + * @see ScrollPane + * @see ScrollPane#setWheelScrollingEnabled(boolean) + * @see JScrollPane + * @see JScrollPane#setWheelScrollingEnabled(boolean) + */ + public int getUnitsToScroll() + { + return wheelRotation * scrollAmount; + } + + /** + * Returns a string identifying this event. For mouse wheel events, this + * is <code>super.paramString() + ",scrollType=WHEEL_" + + * (getScrollType() == WHEEL_UNIT_SCROLL ? "UNIT" : "BLOCK") + * + "_SCROLL,scrollAmount=" + getScrollAmount() + ",wheelRotation=" + * + getWheelRotation()</code>. + * + * @return a string identifying this event + */ + public String paramString() + { + return super.paramString() + ",scrollType=" + + (scrollType == WHEEL_UNIT_SCROLL ? "WHEEL_UNIT_SCROLL" + : scrollType == WHEEL_BLOCK_SCROLL ? "WHEEL_BLOCK_SCROLL" + : "unknown scroll type") + + ",scrollAmount=" + scrollAmount + ",wheelRotation=" + wheelRotation; + } +} // class MouseWheelEvent diff --git a/libjava/java/awt/event/MouseWheelListener.java b/libjava/java/awt/event/MouseWheelListener.java new file mode 100644 index 00000000000..15cbd0370f1 --- /dev/null +++ b/libjava/java/awt/event/MouseWheelListener.java @@ -0,0 +1,60 @@ +/* MouseWheelListener.java -- listen for mouse wheel events + 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.event; + +import java.util.EventListener; + +/** + * This interface is for classes that wish to receive mouse wheel events. For + * other events, use MouseListener or MouseMotionListener. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see MouseWheelEvent + * @since 1.4 + * @status updated to 1.4 + */ +public interface MouseWheelListener extends EventListener +{ + /** + * This method is called when the mouse wheel is rotated. + * + * @param event the <code>MouseWheelEvent</code> indicating the rotation + */ + void mouseWheelMoved(MouseWheelEvent event); +} // interface MouseWheelListener diff --git a/libjava/java/awt/event/PaintEvent.java b/libjava/java/awt/event/PaintEvent.java index 21c42e49a7c..107c6b390b6 100644 --- a/libjava/java/awt/event/PaintEvent.java +++ b/libjava/java/awt/event/PaintEvent.java @@ -1,63 +1,127 @@ -/* Copyright (C) 2000 Free Software Foundation +/* PaintEvent.java -- an area of the screen needs to be repainted + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; + +import java.awt.Component; +import java.awt.Rectangle; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date April 8, 2000 + * This event is generated when an area of the screen needs to be painted. + * This event is not meant for users, but exists to allow proper serialization + * behavior in the EventQueue with user-accessible events. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct to JDK 1.2. */ - public class PaintEvent extends ComponentEvent { - public static final int PAINT = 800; + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = 1267492026433337593L; + + /** This is the first id in the range of event ids used by this class. */ public static final int PAINT_FIRST = 800; + + /** This is the last id in the range of event ids used by this class. */ public static final int PAINT_LAST = 801; + + /** This id is for paint event types. */ + public static final int PAINT = 800; + + /** This id is for update event types. */ public static final int UPDATE = 801; - public PaintEvent (Component source, int id, Rectangle updateRect) + /** + * This is the rectange to be painted or updated. + * + * @see #getUpdateRect() + * @see #setUpdateRect(Rectangle) + * @serial the non-null rectangle to be painted + */ + private Rectangle updateRect; + + /** + * Initializes a new instance of <code>PaintEvent</code> with the specified + * source, id, and update region. Note that an invalid id leads to + * unspecified results. + * + * @param source the event source + * @param id the event id + * @param updateRect the rectangle to repaint + * @throws IllegalArgumentException if source is null + */ + public PaintEvent(Component source, int id, Rectangle updateRect) { - super (source, id); + super(source, id); this.updateRect = updateRect; } - public Rectangle getUpdateRect () + /** + * Returns the rectange to be updated for this event. + * + * @return the rectangle to update + */ + public Rectangle getUpdateRect() { return updateRect; } - public String paramString () + /** + * Sets the rectangle to be updated for this event. + * + * @param updateRect the new update rectangle for this event + */ + public void setUpdateRect(Rectangle updateRect) { - String r; - switch (id) - { - case UPDATE: - r = "UPDATE"; - break; - case PAINT: - r = "PAINT"; - break; - default: - r = "unknown id"; - break; - } - - r += ",updateRect=" + updateRect; - return r; + this.updateRect = updateRect; } - public void setUpdateRect (Rectangle updateRect) + /** + * Returns a string identifying this event. + * + * @return a string identifying this event + */ + public String paramString() { - this.updateRect = updateRect; + return (id == PAINT ? "PAINT,updateRect=" : id == UPDATE + ? "UPDATE,updateRect=" : "unknown type,updateRect=") + updateRect; } - - private Rectangle updateRect; -} +} // class PaintEvent diff --git a/libjava/java/awt/event/TextEvent.java b/libjava/java/awt/event/TextEvent.java index 85c5d85a4eb..58d9ab6086f 100644 --- a/libjava/java/awt/event/TextEvent.java +++ b/libjava/java/awt/event/TextEvent.java @@ -1,29 +1,92 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* TextEvent.java -- event for text changes + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; -/* Status: Believed complete and correct to JDK 1.2. */ +import java.awt.AWTEvent; +/** + * This event is generated when a text box changes contents. This is an + * abstraction that distills a large number of individual mouse or keyboard + * events into a simpler "text changed" event. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see TextComponent + * @see TextListener + * @since 1.1 + * @status updated to 1.4 + */ public class TextEvent extends AWTEvent { + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = 6269902291250941179L; + + /** This is the first id in the range of event ids used by this class. */ public static final int TEXT_FIRST = 900; + + /** This is the last id in the range of event ids used by this class. */ public static final int TEXT_LAST = 900; + + /** This event id indicates that the text of an object has changed. */ public static final int TEXT_VALUE_CHANGED = 900; - public TextEvent (Object source, int id) + /** + * Initializes a new instance of <code>TextEvent</code> with the specified + * source and id. Note that an invalid id leads to unspecified results. + * + * @param source the (TextComponent) object that generated this event + * @param id the event id + * @throws IllegalArgumentException if source is null + */ + public TextEvent(Object source, int id) { - super (source, id); + super(source, id); } - public String paramString () + /** + * Returns a string identifying this event. This is "TEXT_VALUE_CHANGED". + * + * @return a string identifying this event + */ + public String paramString() { - return "TEXT_VALUE_CHANGED"; + return id == TEXT_VALUE_CHANGED ? "TEXT_VALUE_CHANGED" : "unknown type"; } -} +} // class TextEvent diff --git a/libjava/java/awt/event/TextListener.java b/libjava/java/awt/event/TextListener.java index 45c4da898ee..efdd103d509 100644 --- a/libjava/java/awt/event/TextListener.java +++ b/libjava/java/awt/event/TextListener.java @@ -1,22 +1,60 @@ -/* Copyright (C) 1999 Free Software Foundation +/* TextListener.java -- listen for text changes + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Per Bothner <bothner@cygnus.com> - * @date Fenruary, 1999. + * This interface is for classes that wish to be notified when text changes + * in a component. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see TextEvent + * @since 1.1 + * @status updated to 1.4 */ - -/* Status: Believed complete and correct. */ - -public interface TextListener extends java.util.EventListener +public interface TextListener extends EventListener { - public void textValueChanged (TextEvent w); -} - + /** + * This method is called when the text being monitored changes. + * + * @param event the <code>TextEvent</code> indicating the change + */ + void textValueChanged(TextEvent event); +} // interface TextListener diff --git a/libjava/java/awt/event/WindowAdapter.java b/libjava/java/awt/event/WindowAdapter.java index d264756f370..5dea18c3e8f 100644 --- a/libjava/java/awt/event/WindowAdapter.java +++ b/libjava/java/awt/event/WindowAdapter.java @@ -1,27 +1,156 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* WindowAdapter.java -- convenience class for writing window listeners + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; /** - * @author Per Bothner <bothner@cygnus.com> - * @date February, 1999. + * This class implements <code>WindowListener</code>, + * <code>WindowStateListener</code>, and <code>WindowFocusListener</code>, and + * implements all methods with empty bodies. This allows a listener + * interested in listening to only a subset of any <code>WindowEvent</code> + * actions to extend this class and override only the desired methods. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see ComponentEvent + * @see ComponentListener + * @since 1.1 + * @status updated to 1.4 */ +public abstract class WindowAdapter + implements WindowListener, WindowStateListener, WindowFocusListener +{ + /** + * Do nothing default constructor for subclasses. + */ + public WindowAdapter() + { + } -/* Status: Believed complete and correct. */ + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void windowOpened(WindowEvent event) + { + } -public abstract class WindowAdapter implements WindowListener -{ - public void windowActivated (WindowEvent w) { } - public void windowClosed (WindowEvent w) { } - public void windowClosing (WindowEvent w) { } - public void windowDeactivated (WindowEvent w) { } - public void windowDeiconified (WindowEvent w) { } - public void windowIconified (WindowEvent w) { } - public void windowOpened (WindowEvent w) { } -} + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void windowClosing(WindowEvent event) + { + } + + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void windowClosed(WindowEvent event) + { + } + + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void windowIconified(WindowEvent event) + { + } + + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void windowDeiconified(WindowEvent event) + { + } + + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void windowActivated(WindowEvent event) + { + } + + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + */ + public void windowDeactivated(WindowEvent event) + { + } + + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + * @since 1.4 + */ + public void windowStateChanged(WindowEvent event) + { + } + + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + * @since 1.4 + */ + public void windowGainedFocus(WindowEvent event) + { + } + + /** + * Implements this method from the interface with an empty method body. + * + * @param event the event, ignored in this implementation + * @since 1.4 + */ + public void windowLostFocus(WindowEvent event) + { + } +} // class WindowAdapter diff --git a/libjava/java/awt/event/WindowEvent.java b/libjava/java/awt/event/WindowEvent.java index 28108f8e4a8..ca51ba545b4 100644 --- a/libjava/java/awt/event/WindowEvent.java +++ b/libjava/java/awt/event/WindowEvent.java @@ -1,65 +1,311 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* WindowEvent.java -- window change event + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; -import java.awt.*; -/* Status: Believed complete and correct to JDK 1.2. */ +import java.awt.Window; +/** + * This event is generated when there is a change in a window. This includes + * creation, closing, iconification, activation, and focus changes. There + * are three listeners, for three types of events: WindowListeners deal with + * the lifecycle of a window, WindowStateListeners deal with window state + * like maximization, and WindowFocusListeners deal with focus switching to + * or from a window. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see WindowAdapter + * @see WindowListener + * @see WindowFocusListener + * @see WindowStateListener + * @since 1.1 + * @status updated to 1.4 + */ public class WindowEvent extends ComponentEvent { - public static final int WINDOW_ACTIVATED = 205; - public static final int WINDOW_CLOSED = 202; - public static final int WINDOW_CLOSING = 201; - public static final int WINDOW_DEACTIVATED = 206; - public static final int WINDOW_DEICONIFIED = 204; + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = -1567959133147912127L; + + /** This is the first id in the range of event ids used by this class. */ public static final int WINDOW_FIRST = 200; - public static final int WINDOW_ICONIFIED = 203; - public static final int WINDOW_LAST = 206; + + /** This is the id for a window that is opened. */ public static final int WINDOW_OPENED = 200; - public WindowEvent (Window source, int id) + /** This is the id for a window that is about to close. */ + public static final int WINDOW_CLOSING = 201; + + /** This is the id for a window that finished closing. */ + public static final int WINDOW_CLOSED = 202; + + /** This is the id for a window that is iconified. */ + public static final int WINDOW_ICONIFIED = 203; + + /** This is the id for a window that is de-iconified. */ + public static final int WINDOW_DEICONIFIED = 204; + + /** This is the id for a window that is activated. */ + public static final int WINDOW_ACTIVATED = 205; + + /** This is the id for a window that is de-activated. */ + public static final int WINDOW_DEACTIVATED = 206; + + /** + * This is the id for a window becoming the focused window. + * + * @since 1.4 + */ + public static final int WINDOW_GAINED_FOCUS = 207; + + /** + * This is the id for a window losing all focus. + * + * @since 1.4 + */ + public static final int WINDOW_LOST_FOCUS = 208; + + /** + * This is the id for a window state change, such as maximization. + * + * @since 1.4 + */ + public static final int WINDOW_STATE_CHANGED = 209; + + /** This is the last id in the range of event ids used by this class. */ + public static final int WINDOW_LAST = 207; + + /** + * The other Window involved in a focus or activation change. For + * WINDOW_ACTIVATED and WINDOW_GAINED_FOCUS events, this is the window that + * lost focus; for WINDOW_DEACTIVATED and WINDOW_LOST_FOCUS, this is the + * window that stole focus; and for other events (or when native + * implementation does not have the data available), this is null. + * + * @see #getOppositeWindow() + * @serial the opposite window, or null + * @since 1.4 + */ + private final Window opposite; + + /** + * The former state of the window. + * + * @serial bitmask of the old window state + * @since 1.4 + */ + private final int oldState; + + /** + * The present state of the window. + * + * @serial bitmask of the new window state + * @since 1.4 + */ + private final int newState; + + /** + * Initializes a new instance of <code>WindowEvent</code> with the specified + * parameters. Note that an invalid id leads to unspecified results. + * + * @param source the window that generated this event + * @param id the event id + * @param opposite the window that received the opposite event, or null + * @param oldState the previous state of this window + * @param newState the new state of this window + * @throws IllegalArgumentException if source is null + * @since 1.4 + */ + public WindowEvent(Window source, int id, Window opposite, + int oldState, int newState) + { + super(source, id); + this.opposite = opposite; + this.oldState = oldState; + this.newState = newState; + } + + /** + * Initializes a new instance of <code>WindowEvent</code> with the specified + * parameters. Note that an invalid id leads to unspecified results. + * + * @param source the window that generated this event + * @param id the event id + * @param opposite the window that received the opposite event, or null + * @throws IllegalArgumentException if source is null + * @since 1.4 + */ + public WindowEvent(Window source, int id, Window opposite) + { + this(source, id, opposite, 0, 0); + } + + /** + * Initializes a new instance of <code>WindowEvent</code> with the specified + * parameters. Note that an invalid id leads to unspecified results. + * + * @param source the window that generated this event + * @param id the event id + * @param oldState the previous state of this window + * @param newState the new state of this window + * @throws IllegalArgumentException if source is null + * @since 1.4 + */ + public WindowEvent(Window source, int id, int oldState, int newState) + { + this(source, id, null, oldState, newState); + } + + /** + * Initializes a new instance of <code>WindowEvent</code> with the specified + * parameters. Note that an invalid id leads to unspecified results. + * + * @param source the window that generated this event + * @param id the event id + * @throws IllegalArgumentException if source is null + */ + public WindowEvent(Window source, int id) + { + this(source, id, null, 0, 0); + } + + /** + * Returns the event source as a <code>Window</code>. If the source has + * subsequently been modified to a non-Window, this returns null. + * + * @return the event source as a <code>Window</code> + */ + public Window getWindow() + { + return source instanceof Window ? (Window) source : null; + } + + /** + * Returns the opposite window if this window was involved in an activation + * or focus change. For WINDOW_ACTIVATED and WINDOW_GAINED_FOCUS events, + * this is the window that lost focus; for WINDOW_DEACTIVATED and + * WINDOW_LOST_FOCUS, this is the window that stole focus; and for other + * events (or when native implementation does not have the data available), + * this is null. + * + * @return the opposite window, or null + * @since 1.4 + */ + public Window getOppositeWindow() + { + return opposite; + } + + /** + * Returns the state of this window before the event. This is the bitwise + * or of fields in Frame: NORMAL, ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT, + * and MAXIMIZED_BOTH. + * + * @return the former state + * @see Frame#getExtendedState() + * @since 1.4 + */ + public int getOldState() { - super (source, id); + return oldState; } - public Window getWindow () + /** + * Returns the state of this window after the event. This is the bitwise + * or of fields in Frame: NORMAL, ICONIFIED, MAXIMIZED_HORIZ, MAXIMIZED_VERT, + * and MAXIMIZED_BOTH. + * + * @return the updated state + * @see Frame#getExtendedState() + * @since 1.4 + */ + public int getNewState() { - return (Window) source; + return newState; } - public String paramString () + /** + * Returns a string that identifies this event. This is formatted as the + * field name of the id, followed by the opposite window, old state, and + * new state. + * + * @return a string that identifies this event + */ + public String paramString() { - String r = ""; + StringBuffer s = new StringBuffer(); switch (id) { - case WINDOW_ACTIVATED: - r = "WINDOW_ACTIVATED"; - break; - case WINDOW_CLOSED: - r = "WINDOW_CLOSED"; - break; - case WINDOW_CLOSING: - r = "WINDOW_CLOSING"; - break; - case WINDOW_DEACTIVATED: - r = "WINDOW_DEACTIVATED"; - break; - case WINDOW_DEICONIFIED: - r = "WINDOW_DEICONIFIED"; - break; - case WINDOW_ICONIFIED: - r = "WINDOW_ICONIFIED"; - break; - case WINDOW_OPENED: - r = "WINDOW_OPENED"; - break; + case WINDOW_OPENED: + s.append("WINDOW_OPENED,opposite="); + break; + case WINDOW_CLOSING: + s.append("WINDOW_CLOSING,opposite="); + break; + case WINDOW_CLOSED: + s.append("WINDOW_CLOSED,opposite="); + break; + case WINDOW_ICONIFIED: + s.append("WINDOW_ICONIFIED,opposite="); + break; + case WINDOW_DEICONIFIED: + s.append("WINDOW_DEICONIFIED,opposite="); + break; + case WINDOW_ACTIVATED: + s.append("WINDOW_ACTIVATED,opposite="); + break; + case WINDOW_DEACTIVATED: + s.append("WINDOW_DEACTIVATED,opposite="); + break; + case WINDOW_GAINED_FOCUS: + s.append("WINDOW_GAINED_FOCUS,opposite="); + break; + case WINDOW_LOST_FOCUS: + s.append("WINDOW_LOST_FOCUS,opposite="); + break; + case WINDOW_STATE_CHANGED: + s.append("WINDOW_STATE_CHANGED,opposite="); + break; + default: + s.append("unknown type,opposite="); } - return r; + return s.append(opposite).append(",oldState=").append(oldState) + .append(",newState=").append(newState).toString(); } -} +} // class WindowEvent diff --git a/libjava/java/awt/event/WindowFocusListener.java b/libjava/java/awt/event/WindowFocusListener.java new file mode 100644 index 00000000000..de684fbfce1 --- /dev/null +++ b/libjava/java/awt/event/WindowFocusListener.java @@ -0,0 +1,68 @@ +/* WindowFocusListener.java -- listens for window focus events + 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.event; + +import java.util.EventListener; + +/** + * This interface is for classes that wish to monitor events for window + * focus changes. To watch a subset of these events, use a WindowAdapter. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see WindowAdapter + * @see WindowEvent + * @since 1.4 + * @status updated to 1.4 + */ +public interface WindowFocusListener extends EventListener +{ + /** + * This method is called when a window gains focus. + * + * @param event the <code>WindowEvent</code> indicating the focus change + */ + void windowGainedFocus(WindowEvent event); + + /** + * This method is called when a window loses focus. + * + * @param event the <code>WindowEvent</code> indicating the focus change + */ + void windowLostFocus(WindowEvent event); +} // interface WindowFocusListener diff --git a/libjava/java/awt/event/WindowListener.java b/libjava/java/awt/event/WindowListener.java index e939ce7dcf6..ab22c8fb826 100644 --- a/libjava/java/awt/event/WindowListener.java +++ b/libjava/java/awt/event/WindowListener.java @@ -1,27 +1,107 @@ -/* Copyright (C) 1999 Free Software Foundation +/* WindowListener.java -- listens for window events + Copyright (C) 1999, 2002 Free Software Foundation, Inc. - This file is part of libjava. +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. */ -This software is copyrighted work licensed under the terms of the -Libjava License. Please consult the file "LIBJAVA_LICENSE" for -details. */ package java.awt.event; +import java.util.EventListener; + /** - * @author Per Bothner <bothner@cygnus.com> - * @date Fenruary, 1999. + * This interface is for classes that wish to monitor events for window + * changes. To watch a subset of these events, use a WindowAdapter. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @see WindowAdapter + * @see WindowEvent + * @since 1.1 + * @status updated to 1.4 */ +public interface WindowListener extends EventListener +{ + /** + * This method is called when the window is made visible. + * + * @param event the <code>WindowEvent</code> indicating the change + */ + void windowOpened(WindowEvent event); -/* Status: Believed complete and correct. */ + /** + * This method is called when the user calls the system menu close + * function, giving the program a chance to cancel the close. + * + * @param event the <code>WindowEvent</code> indicating the close attempt + */ + void windowClosing(WindowEvent event); -public interface WindowListener extends java.util.EventListener -{ - public void windowActivated (WindowEvent w); - public void windowClosed (WindowEvent w); - public void windowClosing (WindowEvent w); - public void windowDeactivated (WindowEvent w); - public void windowDeiconified (WindowEvent w); - public void windowIconified (WindowEvent w); - public void windowOpened (WindowEvent w); -} + /** + * This method is called when the window is closed. + * + * @param event the <code>WindowEvent</code> indicating the dispose + */ + void windowClosed(WindowEvent event); + + /** + * This method is called when the window is iconified. + * + * @param event the <code>WindowEvent</code> indicating the iconification + * @see Frame#setIconImage(Image) + */ + void windowIconified(WindowEvent event); + + /** + * This method is called when the window is deiconified. + * + * @param event the <code>WindowEvent</code> indicating the deiconification + */ + void windowDeiconified(WindowEvent event); + + /** + * This method is called when a window is activated. Only Frames and Dialogs + * can be active, and the active window always contains the component with + * focus. + * + * @param event the <code>WindowEvent</code> indicating the activation + */ + void windowActivated(WindowEvent event); + + /** + * This method is called when the window is deactivated. + * + * @param event the <code>WindowEvent</code> indicating the deactivation + */ + void windowDeactivated(WindowEvent event); +} // interface WindowListener diff --git a/libjava/java/awt/event/WindowStateListener.java b/libjava/java/awt/event/WindowStateListener.java new file mode 100644 index 00000000000..2d870a8dd9f --- /dev/null +++ b/libjava/java/awt/event/WindowStateListener.java @@ -0,0 +1,62 @@ +/* WindowStateListener.java -- listens for window state changes + 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.event; + +import java.util.EventListener; + +/** + * This interface is for classes that wish to monitor events for window + * state changes. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see WindowAdapter + * @see WindowEvent + * @since 1.4 + * @status updated to 1.4 + */ +public interface WindowStateListener extends EventListener +{ + /** + * This method is called when the window state is changed, because of + * iconification or maximization. + * + * @param event the <code>WindowEvent</code> indicating the change + */ + void windowStateChanged(WindowEvent event); +} // interface WindowStateListener diff --git a/libjava/java/awt/font/TextHitInfo.java b/libjava/java/awt/font/TextHitInfo.java new file mode 100644 index 00000000000..295b63478c5 --- /dev/null +++ b/libjava/java/awt/font/TextHitInfo.java @@ -0,0 +1,110 @@ +/* TextHitInfo.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.font; + +/** + * @author John Leuner <jewel@debian.org> + * + * + */ + +public final class TextHitInfo { + + public int getCharIndex() + { + return -1; + } + + public boolean isLeadingEdge() + { + return false; + } + + public int getInsertionIndex() + { + return -1; + } + + public int hashCode() + { + return getCharIndex(); + } + + public boolean equals(Object obj) + { + if(obj instanceof TextHitInfo) + return this.equals((TextHitInfo) obj); + return false; + } + + public boolean equals(TextHitInfo hitInfo) + { + return (getCharIndex() == hitInfo.getCharIndex()) && (isLeadingEdge() == hitInfo.isLeadingEdge()); + } + + public static TextHitInfo leading(int charIndex) + { + return new TextHitInfo(); + } + + public static TextHitInfo trailing(int charIndex) + { + return new TextHitInfo(); + } + + public static TextHitInfo beforeOffset(int offset) + { + return new TextHitInfo(); + } + + public static TextHitInfo afterOffset(int offset) + { + return new TextHitInfo(); + } + + public TextHitInfo getOtherHit() + { + return new TextHitInfo(); + } + + public TextHitInfo getOffsetHit(int offset) + { + return new TextHitInfo(); + } + +} diff --git a/libjava/java/awt/geom/AffineTransform.java b/libjava/java/awt/geom/AffineTransform.java index 436a842c205..3c9486e6875 100644 --- a/libjava/java/awt/geom/AffineTransform.java +++ b/libjava/java/awt/geom/AffineTransform.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2001, 2002 Free Software Foundation +/* AffineTransform.java -- transform coordinates between two 2-D spaces + Copyright (C) 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,44 +35,276 @@ 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.geom; -import java.awt.*; + +import java.awt.Shape; +import java.io.IOException; +import java.io.ObjectInputStream; import java.io.Serializable; /** + * This class represents an affine transformation between two coordinate + * spaces in 2 dimensions. Such a transform preserves the "straightness" + * and "parallelness" of lines. The transform is built from a sequence of + * translations, scales, flips, rotations, and shears. + * + * <p>The transformation can be represented using matrix math on a 3x3 array. + * Given (x,y), the transformation (x',y') can be found by: + * <pre> + * [ x'] [ m00 m01 m02 ] [ x ] [ m00*x + m01*y + m02 ] + * [ y'] = [ m10 m11 m12 ] [ y ] = [ m10*x + m11*y + m12 ] + * [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ] + * </pre> + * The bottom row of the matrix is constant, so a transform can be uniquely + * represented (as in toString) by "[[m00, m01, m02], [m10, m11, m12]]". + * * @author Tom Tromey <tromey@cygnus.com> - * @date April 16, 2000 + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status partially updated to 1.4, still has some problems */ - -/* Status: mostly complete. Search for fixme to see problems. - Also, TYPE_ returns are not handled correctly. */ - public class AffineTransform implements Cloneable, Serializable { + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 1330973210523860834L; + + /** + * The transformation is the identity (x' = x, y' = y). All other transforms + * have either a combination of the appropriate transform flag bits for + * their type, or the type GENERAL_TRANSFORM. + * + * @see #TYPE_TRANSLATION + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_GENERAL_SCALE + * @see #TYPE_FLIP + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_ROTATION + * @see #TYPE_GENERAL_TRANSFORM + * @see #getType() + */ public static final int TYPE_IDENTITY = 0; - public static final int TYPE_FLIP = 64; - public static final int TYPE_GENERAL_ROTATION = 16; + + /** + * The transformation includes a translation - shifting in the x or y + * direction without changing length or angles. + * + * @see #TYPE_IDENTITY + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_GENERAL_SCALE + * @see #TYPE_FLIP + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_ROTATION + * @see #TYPE_GENERAL_TRANSFORM + * @see #getType() + */ + public static final int TYPE_TRANSLATION = 1; + + /** + * The transformation includes a uniform scale - length is scaled in both + * the x and y directions by the same amount, without affecting angles. + * This is mutually exclusive with TYPE_GENERAL_SCALE. + * + * @see #TYPE_IDENTITY + * @see #TYPE_TRANSLATION + * @see #TYPE_GENERAL_SCALE + * @see #TYPE_FLIP + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_ROTATION + * @see #TYPE_GENERAL_TRANSFORM + * @see #TYPE_MASK_SCALE + * @see #getType() + */ + public static final int TYPE_UNIFORM_SCALE = 2; + + /** + * The transformation includes a general scale - length is scaled in either + * or both the x and y directions, but by different amounts; without + * affecting angles. This is mutually exclusive with TYPE_UNIFORM_SCALE. + * + * @see #TYPE_IDENTITY + * @see #TYPE_TRANSLATION + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_FLIP + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_ROTATION + * @see #TYPE_GENERAL_TRANSFORM + * @see #TYPE_MASK_SCALE + * @see #getType() + */ public static final int TYPE_GENERAL_SCALE = 4; - public static final int TYPE_GENERAL_TRANSFORM = 32; - public static final int TYPE_MASK_ROTATION = 24; + + /** + * This constant checks if either variety of scale transform is performed. + * + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_GENERAL_SCALE + */ public static final int TYPE_MASK_SCALE = 6; + + /** + * The transformation includes a flip about an axis, swapping between + * right-handed and left-handed coordinate systems. In a right-handed + * system, the positive x-axis rotates counter-clockwise to the positive + * y-axis; in a left-handed system it rotates clockwise. + * + * @see #TYPE_IDENTITY + * @see #TYPE_TRANSLATION + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_GENERAL_SCALE + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_ROTATION + * @see #TYPE_GENERAL_TRANSFORM + * @see #getType() + */ + public static final int TYPE_FLIP = 64; + + /** + * The transformation includes a rotation of a multiple of 90 degrees (PI/2 + * radians). Angles are rotated, but length is preserved. This is mutually + * exclusive with TYPE_GENERAL_ROTATION. + * + * @see #TYPE_IDENTITY + * @see #TYPE_TRANSLATION + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_GENERAL_SCALE + * @see #TYPE_FLIP + * @see #TYPE_GENERAL_ROTATION + * @see #TYPE_GENERAL_TRANSFORM + * @see #TYPE_MASK_ROTATION + * @see #getType() + */ public static final int TYPE_QUADRANT_ROTATION = 8; - public static final int TYPE_TRANSLATION = 1; - public static final int TYPE_UNIFORM_SCALE = 2; - public AffineTransform () + /** + * The transformation includes a rotation by an arbitrary angle. Angles are + * rotated, but length is preserved. This is mutually exclusive with + * TYPE_QUADRANT_ROTATION. + * + * @see #TYPE_IDENTITY + * @see #TYPE_TRANSLATION + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_GENERAL_SCALE + * @see #TYPE_FLIP + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_TRANSFORM + * @see #TYPE_MASK_ROTATION + * @see #getType() + */ + public static final int TYPE_GENERAL_ROTATION = 16; + + /** + * This constant checks if either variety of rotation is performed. + * + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_ROTATION + */ + public static final int TYPE_MASK_ROTATION = 24; + + /** + * The transformation is an arbitrary conversion of coordinates which + * could not be decomposed into the other TYPEs. + * + * @see #TYPE_IDENTITY + * @see #TYPE_TRANSLATION + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_GENERAL_SCALE + * @see #TYPE_FLIP + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_ROTATION + * @see #getType() + */ + public static final int TYPE_GENERAL_TRANSFORM = 32; + + /** + * The X coordinate scaling element of the transform matrix. + * + * @serial matrix[0,0] + */ + private double m00; + + /** + * The Y coordinate scaling element of the transform matrix. + * + * @serial matrix[1,0] + */ + private double m10; + + /** + * The X coordinate shearing element of the transform matrix. + * + * @serial matrix[0,1] + */ + private double m01; + + /** + * The Y coordinate shearing element of the transform matrix. + * + * @serial matrix[1,1] + */ + private double m11; + + /** + * The X coordinate translation element of the transform matrix. + * + * @serial matrix[0,2] + */ + private double m02; + + /** + * The Y coordinate translation element of the transform matrix. + * + * @serial matrix[1,2] + */ + private double m12; + + /** The type of this transform. */ + private transient int type; + + /** + * Construct a new identity transform: + * <pre> + * [ 1 0 0 ] + * [ 0 1 0 ] + * [ 0 0 1 ] + * </pre> + */ + public AffineTransform() { - setToIdentity (); + m00 = m11 = 1; } - public AffineTransform (AffineTransform tx) + /** + * Create a new transform which copies the given one. + * + * @param tx the transform to copy + * @throws NullPointerException if tx is null + */ + public AffineTransform(AffineTransform tx) { - setTransform (tx); + setTransform(tx); } - public AffineTransform (float m00, float m10, - float m01, float m11, - float m02, float m12) + /** + * Construct a transform with the given matrix entries: + * <pre> + * [ m00 m01 m02 ] + * [ m10 m11 m12 ] + * [ 0 0 1 ] + * </pre> + * + * @param m00 the x scaling component + * @param m10 the y shearing component + * @param m01 the x shearing component + * @param m11 the y scaling component + * @param m02 the x translation component + * @param m12 the y translation component + */ + public AffineTransform(float m00, float m10, + float m01, float m11, + float m02, float m12) { this.m00 = m00; this.m10 = m10; @@ -79,24 +312,54 @@ public class AffineTransform implements Cloneable, Serializable this.m11 = m11; this.m02 = m02; this.m12 = m12; - this.type = TYPE_GENERAL_TRANSFORM; + updateType(); } - public AffineTransform (float[] flatmatrix) + /** + * Construct a transform from a sequence of float entries. The array must + * have at least 4 entries, which has a translation factor of 0; or 6 + * entries, for specifying all parameters: + * <pre> + * [ f[0] f[2] (f[4]) ] + * [ f[1] f[3] (f[5]) ] + * [ 0 0 1 ] + * </pre> + * + * @param f the matrix to copy from, with at least 4 (6) entries + * @throws NullPointerException if f is null + * @throws ArrayIndexOutOfBoundsException if f is too small + */ + public AffineTransform(float[] f) { - m00 = flatmatrix[0]; - m10 = flatmatrix[1]; - m01 = flatmatrix[2]; - m11 = flatmatrix[3]; - if (flatmatrix.length >= 6) + m00 = f[0]; + m10 = f[1]; + m01 = f[2]; + m11 = f[3]; + if (f.length >= 6) { - m02 = flatmatrix[4]; - m12 = flatmatrix[5]; + m02 = f[4]; + m12 = f[5]; } + updateType(); } - public AffineTransform (double m00, double m10, double m01, - double m11, double m02, double m12) + /** + * Construct a transform with the given matrix entries: + * <pre> + * [ m00 m01 m02 ] + * [ m10 m11 m12 ] + * [ 0 0 1 ] + * </pre> + * + * @param m00 the x scaling component + * @param m10 the y shearing component + * @param m01 the x shearing component + * @param m11 the y scaling component + * @param m02 the x translation component + * @param m12 the y translation component + */ + public AffineTransform(double m00, double m10, double m01, + double m11, double m02, double m12) { this.m00 = m00; this.m10 = m10; @@ -104,222 +367,532 @@ public class AffineTransform implements Cloneable, Serializable this.m11 = m11; this.m02 = m02; this.m12 = m12; - this.type = TYPE_GENERAL_TRANSFORM; + updateType(); } - public AffineTransform (double[] flatmatrix) + /** + * Construct a transform from a sequence of double entries. The array must + * have at least 4 entries, which has a translation factor of 0; or 6 + * entries, for specifying all parameters: + * <pre> + * [ d[0] d[2] (d[4]) ] + * [ d[1] d[3] (d[5]) ] + * [ 0 0 1 ] + * </pre> + * + * @param d the matrix to copy from, with at least 4 (6) entries + * @throws NullPointerException if d is null + * @throws ArrayIndexOutOfBoundsException if d is too small + */ + public AffineTransform(double[] d) { - m00 = flatmatrix[0]; - m10 = flatmatrix[1]; - m01 = flatmatrix[2]; - m11 = flatmatrix[3]; - if (flatmatrix.length >= 6) + m00 = d[0]; + m10 = d[1]; + m01 = d[2]; + m11 = d[3]; + if (d.length >= 6) { - m02 = flatmatrix[4]; - m12 = flatmatrix[5]; + m02 = d[4]; + m12 = d[5]; } + updateType(); } - public static AffineTransform getTranslateInstance (double tx, double ty) + /** + * Returns a translation transform: + * <pre> + * [ 1 0 tx ] + * [ 0 1 ty ] + * [ 0 0 1 ] + * </pre> + * + * @param tx the x translation distance + * @param ty the y translation distance + * @return the translating transform + */ + public static AffineTransform getTranslateInstance(double tx, double ty) { - AffineTransform t = new AffineTransform (); - t.setToTranslation (tx, ty); + AffineTransform t = new AffineTransform(); + t.setToTranslation(tx, ty); return t; } - public static AffineTransform getRotateInstance (double theta) + /** + * Returns a rotation transform. A positive angle (in radians) rotates + * the positive x-axis to the positive y-axis: + * <pre> + * [ cos(theta) -sin(theta) 0 ] + * [ sin(theta) cos(theta) 0 ] + * [ 0 0 1 ] + * </pre> + * + * @param theta the rotation angle + * @return the rotating transform + */ + public static AffineTransform getRotateInstance(double theta) { - AffineTransform t = new AffineTransform (); - t.setToRotation (theta); + AffineTransform t = new AffineTransform(); + t.setToRotation(theta); return t; } - public static AffineTransform getRotateInstance (double theta, - double x, double y) + /** + * Returns a rotation transform about a point. A positive angle (in radians) + * rotates the positive x-axis to the positive y-axis. This is the same + * as calling: + * <pre> + * AffineTransform tx = new AffineTransform(); + * tx.setToTranslation(x, y); + * tx.rotate(theta); + * tx.translate(-x, -y); + * </pre> + * + * <p>The resulting matrix is: + * <pre> + * [ cos(theta) -sin(theta) x-x*cos+y*sin ] + * [ sin(theta) cos(theta) y-x*sin-y*cos ] + * [ 0 0 1 ] + * </pre> + * + * @param theta the rotation angle + * @param x the x coordinate of the pivot point + * @param y the y coordinate of the pivot point + * @return the rotating transform + */ + public static AffineTransform getRotateInstance(double theta, + double x, double y) { - AffineTransform t = new AffineTransform (); - t.rotate (theta, x, y); + AffineTransform t = new AffineTransform(); + t.setToTranslation(x, y); + t.rotate(theta); + t.translate(-x, -y); return t; } - public static AffineTransform getScaleInstance (double sx, double sy) + /** + * Returns a scaling transform: + * <pre> + * [ sx 0 0 ] + * [ 0 sy 0 ] + * [ 0 0 1 ] + * </pre> + * + * @param sx the x scaling factor + * @param sy the y scaling factor + * @return the scaling transform + */ + public static AffineTransform getScaleInstance(double sx, double sy) { - AffineTransform t = new AffineTransform (); - t.setToScale (sx, sy); + AffineTransform t = new AffineTransform(); + t.setToScale(sx, sy); return t; } - public static AffineTransform getShearInstance (double shx, double shy) + /** + * Returns a shearing transform (points are shifted in the x direction based + * on a factor of their y coordinate, and in the y direction as a factor of + * their x coordinate): + * <pre> + * [ 1 shx 0 ] + * [ shy 1 0 ] + * [ 0 0 1 ] + * </pre> + * + * @param shx the x shearing factor + * @param shy the y shearing factor + * @return the shearing transform + */ + public static AffineTransform getShearInstance(double shx, double shy) { - AffineTransform t = new AffineTransform (); - t.setToShear (shx, shy); + AffineTransform t = new AffineTransform(); + t.setToShear(shx, shy); return t; } - public int getType () + /** + * Returns the type of this transform. The result is always valid, although + * it may not be the simplest interpretation (in other words, there are + * sequences of transforms which reduce to something simpler, which this + * does not always detect). The result is either TYPE_GENERAL_TRANSFORM, + * or a bit-wise combination of TYPE_TRANSLATION, the mutually exclusive + * TYPE_*_ROTATIONs, and the mutually exclusive TYPE_*_SCALEs. + * + * @see #TYPE_IDENTITY + * @see #TYPE_TRANSLATION + * @see #TYPE_UNIFORM_SCALE + * @see #TYPE_GENERAL_SCALE + * @see #TYPE_QUADRANT_ROTATION + * @see #TYPE_GENERAL_ROTATION + * @see #TYPE_GENERAL_TRANSFORM + */ + public int getType() { return type; } - public double getDeterminant () + /** + * Return the determinant of this transform matrix. If the determinant is + * non-zero, the transform is invertible; otherwise operations which require + * an inverse throw a NoninvertibleTransformException. A result very near + * zero, due to rounding errors, may indicate that inversion results do not + * carry enough precision to be meaningful. + * + * <p>If this is a uniform scale transformation, the determinant also + * represents the squared value of the scale. Otherwise, it carries little + * additional meaning. The determinant is calculated as: + * <pre> + * | m00 m01 m02 | + * | m10 m11 m12 | = m00 * m11 - m01 * m10 + * | 0 0 1 | + * </pre> + * + * @return the determinant + * @see #createInverse() + */ + public double getDeterminant() { return m00 * m11 - m01 * m10; } - public void getMatrix (double[] flatmatrix) + /** + * Return the matrix of values used in this transform. If the matrix has + * fewer than 6 entries, only the scale and shear factors are returned; + * otherwise the translation factors are copied as well. The resulting + * values are: + * <pre> + * [ d[0] d[2] (d[4]) ] + * [ d[1] d[3] (d[5]) ] + * [ 0 0 1 ] + * </pre> + * + * @param d the matrix to store the results into; with 4 (6) entries + * @throws NullPointerException if d is null + * @throws ArrayIndexOutOfBoundsException if d is too small + */ + public void getMatrix(double[] d) { - flatmatrix[0] = m00; - flatmatrix[1] = m10; - flatmatrix[2] = m01; - flatmatrix[3] = m11; - if (flatmatrix.length >= 6) + d[0] = m00; + d[1] = m10; + d[2] = m01; + d[3] = m11; + if (d.length >= 6) { - flatmatrix[4] = m02; - flatmatrix[5] = m12; + d[4] = m02; + d[5] = m12; } } - public double getScaleX () + /** + * Returns the X coordinate scaling factor of the matrix. + * + * @return m00 + * @see #getMatrix(double[]) + */ + public double getScaleX() { return m00; } - public double getScaleY () + /** + * Returns the Y coordinate scaling factor of the matrix. + * + * @return m11 + * @see #getMatrix(double[]) + */ + public double getScaleY() { return m11; } - public double getShearX () + /** + * Returns the X coordinate shearing factor of the matrix. + * + * @return m01 + * @see #getMatrix(double[]) + */ + public double getShearX() { return m01; } - public double getShearY () + /** + * Returns the Y coordinate shearing factor of the matrix. + * + * @return m10 + * @see #getMatrix(double[]) + */ + public double getShearY() { return m10; } - public double getTranslateX () + /** + * Returns the X coordinate translation factor of the matrix. + * + * @return m02 + * @see #getMatrix(double[]) + */ + public double getTranslateX() { return m02; } - public double getTranslateY () + /** + * Returns the Y coordinate translation factor of the matrix. + * + * @return m12 + * @see #getMatrix(double[]) + */ + public double getTranslateY() { return m12; } - public void translate (double tx, double ty) + /** + * Concatenate a translation onto this transform. This is equivalent, but + * more efficient than + * <code>concatenate(AffineTransform.getTranslateInstance(tx, ty))</code>. + * + * @param tx the x translation distance + * @param ty the y translation distance + * @see #getTranslateInstance(double, double) + * @see #concatenate(AffineTransform) + */ + public void translate(double tx, double ty) { m02 += tx * m00 + ty * m01; m12 += tx * m10 + ty * m11; + updateType(); } - public void rotate (double theta) + /** + * Concatenate a rotation onto this transform. This is equivalent, but + * more efficient than + * <code>concatenate(AffineTransform.getRotateInstance(theta))</code>. + * + * @param theta the rotation angle + * @see #getRotateInstance(double) + * @see #concatenate(AffineTransform) + */ + public void rotate(double theta) { - double c = Math.cos (theta); - double s = Math.sin (theta); + double c = Math.cos(theta); + double s = Math.sin(theta); double n00 = m00 * c + m01 * s; double n01 = m00 * -s + m01 * c; double n10 = m10 * c + m11 * s; double n11 = m10 * -s + m11 * c; - m00 = n00; m01 = n01; m10 = n10; m11 = n11; + updateType(); } - public void rotate (double theta, double x, double y) + /** + * Concatenate a rotation about a point onto this transform. This is + * equivalent, but more efficient than + * <code>concatenate(AffineTransform.getRotateInstance(theta, x, y))</code>. + * + * @param theta the rotation angle + * @param x the x coordinate of the pivot point + * @param y the y coordinate of the pivot point + * @see #getRotateInstance(double, double, double) + * @see #concatenate(AffineTransform) + */ + public void rotate(double theta, double x, double y) { - translate (x, y); - rotate (theta); - translate (-x, -y); + translate(x, y); + rotate(theta); + translate(-x, -y); } - public void scale (double sx, double sy) + /** + * Concatenate a scale onto this transform. This is equivalent, but more + * efficient than + * <code>concatenate(AffineTransform.getScaleInstance(sx, sy))</code>. + * + * @param sx the x scaling factor + * @param sy the y scaling factor + * @see #getScaleInstance(double, double) + * @see #concatenate(AffineTransform) + */ + public void scale(double sx, double sy) { m00 *= sx; m01 *= sy; m10 *= sx; m11 *= sy; + updateType(); } - public void shear (double shx, double shy) + /** + * Concatenate a shearing onto this transform. This is equivalent, but more + * efficient than + * <code>concatenate(AffineTransform.getShearInstance(sx, sy))</code>. + * + * @param shx the x shearing factor + * @param shy the y shearing factor + * @see #getShearInstance(double, double) + * @see #concatenate(AffineTransform) + */ + public void shear(double shx, double shy) { double n00 = m00 + shx * m01; double n01 = shx * m00 + m01; double n10 = m10 * shy + m11; double n11 = shx * m10 + m11; - m00 = n00; m01 = n01; m10 = n10; m11 = n11; + updateType(); } - public void setToIdentity () + /** + * Reset this transform to the identity (no transformation): + * <pre> + * [ 1 0 0 ] + * [ 0 1 0 ] + * [ 0 0 1 ] + * </pre> + */ + public void setToIdentity() { m00 = m11 = 1; m01 = m02 = m10 = m12 = 0; type = TYPE_IDENTITY; } - public void setToTranslation (double tx, double ty) + /** + * Set this transform to a translation: + * <pre> + * [ 1 0 tx ] + * [ 0 1 ty ] + * [ 0 0 1 ] + * </pre> + * + * @param tx the x translation distance + * @param ty the y translation distance + */ + public void setToTranslation(double tx, double ty) { m00 = m11 = 1; m01 = m10 = 0; m02 = tx; m12 = ty; - type = TYPE_TRANSLATION; + type = (tx == 0 && ty == 0) ? TYPE_UNIFORM_SCALE : TYPE_TRANSLATION; } - public void setToRotation (double theta) + /** + * Set this transform to a rotation. A positive angle (in radians) rotates + * the positive x-axis to the positive y-axis: + * <pre> + * [ cos(theta) -sin(theta) 0 ] + * [ sin(theta) cos(theta) 0 ] + * [ 0 0 1 ] + * </pre> + * + * @param theta the rotation angle + */ + public void setToRotation(double theta) { - double c = Math.cos (theta); - double s = Math.sin (theta); - + double c = Math.cos(theta); + double s = Math.sin(theta); m00 = c; m01 = -s; m02 = 0; m10 = s; m11 = c; m12 = 0; - type = TYPE_GENERAL_ROTATION; + type = (c == 1 ? TYPE_IDENTITY + : c == 0 || c == -1 ? TYPE_QUADRANT_ROTATION + : TYPE_GENERAL_ROTATION); } - public void setToRotation (double theta, double x, double y) + /** + * Set this transform to a rotation about a point. A positive angle (in + * radians) rotates the positive x-axis to the positive y-axis. This is the + * same as calling: + * <pre> + * tx.setToTranslation(x, y); + * tx.rotate(theta); + * tx.translate(-x, -y); + * </pre> + * + * <p>The resulting matrix is: + * <pre> + * [ cos(theta) -sin(theta) x-x*cos+y*sin ] + * [ sin(theta) cos(theta) y-x*sin-y*cos ] + * [ 0 0 1 ] + * </pre> + * + * @param theta the rotation angle + * @param x the x coordinate of the pivot point + * @param y the y coordinate of the pivot point + */ + public void setToRotation(double theta, double x, double y) { - double c = Math.cos (theta); - double s = Math.sin (theta); - + double c = Math.cos(theta); + double s = Math.sin(theta); m00 = c; m01 = -s; m02 = x - x * c + y * s; m10 = s; m11 = c; m12 = y - x * s - y * c; - type = TYPE_GENERAL_TRANSFORM; + updateType(); } - public void setToScale (double sx, double sy) + /** + * Set this transform to a scale: + * <pre> + * [ sx 0 0 ] + * [ 0 sy 0 ] + * [ 0 0 1 ] + * </pre> + * + * @param sx the x scaling factor + * @param sy the y scaling factor + */ + public void setToScale(double sx, double sy) { m00 = sx; m01 = m02 = m10 = m12 = 0; m11 = sy; - type = (sx == sy) ? TYPE_UNIFORM_SCALE : TYPE_GENERAL_SCALE; + type = (sx != sy ? TYPE_GENERAL_SCALE + : sx == 1 ? TYPE_IDENTITY : TYPE_UNIFORM_SCALE); } - public void setToShear (double shx, double shy) + /** + * Set this transform to a shear (points are shifted in the x direction based + * on a factor of their y coordinate, and in the y direction as a factor of + * their x coordinate): + * <pre> + * [ 1 shx 0 ] + * [ shy 1 0 ] + * [ 0 0 1 ] + * </pre> + * + * @param shx the x shearing factor + * @param shy the y shearing factor + */ + public void setToShear(double shx, double shy) { m00 = m11 = 1; m01 = shx; m10 = shy; m02 = m12 = 0; - type = TYPE_GENERAL_TRANSFORM; + updateType(); } - public void setTransform (AffineTransform tx) + /** + * Set this transform to a copy of the given one. + * + * @param tx the transform to copy + * @throws NullPointerException if tx is null + */ + public void setTransform(AffineTransform tx) { m00 = tx.m00; m01 = tx.m01; @@ -330,8 +903,23 @@ public class AffineTransform implements Cloneable, Serializable type = tx.type; } - public void setTransform (double m00, double m10, double m01, - double m11, double m02, double m12) + /** + * Set this transform to the given values: + * <pre> + * [ m00 m01 m02 ] + * [ m10 m11 m12 ] + * [ 0 0 1 ] + * </pre> + * + * @param m00 the x scaling component + * @param m10 the y shearing component + * @param m01 the x shearing component + * @param m11 the y scaling component + * @param m02 the x translation component + * @param m12 the y translation component + */ + public void setTransform(double m00, double m10, double m01, + double m11, double m02, double m12) { this.m00 = m00; this.m10 = m10; @@ -339,10 +927,22 @@ public class AffineTransform implements Cloneable, Serializable this.m11 = m11; this.m02 = m02; this.m12 = m12; - this.type = 0; // FIXME + updateType(); } - public void concatenate (AffineTransform tx) + /** + * Set this transform to the result of performing the original version of + * this followed by tx. This is commonly used when chaining transformations + * from one space to another. In matrix form: + * <pre> + * [ this ] = [ this ] x [ tx ] + * </pre> + * + * @param tx the transform to concatenate + * @throws NullPointerException if tx is null + * @see #preConcatenate(AffineTransform) + */ + public void concatenate(AffineTransform tx) { double n00 = m00 * tx.m00 + m01 * tx.m10; double n01 = m00 * tx.m01 + m01 * tx.m11; @@ -350,16 +950,29 @@ public class AffineTransform implements Cloneable, Serializable double n10 = m10 * tx.m00 + m11 * tx.m10; double n11 = m10 * tx.m01 + m11 * tx.m11; double n12 = m10 * tx.m02 + m11 * tx.m12 + m12; - m00 = n00; m01 = n01; m02 = n02; m10 = n10; m11 = n11; m12 = n12; + updateType(); } - public void preConcatenate (AffineTransform tx) + /** + * Set this transform to the result of performing tx followed by the + * original version of this. This is less common than normal concatenation, + * but can still be used to chain transformations from one space to another. + * In matrix form: + * <pre> + * [ this ] = [ tx ] x [ this ] + * </pre> + * + * @param tx the transform to concatenate + * @throws NullPointerException if tx is null + * @see #concatenate(AffineTransform) + */ + public void preConcatenate(AffineTransform tx) { double n00 = tx.m00 * m00 + tx.m01 * m10; double n01 = tx.m00 * m01 + tx.m01 * m11; @@ -367,328 +980,490 @@ public class AffineTransform implements Cloneable, Serializable double n10 = tx.m10 * m00 + tx.m11 * m10; double n11 = tx.m10 * m01 + tx.m11 * m11; double n12 = tx.m10 * m02 + tx.m11 * m12 + tx.m12; - m00 = n00; m01 = n01; m02 = n02; m10 = n10; m11 = n11; m12 = n12; + updateType(); } - public AffineTransform createInverse () + /** + * Returns a transform, which if concatenated to this one, will result in + * the identity transform. This is useful for undoing transformations, but + * is only possible if the original transform has an inverse (ie. does not + * map multiple points to the same line or point). A transform exists only + * if getDeterminant() has a non-zero value. + * + * @return a new inverse transform + * @throws NoninvertibleTransformException if inversion is not possible + * @see #getDeterminant() + */ + public AffineTransform createInverse() throws NoninvertibleTransformException { - double det = getDeterminant (); + double det = getDeterminant(); if (det == 0) - throw new NoninvertibleTransformException ("can't invert transform"); - - double i00 = m11 / det; - double i01 = -m10 / det; - double i02 = 0; - double i10 = m01 / det; - double i11 = -m00 / det; - double i12 = 0; - - return new AffineTransform (i00, i01, i02, - i10, i11, i12); + throw new NoninvertibleTransformException("can't invert transform"); + return new AffineTransform(m11 / det, -m10 / det, m01 / det, -m00 / det, + -m02, -m12); } - public Point2D transform (Point2D src, Point2D dst) + /** + * Perform this transformation on the given source point, and store the + * result in the destination (creating it if necessary). It is safe for + * src and dst to be the same. + * + * @param src the source point + * @param dst the destination, or null + * @return the transformation of src, in dst if it was non-null + * @throws NullPointerException if src is null + */ + public Point2D transform(Point2D src, Point2D dst) { if (dst == null) - dst = new Point2D.Double (); - - // We compute and set separately to correctly overwrite if - // src==dst. - double x = src.getX (); - double y = src.getY (); + dst = new Point2D.Double(); + double x = src.getX(); + double y = src.getY(); double nx = m00 * x + m01 * y + m02; double ny = m10 * x + m11 * y + m12; - - dst.setLocation (nx, ny); - + dst.setLocation(nx, ny); return dst; } - public void transform (Point2D[] src, int srcOff, - Point2D[] dst, int dstOff, - int num) + /** + * Perform this transformation on an array of points, storing the results + * in another (possibly same) array. This will not create a destination + * array, but will create points for the null entries of the destination. + * The transformation is done sequentially. While having a single source + * and destination point be the same is safe, you should be aware that + * duplicate references to the same point in the source, and having the + * source overlap the destination, may result in your source points changing + * from a previous transform before it is their turn to be evaluated. + * + * @param src the array of source points + * @param srcOff the starting offset into src + * @param dst the array of destination points (may have null entries) + * @param dstOff the starting offset into dst + * @param num the number of points to transform + * @throws NullPointerException if src or dst is null, or src has null + * entries + * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded + * @throws ArrayStoreException if new points are incompatible with dst + */ + public void transform(Point2D[] src, int srcOff, + Point2D[] dst, int dstOff, int num) { - while (num-- > 0) - { - dst[dstOff] = transform (src[srcOff], dst[dstOff]); - ++srcOff; - ++dstOff; - } + while (--num >= 0) + dst[dstOff] = transform(src[srcOff++], dst[dstOff++]); } - public void transform (float[] srcPts, int srcOff, - float[] dstPts, int dstOff, - int num) + /** + * Perform this transformation on an array of points, in (x,y) pairs, + * storing the results in another (possibly same) array. This will not + * create a destination array. All sources are copied before the + * transformation, so that no result will overwrite a point that has not yet + * been evaluated. + * + * @param src the array of source points + * @param srcOff the starting offset into src + * @param dst the array of destination points + * @param dstOff the starting offset into dst + * @param num the number of points to transform + * @throws NullPointerException if src or dst is null + * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded + */ + public void transform(float[] srcPts, int srcOff, + float[] dstPts, int dstOff, int num) { - while (num-- > 0) + if (srcPts == dstPts && dstOff > srcOff + && num > 1 && srcOff + 2 * num > dstOff) { - float x = srcPts[srcOff]; - float y = srcPts[srcOff + 1]; - srcOff += 2; - float nx = (float) (m00 * x + m01 * y + m02); - float ny = (float) (m10 * x + m10 * y + m12); - dstPts[dstOff] = nx; - dstPts[dstOff + 1] = ny; - dstOff += 2; + float[] f = new float[2 * num]; + System.arraycopy(srcPts, srcOff, f, 0, 2 * num); + srcPts = f; + } + while (--num >= 0) + { + float x = srcPts[srcOff++]; + float y = srcPts[srcOff++]; + dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02); + dstPts[dstOff++] = (float) (m10 * x + m10 * y + m12); } } - public void transform (double[] srcPts, int srcOff, - double[] dstPts, int dstOff, - int num) + /** + * Perform this transformation on an array of points, in (x,y) pairs, + * storing the results in another (possibly same) array. This will not + * create a destination array. All sources are copied before the + * transformation, so that no result will overwrite a point that has not yet + * been evaluated. + * + * @param src the array of source points + * @param srcOff the starting offset into src + * @param dst the array of destination points + * @param dstOff the starting offset into dst + * @param num the number of points to transform + * @throws NullPointerException if src or dst is null + * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded + */ + public void transform(double[] srcPts, int srcOff, + double[] dstPts, int dstOff, int num) { - while (num-- > 0) + if (srcPts == dstPts && dstOff > srcOff + && num > 1 && srcOff + 2 * num > dstOff) + { + double[] d = new double[2 * num]; + System.arraycopy(srcPts, srcOff, d, 0, 2 * num); + srcPts = d; + } + while (--num >= 0) { - double x = srcPts[srcOff]; - double y = srcPts[srcOff + 1]; - srcOff += 2; - double nx = m00 * x + m01 * y + m02; - double ny = m10 * x + m10 * y + m12; - dstPts[dstOff] = nx; - dstPts[dstOff + 1] = ny; - dstOff += 2; + double x = srcPts[srcOff++]; + double y = srcPts[srcOff++]; + dstPts[dstOff++] = m00 * x + m01 * y + m02; + dstPts[dstOff++] = m10 * x + m10 * y + m12; } } - public void transform (float[] srcPts, int srcOff, - double[] dstPts, int dstOff, - int num) + /** + * Perform this transformation on an array of points, in (x,y) pairs, + * storing the results in another array. This will not create a destination + * array. + * + * @param src the array of source points + * @param srcOff the starting offset into src + * @param dst the array of destination points + * @param dstOff the starting offset into dst + * @param num the number of points to transform + * @throws NullPointerException if src or dst is null + * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded + */ + public void transform(float[] srcPts, int srcOff, + double[] dstPts, int dstOff, int num) { - while (num-- > 0) + while (--num >= 0) { - float x = srcPts[srcOff]; - float y = srcPts[srcOff + 1]; - srcOff += 2; - double nx = m00 * x + m01 * y + m02; - double ny = m10 * x + m10 * y + m12; - dstPts[dstOff] = nx; - dstPts[dstOff + 1] = ny; - dstOff += 2; + float x = srcPts[srcOff++]; + float y = srcPts[srcOff++]; + dstPts[dstOff++] = m00 * x + m01 * y + m02; + dstPts[dstOff++] = m10 * x + m10 * y + m12; } } - public void transform (double[] srcPts, int srcOff, - float[] dstPts, int dstOff, - int num) + /** + * Perform this transformation on an array of points, in (x,y) pairs, + * storing the results in another array. This will not create a destination + * array. + * + * @param src the array of source points + * @param srcOff the starting offset into src + * @param dst the array of destination points + * @param dstOff the starting offset into dst + * @param num the number of points to transform + * @throws NullPointerException if src or dst is null + * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded + */ + public void transform(double[] srcPts, int srcOff, + float[] dstPts, int dstOff, int num) { - while (num-- > 0) + while (--num >= 0) { - double x = srcPts[srcOff]; - double y = srcPts[srcOff + 1]; - srcOff += 2; - float nx = (float) (m00 * x + m01 * y + m02); - float ny = (float) (m10 * x + m10 * y + m12); - dstPts[dstOff] = nx; - dstPts[dstOff + 1] = ny; - dstOff += 2; + double x = srcPts[srcOff++]; + double y = srcPts[srcOff++]; + dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02); + dstPts[dstOff++] = (float) (m10 * x + m10 * y + m12); } } - public Point2D inverseTransform (Point2D src, Point2D dst) + /** + * Perform the inverse of this transformation on the given source point, + * and store the result in the destination (creating it if necessary). It + * is safe for src and dst to be the same. + * + * @param src the source point + * @param dst the destination, or null + * @return the inverse transformation of src, in dst if it was non-null + * @throws NullPointerException if src is null + * @throws NoninvertibleTransformException if the inverse does not exist + * @see #getDeterminant() + */ + public Point2D inverseTransform(Point2D src, Point2D dst) throws NoninvertibleTransformException { - double det = getDeterminant (); + double det = getDeterminant(); if (det == 0) - throw new NoninvertibleTransformException ("couldn't invert transform"); - + throw new NoninvertibleTransformException("couldn't invert transform"); if (dst == null) - dst = new Point2D.Double (); - double x = src.getX (); - double y = src.getY (); - double nx = (m11 * x + - m10 * y) / det; - double ny = (m01 * x + - m00 * y) / det; - dst.setLocation (nx, ny); + dst = new Point2D.Double(); + double x = src.getX(); + double y = src.getY(); + double nx = (m11 * x + -m10 * y) / det - m02; + double ny = (m01 * x + -m00 * y) / det - m12; + dst.setLocation(nx, ny); return dst; } - public void inverseTransform (double[] srcPts, int srcOff, - double[] dstPts, int dstOff, - int num) + /** + * Perform the inverse of this transformation on an array of points, in + * (x,y) pairs, storing the results in another (possibly same) array. This + * will not create a destination array. All sources are copied before the + * transformation, so that no result will overwrite a point that has not yet + * been evaluated. + * + * @param src the array of source points + * @param srcOff the starting offset into src + * @param dst the array of destination points + * @param dstOff the starting offset into dst + * @param num the number of points to transform + * @throws NullPointerException if src or dst is null + * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded + * @throws NoninvertibleTransformException if the inverse does not exist + * @see #getDeterminant() + */ + public void inverseTransform(double[] srcPts, int srcOff, + double[] dstPts, int dstOff, int num) throws NoninvertibleTransformException { - double det = getDeterminant (); + double det = getDeterminant(); if (det == 0) - throw new NoninvertibleTransformException ("couldn't invert transform"); - - while (num-- > 0) + throw new NoninvertibleTransformException("couldn't invert transform"); + if (srcPts == dstPts && dstOff > srcOff + && num > 1 && srcOff + 2 * num > dstOff) + { + double[] d = new double[2 * num]; + System.arraycopy(srcPts, srcOff, d, 0, 2 * num); + srcPts = d; + } + while (--num >= 0) { - double x = srcPts[srcOff]; - double y = srcPts[srcOff + 1]; - double nx = (m11 * x + - m10 * y) / det; - double ny = (m01 * x + - m00 * y) / det; - dstPts[dstOff] = nx; - dstPts[dstOff + 1] = ny; - dstOff += 2; - srcOff += 2; + double x = srcPts[srcOff++]; + double y = srcPts[srcOff++]; + dstPts[dstOff++] = (m11 * x + -m10 * y) / det - m02; + dstPts[dstOff++] = (m01 * x + -m00 * y) / det - m12; } } - public Point2D deltaTransform (Point2D src, Point2D dst) + /** + * Perform this transformation, less any translation, on the given source + * point, and store the result in the destination (creating it if + * necessary). It is safe for src and dst to be the same. The reduced + * transform is equivalent to: + * <pre> + * [ x' ] = [ m00 m01 ] [ x ] = [ m00 * x + m01 * y ] + * [ y' ] [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ] + * </pre> + * + * @param src the source point + * @param dst the destination, or null + * @return the delta transformation of src, in dst if it was non-null + * @throws NullPointerException if src is null + */ + public Point2D deltaTransform(Point2D src, Point2D dst) { if (dst == null) - dst = new Point2D.Double (); - double x = src.getX (); - double y = src.getY (); + dst = new Point2D.Double(); + double x = src.getX(); + double y = src.getY(); double nx = m00 * x + m01 * y; double ny = m10 * x + m11 * y; - dst.setLocation (nx, ny); + dst.setLocation(nx, ny); return dst; } - public void deltaTransform (double[] srcPts, int srcOff, - double[] dstPts, int dstOff, - int num) + /** + * Perform this transformation, less any translation, on an array of points, + * in (x,y) pairs, storing the results in another (possibly same) array. + * This will not create a destination array. All sources are copied before + * the transformation, so that no result will overwrite a point that has + * not yet been evaluated. The reduced transform is equivalent to: + * <pre> + * [ x' ] = [ m00 m01 ] [ x ] = [ m00 * x + m01 * y ] + * [ y' ] [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ] + * </pre> + * + * @param src the array of source points + * @param srcOff the starting offset into src + * @param dst the array of destination points + * @param dstOff the starting offset into dst + * @param num the number of points to transform + * @throws NullPointerException if src or dst is null + * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded + */ + public void deltaTransform(double[] srcPts, int srcOff, + double[] dstPts, int dstOff, + int num) { - while (num-- > 0) + if (srcPts == dstPts && dstOff > srcOff + && num > 1 && srcOff + 2 * num > dstOff) { - double x = srcPts[srcOff]; - double y = srcPts[srcOff + 1]; - double nx = m00 * x + m01 * y; - double ny = m10 * x + m11 * y; - dstPts[dstOff] = nx; - dstPts[dstOff + 1] = ny; - dstOff += 2; - srcOff += 2; + double[] d = new double[2 * num]; + System.arraycopy(srcPts, srcOff, d, 0, 2 * num); + srcPts = d; + } + while (--num >= 0) + { + double x = srcPts[srcOff++]; + double y = srcPts[srcOff++]; + dstPts[dstOff++] = m00 * x + m01 * y; + dstPts[dstOff++] = m10 * x + m11 * y; } } - public Shape createTransformedShape (Shape pSrc) + /** + * Return a new Shape, based on the given one, where the path of the shape + * has been transformed by this transform. Notice that this uses GeneralPath, + * which only stores points in float precision. + * + * @param src the shape source to transform + * @return the shape, transformed by this + * @throws NullPointerException if src is null + * @see GeneralPath#transform(AffineTransform) + */ + public Shape createTransformedShape(Shape src) { - // FIXME - return null; + GeneralPath p = new GeneralPath(src); + p.transform(this); + return p; } - public String toString () + /** + * Returns a string representation of the transform, in the format: + * <code>"AffineTransform[[" + m00 + ", " + m01 + ", " + m02 + "], [" + * + m10 + ", " + m11 + ", " + m12 + "]]"</code>. + * + * @return the string representation + */ + public String toString() { - // FIXME - return null; + return "AffineTransform[[" + m00 + ", " + m01 + ", " + m02 + "], [" + + m10 + ", " + m11 + ", " + m12 + "]]"; } - public boolean isIdentity () + /** + * Tests if this transformation is the identity: + * <pre> + * [ 1 0 0 ] + * [ 0 1 0 ] + * [ 0 0 1 ] + * </pre> + * + * @return true if this is the identity transform + */ + public boolean isIdentity() { + // Rather than rely on type, check explicitly. return (m00 == 1 && m01 == 0 && m02 == 0 - && m10 == 0 && m11 == 1 && m12 == 0); + && m10 == 0 && m11 == 1 && m12 == 0); } - public Object clone () + /** + * Create a new transform of the same run-time type, with the same + * transforming properties as this one. + * + * @return the clone + */ + public Object clone() { - return new AffineTransform (this); + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } } - public int hashCode () + /** + * Return the hashcode for this transformation. The formula is not + * documented, but appears to be the same as: + * <pre> + * long l = Double.doubleToLongBits(getScaleX()); + * l = l * 31 + Double.doubleToLongBits(getShearY()); + * l = l * 31 + Double.doubleToLongBits(getShearX()); + * l = l * 31 + Double.doubleToLongBits(getScaleY()); + * l = l * 31 + Double.doubleToLongBits(getTranslateX()); + * l = l * 31 + Double.doubleToLongBits(getTranslateY()); + * return (int) ((l >> 32) ^ l); + * </pre> + * + * @return the hashcode + */ + public int hashCode() { - // FIXME - return 23; + long l = Double.doubleToLongBits(m00); + l = l * 31 + Double.doubleToLongBits(m10); + l = l * 31 + Double.doubleToLongBits(m01); + l = l * 31 + Double.doubleToLongBits(m11); + l = l * 31 + Double.doubleToLongBits(m02); + l = l * 31 + Double.doubleToLongBits(m12); + return (int) ((l >> 32) ^ l); } - public boolean equals (Object obj) + /** + * Compares two transforms for equality. This returns true if they have the + * same matrix values. + * + * @param o the transform to compare + * @return true if it is equal + */ + public boolean equals(Object obj) { if (! (obj instanceof AffineTransform)) return false; AffineTransform t = (AffineTransform) obj; return (m00 == t.m00 && m01 == t.m01 && m02 == t.m02 - && m10 == t.m10 && m11 == t.m11 && m12 == t.m12); - } - - // This iterator is used to apply an AffineTransform to some other - // iterator. It is not private because we want to be able to access - // it from the rest of this package. - class Iterator implements PathIterator - { - // The iterator we are applied to. - private PathIterator subIterator; - - public Iterator (PathIterator subIterator) - { - this.subIterator = subIterator; - } - - public int currentSegment (double[] coords) - { - int r = subIterator.currentSegment (coords); - int count = 0; - - switch (r) - { - case SEG_CUBICTO: - count = 3; - break; - - case SEG_QUADTO: - count = 2; - break; - - case SEG_LINETO: - case SEG_MOVETO: - count = 1; - break; - - default: - // Error. But how to report? - case SEG_CLOSE: - break; - } - - transform (coords, 0, coords, 0, count); - - return r; - } - - public int currentSegment (float[] coords) - { - int r = subIterator.currentSegment (coords); - int count = 0; - - switch (r) - { - case SEG_CUBICTO: - count = 3; - break; - - case SEG_QUADTO: - count = 2; - break; - - case SEG_LINETO: - case SEG_MOVETO: - count = 1; - break; - - default: - // Error. But how to report? - case SEG_CLOSE: - break; - } - - transform (coords, 0, coords, 0, count); - - return r; - } - - public int getWindingRule () - { - return subIterator.getWindingRule (); - } - - public boolean isDone () - { - return subIterator.isDone (); - } - - public void next () - { - subIterator.next (); - } - } - - private double m00, m01, m02; - private double m10, m11, m12; - private int type; -} + && m10 == t.m10 && m11 == t.m11 && m12 == t.m12); + } + + /** + * Helper to decode the type from the matrix. This is not guaranteed + * to find the optimal type, but at least it will be valid. + */ + private void updateType() + { + double det = getDeterminant(); + if (det == 0) + { + type = TYPE_GENERAL_TRANSFORM; + return; + } + // Scale (includes rotation by PI) or translation. + if (m01 == 0 && m10 == 0) + { + if (m00 == m11) + type = m00 == 1 ? TYPE_IDENTITY : TYPE_UNIFORM_SCALE; + else + type = TYPE_GENERAL_SCALE; + if (m02 != 0 || m12 != 0) + type |= TYPE_TRANSLATION; + } + // Rotation. + else if (m00 == m11 && m01 == -m10) + { + type = m00 == 0 ? TYPE_QUADRANT_ROTATION : TYPE_GENERAL_ROTATION; + if (det != 1) + type |= TYPE_UNIFORM_SCALE; + if (m02 != 0 || m12 != 0) + type |= TYPE_TRANSLATION; + } + else + type = TYPE_GENERAL_TRANSFORM; + } + + /** + * Reads a transform from an object stream. + * + * @param s the stream to read from + * @throws ClassNotFoundException if there is a problem deserializing + * @throws IOException if there is a problem deserializing + */ + private void readObject(ObjectInputStream s) + throws ClassNotFoundException, IOException + { + s.defaultReadObject(); + updateType(); + } +} // class AffineTransform diff --git a/libjava/java/awt/geom/Arc2D.java b/libjava/java/awt/geom/Arc2D.java new file mode 100644 index 00000000000..d62fa676f89 --- /dev/null +++ b/libjava/java/awt/geom/Arc2D.java @@ -0,0 +1,1123 @@ +/* Arc2D.java -- represents an arc in 2-D space + 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.geom; + +import java.util.NoSuchElementException; + +/** + * 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) + throw new IllegalArgumentException(); + this.type = type; + } + + /** + * Get the starting angle of the arc in degrees. + * + * @return the starting angle + * @see #setAngleStart(double) + */ + public abstract double getAngleStart(); + + /** + * 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() + { + 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() + { + 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); + } + + /** + * 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"); + } + + /** + * Set the start, in degrees. + * + * @param start the new start angle + * @see #getAngleStart() + */ + public abstract void setAngleStart(double start); + + /** + * 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) + { + 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) + { + // 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) + { + 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() + { + 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) + { + 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) + { + 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) + { + 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); + } + + /** + * 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 + { + /** The current iteration. */ + private int current; + + /** 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; + + /** The start angle, in radians (not degrees). */ + private final double start; + + /** 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; + x = a.getX(); + y = a.getY(); + w = a.getWidth(); + h = a.getHeight(); + start = a.getAngleStart() * (Math.PI / 180); + extent = a.getAngleExtent() * (Math.PI / 180); + type = a.type; + double e = extent < 0 ? -extent : extent; + if (w < 0 || h < 0) + limit = -1; + else if (e == 0) + limit = type; + else if (e <= 90) + limit = type + 1; + else if (e <= 180) + limit = type + 2; + else if (e <= 270) + limit = type + 3; + else + 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; + x = e.getX(); + y = e.getY(); + w = e.getWidth(); + h = e.getHeight(); + start = 0; + extent = -2 * Math.PI; + type = CHORD; + 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) + { + 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; + } + if (type != OPEN && current == limit) + return SEG_CLOSE; + if (type == PIE && current == limit - 1) + { + coords[0] = (float) (x + w / 2); + coords[1] = (float) (y + h / 2); + if (xform != null) + xform.transform(coords, 0, coords, 0, 1); + return SEG_LINETO; + } + // XXX Fill coords with 2 control points and next quarter point + coords[0] = (float) 0; + coords[1] = (float) 0; + coords[2] = (float) 0; + coords[3] = (float) 0; + coords[4] = (float) 0; + coords[5] = (float) 0; + if (xform != null) + xform.transform(coords, 0, coords, 0, 3); + 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) + { + 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; + } + if (type != OPEN && current == limit) + return SEG_CLOSE; + if (type == PIE && current == limit - 1) + { + coords[0] = (float) (x + w / 2); + coords[1] = (float) (y + h / 2); + if (xform != null) + xform.transform(coords, 0, coords, 0, 1); + return SEG_LINETO; + } + // XXX Fill coords with 2 control points and next quarter point + coords[0] = 0; + coords[1] = 0; + coords[2] = 0; + coords[3] = 0; + coords[4] = 0; + coords[5] = 0; + if (xform != null) + xform.transform(coords, 0, coords, 0, 3); + return SEG_CUBICTO; + } + } // class ArcIterator + + /** + * 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) + { + super(type); + this.x = x; + this.y = y; + width = w; + height = h; + this.start = start; + 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); + x = r.getX(); + y = r.getY(); + width = r.getWidth(); + height = r.getHeight(); + this.start = start; + 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) + { + this.x = x; + this.y = y; + width = w; + height = h; + this.start = start; + 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); + } + } // class Double + + /** + * 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) + { + super(type); + this.x = x; + this.y = y; + width = w; + height = h; + this.start = start; + 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); + x = (float) r.getX(); + y = (float) r.getY(); + width = (float) r.getWidth(); + height = (float) r.getHeight(); + this.start = start; + 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) + { + this.x = (float) x; + this.y = (float) y; + width = (float) w; + height = (float) h; + this.start = (float) start; + 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((float) x, (float) y, (float) w, (float) h); + } + } // class Float +} // class Arc2D diff --git a/libjava/java/awt/geom/Area.java b/libjava/java/awt/geom/Area.java new file mode 100644 index 00000000000..85bc642cb22 --- /dev/null +++ b/libjava/java/awt/geom/Area.java @@ -0,0 +1,183 @@ +/* Area.java -- represents a shape built by constructive area geometry + 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.geom; + +import java.awt.Rectangle; +import java.awt.Shape; + +/** + * STUBS ONLY + * XXX Implement and document. + */ +public class Area implements Shape, Cloneable +{ + public Area() + { + } + public Area(Shape s) + { + } + public void add(Area a) + { + // XXX Implement. + throw new Error("not implemented"); + } + public void subtract(Area a) + { + // XXX Implement. + throw new Error("not implemented"); + } + public void intersect(Area a) + { + // XXX Implement. + throw new Error("not implemented"); + } + public void exclusiveOr(Area a) + { + // XXX Implement. + throw new Error("not implemented"); + } + public void reset() + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean isEmpty() + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean isPolygonal() + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean isRectangular() + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean isSingular() + { + // XXX Implement. + throw new Error("not implemented"); + } + public Rectangle2D getBounds2D() + { + // XXX Implement. + throw new Error("not implemented"); + } + public Rectangle getBounds() + { + return getBounds2D().getBounds(); + } + + /** + * Create a new area of the same run-time type with the same contents as + * this one. + * + * @return the clone + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } + } + + public boolean equals(Area a) + { + // XXX Implement. + throw new Error("not implemented"); + } + + public void transform(AffineTransform at) + { + // XXX Implement. + throw new Error("not implemented"); + } + public Area createTransformedArea(AffineTransform at) + { + Area a = (Area) clone(); + a.transform(at); + return a; + } + public boolean contains(double x, double y) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean contains(Point2D p) + { + return contains(p.getX(), p.getY()); + } + public boolean contains(double x, double y, double w, double h) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean contains(Rectangle2D r) + { + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + public boolean intersects(double x, double y, double w, double h) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean intersects(Rectangle2D r) + { + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + public PathIterator getPathIterator(AffineTransform at) + { + // XXX Implement. + throw new Error("not implemented"); + } + public PathIterator getPathIterator(AffineTransform at, double flatness) + { + return new FlatteningPathIterator(getPathIterator(at), flatness); + } +} // class Area diff --git a/libjava/java/awt/geom/CubicCurve2D.java b/libjava/java/awt/geom/CubicCurve2D.java new file mode 100644 index 00000000000..2d303c7f6a7 --- /dev/null +++ b/libjava/java/awt/geom/CubicCurve2D.java @@ -0,0 +1,519 @@ +/* CubicCurve2D.java -- represents a parameterized cubic curve in 2-D space + 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.geom; + +import java.awt.Rectangle; +import java.awt.Shape; +import java.util.NoSuchElementException; + +/** + * STUBS ONLY + * XXX Implement and document. + */ +public abstract class CubicCurve2D implements Shape, Cloneable +{ + protected CubicCurve2D() + { + } + + public abstract double getX1(); + public abstract double getY1(); + public abstract Point2D getP1(); + public abstract double getCtrlX1(); + public abstract double getCtrlY1(); + public abstract Point2D getCtrlP1(); + public abstract double getCtrlX2(); + public abstract double getCtrlY2(); + public abstract Point2D getCtrlP2(); + public abstract double getX2(); + public abstract double getY2(); + public abstract Point2D getP2(); + + public abstract void setCurve(double x1, double y1, double cx1, double cy1, + double cx2, double cy2, double x2, double y2); + public void setCurve(double[] coords, int offset) + { + setCurve(coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++]); + } + public void setCurve(Point2D p1, Point2D c1, Point2D c2, Point2D p2) + { + setCurve(p1.getX(), p1.getY(), c1.getX(), c1.getY(), + c2.getX(), c2.getY(), p2.getX(), p2.getY()); + } + public void setCurve(Point2D[] pts, int offset) + { + setCurve(pts[offset].getX(), pts[offset++].getY(), + pts[offset].getX(), pts[offset++].getY(), + pts[offset].getX(), pts[offset++].getY(), + pts[offset].getX(), pts[offset++].getY()); + } + public void setCurve(CubicCurve2D c) + { + setCurve(c.getX1(), c.getY1(), c.getCtrlX1(), c.getCtrlY1(), + c.getCtrlX2(), c.getCtrlY2(), c.getX2(), c.getY2()); + } + public static double getFlatnessSq(double x1, double y1, double cx1, + double cy1, double cx2, double cy2, + double x2, double y2) + { + // XXX Implement. + throw new Error("not implemented"); + } + public static double getFlatness(double x1, double y1, double cx1, + double cy1, double cx2, double cy2, + double x2, double y2) + { + return Math.sqrt(getFlatnessSq(x1, y1, cx1, cy1, cx2, cy2, x2, y2)); + } + public static double getFlatnessSq(double[] coords, int offset) + { + return getFlatnessSq(coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++]); + } + public static double getFlatness(double[] coords, int offset) + { + return Math.sqrt(getFlatnessSq(coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++])); + } + public double getFlatnessSq() + { + return getFlatnessSq(getX1(), getY1(), getCtrlX1(), getCtrlY1(), + getCtrlX2(), getCtrlY2(), getX2(), getY2()); + } + public double getFlatness() + { + return Math.sqrt(getFlatnessSq(getX1(), getY1(), getCtrlX1(), + getCtrlY1(), getCtrlX2(), getCtrlY2(), + getX2(), getY2())); + } + + public void subdivide(CubicCurve2D l, CubicCurve2D r) + { + if (l == null) + l = new CubicCurve2D.Double(); + if (r == null) + r = new CubicCurve2D.Double(); + // Use empty slots at end to share single array. + double[] d = new double[] { getX1(), getY1(), getCtrlX1(), getCtrlY1(), + getCtrlX2(), getCtrlY2(), getX2(), getY2(), + 0, 0, 0, 0, 0, 0 }; + subdivide(d, 0, d, 0, d, 6); + l.setCurve(d, 0); + r.setCurve(d, 6); + } + public static void subdivide(CubicCurve2D src, + CubicCurve2D l, CubicCurve2D r) + { + src.subdivide(l, r); + } + public static void subdivide(double[] src, int srcOff, + double[] left, int leftOff, + double[] right, int rightOff) + { + // XXX Implement. + throw new Error("not implemented"); + } + public static int solveCubic(double[] eqn) + { + return solveCubic(eqn, eqn); + } + public static int solveCubic(double[] eqn, double[] res) + { + if (eqn[3] == 0) + return QuadCurve2D.solveQuadratic(eqn, res); + // XXX Implement. + throw new Error("not implemented"); + } + + public boolean contains(double x, double y) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean contains(Point2D p) + { + return contains(p.getX(), p.getY()); + } + public boolean intersects(double x, double y, double w, double h) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean intersects(Rectangle2D r) + { + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + public boolean contains(double x, double y, double w, double h) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean contains(Rectangle2D r) + { + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + public Rectangle getBounds() + { + return getBounds2D().getBounds(); + } + public PathIterator getPathIterator(final AffineTransform at) + { + return new PathIterator() + { + /** Current coordinate. */ + private int current; + + public int getWindingRule() + { + return WIND_NON_ZERO; + } + + public boolean isDone() + { + return current < 2; + } + + public void next() + { + current++; + } + + public int currentSegment(float[] coords) + { + if (current == 0) + { + coords[0] = (float) getX1(); + coords[1] = (float) getY1(); + if (at != null) + at.transform(coords, 0, coords, 0, 1); + return SEG_MOVETO; + } + if (current == 1) + { + coords[0] = (float) getCtrlX1(); + coords[1] = (float) getCtrlY1(); + coords[2] = (float) getCtrlX2(); + coords[3] = (float) getCtrlY2(); + coords[4] = (float) getX2(); + coords[5] = (float) getY2(); + if (at != null) + at.transform(coords, 0, coords, 0, 3); + return SEG_CUBICTO; + } + throw new NoSuchElementException("cubic iterator out of bounds"); + } + + public int currentSegment(double[] coords) + { + if (current == 0) + { + coords[0] = getX1(); + coords[1] = getY1(); + if (at != null) + at.transform(coords, 0, coords, 0, 1); + return SEG_MOVETO; + } + if (current == 1) + { + coords[0] = getCtrlX1(); + coords[1] = getCtrlY1(); + coords[2] = getCtrlX2(); + coords[3] = getCtrlY2(); + coords[4] = getX2(); + coords[5] = getY2(); + if (at != null) + at.transform(coords, 0, coords, 0, 3); + return SEG_CUBICTO; + } + throw new NoSuchElementException("cubic iterator out of bounds"); + } + }; + } + public PathIterator getPathIterator(AffineTransform at, double flatness) + { + return new FlatteningPathIterator(getPathIterator(at), flatness); + } + + /** + * Create a new curve of the same run-time type with the same contents as + * this one. + * + * @return the clone + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } + } + + /** + * STUBS ONLY + */ + public static class Double extends CubicCurve2D + { + public double x1; + public double y1; + public double ctrlx1; + public double ctrly1; + public double ctrlx2; + public double ctrly2; + public double x2; + public double y2; + + public Double() + { + } + + public Double(double x1, double y1, double cx1, double cy1, + double cx2, double cy2, double x2, double y2) + { + this.x1 = x1; + this.y1 = y1; + ctrlx1 = cx1; + ctrly1 = cy1; + ctrlx2 = cx2; + ctrly2 = cy2; + this.x2 = x2; + this.y2 = y2; + } + + public double getX1() + { + return x1; + } + public double getY1() + { + return y1; + } + public Point2D getP1() + { + return new Point2D.Double(x1, y1); + } + + public double getCtrlX1() + { + return ctrlx1; + } + public double getCtrlY1() + { + return ctrly1; + } + public Point2D getCtrlP1() + { + return new Point2D.Double(ctrlx1, ctrly1); + } + + public double getCtrlX2() + { + return ctrlx2; + } + public double getCtrlY2() + { + return ctrly2; + } + public Point2D getCtrlP2() + { + return new Point2D.Double(ctrlx2, ctrly2); + } + + public double getX2() + { + return x2; + } + public double getY2() + { + return y2; + } + public Point2D getP2() + { + return new Point2D.Double(x2, y2); + } + + public void setCurve(double x1, double y1, double cx1, double cy1, + double cx2, double cy2, double x2, double y2) + { + this.x1 = x1; + this.y1 = y1; + ctrlx1 = cx1; + ctrly1 = cy1; + ctrlx2 = cx2; + ctrly2 = cy2; + this.x2 = x2; + this.y2 = y2; + } + public Rectangle2D getBounds2D() + { + double nx1 = Math.min(Math.min(x1, ctrlx1), Math.min(ctrlx2, x2)); + double ny1 = Math.min(Math.min(y1, ctrly1), Math.min(ctrly2, y2)); + double nx2 = Math.max(Math.max(x1, ctrlx1), Math.max(ctrlx2, x2)); + double ny2 = Math.max(Math.max(y1, ctrly1), Math.max(ctrly2, y2)); + return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1); + } + } // class Double + + /** + * STUBS ONLY + */ + public static class Float extends CubicCurve2D + { + public float x1; + public float y1; + public float ctrlx1; + public float ctrly1; + public float ctrlx2; + public float ctrly2; + public float x2; + public float y2; + + public Float() + { + } + + public Float(float x1, float y1, float cx1, float cy1, + float cx2, float cy2, float x2, float y2) + { + this.x1 = x1; + this.y1 = y1; + ctrlx1 = cx1; + ctrly1 = cy1; + ctrlx2 = cx2; + ctrly2 = cy2; + this.x2 = x2; + this.y2 = y2; + } + + public double getX1() + { + return x1; + } + public double getY1() + { + return y1; + } + public Point2D getP1() + { + return new Point2D.Float(x1, y1); + } + + public double getCtrlX1() + { + return ctrlx1; + } + public double getCtrlY1() + { + return ctrly1; + } + public Point2D getCtrlP1() + { + return new Point2D.Float(ctrlx1, ctrly1); + } + + public double getCtrlX2() + { + return ctrlx2; + } + public double getCtrlY2() + { + return ctrly2; + } + public Point2D getCtrlP2() + { + return new Point2D.Float(ctrlx2, ctrly2); + } + + public double getX2() + { + return x2; + } + public double getY2() + { + return y2; + } + public Point2D getP2() + { + return new Point2D.Float(x2, y2); + } + + public void setCurve(double x1, double y1, double cx1, double cy1, + double cx2, double cy2, double x2, double y2) + { + this.x1 = (float) x1; + this.y1 = (float) y1; + ctrlx1 = (float) cx1; + ctrly1 = (float) cy1; + ctrlx2 = (float) cx2; + ctrly2 = (float) cy2; + this.x2 = (float) x2; + this.y2 = (float) y2; + } + public void setCurve(float x1, float y1, float cx1, float cy1, + float cx2, float cy2, float x2, float y2) + { + this.x1 = x1; + this.y1 = y1; + ctrlx1 = cx1; + ctrly1 = cy1; + ctrlx2 = cx2; + ctrly2 = cy2; + this.x2 = x2; + this.y2 = y2; + } + public Rectangle2D getBounds2D() + { + float nx1 = (float) Math.min(Math.min(x1, ctrlx1), Math.min(ctrlx2, x2)); + float ny1 = (float) Math.min(Math.min(y1, ctrly1), Math.min(ctrly2, y2)); + float nx2 = (float) Math.max(Math.max(x1, ctrlx1), Math.max(ctrlx2, x2)); + float ny2 = (float) Math.max(Math.max(y1, ctrly1), Math.max(ctrly2, y2)); + return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1); + } + } // class Float +} // class CubicCurve2D diff --git a/libjava/java/awt/geom/Dimension2D.java b/libjava/java/awt/geom/Dimension2D.java index d9f09f0ecb2..e111e5434cf 100644 --- a/libjava/java/awt/geom/Dimension2D.java +++ b/libjava/java/awt/geom/Dimension2D.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2002 Free Software Foundation +/* Dimension2D.java -- abstraction of a dimension + Copyright (C) 1999, 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,39 +35,79 @@ 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.geom; /** + * This stores a dimension in 2-dimensional space - a width (along the x-axis) + * and height (along the y-axis). The storage is left to subclasses. + * * @author Per Bothner <bothner@cygnus.com> - * @date February, 1999. - */ - -/* Written using online API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct. + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 */ - public abstract class Dimension2D implements Cloneable { + /** + * The default constructor. + */ + protected Dimension2D() + { + } + + /** + * Get the width of this dimension. A negative result, while legal, is + * undefined in meaning. + * + * @return the width + */ public abstract double getWidth(); + + /** + * Get the height of this dimension. A negative result, while legal, is + * undefined in meaning. + * + * @return the height + */ public abstract double getHeight(); - public abstract void setSize (double width, double height); + /** + * Set the size of this dimension to the requested values. Loss of precision + * may occur. + * + * @param w the new width + * @param h the new height + */ + public abstract void setSize(double w, double h); - public void setSize (Dimension2D dim) + /** + * Set the size of this dimension to the requested value. Loss of precision + * may occur. + * + * @param d the dimension containing the new values + * @throws NullPointerException if d is null + */ + public void setSize(Dimension2D d) { - setSize(dim.getWidth(), dim.getHeight()); + setSize(d.getWidth(), d.getHeight()); } - public Object clone () + /** + * Create a new dimension of the same run-time type with the same contents + * as this one. + * + * @return the clone + */ + public Object clone() { try - { - return super.clone (); - } - catch (CloneNotSupportedException _) {return null;} - } - - protected Dimension2D () - { + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } } -} +} // class Dimension2D diff --git a/libjava/java/awt/geom/Ellipse2D.java b/libjava/java/awt/geom/Ellipse2D.java index 033c0ef8833..223a1930991 100644 --- a/libjava/java/awt/geom/Ellipse2D.java +++ b/libjava/java/awt/geom/Ellipse2D.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* Ellipse2D.java -- represents an ellipse in 2-D space + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -38,39 +39,40 @@ package java.awt.geom; /** * @author Tom Tromey <tromey@cygnus.com> - * @date April 16, 2000 + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status still needs documentation */ - public abstract class Ellipse2D extends RectangularShape { - protected Ellipse2D () + protected Ellipse2D() { } - public boolean contains (double x, double y) + public boolean contains(double x, double y) { - double rx = getWidth () / 2; - double ry = getHeight () / 2; - double tx = (x - getCenterX ()) / rx; - double ty = (y - getCenterY ()) / ry; + double rx = getWidth() / 2; + double ry = getHeight() / 2; + double tx = (x - getCenterX()) / rx; + double ty = (y - getCenterY()) / ry; return tx * tx + ty * ty <= 1.0; } - public boolean contains (double x, double y, double w, double h) + public boolean contains(double x, double y, double w, double h) { double x2 = x + w; double y2 = y + h; - return (contains (x, y) && contains (x, y2) - && contains (x2, y) && contains (x2, y2)); + return (contains(x, y) && contains(x, y2) + && contains(x2, y) && contains(x2, y2)); } - public PathIterator getPathIterator (AffineTransform at) + public PathIterator getPathIterator(AffineTransform at) { - // fixme; - return null; + // An ellipse is just a complete arc. + return new Arc2D.ArcIterator(this, at); } - public boolean intersects (double x, double y, double w, double h) + public boolean intersects(double x, double y, double w, double h) { // fixme return false; @@ -83,57 +85,56 @@ public abstract class Ellipse2D extends RectangularShape public double x; public double y; - public Double () + public Double() { - height = width = x = y = 0; } - public Double (double x, double y, double w, double h) + public Double(double x, double y, double w, double h) { this.x = x; this.y = y; - this.height = h; - this.width = w; + height = h; + width = w; } - public Rectangle2D getBounds2D () + public Rectangle2D getBounds2D() { - return new Rectangle2D.Double (x, y, width, height); + return new Rectangle2D.Double(x, y, width, height); } - public double getHeight () + public double getHeight() { return height; } - public double getWidth () + public double getWidth() { return width; } - public double getX () + public double getX() { return x; } - public double getY () + public double getY() { return y; } - public boolean isEmpty () + public boolean isEmpty() { return height <= 0 || width <= 0; } - public void setFrame (double x, double y, double w, double h) + public void setFrame(double x, double y, double w, double h) { this.x = x; this.y = y; - this.height = h; - this.width = w; + height = h; + width = w; } - } + } // class Double public static class Float extends Ellipse2D { @@ -142,12 +143,11 @@ public abstract class Ellipse2D extends RectangularShape public float x; public float y; - public Float () + public Float() { - height = width = x = y = 0; } - public Float (float x, float y, float w, float h) + public Float(float x, float y, float w, float h) { this.x = x; this.y = y; @@ -155,50 +155,50 @@ public abstract class Ellipse2D extends RectangularShape this.width = w; } - public Rectangle2D getBounds2D () + public Rectangle2D getBounds2D() { - return new Rectangle2D.Float (x, y, width, height); + return new Rectangle2D.Float(x, y, width, height); } - public double getHeight () + public double getHeight() { return height; } - public double getWidth () + public double getWidth() { return width; } - public double getX () + public double getX() { return x; } - public double getY () + public double getY() { return y; } - public boolean isEmpty () + public boolean isEmpty() { return height <= 0 || width <= 0; } - public void setFrame (float x, float y, float w, float h) + public void setFrame(float x, float y, float w, float h) { this.x = x; this.y = y; - this.height = h; - this.width = w; + height = h; + width = w; } - public void setFrame (double x, double y, double w, double h) + public void setFrame(double x, double y, double w, double h) { this.x = (float) x; this.y = (float) y; - this.height = (float) h; - this.width = (float) w; + height = (float) h; + width = (float) w; } - } -} + } // class Float +} // class Ellipse2D diff --git a/libjava/java/awt/geom/FlatteningPathIterator.java b/libjava/java/awt/geom/FlatteningPathIterator.java new file mode 100644 index 00000000000..a7a57ef6fed --- /dev/null +++ b/libjava/java/awt/geom/FlatteningPathIterator.java @@ -0,0 +1,105 @@ +/* FlatteningPathIterator.java -- performs interpolation of curved paths + 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.geom; + +/** + * This class can be used to perform the flattening required by the Shape + * interface. It interpolates a curved path segment into a sequence of flat + * ones within a certain flatness, up to a recursion limit. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Shape + * @see RectangularShape#getPathIterator(AffineTransform, double) + * @since 1.2 + * @status STUBS ONLY + */ +public class FlatteningPathIterator implements PathIterator +{ + // The iterator we are applied to. + private PathIterator subIterator; + private double flatness; + private int limit; + + public FlatteningPathIterator(PathIterator src, double flatness) + { + this(src, flatness, 10); + } + public FlatteningPathIterator(PathIterator src, double flatness, int limit) + { + subIterator = src; + this.flatness = flatness; + this.limit = limit; + if (flatness < 0 || limit < 0) + throw new IllegalArgumentException(); + } + + public double getFlatness() + { + return flatness; + } + + public int getRecursionLimit() + { + return limit; + } + + public int getWindingRule() + { + return subIterator.getWindingRule(); + } + + public boolean isDone() + { + return subIterator.isDone(); + } + + public void next() + { + throw new Error("not implemented"); + } + + public int currentSegment(double[] coords) + { + throw new Error("not implemented"); + } + public int currentSegment(float[] coords) + { + throw new Error("not implemented"); + } +} // class FlatteningPathIterator diff --git a/libjava/java/awt/geom/GeneralPath.java b/libjava/java/awt/geom/GeneralPath.java new file mode 100644 index 00000000000..267db6ca0e3 --- /dev/null +++ b/libjava/java/awt/geom/GeneralPath.java @@ -0,0 +1,361 @@ +/* GeneralPath.java -- represents a shape built from subpaths + 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.geom; + +import java.awt.Rectangle; +import java.awt.Shape; + +/** + * STUBS ONLY + * XXX Implement and document. Note that Sun's implementation only expects + * float precision, not double. + */ +public final class GeneralPath implements Shape, Cloneable +{ + public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD; + public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO; + + /** Initial size if not specified. */ + private static final int INIT_SIZE = 20; + + /** The winding rule. */ + private int rule; + /** + * The path type in points. Note that points[index] maps to + * types[index >> 1]; the control points of quad and cubic paths map as + * well but are ignored. + */ + private byte[] types; + /** + * The list of all points seen. Since you can only append floats, it makes + * sense for this to be a float[]. I have no idea why Sun didn't choose to + * allow a general path of double precision points. + */ + private float[] points; + /** The index of the most recent moveto point, or null. */ + private int subpath = -1; + /** The next available index into points. */ + private int index; + + public GeneralPath() + { + this(WIND_NON_ZERO, INIT_SIZE); + } + public GeneralPath(int rule) + { + this(rule, INIT_SIZE); + } + public GeneralPath(int rule, int capacity) + { + if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) + throw new IllegalArgumentException(); + this.rule = rule; + if (capacity < INIT_SIZE) + capacity = INIT_SIZE; + types = new byte[capacity >> 1]; + points = new float[capacity]; + } + public GeneralPath(Shape s) + { + types = new byte[INIT_SIZE >> 1]; + points = new float[INIT_SIZE]; + PathIterator pi = s.getPathIterator(null); + setWindingRule(pi.getWindingRule()); + append(pi, false); + } + + public void moveTo(float x, float y) + { + subpath = index; + ensureSize(index + 2); + types[index >> 1] = PathIterator.SEG_MOVETO; + points[index++] = x; + points[index++] = y; + } + public void lineTo(float x, float y) + { + ensureSize(index + 2); + types[index >> 1] = PathIterator.SEG_LINETO; + points[index++] = x; + points[index++] = y; + } + public void quadTo(float x1, float y1, float x2, float y2) + { + ensureSize(index + 4); + types[index >> 1] = PathIterator.SEG_QUADTO; + points[index++] = x1; + points[index++] = y1; + points[index++] = x2; + points[index++] = y2; + } + public void curveTo(float x1, float y1, float x2, float y2, + float x3, float y3) + { + ensureSize(index + 6); + types[index >> 1] = PathIterator.SEG_QUADTO; + points[index++] = x1; + points[index++] = y1; + points[index++] = x2; + points[index++] = y2; + points[index++] = x3; + points[index++] = y3; + } + public void closePath() + { + ensureSize(index + 2); + types[index >> 1] = PathIterator.SEG_CLOSE; + points[index++] = points[subpath]; + points[index++] = points[subpath + 1]; + } + + public void append(Shape s, boolean connect) + { + append(s.getPathIterator(null), connect); + } + public void append(PathIterator i, boolean connect) + { + float[] f = new float[6]; + while (! i.isDone()) + { + int result = i.currentSegment(f); + switch (result) + { + case PathIterator.SEG_MOVETO: + if (! connect) + { + moveTo(f[0], f[1]); + break; + } + if (subpath >= 0 && f[0] == points[subpath] + && f[1] == points[subpath + 1]) + break; + // Fallthrough. + case PathIterator.SEG_LINETO: + lineTo(f[0], f[1]); + break; + case PathIterator.SEG_QUADTO: + quadTo(f[0], f[1], f[2], f[3]); + break; + case PathIterator.SEG_CUBICTO: + curveTo(f[0], f[1], f[2], f[3], f[4], f[5]); + break; + default: + closePath(); + } + connect = false; + } + } + + public int getWindingRule() + { + return rule; + } + public void setWindingRule(int rule) + { + if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) + throw new IllegalArgumentException(); + this.rule = rule; + } + + public Point2D getCurrentPoint() + { + if (subpath < 0) + return null; + return new Point2D.Float(points[subpath], points[subpath + 1]); + } + public void reset() + { + subpath = -1; + index = 0; + } + + public void transform(AffineTransform xform) + { + xform.transform(points, 0, points, 0, index >> 1); + } + public Shape createTransformedShape(AffineTransform xform) + { + GeneralPath p = new GeneralPath(this); + p.transform(xform); + return p; + } + + public Rectangle getBounds() + { + return getBounds2D().getBounds(); + } + public Rectangle2D getBounds2D() + { + // XXX Implement. + throw new Error("not implemented"); + } + + public boolean contains(double x, double y) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean contains(Point2D p) + { + return contains(p.getX(), p.getY()); + } + public boolean contains(double x, double y, double w, double h) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean contains(Rectangle2D r) + { + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + public boolean intersects(double x, double y, double w, double h) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean intersects(Rectangle2D r) + { + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + public PathIterator getPathIterator(final AffineTransform at) + { + return new PathIterator() + { + int current = 0; + + public int getWindingRule() + { + return rule; + } + + public boolean isDone() + { + return current >= index; + } + + public void next() + { + current++; + } + + public int currentSegment(float[] coords) + { + if (current >= index) + return SEG_CLOSE; + int result = types[current >> 1]; + int i = 0; + if (result == 3) + { + coords[i++] = points[current++]; + coords[i++] = points[current++]; + } + if (result == 2) + { + coords[i++] = points[current++]; + coords[i++] = points[current++]; + } + if (result < 2) + { + coords[i++] = points[current++]; + coords[i++] = points[current++]; + if (at != null) + at.transform(coords, 0, coords, 0, result == 0 ? 1 : result); + } + return result; + } + + public int currentSegment(double[] coords) + { + if (current >= index) + return SEG_CLOSE; + int result = types[current >> 1]; + int i = 0; + if (result == 3) + { + coords[i++] = points[current++]; + coords[i++] = points[current++]; + } + if (result == 2) + { + coords[i++] = points[current++]; + coords[i++] = points[current++]; + } + if (result < 2) + { + coords[i++] = points[current++]; + coords[i++] = points[current++]; + if (at != null) + at.transform(coords, 0, coords, 0, result == 0 ? 1 : result); + } + return result; + } + }; + } + public PathIterator getPathIterator(AffineTransform at, double flatness) + { + return new FlatteningPathIterator(getPathIterator(at), flatness); + } + + /** + * Create a new shape of the same run-time type with the same contents as + * this one. + * + * @return the clone + */ + public Object clone() + { + // This class is final; no need to use super.clone(). + return new GeneralPath(this); + } + + private void ensureSize(int size) + { + if (subpath < 0) + throw new IllegalPathStateException("need initial moveto"); + if (size <= points.length) + return; + byte[] b = new byte[points.length]; + System.arraycopy(types, 0, b, 0, index >> 1); + types = b; + float[] f = new float[points.length << 1]; + System.arraycopy(points, 0, f, 0, index); + points = f; + } +} // class GeneralPath diff --git a/libjava/java/awt/geom/IllegalPathStateException.java b/libjava/java/awt/geom/IllegalPathStateException.java index 3e36b081775..f0e388aac55 100644 --- a/libjava/java/awt/geom/IllegalPathStateException.java +++ b/libjava/java/awt/geom/IllegalPathStateException.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* IllegalPathStateException.java -- an operation was in an illegal path state + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,19 +38,34 @@ exception statement from your version. */ package java.awt.geom; /** + * Thrown when an operation on a path is in an illegal state, such as appending + * a segment to a <code>GeneralPath</code> without an initial moveto. + * * @author Tom Tromey <tromey@cygnus.com> - * @date July 17, 2000 + * @see GeneralPath + * @status updated to 1.4 */ - public class IllegalPathStateException extends RuntimeException { - public IllegalPathStateException () + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = -5158084205220481094L; + + /** + * Create an exception with no message. + */ + public IllegalPathStateException() { - super (); } - public IllegalPathStateException (String msg) + /** + * Create an exception with a message. + * + * @param msg the message + */ + public IllegalPathStateException(String msg) { - super (msg); + super(msg); } } diff --git a/libjava/java/awt/geom/Line2D.java b/libjava/java/awt/geom/Line2D.java index 608b5660c75..9e551103332 100644 --- a/libjava/java/awt/geom/Line2D.java +++ b/libjava/java/awt/geom/Line2D.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2001, 2002 Free Software Foundation +/* Line2D.java -- represents a line in 2-D space, plus operations on a line + Copyright (C) 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -38,325 +39,769 @@ package java.awt.geom; import java.awt.Rectangle; import java.awt.Shape; +import java.util.NoSuchElementException; /** + * Represents a directed line bewteen two points in (x,y) Cartesian space. + * Remember, on-screen graphics have increasing x from left-to-right, and + * increasing y from top-to-bottom. The storage is left to subclasses. + * * @author Tom Tromey <tromey@cygnus.com> - * @date April 21, 2001 + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 */ - public abstract class Line2D implements Shape, Cloneable { - protected Line2D () + /** + * The default constructor. + */ + protected Line2D() { } - public Object clone () + /** + * Return the x coordinate of the first point. + * + * @return the starting x coordinate + */ + public abstract double getX1(); + + /** + * Return the y coordinate of the first point. + * + * @return the starting y coordinate + */ + public abstract double getY1(); + + /** + * Return the first point. + * + * @return the starting point + */ + public abstract Point2D getP1(); + + /** + * Return the x coordinate of the second point. + * + * @return the ending x coordinate + */ + public abstract double getX2(); + + /** + * Return the y coordinate of the second point. + * + * @return the ending y coordinate + */ + public abstract double getY2(); + + /** + * Return the second point. + * + * @return the ending point + */ + public abstract Point2D getP2(); + + /** + * Set the coordinates of the line to the given coordinates. Loss of + * precision may occur due to rounding issues. + * + * @param x1 the first x coordinate + * @param y1 the first y coordinate + * @param x2 the second x coordinate + * @param y2 the second y coordinate + */ + public abstract void setLine(double x1, double y1, double x2, double y2); + + /** + * Set the coordinates to the given points. + * + * @param p1 the first point + * @param p2 the second point + * @throws NullPointerException if either point is null + */ + public void setLine(Point2D p1, Point2D p2) { - try - { - return super.clone (); - } - catch (CloneNotSupportedException _) - { - // Can't happen. - return null; - } + setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY()); } - public boolean contains (double x, double y) + /** + * Set the coordinates to those of the given line. + * + * @param l the line to copy + * @throws NullPointerException if l is null + */ + public void setLine(Line2D l) { - double x1 = getX1 (); - double t1 = (x - x1) / (getX2 () - x1); - if (t1 < 0 || t1 > 1) - return false; - double y1 = getY1 (); - double t2 = (y - y1) / (getY2 () - y1); - // FIXME: use of == here is bogus - return t2 >= 0 && t2 <= 1 && t1 == t2; + setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2()); } - public boolean contains (double x, double y, double w, double h) + /** + * Computes the relative rotation direction needed to pivot the line about + * the first point in order to have the second point colinear with point p. + * Because of floating point rounding, don't expect this to be a perfect + * measure of colinearity. The answer is 1 if the line has a shorter rotation + * in the direction of the positive X axis to the negative Y axis + * (counter-clockwise in the default Java coordinate system), or -1 if the + * shortest rotation is in the opposite direction (clockwise). If p + * is already colinear, the return value is -1 if it lies beyond the first + * point, 0 if it lies in the segment, or 1 if it lies beyond the second + * point. If the first and second point are coincident, this returns 0. + * + * @param x1 the first x coordinate + * @param y1 the first y coordinate + * @param x2 the second x coordinate + * @param y2 the second y coordinate + * @param px the reference x coordinate + * @param py the reference y coordinate + * @return the relative rotation direction + */ + public static int relativeCCW(double x1, double y1, double x2, double y2, + double px, double py) { - return false; + if ((x1 == x2 && y1 == y2) + || (x1 == px && y1 == py)) + return 0; // Coincident points. + // Translate to the origin. + x2 -= x1; + y2 -= y1; + px -= x1; + py -= y1; + double slope2 = y2 / x2; + double slopep = py / px; + if (slope2 == slopep || (x2 == 0 && px == 0)) + return y2 > 0 // Colinear. + ? (py < 0 ? -1 : py > y2 ? 1 : 0) + : (py > 0 ? -1 : py < y2 ? 1 : 0); + if (x2 >= 0 && slope2 >= 0) + return px >= 0 // Quadrant 1. + ? (slope2 > slopep ? 1 : -1) + : (slope2 < slopep ? 1 : -1); + if (y2 > 0) + return px < 0 // Quadrant 2. + ? (slope2 > slopep ? 1 : -1) + : (slope2 < slopep ? 1 : -1); + if (slope2 >= 0.0) + return px >= 0 // Quadrant 3. + ? (slope2 < slopep ? 1 : -1) + : (slope2 > slopep ? 1 : -1); + return px < 0 // Quadrant 4. + ? (slope2 < slopep ? 1 : -1) + : (slope2 > slopep ? 1 : -1); } - public boolean contains (Point2D p) + /** + * Computes the relative rotation direction needed to pivot this line about + * the first point in order to have the second point colinear with point p. + * Because of floating point rounding, don't expect this to be a perfect + * measure of colinearity. The answer is 1 if the line has a shorter rotation + * in the direction of the positive X axis to the negative Y axis + * (counter-clockwise in the default Java coordinate system), or -1 if the + * shortest rotation is in the opposite direction (clockwise). If p + * is already colinear, the return value is -1 if it lies beyond the first + * point, 0 if it lies in the segment, or 1 if it lies beyond the second + * point. If the first and second point are coincident, this returns 0. + * + * @param px the reference x coordinate + * @param py the reference y coordinate + * @return the relative rotation direction + * @see #relativeCCW(double, double, double, double, double, double) + */ + public int relativeCCW(double px, double py) { - return contains (p.getX (), p.getY ()); + return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py); } - public boolean contains (Rectangle2D r) + /** + * Computes the relative rotation direction needed to pivot this line about + * the first point in order to have the second point colinear with point p. + * Because of floating point rounding, don't expect this to be a perfect + * measure of colinearity. The answer is 1 if the line has a shorter rotation + * in the direction of the positive X axis to the negative Y axis + * (counter-clockwise in the default Java coordinate system), or -1 if the + * shortest rotation is in the opposite direction (clockwise). If p + * is already colinear, the return value is -1 if it lies beyond the first + * point, 0 if it lies in the segment, or 1 if it lies beyond the second + * point. If the first and second point are coincident, this returns 0. + * + * @param p the reference point + * @return the relative rotation direction + * @throws NullPointerException if p is null + * @see #relativeCCW(double, double, double, double, double, double) + */ + public int relativeCCW(Point2D p) { - return false; + return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY()); } - public Rectangle getBounds () + /** + * Test if the line segment (x1,y1)->(x2,y2) intersects the line segment + * (x3,y3)->(x4,y4). + * + * @param x1 the first x coordinate of the first segment + * @param y1 the first y coordinate of the first segment + * @param x2 the second x coordinate of the first segment + * @param y2 the second y coordinate of the first segment + * @param x3 the first x coordinate of the second segment + * @param y3 the first y coordinate of the second segment + * @param x4 the second x coordinate of the second segment + * @param y4 the second y coordinate of the second segment + * @return true if the segments intersect + */ + public static boolean linesIntersect(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) { - double x1 = getX1 (); - double y1 = getY1 (); - double x2 = getX2 (); - double y2 = getY2 (); - - double x = Math.min (x1, x2); - double y = Math.min (y1, y2); - double w = Math.abs (x1 - x2); - double h = Math.abs (y1 - y2); - - return new Rectangle ((int) x, (int) y, (int) w, (int) h); + double beta = (((y1 - y3) * (x4 - x3) + (x1 - x3) * (y4 - y3)) + / ((y2 - y1) * (x4 - x3) + (x2 - x1) * (y4 - y3))); + if (beta < 0.0 || beta > 1.0) + return false; + double alpha = (x1 + beta * (x2 - x1) - x3) / (x4 - x3); + return alpha >= 0.0 && alpha <= 1.0; } - public abstract Point2D getP1 (); - public abstract Point2D getP2 (); - - public PathIterator getPathIterator (AffineTransform at) + /** + * Test if this line intersects the line given by (x1,y1)->(x2,y2). + * + * @param x1 the first x coordinate of the other segment + * @param y1 the first y coordinate of the other segment + * @param x2 the second x coordinate of the other segment + * @param y2 the second y coordinate of the other segment + * @return true if the segments intersect + * @see #linesIntersect(double, double, double, double, + * double, double, double, double) + */ + public boolean intersectsLine(double x1, double y1, double x2, double y2) { - return getPathIterator (at, 0); + return linesIntersect(getX1(), getY1(), getX2(), getY2(), + x1, y1, x2, y2); } - public PathIterator getPathIterator (AffineTransform at, double flatness) + /** + * Test if this line intersects the given line. + * + * @param l the other segment + * @return true if the segments intersect + * @throws NullPointerException if l is null + * @see #linesIntersect(double, double, double, double, + * double, double, double, double) + */ + public boolean intersectsLine(Line2D l) { - return at.new Iterator (new Iterator ()); + return linesIntersect(getX1(), getY1(), getX2(), getY2(), + l.getX1(), l.getY1(), l.getX2(), l.getY2()); } - public abstract double getX1 (); - public abstract double getY1 (); - public abstract double getX2 (); - public abstract double getY2 (); - - public boolean intersects (double x, double y, double w, double h) + /** + * Measures the square of the shortest distance from the reference point + * to a point on the line segment. If the point is on the segment, the + * result will be 0. + * + * @param x1 the first x coordinate of the segment + * @param y1 the first y coordinate of the segment + * @param x2 the second x coordinate of the segment + * @param y2 the second y coordinate of the segment + * @param px the x coordinate of the point + * @param py the y coordinate of the point + * @return the square of the distance from the point to the segment + * @see #ptSegDist(double, double, double, double, double, double) + * @see #ptLineDistSq(double, double, double, double, double, double) + */ + public static double ptSegDistSq(double x1, double y1, double x2, double y2, + double px, double py) { - double x1 = getX1 (); - double y1 = getY1 (); - double x2 = getX2 (); - double y2 = getY2 (); - - if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y +h) - return true; - if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y +h) - return true; - - double x3 = x + w; - double y3 = y + h; - - return (linesIntersect (x1, y1, x2, y2, x, y, x, y3) - || linesIntersect (x1, y1, x2, y2, x, y3, x3, y3) - || linesIntersect (x1, y1, x2, y2, x3, y3, x3, y) - || linesIntersect (x1, y1, x2, y2, x3, y, x, y)); - } - - public boolean intersects (Rectangle2D r) - { - return intersects (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); - } + double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); - public boolean intersectsLine (double x1, double y1, double x2, double y2) - { - return linesIntersect (getX1 (), getY1 (), getX2 (), getY2(), - x1, y1, x2, y2); - } + double x, y; + if (pd2 == 0) + { + // Points are coincident. + x = x1; + y = y2; + } + else + { + double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2; + + if (u < 0) + { + // "Off the end" + x = x1; + y = y1; + } + else if (u > 1.0) + { + x = x2; + y = y2; + } + else + { + x = x1 + u * (x2 - x1); + y = y1 + u * (y2 - y1); + } + } - public boolean intersectsLine (Line2D l) - { - return linesIntersect (getX1 (), getY1 (), getX2 (), getY2(), - l.getX1 (), l.getY1 (), l.getX2 (), l.getY2 ()); + return (x - px) * (x - px) + (y - py) * (y - py); } - public static boolean linesIntersect (double x1, double y1, - double x2, double y2, - double x3,double y3, - double x4, double y4) + /** + * Measures the shortest distance from the reference point to a point on + * the line segment. If the point is on the segment, the result will be 0. + * + * @param x1 the first x coordinate of the segment + * @param y1 the first y coordinate of the segment + * @param x2 the second x coordinate of the segment + * @param y2 the second y coordinate of the segment + * @param px the x coordinate of the point + * @param py the y coordinate of the point + * @return the distance from the point to the segment + * @see #ptSegDistSq(double, double, double, double, double, double) + * @see #ptLineDist(double, double, double, double, double, double) + */ + public static double ptSegDist(double x1, double y1, double x2, double y2, + double px, double py) { - double beta = (((y1 - y3) * (x4 - x3) + (x1 - x3) * (y4 - y3)) - / ((y2 - y1) * (x4 - x3) + (x2 - x1) * (y4 - y3))); - if (beta < 0.0 || beta > 1.0) - return false; - double alpha = (x1 + beta * (x2 - x1) - x3) / (x4 - x3); - return alpha >= 0.0 && alpha <= 1.0; + return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py)); } - public double ptLineDist (double px, double py) + /** + * Measures the square of the shortest distance from the reference point + * to a point on this line segment. If the point is on the segment, the + * result will be 0. + * + * @param px the x coordinate of the point + * @param py the y coordinate of the point + * @return the square of the distance from the point to the segment + * @see #ptSegDistSq(double, double, double, double, double, double) + */ + public double ptSegDistSq(double px, double py) { - return ptLineDist (getX1 (), getY1 (), getX2 (), getY2 (), - px, py); + return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py); } - public static double ptLineDist (double x1, double y1, - double x2, double y2, - double px, double py) + /** + * Measures the square of the shortest distance from the reference point + * to a point on this line segment. If the point is on the segment, the + * result will be 0. + * + * @param p the point + * @return the square of the distance from the point to the segment + * @throws NullPointerException if p is null + * @see #ptSegDistSq(double, double, double, double, double, double) + */ + public double ptSegDistSq(Point2D p) { - return Math.sqrt (ptLineDistSq (x1, y1, x2, y2, px, py)); + return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY()); } - public double ptLineDist (Point2D p) + /** + * Measures the shortest distance from the reference point to a point on + * this line segment. If the point is on the segment, the result will be 0. + * + * @param px the x coordinate of the point + * @param py the y coordinate of the point + * @return the distance from the point to the segment + * @see #ptSegDist(double, double, double, double, double, double) + */ + public double ptSegDist(double px, double py) { - return ptLineDist (getX1 (), getY1 (), getX2 (), getY2 (), - p.getX (), p.getY ()); + return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py); } - public double ptLineDistSq (double px, double py) + /** + * Measures the shortest distance from the reference point to a point on + * this line segment. If the point is on the segment, the result will be 0. + * + * @param p the point + * @return the distance from the point to the segment + * @throws NullPointerException if p is null + * @see #ptSegDist(double, double, double, double, double, double) + */ + public double ptSegDist(Point2D p) { - return ptLineDistSq (getX1 (), getY1 (), getX2 (), getY2 (), - px, py); + return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY()); } - public static double ptLineDistSq (double x1, double y1, - double x2, double y2, - double px, double py) + /** + * Measures the square of the shortest distance from the reference point + * to a point on the infinite line extended from the segment. If the point + * is on the segment, the result will be 0. If the segment is length 0, + * the distance is to the common endpoint. + * + * @param x1 the first x coordinate of the segment + * @param y1 the first y coordinate of the segment + * @param x2 the second x coordinate of the segment + * @param y2 the second y coordinate of the segment + * @param px the x coordinate of the point + * @param py the y coordinate of the point + * @return the square of the distance from the point to the extended line + * @see #ptLineDist(double, double, double, double, double, double) + * @see #ptSegDistSq(double, double, double, double, double, double) + */ + public static double ptLineDistSq(double x1, double y1, double x2, double y2, + double px, double py) { double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); double x, y; if (pd2 == 0) { - // Points are coincident. - x = x1; - y = y2; + // Points are coincident. + x = x1; + y = y2; } else { - double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2; - x = x1 + u * (x2 - x1); - y = y1 + u * (y2 - y1); + double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2; + x = x1 + u * (x2 - x1); + y = y1 + u * (y2 - y1); } return (x - px) * (x - px) + (y - py) * (y - py); } - public double ptLineDistSq (Point2D p) + /** + * Measures the shortest distance from the reference point to a point on + * the infinite line extended from the segment. If the point is on the + * segment, the result will be 0. If the segment is length 0, the distance + * is to the common endpoint. + * + * @param x1 the first x coordinate of the segment + * @param y1 the first y coordinate of the segment + * @param x2 the second x coordinate of the segment + * @param y2 the second y coordinate of the segment + * @param px the x coordinate of the point + * @param py the y coordinate of the point + * @return the distance from the point to the extended line + * @see #ptLineDistSq(double, double, double, double, double, double) + * @see #ptSegDist(double, double, double, double, double, double) + */ + public static double ptLineDist(double x1, double y1, + double x2, double y2, + double px, double py) { - return ptLineDistSq (getX1 (), getY1 (), getX2 (), getY2 (), - p.getX (), p.getY ()); + return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py)); } - public double ptSegDist (double px, double py) + /** + * Measures the square of the shortest distance from the reference point + * to a point on the infinite line extended from this segment. If the point + * is on the segment, the result will be 0. If the segment is length 0, + * the distance is to the common endpoint. + * + * @param px the x coordinate of the point + * @param py the y coordinate of the point + * @return the square of the distance from the point to the extended line + * @see #ptLineDistSq(double, double, double, double, double, double) + */ + public double ptLineDistSq(double px, double py) { - return ptSegDist (getX1 (), getY1 (), getX2 (), getY2 (), - px, py); + return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py); } - public static double ptSegDist (double x1, double y1, - double x2, double y2, - double px, double py) + /** + * Measures the square of the shortest distance from the reference point + * to a point on the infinite line extended from this segment. If the point + * is on the segment, the result will be 0. If the segment is length 0, + * the distance is to the common endpoint. + * + * @param p the point + * @return the square of the distance from the point to the extended line + * @throws NullPointerException if p is null + * @see #ptLineDistSq(double, double, double, double, double, double) + */ + public double ptLineDistSq(Point2D p) { - return Math.sqrt (ptSegDistSq (x1, y1, x2, y2, px, py)); + return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), + p.getX(), p.getY()); } - public double ptSegDist (Point2D p) + /** + * Measures the shortest distance from the reference point to a point on + * the infinite line extended from this segment. If the point is on the + * segment, the result will be 0. If the segment is length 0, the distance + * is to the common endpoint. + * + * @param px the x coordinate of the point + * @param py the y coordinate of the point + * @return the distance from the point to the extended line + * @see #ptLineDist(double, double, double, double, double, double) + */ + public double ptLineDist(double px, double py) { - return ptSegDist (getX1 (), getY1 (), getX2 (), getY2 (), - p.getX (), p.getY ()); + return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py); } - public double ptSegDistSq (double px, double py) + /** + * Measures the shortest distance from the reference point to a point on + * the infinite line extended from this segment. If the point is on the + * segment, the result will be 0. If the segment is length 0, the distance + * is to the common endpoint. + * + * @param p the point + * @return the distance from the point to the extended line + * @throws NullPointerException if p is null + * @see #ptLineDist(double, double, double, double, double, double) + */ + public double ptLineDist(Point2D p) { - return ptSegDistSq (getX1 (), getY1 (), getX2 (), getY2 (), - px, py); + return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY()); } - public static double ptSegDistSq (double x1, double y1, - double x2, double y2, - double px, double py) + /** + * Test if a point is contained inside the line. Since a line has no area, + * this returns false. + * + * @param x the x coordinate + * @param y the y coordinate + * @return false; the line does not contain points + */ + public boolean contains(double x, double y) { - double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); + return false; + } - double x, y; - if (pd2 == 0) - { - // Points are coincident. - x = x1; - y = y2; - } - else - { - double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2; - - if (u < 0) - { - // "Off the end" - x = x1; - y = y1; - } - else if (u > 1.0) - { - x = x2; - y = y2; - } - else - { - x = x1 + u * (x2 - x1); - y = y1 + u * (y2 - y1); - } - } + /** + * Test if a point is contained inside the line. Since a line has no area, + * this returns false. + * + * @param p the point + * @return false; the line does not contain points + */ + public boolean contains(Point2D p) + { + return false; + } - return (x - px) * (x - px) + (y - py) * (y - py); + /** + * Tests if this line intersects the interior of the specified rectangle. + * + * @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 line intersects the rectangle + */ + public boolean intersects(double x, double y, double w, double h) + { + if (w <= 0 || h <= 0) + return false; + double x1 = getX1(); + double y1 = getY1(); + double x2 = getX2(); + double y2 = getY2(); + + if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h) + return true; + if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y + h) + return true; + + double x3 = x + w; + double y3 = y + h; + + return (linesIntersect(x1, y1, x2, y2, x, y, x, y3) + || linesIntersect(x1, y1, x2, y2, x, y3, x3, y3) + || linesIntersect(x1, y1, x2, y2, x3, y3, x3, y) + || linesIntersect(x1, y1, x2, y2, x3, y, x, y)); } - public double ptSegDistSq (Point2D p) + /** + * Tests if this line intersects the interior of the specified rectangle. + * + * @param r the rectangle + * @return true if the line intersects the rectangle + * @throws NullPointerException if r is null + */ + public boolean intersects(Rectangle2D r) { - return ptSegDistSq (getX1 (), getY1 (), getX2 (), getY2 (), - p.getX (), p.getY ()); + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + /** + * Tests if the line contains a rectangle. Since lines have no area, this + * always returns false. + * + * @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 false; the line does not contain points + */ + public boolean contains(double x, double y, double w, double h) + { + return false; + } + + /** + * Tests if the line contains a rectangle. Since lines have no area, this + * always returns false. + * + * @param r the rectangle + * @return false; the line does not contain points + */ + public boolean contains(Rectangle2D r) + { + return false; } - public int relativeCCW (double px, double py) + /** + * Gets a bounding box (not necessarily minimal) for this line. + * + * @return the integer bounding box + * @see #getBounds2D() + */ + public Rectangle getBounds() { - return relativeCCW (getX1 (), getY1 (), - getX2 (), getY2 (), - px, py); + return getBounds2D().getBounds(); } - public static int relativeCCW (double x1, double y1, - double x2, double y2, - double px, double py) + /** + * Return a path iterator, possibly applying a transform on the result. This + * iterator is not threadsafe. + * + * @param at the transform, or null + * @return a new path iterator + */ + public PathIterator getPathIterator(final AffineTransform at) { - // This is a somewhat silly way to compute this. - // Please write a better one. - double a1 = Math.atan2 (y2 - y1, x2 - x1); - double a2 = Math.atan2 (py - y1, px - x1); + return new PathIterator() + { + /** Current coordinate. */ + private int current; + + public int getWindingRule() + { + return WIND_NON_ZERO; + } + + public boolean isDone() + { + return current < 2; + } + + public void next() + { + current++; + } - double a = (a1 - a2) % (2 * Math.PI); - if (a == 0 || a == Math.PI) + public int currentSegment(float[] coords) { - double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)); - if (u < 0.0) - return 1; - else if (u > 1.0) - return -1; - else - return 0; + int result; + switch (current) + { + case 0: + coords[0] = (float) getX1(); + coords[1] = (float) getY1(); + result = SEG_MOVETO; + break; + case 1: + coords[0] = (float) getX2(); + coords[1] = (float) getY2(); + result = SEG_LINETO; + break; + default: + throw new NoSuchElementException("line iterator out of bounds"); + } + if (at != null) + at.transform(coords, 0, coords, 0, 1); + return result; } - return (a > 0 && a < Math.PI) ? 1 : -1; + public int currentSegment(double[] coords) + { + int result; + switch (current) + { + case 0: + coords[0] = getX1(); + coords[1] = getY1(); + result = SEG_MOVETO; + break; + case 1: + coords[0] = getX2(); + coords[1] = getY2(); + result = SEG_LINETO; + break; + default: + throw new NoSuchElementException("line iterator out of bounds"); + } + if (at != null) + at.transform(coords, 0, coords, 0, 1); + return result; + } + }; } - public int relativeCCW (Point2D p) + /** + * Return a flat path iterator, possibly applying a transform on the result. + * This iterator is not threadsafe. + * + * @param at the transform, or null + * @param flatness ignored, since lines are already flat + * @return a new path iterator + * @see #getPathIterator(AffineTransform) + */ + public PathIterator getPathIterator(AffineTransform at, double flatness) { - return relativeCCW (getX1 (), getY1 (), - getX2 (), getY2 (), - p.getX (), p.getY ()); + return getPathIterator(at); } - public abstract void setLine (double x1, double y1, double x2, double y2); - - public void setLine (Line2D l) + /** + * Create a new line of the same run-time type with the same contents as + * this one. + * + * @return the clone + */ + public Object clone() { - setLine (l.getX1 (), l.getY1 (), l.getX2 (), l.getY2 ()); + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } } - public void setLine (Point2D p1, Point2D p2) + /** + * This class defines a point in <code>double</code> precision. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ + public static class Double extends Line2D { - setLine (p1.getX (), p1.getY (), p2.getX (), p2.getY ()); - } + /** The x coordinate of the first point. */ + public double x1; - public static class Float extends Line2D - { - float x1, y1, x2, y2; + /** The y coordinate of the first point. */ + public double y1; + + /** The x coordinate of the second point. */ + public double x2; + + /** The y coordinate of the second point. */ + public double y2; - public Float () + /** + * Construct the line segment (0,0)->(0,0). + */ + public Double() { - this (0.0F, 0.0F, 0.0F, 0.0F); } - public Float (float x1, float y1, float x2, float y2) + /** + * Construct the line segment with the specified points. + * + * @param x1 the x coordinate of the first point + * @param y1 the y coordinate of the first point + * @param x2 the x coordinate of the second point + * @param y2 the y coordinate of the second point + */ + public Double(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; @@ -364,80 +809,149 @@ public abstract class Line2D implements Shape, Cloneable this.y2 = y2; } - public Float (Point2D p1, Point2D p2) - { - this.x1 = (float) p1.getX (); - this.y1 = (float) p1.getY (); - this.x2 = (float) p2.getX (); - this.y2 = (float) p2.getY (); - } - - public Rectangle2D getBounds2D () + /** + * Construct the line segment with the specified points. + * + * @param p1 the first point + * @param p2 the second point + * @throws NullPointerException if either point is null + */ + public Double(Point2D p1, Point2D p2) { - float x = Math.min (x1, x2); - float w = Math.abs (x1 - x2); - float y = Math.min (y1, y2); - float h = Math.abs (y1 - y2); - return new Rectangle2D.Float (x, y, w, h); + x1 = p1.getX(); + y1 = p1.getY(); + x2 = p2.getX(); + y2 = p2.getY(); } - public Point2D getP1 () + /** + * Return the x coordinate of the first point. + * + * @return the value of x1 + */ + public double getX1() { - return new Point2D.Float (x1, y1); - } - - public Point2D getP2 () - { - return new Point2D.Float (x2, y2); + return x1; } - public double getX1 () + /** + * Return the y coordinate of the first point. + * + * @return the value of y1 + */ + public double getY1() { - return x1; + return y1; } - public double getY1 () + /** + * Return the first point. + * + * @return the point (x1,y1) + */ + public Point2D getP1() { - return y1; + return new Point2D.Double(x1, y1); } - public double getX2 () + /** + * Return the x coordinate of the second point. + * + * @return the value of x2 + */ + public double getX2() { return x2; } - public double getY2 () + /** + * Return the y coordinate of the second point. + * + * @return the value of y2 + */ + public double getY2() { return y2; } - public void setLine (double x1, double y1, double x2, double y2) + /** + * Return the second point. + * + * @return the point (x2,y2) + */ + public Point2D getP2() { - this.x1 = (float) x1; - this.y1 = (float) y1; - this.x2 = (float) x2; - this.y2 = (float) y2; + return new Point2D.Double(x2, y2); } - public void setLine (float x1, float y1, float x2, float y2) + /** + * Set this line to the given points. + * + * @param x1 the new x coordinate of the first point + * @param y1 the new y coordinate of the first point + * @param x2 the new x coordinate of the second point + * @param y2 the new y coordinate of the second point + */ + public void setLine(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } - } - public static class Double extends Line2D + /** + * Return the exact bounds of this line segment. + * + * @return the bounding box + */ + public Rectangle2D getBounds2D() + { + double x = Math.min(x1, x2); + double y = Math.min(y1, y2); + double w = Math.abs(x1 - x2); + double h = Math.abs(y1 - y2); + return new Rectangle2D.Double(x, y, w, h); + } + } // class Double + + /** + * This class defines a point in <code>float</code> precision. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ + public static class Float extends Line2D { - double x1, y1, x2, y2; + /** The x coordinate of the first point. */ + public float x1; + + /** The y coordinate of the first point. */ + public float y1; + + /** The x coordinate of the second point. */ + public float x2; - public Double () + /** The y coordinate of the second point. */ + public float y2; + + /** + * Construct the line segment (0,0)->(0,0). + */ + public Float() { - this (0.0, 0.0, 0.0, 0.0); } - public Double (double x1, double y1, double x2, double y2) + /** + * Construct the line segment with the specified points. + * + * @param x1 the x coordinate of the first point + * @param y1 the y coordinate of the first point + * @param x2 the x coordinate of the second point + * @param y2 the y coordinate of the second point + */ + public Float(float x1, float y1, float x2, float y2) { this.x1 = x1; this.y1 = y1; @@ -445,129 +959,125 @@ public abstract class Line2D implements Shape, Cloneable this.y2 = y2; } - public Double (Point2D p1, Point2D p2) + /** + * Construct the line segment with the specified points. + * + * @param p1 the first point + * @param p2 the second point + * @throws NullPointerException if either point is null + */ + public Float(Point2D p1, Point2D p2) { - this.x1 = (double) p1.getX (); - this.y1 = p1.getY (); - this.x2 = p2.getX (); - this.y2 = p2.getY (); + x1 = (float) p1.getX(); + y1 = (float) p1.getY(); + x2 = (float) p2.getX(); + y2 = (float) p2.getY(); } - public Rectangle2D getBounds2D () + /** + * Return the x coordinate of the first point. + * + * @return the value of x1 + */ + public double getX1() { - double x = Math.min (x1, x2); - double w = Math.abs (x1 - x2); - double y = Math.min (y1, y2); - double h = Math.abs (y1 - y2); - return new Rectangle2D.Double (x, y, w, h); + return x1; } - public Point2D getP1 () + /** + * Return the y coordinate of the first point. + * + * @return the value of y1 + */ + public double getY1() { - return new Point2D.Double (x1, y1); + return y1; } - public Point2D getP2 () + /** + * Return the first point. + * + * @return the point (x1,y1) + */ + public Point2D getP1() { - return new Point2D.Double (x2, y2); + return new Point2D.Float(x1, y1); } - public double getX1 () + /** + * Return the x coordinate of the second point. + * + * @return the value of x2 + */ + public double getX2() { - return x1; + return x2; } - public double getY1 () + /** + * Return the y coordinate of the second point. + * + * @return the value of y2 + */ + public double getY2() { - return y1; + return y2; } - public double getX2 () + /** + * Return the second point. + * + * @return the point (x2,y2) + */ + public Point2D getP2() { - return x2; + return new Point2D.Float(x2, y2); } - public double getY2 () + /** + * Set this line to the given points. + * + * @param x1 the new x coordinate of the first point + * @param y1 the new y coordinate of the first point + * @param x2 the new x coordinate of the second point + * @param y2 the new y coordinate of the second point + */ + public void setLine(double x1, double y1, double x2, double y2) { - return y2; + this.x1 = (float) x1; + this.y1 = (float) y1; + this.x2 = (float) x2; + this.y2 = (float) y2; } - public void setLine (double x1, double y1, double x2, double y2) + /** + * Set this line to the given points. + * + * @param x1 the new x coordinate of the first point + * @param y1 the new y coordinate of the first point + * @param x2 the new x coordinate of the second point + * @param y2 the new y coordinate of the second point + */ + public void setLine(float x1, float y1, float x2, float y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } - } - - // This implements the PathIterator for all line objects that don't - // override getPathIterator. - private class Iterator implements PathIterator - { - // Current coordinate. - private int coord; - - private static final int START = 0; - private static final int END_PLUS_ONE = 2; - - public Iterator () - { - coord = START; - } - public int currentSegment (double[] coords) + /** + * Return the exact bounds of this line segment. + * + * @return the bounding box + */ + public Rectangle2D getBounds2D() { - int r = SEG_MOVETO; - if (coord == 0) - { - coords[0] = getX1 (); - coords[1] = getY1 (); - } - else if (coord == 1) - { - coords[0] = getX2 (); - coords[1] = getY2 (); - } - else - r = SEG_CLOSE; - - return r; + float x = Math.min(x1, x2); + float y = Math.min(y1, y2); + float w = Math.abs(x1 - x2); + float h = Math.abs(y1 - y2); + return new Rectangle2D.Float(x, y, w, h); } - - public int currentSegment (float[] coords) - { - int r = SEG_MOVETO; - if (coord == 0) - { - coords[0] = (float) getX1 (); - coords[1] = (float) getY1 (); - } - else if (coord == 1) - { - coords[0] = (float) getX2 (); - coords[1] = (float) getY2 (); - } - else - r = SEG_CLOSE; - - return r; - } - - public int getWindingRule () - { - return WIND_NON_ZERO; - } - - public boolean isDone () - { - return coord == END_PLUS_ONE; - } - - public void next () - { - if (coord < END_PLUS_ONE) - ++coord; - } - } -} + } // class Float +} // class Line2D diff --git a/libjava/java/awt/geom/NoninvertibleTransformException.java b/libjava/java/awt/geom/NoninvertibleTransformException.java index cd561cffffe..40b2c180298 100644 --- a/libjava/java/awt/geom/NoninvertibleTransformException.java +++ b/libjava/java/awt/geom/NoninvertibleTransformException.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* NoninvertibleTransformException.java -- a transform can't be inverted + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,14 +38,28 @@ exception statement from your version. */ package java.awt.geom; /** + * Thrown if an operation requires an inverse of an + * <code>AffineTransform</code>, but the transform is in a non-invertible + * state. + * * @author Tom Tromey <tromey@cygnus.com> - * @date July 15, 2000 + * @see AffineTransform + * @status updated to 1.4 */ - public class NoninvertibleTransformException extends Exception { - public NoninvertibleTransformException (String s) + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 6137225240503990466L; + + /** + * Create an exception with a message. + * + * @param s the message + */ + public NoninvertibleTransformException(String s) { - super (s); + super(s); } } diff --git a/libjava/java/awt/geom/PathIterator.java b/libjava/java/awt/geom/PathIterator.java index 50178d3bbcb..871c9a8719b 100644 --- a/libjava/java/awt/geom/PathIterator.java +++ b/libjava/java/awt/geom/PathIterator.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* PathIterator.java -- describes a shape by iterating over its vertices + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,23 +38,152 @@ exception statement from your version. */ package java.awt.geom; /** + * This interface provides a directed path over the boundary of a shape. The + * path can contain 1st through 3rd order Bezier curves (lines, and quadratic + * and cubic splines). A shape can have multiple disjoint paths via the + * MOVETO directive, and can close a circular path back to the previos + * MOVETO via the CLOSE directive. + * * @author Tom Tromey <tromey@cygnus.com> - * @date April 16, 2000 + * @author Eric Blake <ebb9@email.byu.edu> + * @see Shape + * @see Stroke + * @see FlatteningPathIterator + * @since 1.2 + * @status updated to 1.4 */ - public interface PathIterator { - public static final int SEG_CLOSE = 4; - public static final int SEG_CUBICTO = 3; - public static final int SEG_LINETO = 1; - public static final int SEG_MOVETO = 0; - public static final int SEG_QUADTO = 2; - public static final int WIND_EVEN_ODD = 0; - public static final int WIND_NON_ZERO = 1; - - public int currentSegment (double[] coords); - public int currentSegment (float[] coords); - public int getWindingRule (); - public boolean isDone (); - public void next (); -} + /** + * The even-odd winding mode: a point is internal to the shape if a ray + * from the point to infinity (in any direction) crosses an odd number of + * segments. + */ + int WIND_EVEN_ODD = 0; + + /** + * The non-zero winding mode: a point is internal to the shape if a ray + * from the point to infinity (in any direction) crosses a different number + * of segments headed clockwise than those headed counterclockwise. + */ + int WIND_NON_ZERO = 1; + + /** + * Starts a new subpath. There is no segment from the previous vertex. + */ + int SEG_MOVETO = 0; + + /** + * The current segment is a line. + */ + int SEG_LINETO = 1; + + /** + * The current segment is a quadratic parametric curve. It is interpolated + * as t varies from 0 to 1 over the current point (CP), first control point + * (P1), and final interpolated control point (P2): + * <pre> + * P(t) = B(2,0)*CP + B(2,1)*P1 + B(2,2)*P2 + * 0 <= t <= 1 + * B(n,m) = mth coefficient of nth degree Bernstein polynomial + * = C(n,m) * t^(m) * (1 - t)^(n-m) + * C(n,m) = Combinations of n things, taken m at a time + * = n! / (m! * (n-m)!) + * </pre> + */ + int SEG_QUADTO = 2; + + /** + * The current segment is a cubic parametric curve (more commonly known as + * a Bezier curve). It is interpolated as t varies from 0 to 1 over the + * current point (CP), first control point (P1), the second control point + * (P2), and final interpolated control point (P3): + * <pre> + * P(t) = B(3,0)*CP + B(3,1)*P1 + B(3,2)*P2 + B(3,3)*P3 + * 0 <= t <= 1 + * B(n,m) = mth coefficient of nth degree Bernstein polynomial + * = C(n,m) * t^(m) * (1 - t)^(n-m) + * C(n,m) = Combinations of n things, taken m at a time + * = n! / (m! * (n-m)!) + * </pre> + */ + int SEG_CUBICTO = 3; + + /** + * The current segment closes a loop by an implicit line to the previous + * SEG_MOVETO coordinate. + */ + int SEG_CLOSE = 4; + + /** + * Returns the winding rule to determine which points are inside this path. + * + * @return the winding rule + * @see #WIND_EVEN_ODD + * @see #WIND_NON_ZERO + */ + int getWindingRule(); + + /** + * Tests if the iterator is exhausted. If this returns false, currentSegment + * and next may throw a NoSuchElementException (although this is not + * required). + * + * @return true if the iteration is complete + */ + boolean isDone(); + + /** + * Advance to the next segment in the iteration. It is not specified what + * this does if called when isDone() returns false. + * + * @throws java.util.NoSuchElementException optional when isDone() is true + */ + void next(); + + /** + * Returns the coordinates of the next point(s), as well as the type of + * line segment. The input array must be at least a float[6], to accomodate + * up to three (x,y) point pairs (although if you know the iterator is + * flat, you can probably get by with a float[2]). If the returned type is + * SEG_MOVETO or SEG_LINETO, the first point in the array is modified; if + * the returned type is SEG_QUADTO, the first two points are modified; if + * the returned type is SEG_CUBICTO, all three points are modified; and if + * the returned type is SEG_CLOSE, the array is untouched. + * + * @param coords the array to place the point coordinates in + * @return the segment type + * @throws NullPointerException if coords is null + * @throws ArrayIndexOutOfBoundsException if coords is too small + * @throws java.util.NoSuchElementException optional when isDone() is true + * @see #SEG_MOVETO + * @see #SEG_LINETO + * @see #SEG_QUADTO + * @see #SEG_CUBICTO + * @see #SEG_CLOSE + */ + int currentSegment(float[] coords); + + /** + * Returns the coordinates of the next point(s), as well as the type of + * line segment. The input array must be at least a double[6], to accomodate + * up to three (x,y) point pairs (although if you know the iterator is + * flat, you can probably get by with a double[2]). If the returned type is + * SEG_MOVETO or SEG_LINETO, the first point in the array is modified; if + * the returned type is SEG_QUADTO, the first two points are modified; if + * the returned type is SEG_CUBICTO, all three points are modified; and if + * the returned type is SEG_CLOSE, the array is untouched. + * + * @param coords the array to place the point coordinates in + * @return the segment type + * @throws NullPointerException if coords is null + * @throws ArrayIndexOutOfBoundsException if coords is too small + * @throws java.util.NoSuchElementException optional when isDone() is true + * @see #SEG_MOVETO + * @see #SEG_LINETO + * @see #SEG_QUADTO + * @see #SEG_CUBICTO + * @see #SEG_CLOSE + */ + int currentSegment(double[] coords); +} // interface PathIterator diff --git a/libjava/java/awt/geom/Point2D.java b/libjava/java/awt/geom/Point2D.java index 598402b00c0..48b12f67dbd 100644 --- a/libjava/java/awt/geom/Point2D.java +++ b/libjava/java/awt/geom/Point2D.java @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2000, 2002 Free Software Foundation +/* Point2D.java -- generic point in 2-D space + Copyright (C) 1999, 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -37,161 +38,358 @@ exception statement from your version. */ package java.awt.geom; /** + * This class implements a generic point in 2D Cartesian space. The storage + * representation is left up to the subclass. Point includes two useful + * nested classes, for float and double storage respectively. + * * @author Per Bothner <bothner@cygnus.com> - * @date February 8, 1999. + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 */ - -/* Written using "Java Class Libraries", 2nd edition, plus online - * API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct, except that neither toString - * nor hashCode have been compared with JDK output. - */ - public abstract class Point2D implements Cloneable { + /** + * The default constructor. + * + * @see Point + * @see Point2D.Float + * @see Point2D.Double + */ + protected Point2D() + { + } + + /** + * Get the X coordinate, in double precision. + * + * @return the x coordinate + */ public abstract double getX(); - public abstract double getY(); - public abstract void setLocation (double x, double y); + /** + * Get the Y coordinate, in double precision. + * + * @return the y coordinate + */ + public abstract double getY(); - protected Point2D () + /** + * Set the location of this point to the new coordinates. There may be a + * loss of precision. + * + * @param x the new x coordinate + * @param y the new y coordinate + */ + public abstract void setLocation(double x, double y); + + /** + * Set the location of this point to the new coordinates. There may be a + * loss of precision. + * + * @param p the point to copy + * @throws NullPointerException if p is null + */ + public void setLocation(Point2D p) { + setLocation(p.getX(), p.getY()); } - public void setLocation (Point2D pt) { setLocation(pt.getX(), pt.getY()); } - - static public double distanceSq (double X1, double Y1, double X2, double Y2) + /** + * Return the square of the distance between two points. + * + * @param x1 the x coordinate of point 1 + * @param y1 the y coordinate of point 1 + * @param x2 the x coordinate of point 2 + * @param y2 the y coordinate of point 2 + * @return (x2 - x1)^2 + (y2 - y1)^2 + */ + public static double distanceSq(double x1, double y1, double x2, double y2) { - X2 -= X1; - Y2 -= Y1; - return X2*X2 + Y2*Y2; + x2 -= x1; + y2 -= y1; + return x2 * x2 + y2 * y2; } - static public double distance (double X1, double Y1, double X2, double Y2) + /** + * Return the distance between two points. + * + * @param x1 the x coordinate of point 1 + * @param y1 the y coordinate of point 1 + * @param x2 the x coordinate of point 2 + * @param y2 the y coordinate of point 2 + * @return the distance from (x1,y1) to (x2,y2) + */ + static public double distance(double x1, double y1, double x2, double y2) { - return Math.sqrt(distanceSq(X1, Y1, X2, Y2)); + return Math.sqrt(distanceSq(x1, y1, x2, y2)); } - public double distanceSq (double PX, double PY) + /** + * Return the square of the distance from this point to the given one. + * + * @param x the x coordinate of the other point + * @param y the y coordinate of the other point + * @return the square of the distance + */ + public double distanceSq(double x, double y) { - return distanceSq (getX(), PX, getY(), PY); + return distanceSq(getX(), x, getY(), y); } - public double distance (double PX, double PY) + /** + * Return the square of the distance from this point to the given one. + * + * @param p the other point + * @return the square of the distance + * @throws NullPointerException if p is null + */ + public double distanceSq(Point2D p) { - return distance (getX(), PX, getY(), PY); + return distanceSq(getX(), p.getX(), getY(), p.getY()); } - public double distanceSq (Point2D pt) + /** + * Return the distance from this point to the given one. + * + * @param x the x coordinate of the other point + * @param y the y coordinate of the other point + * @return the distance + */ + public double distance(double x, double y) { - return distanceSq (getX(), pt.getX(), getY(), pt.getY()); + return distance(getX(), x, getY(), y); } - public double distance (Point2D pt) + /** + * Return the distance from this point to the given one. + * + * @param p the other point + * @return the distance + * @throws NullPointerException if p is null + */ + public double distance(Point2D p) { - return distance (getX(), pt.getX(), getY(), pt.getY()); + return distance(getX(), p.getX(), getY(), p.getY()); } - public int hashCode() { return (int) getX() ^ (int) getY(); } - + /** + * Create a new point of the same run-time type with the same contents as + * this one. + * + * @return the clone + */ public Object clone() { try - { - return super.clone (); - } - catch (CloneNotSupportedException _) {return null;} + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } } - public boolean equals (Object o) + /** + * Return the hashcode for this point. The formula is not documented, but + * appears to be the same as: + * <pre> + * long l = Double.doubleToLongBits(getY()); + * l = l * 31 ^ Double.doubleToLongBits(getX()); + * return (int) ((l >> 32) ^ l); + * </pre> + * + * @return the hashcode + */ + public int hashCode() + { + // Talk about a fun time reverse engineering this one! + long l = java.lang.Double.doubleToLongBits(getY()); + l = l * 31 ^ java.lang.Double.doubleToLongBits(getX()); + return (int) ((l >> 32) ^ l); + } + + /** + * Compares two points for equality. This returns true if they have the + * same coordinates. + * + * @param o the point to compare + * @return true if it is equal + */ + public boolean equals(Object o) { if (! (o instanceof Point2D)) return false; Point2D p = (Point2D) o; - return getX () == p.getX () && getY () == p.getY (); + return getX() == p.getX() && getY() == p.getY(); } + /** + * This class defines a point in <code>double</code> precision. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ public static class Double extends Point2D { + /** The X coordinate. */ public double x; + + /** The Y coordinate. */ public double y; - public Double () + /** + * Create a new point at (0,0). + */ + public Double() { - x = 0; - y = 0; } - public Double (double x, double y) + /** + * Create a new point at (x,y). + * + * @param x the x coordinate + * @param y the y coordinate + */ + public Double(double x, double y) { this.x = x; this.y = y; } - public double getX () + /** + * Return the x coordinate. + * + * @return the x coordinate + */ + public double getX() { return x; } - public double getY () + /** + * Return the y coordinate. + * + * @return the y coordinate + */ + public double getY() { return y; } - public void setLocation (double x, double y) + /** + * Sets the location of this point. + * + * @param x the new x coordinate + * @param y the new y coordinate + */ + public void setLocation(double x, double y) { this.x = x; this.y = y; } - public String toString () + /** + * Returns a string representation of this object. The format is: + * <code>"Point2D.Double[" + x + ", " + y + ']'</code>. + * + * @return a string representation of this object + */ + public String toString() { - return "(" + x + ", " + y + ")"; + return "Point2D.Double[" + x + ", " + y + ']'; } - } - + } // class Double + + /** + * This class defines a point in <code>float</code> precision. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ public static class Float extends Point2D { + /** The X coordinate. */ public float x; + + /** The Y coordinate. */ public float y; - public Float () + /** + * Create a new point at (0,0). + */ + public Float() { - x = 0; - y = 0; } - public Float (float x, float y) + /** + * Create a new point at (x,y). + * + * @param x the x coordinate + * @param y the y coordinate + */ + public Float(float x, float y) { this.x = x; this.y = y; } - public double getX () + /** + * Return the x coordinate. + * + * @return the x coordinate + */ + public double getX() { return x; } - public double getY () + /** + * Return the y coordinate. + * + * @return the y coordinate + */ + public double getY() { return y; } - public void setLocation (double x, double y) + /** + * Sets the location of this point. + * + * @param x the new x coordinate + * @param y the new y coordinate + */ + public void setLocation(double x, double y) { this.x = (float) x; this.y = (float) y; } - public void setLocation (float x, float y) + /** + * Sets the location of this point. + * + * @param x the new x coordinate + * @param y the new y coordinate + */ + public void setLocation(float x, float y) { this.x = x; this.y = y; } - public String toString () + /** + * Returns a string representation of this object. The format is: + * <code>"Point2D.Float[" + x + ", " + y + ']'</code>. + * + * @return a string representation of this object + */ + public String toString() { - return "(" + x + ", " + y + ")"; + return "Point2D.Float[" + x + ", " + y + ']'; } - } -} + } // class Float +} // class Point2D diff --git a/libjava/java/awt/geom/QuadCurve2D.java b/libjava/java/awt/geom/QuadCurve2D.java new file mode 100644 index 00000000000..2f1aafad21b --- /dev/null +++ b/libjava/java/awt/geom/QuadCurve2D.java @@ -0,0 +1,486 @@ +/* QuadCurve2D.java -- represents a parameterized quadratic curve in 2-D space + 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.geom; + +import java.awt.Rectangle; +import java.awt.Shape; +import java.util.NoSuchElementException; + +/** + * STUBS ONLY + * XXX Implement and document. + */ +public abstract class QuadCurve2D implements Shape, Cloneable +{ + protected QuadCurve2D() + { + } + + public abstract double getX1(); + public abstract double getY1(); + public abstract Point2D getP1(); + public abstract double getCtrlX(); + public abstract double getCtrlY(); + public abstract Point2D getCtrlPt(); + public abstract double getX2(); + public abstract double getY2(); + public abstract Point2D getP2(); + + public abstract void setCurve(double x1, double y1, double cx, double cy, + double x2, double y2); + public void setCurve(double[] coords, int offset) + { + setCurve(coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++]); + } + public void setCurve(Point2D p1, Point2D c, Point2D p2) + { + setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(), + p2.getX(), p2.getY()); + } + public void setCurve(Point2D[] pts, int offset) + { + setCurve(pts[offset].getX(), pts[offset++].getY(), + pts[offset].getX(), pts[offset++].getY(), + pts[offset].getX(), pts[offset++].getY()); + } + public void setCurve(QuadCurve2D c) + { + setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(), + c.getX2(), c.getY2()); + } + public static double getFlatnessSq(double x1, double y1, double cx, + double cy, double x2, double y2) + { + // XXX Implement. + throw new Error("not implemented"); + } + public static double getFlatness(double x1, double y1, double cx, double cy, + double x2, double y2) + { + return Math.sqrt(getFlatnessSq(x1, y1, cx, cy, x2, y2)); + } + public static double getFlatnessSq(double[] coords, int offset) + { + return getFlatnessSq(coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++]); + } + public static double getFlatness(double[] coords, int offset) + { + return Math.sqrt(getFlatnessSq(coords[offset++], coords[offset++], + coords[offset++], coords[offset++], + coords[offset++], coords[offset++])); + } + public double getFlatnessSq() + { + return getFlatnessSq(getX1(), getY1(), getCtrlX(), getCtrlY(), + getX2(), getY2()); + } + public double getFlatness() + { + return Math.sqrt(getFlatnessSq(getX1(), getY1(), getCtrlX(), getCtrlY(), + getX2(), getY2())); + } + + public void subdivide(QuadCurve2D l, QuadCurve2D r) + { + if (l == null) + l = new QuadCurve2D.Double(); + if (r == null) + r = new QuadCurve2D.Double(); + // Use empty slots at end to share single array. + double[] d = new double[] { getX1(), getY1(), getCtrlX(), getCtrlY(), + getX2(), getY2(), 0, 0, 0, 0 }; + subdivide(d, 0, d, 0, d, 4); + l.setCurve(d, 0); + r.setCurve(d, 4); + } + public static void subdivide(QuadCurve2D src, QuadCurve2D l, QuadCurve2D r) + { + src.subdivide(l, r); + } + public static void subdivide(double[] src, int srcOff, + double[] left, int leftOff, + double[] right, int rightOff) + { + // XXX Implement. + throw new Error("not implemented"); + } + public static int solveQuadratic(double[] eqn) + { + return solveQuadratic(eqn, eqn); + } + public static int solveQuadratic(double[] eqn, double[] res) + { + double c = eqn[0]; + double b = eqn[1]; + double a = eqn[2]; + if (a == 0) + { + if (b == 0) + return -1; + res[0] = -c / b; + return 1; + } + c /= a; + b /= a * 2; + double det = Math.sqrt(b * b - c); + if (det != det) + return 0; + // For fewer rounding errors, we calculate the two roots differently. + if (b > 0) + { + res[0] = -b - det; + res[1] = -c / (b + det); + } + else + { + res[0] = -c / (b - det); + res[1] = -b + det; + } + return 2; + } + + public boolean contains(double x, double y) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean contains(Point2D p) + { + return contains(p.getX(), p.getY()); + } + public boolean intersects(double x, double y, double w, double h) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean intersects(Rectangle2D r) + { + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + public boolean contains(double x, double y, double w, double h) + { + // XXX Implement. + throw new Error("not implemented"); + } + public boolean contains(Rectangle2D r) + { + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + public Rectangle getBounds() + { + return getBounds2D().getBounds(); + } + public PathIterator getPathIterator(final AffineTransform at) + { + return new PathIterator() + { + /** Current coordinate. */ + private int current; + + public int getWindingRule() + { + return WIND_NON_ZERO; + } + + public boolean isDone() + { + return current < 2; + } + + public void next() + { + current++; + } + + public int currentSegment(float[] coords) + { + if (current == 0) + { + coords[0] = (float) getX1(); + coords[1] = (float) getY1(); + if (at != null) + at.transform(coords, 0, coords, 0, 1); + return SEG_MOVETO; + } + if (current == 1) + { + coords[0] = (float) getCtrlX(); + coords[1] = (float) getCtrlY(); + coords[2] = (float) getX2(); + coords[3] = (float) getY2(); + if (at != null) + at.transform(coords, 0, coords, 0, 2); + return SEG_QUADTO; + } + throw new NoSuchElementException("quad iterator out of bounds"); + } + + public int currentSegment(double[] coords) + { + if (current == 0) + { + coords[0] = getX1(); + coords[1] = getY1(); + if (at != null) + at.transform(coords, 0, coords, 0, 1); + return SEG_MOVETO; + } + if (current == 1) + { + coords[0] = getCtrlX(); + coords[1] = getCtrlY(); + coords[2] = getX2(); + coords[3] = getY2(); + if (at != null) + at.transform(coords, 0, coords, 0, 2); + return SEG_QUADTO; + } + throw new NoSuchElementException("quad iterator out of bounds"); + } + }; + } + public PathIterator getPathIterator(AffineTransform at, double flatness) + { + return new FlatteningPathIterator(getPathIterator(at), flatness); + } + + /** + * Create a new curve of the same run-time type with the same contents as + * this one. + * + * @return the clone + */ + public Object clone() + { + try + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } + } + + /** + * STUBS ONLY + */ + public static class Double extends QuadCurve2D + { + public double x1; + public double y1; + public double ctrlx; + public double ctrly; + public double x2; + public double y2; + + public Double() + { + } + + public Double(double x1, double y1, double cx, double cy, + double x2, double y2) + { + this.x1 = x1; + this.y1 = y1; + ctrlx = cx; + ctrly = cy; + this.x2 = x2; + this.y2 = y2; + } + + public double getX1() + { + return x1; + } + public double getY1() + { + return y1; + } + public Point2D getP1() + { + return new Point2D.Double(x1, y1); + } + + public double getCtrlX() + { + return ctrlx; + } + public double getCtrlY() + { + return ctrly; + } + public Point2D getCtrlPt() + { + return new Point2D.Double(ctrlx, ctrly); + } + + public double getX2() + { + return x2; + } + public double getY2() + { + return y2; + } + public Point2D getP2() + { + return new Point2D.Double(x2, y2); + } + + public void setCurve(double x1, double y1, double cx, double cy, + double x2, double y2) + { + this.x1 = x1; + this.y1 = y1; + ctrlx = cx; + ctrly = cy; + this.x2 = x2; + this.y2 = y2; + } + public Rectangle2D getBounds2D() + { + double nx1 = Math.min(Math.min(x1, ctrlx), x2); + double ny1 = Math.min(Math.min(y1, ctrly), y2); + double nx2 = Math.max(Math.max(x1, ctrlx), x2); + double ny2 = Math.max(Math.max(y1, ctrly), y2); + return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1); + } + } // class Double + + /** + * STUBS ONLY + */ + public static class Float extends QuadCurve2D + { + public float x1; + public float y1; + public float ctrlx; + public float ctrly; + public float x2; + public float y2; + + public Float() + { + } + + public Float(float x1, float y1, float cx, float cy, + float x2, float y2) + { + this.x1 = x1; + this.y1 = y1; + ctrlx = cx; + ctrly = cy; + this.x2 = x2; + this.y2 = y2; + } + + public double getX1() + { + return x1; + } + public double getY1() + { + return y1; + } + public Point2D getP1() + { + return new Point2D.Float(x1, y1); + } + + public double getCtrlX() + { + return ctrlx; + } + public double getCtrlY() + { + return ctrly; + } + public Point2D getCtrlPt() + { + return new Point2D.Float(ctrlx, ctrly); + } + + public double getX2() + { + return x2; + } + public double getY2() + { + return y2; + } + public Point2D getP2() + { + return new Point2D.Float(x2, y2); + } + + public void setCurve(double x1, double y1, double cx, double cy, + double x2, double y2) + { + this.x1 = (float) x1; + this.y1 = (float) y1; + ctrlx = (float) cx; + ctrly = (float) cy; + this.x2 = (float) x2; + this.y2 = (float) y2; + } + public void setCurve(float x1, float y1, float cx, float cy, + float x2, float y2) + { + this.x1 = x1; + this.y1 = y1; + ctrlx = cx; + ctrly = cy; + this.x2 = x2; + this.y2 = y2; + } + public Rectangle2D getBounds2D() + { + float nx1 = (float) Math.min(Math.min(x1, ctrlx), x2); + float ny1 = (float) Math.min(Math.min(y1, ctrly), y2); + float nx2 = (float) Math.max(Math.max(x1, ctrlx), x2); + float ny2 = (float) Math.max(Math.max(y1, ctrly), y2); + return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1); + } + } // class Float +} // class CubicCurve2D diff --git a/libjava/java/awt/geom/Rectangle2D.java b/libjava/java/awt/geom/Rectangle2D.java index eeb19259cb6..e0a278a575d 100644 --- a/libjava/java/awt/geom/Rectangle2D.java +++ b/libjava/java/awt/geom/Rectangle2D.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2001, 2002 Free Software Foundation +/* Rectangle2D.java -- generic rectangles in 2-D space + Copyright (C) 2000, 2001, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,431 +35,952 @@ 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.geom; +import java.util.NoSuchElementException; + /** + * This class describes a rectangle by a point (x,y) and dimension (w x h). + * The actual storage is left up to subclasses. + * + * <p>It is valid for a rectangle to have negative width or height; but it + * is considered to have no area or internal points. Therefore, the behavior + * in methods like <code>contains</code> or <code>intersects</code> is + * undefined unless the rectangle has positive width and height. + * * @author Tom Tromey <tromey@cygnus.com> - * @date April 16, 2000 + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 */ - public abstract class Rectangle2D extends RectangularShape { + /** + * The point lies left of the rectangle (p.x < r.x). + * + * @see #outcode() + */ public static final int OUT_LEFT = 1; + + /** + * The point lies above the rectangle (p.y < r.y). + * + * @see #outcode() + */ public static final int OUT_TOP = 2; + + /** + * The point lies right of the rectangle (p.x > r.maxX). + * + * @see #outcode() + */ public static final int OUT_RIGHT = 4; + + /** + * The point lies below of the rectangle (p.y > r.maxY). + * + * @see #outcode() + */ public static final int OUT_BOTTOM = 8; - protected Rectangle2D () + /** + * Default constructor. + */ + protected Rectangle2D() { } - /** Set the bounding box of this rectangle. - * @param x X coordinate - * @param y Y coordinate - * @param w Width - * @param h Height + /** + * Set the bounding box of this rectangle. + * + * @param x the new X coordinate + * @param y the new Y coordinate + * @param w the new width + * @param h the new height */ - public abstract void setRect (double x, double y, double w, double h); + public abstract void setRect(double x, double y, double w, double h); - /** Set the bounding box of this rectangle. - * @param r Bounding rectangle. + /** + * Set the bounding box of this rectangle from the given one. + * + * @param r rectangle to copy + * @throws NullPointerException if r is null */ - public void setRect (Rectangle2D r) + public void setRect(Rectangle2D r) { - setRect (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); + setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - /** Returns true if line segment intersects interior of this - * rectangle. - * @param x1 X coordinate of first end of line segment - * @param y1 Y coordinate of first end of line segment - * @param x2 X coordinate of second end of line segment - * @param y2 Y coordinate of segment end of line segment + /** + * Tests if the specified line intersects the interior of this rectangle. + * + * @param x1 the first x coordinate of line segment + * @param y1 the first y coordinate of line segment + * @param x2 the second x coordinate of line segment + * @param y2 the second y coordinate of line segment + * @return true if the line intersects the rectangle */ - public boolean intersectsLine (double x1, double y1, double x2, double y2) + public boolean intersectsLine(double x1, double y1, double x2, double y2) { - int o1 = outcode (x1, y1); - int o2 = outcode (x2, y2); - - double mx = getX (); - double my = getY (); - double mx2 = getWidth (); - double my2 = getHeight (); - x1 -= mx; - x2 -= mx; - y1 -= my; - y2 -= my; - - // Here we handle all lines that stay entirely on one side of the - // rectangle. We also handle some lines that intersect the - // rectangle. All vertical and horizontal lines are handled here. - int xor = o1 ^ o2; - int or = o1 | o2; - if ((xor & (OUT_BOTTOM | OUT_TOP)) == 0) - { - if ((or & (OUT_BOTTOM | OUT_TOP)) != 0) - return false; - return ((o1 & (OUT_LEFT | OUT_RIGHT)) != 0 - || (o2 & (OUT_LEFT | OUT_RIGHT)) != 0); - } - else if ((xor & (OUT_LEFT | OUT_RIGHT)) == 0) - { - if ((or & (OUT_LEFT | OUT_RIGHT)) != 0) - return false; - return ((o1 & (OUT_BOTTOM | OUT_TOP)) != 0 - || (o2 & (OUT_BOTTOM | OUT_TOP)) != 0); - } - - double dx = x2 - x1; - double dy = y2 - y1; + double x = getX(); + double y = getY(); + double w = getWidth(); + double h = getHeight(); + if (w <= 0 || h <= 0) + return false; - double t1l = - x1 / dx; - double t1h = (mx2 - x1) / dx; + if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h) + return true; + if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y + h) + return true; - if (t1l >= t1h) - return false; - double t2l = - y1 / dy; - double t2h = (my2 - y1) / dy; + double x3 = x + w; + double y3 = y + h; - if (t2l >= t2h || t2l >= t1h || t2h < t1l) - return false; - return true; + return (Line2D.linesIntersect(x1, y1, x2, y2, x, y, x, y3) + || Line2D.linesIntersect(x1, y1, x2, y2, x, y3, x3, y3) + || Line2D.linesIntersect(x1, y1, x2, y2, x3, y3, x3, y) + || Line2D.linesIntersect(x1, y1, x2, y2, x3, y, x, y)); } - /** Return true if line segment intersects interior of this - * rectangle. - * @param l The line segment + /** + * Tests if the specified line intersects the interior of this rectangle. + * + * @param l the line segment + * @return true if the line intersects the rectangle + * @throws NullPointerException if l is null */ -// public boolean intersectsLine (Line2D l) -// { -// } + public boolean intersectsLine(Line2D l) + { + return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2()); + } - public abstract int outcode (double x, double y); + /** + * Determine where the point lies with respect to this rectangle. The + * result will be the binary OR of the appropriate bit masks. + * + * @param x the x coordinate to check + * @param y the y coordinate to check + * @return the binary OR of the result + * @see #OUT_LEFT + * @see #OUT_TOP + * @see #OUT_RIGHT + * @see #OUT_BOTTOM + */ + public abstract int outcode(double x, double y); + + /** + * Determine where the point lies with respect to this rectangle. The + * result will be the binary OR of the appropriate bit masks. + * + * @param p the point to check + * @return the binary OR of the result + * @throws NullPointerException if p is null + * @see #OUT_LEFT + * @see #OUT_TOP + * @see #OUT_RIGHT + * @see #OUT_BOTTOM + */ + public int outcode(Point2D p) + { + return outcode(p.getX(), p.getY()); + } - public int outcode (Point2D p) + /** + * Set the bounding box of this rectangle. + * + * @param x the new X coordinate + * @param y the new Y coordinate + * @param w the new width + * @param h the new height + */ + public void setFrame(double x, double y, double w, double h) { - return outcode (p.getX (), p.getY ()); + setRect(x, y, w, h); } - /** Set bounding frame for this rectangle. - * @param x X coordinate - * @param y Y coordinate - * @param w Width - * @param h Height + /** + * Returns the bounds of this rectangle. A pretty useless method, as this + * is already a rectangle. + * + * @return a copy of this rectangle */ - public void setFrame (double x, double y, double w, double h) + public Rectangle2D getBounds2D() { - setRect (x, y, w, h); + return (Rectangle2D) clone(); } - public Rectangle2D getBounds2D () + /** + * Test if the given point is contained in the rectangle. + * + * @param x the x coordinate of the point + * @param y the y coordinate of the point + * @return true if (x,y) is in the rectangle + */ + public boolean contains(double x, double y) { - // FIXME. - return (Rectangle2D) clone (); + double mx = getX(); + double my = getY(); + double w = getWidth(); + double h = getHeight(); + return w > 0 && h > 0 && x >= mx && x < mx + w && y >= my && y < my + h; } - public boolean contains (double x, double y) + /** + * 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 + * @param w the width of the other rectangle + * @param h the height of the other rectangle + * @return true if the rectangles intersect + */ + public boolean intersects(double x, double y, double w, double h) { - double mx = getX (); - double mw = getWidth (); - if (x < mx || x >= mx + mw) - return false; - double my = getY (); - double mh = getHeight (); - return y >= my && y < my + mh; + double mx = getX(); + double my = getY(); + double mw = getWidth(); + double mh = getHeight(); + return w > 0 && h > 0 && mw > 0 && mh > 0 + && x < mx + mw && x + w > mx && y < my + mh && y + h > my; } - public boolean intersects (double x, double y, double w, double h) + /** + * Tests if this rectangle contains the given one. In other words, test if + * this rectangle contains all points in the given one. + * + * @param x the x coordinate of the other rectangle + * @param y the y coordinate of the other rectangle + * @param w the width of the other rectangle + * @param h the height of the other rectangle + * @return true if this rectangle contains the other + */ + public boolean contains(double x, double y, double w, double h) { - double mx = getX (); - double mw = getWidth (); - if (x < mx || x >= mx + mw || x + w < mx || x + w >= mx + mw) - return false; - double my = getY (); - double mh = getHeight (); - return y >= my && y < my + mh && y + h >= my && y + h < my + mh; + double mx = getX(); + double my = getY(); + double mw = getWidth(); + double mh = getHeight(); + return w > 0 && h > 0 && mw > 0 && mh > 0 + && x >= mx && x + w <= mx + mw && y >= my && y + h <= my + mh; } - public boolean contains (double x, double y, double w, double h) + /** + * Return a new rectangle which is the intersection of this and the given + * one. The result will be empty if there is no intersection. + * + * @param r the rectangle to be intersected + * @return the intersection + * @throws NullPointerException if r is null + */ + public abstract Rectangle2D createIntersection(Rectangle2D r); + + /** + * Intersects a pair of rectangles, and places the result in the + * destination; this can be used to avoid object creation. This method + * even works when the destination is also a source, although you stand + * to lose the original data. + * + * @param src1 the first source + * @param src2 the second source + * @param dest the destination for the intersection + * @throws NullPointerException if any rectangle is null + */ + public static void intersect(Rectangle2D src1, Rectangle2D src2, + Rectangle2D dest) { - return contains (x, y) && contains (x + w, y + h); + double x = Math.max(src1.getX(), src2.getX()); + double y = Math.max(src1.getY(), src2.getY()); + double maxx = Math.min(src1.getMaxX(), src2.getMaxX()); + double maxy = Math.min(src1.getMaxY(), src2.getMaxY()); + dest.setRect(x, y, maxx - x, maxy - y); } - public abstract Rectangle2D createIntersection (Rectangle2D r); + /** + * Return a new rectangle which is the union of this and the given one. + * + * @param r the rectangle to be merged + * @return the union + * @throws NullPointerException if r is null + */ + public abstract Rectangle2D createUnion(Rectangle2D r); + + /** + * Joins a pair of rectangles, and places the result in the destination; + * this can be used to avoid object creation. This method even works when + * the destination is also a source, although you stand to lose the + * original data. + * + * @param src1 the first source + * @param src2 the second source + * @param dest the destination for the union + * @throws NullPointerException if any rectangle is null + */ + public static void union(Rectangle2D src1, Rectangle2D src2, + Rectangle2D dest) + { + double x = Math.min(src1.getX(), src2.getX()); + double y = Math.min(src1.getY(), src2.getY()); + double maxx = Math.max(src1.getMaxX(), src2.getMaxX()); + double maxy = Math.max(src1.getMaxY(), src2.getMaxY()); + dest.setRect(x, y, maxx - x, maxy - y); + } - public static void intersect (Rectangle2D src1, Rectangle2D src2, - Rectangle2D dest) + /** + * Modifies this rectangle so that it represents the smallest rectangle + * that contains both the existing rectangle and the specified point. + * However, if the point falls on one of the two borders which are not + * inside the rectangle, a subsequent call to <code>contains</code> may + * return false. + * + * @param x the X coordinate of the point to add to this rectangle + * @param y the Y coordinate of the point to add to this rectangle + */ + public void add(double newx, double newy) { - double x1l = src1.getMinX (); - double x2l = src2.getMinX (); - double nxl = Math.max (x1l, x2l); - double x1h = src1.getMaxX (); - double x2h = src2.getMaxX (); - double nxh = Math.min (x1h, x2h); - if (nxh < nxl) - nxh = nxl; - double y1l = src1.getMinY (); - double y2l = src2.getMinY (); - double nyl = Math.max (y1l, y2l); - double y1h = src1.getMaxY (); - double y2h = src2.getMaxY (); - double nyh = Math.min (y1h, y2h); - if (nyh < nyl) - nyh = nyl; - dest.setFrameFromDiagonal (nxl, nyl, nxh, nyh); + double minx = Math.min(getX(), newx); + double maxx = Math.max(getMaxX(), newx); + double miny = Math.min(getY(), newy); + double maxy = Math.max(getMaxY(), newy); + setRect(minx, miny, maxx - minx, maxy - miny); } - public abstract Rectangle2D createUnion (Rectangle2D r); + /** + * Modifies this rectangle so that it represents the smallest rectangle + * that contains both the existing rectangle and the specified point. + * However, if the point falls on one of the two borders which are not + * inside the rectangle, a subsequent call to <code>contains</code> may + * return false. + * + * @param p the point to add to this rectangle + * @throws NullPointerException if p is null + */ + public void add(Point2D p) + { + add(p.getX(), p.getY()); + } - public static void union (Rectangle2D src1, Rectangle2D src2, - Rectangle2D dest) + /** + * Modifies this rectangle so that it represents the smallest rectangle + * that contains both the existing rectangle and the specified rectangle. + * + * @param r the rectangle to add to this rectangle + * @throws NullPointerException if r is null + * @see #union(Rectangle2D) + */ + public void add(Rectangle2D r) { - double x1l = src1.getMinX (); - double x2l = src2.getMinX (); - double nxl = Math.max (x1l, x2l); - double x1h = src1.getMaxX (); - double x2h = src2.getMaxX (); - double nxh = Math.min (x1h, x2h); - double y1l = src1.getMinY (); - double y2l = src2.getMinY (); - double nyl = Math.max (y1l, y2l); - double y1h = src1.getMaxY (); - double y2h = src2.getMaxY (); - double nyh = Math.min (y1h, y2h); - dest.setFrameFromDiagonal (nxl, nyl, nxh, nyh); + union(this, r, this); } - public void add (double newx, double newy) + /** + * Return an iterator along the shape boundary. If the optional transform + * is provided, the iterator is transformed accordingly. Each call returns + * a new object, independent from others in use. This iterator is thread + * safe; modifications to the rectangle do not affect the results of this + * path instance. + * + * @param transform an optional transform to apply to the iterator + * @return a new iterator over the boundary + * @since 1.2 + */ + public PathIterator getPathIterator(final AffineTransform at) { - double minx = Math.min (getMinX (), newx); - double maxx = Math.max (getMaxX (), newx); - double miny = Math.min (getMinY (), newy); - double maxy = Math.max (getMaxY (), newy); - setFrameFromDiagonal (minx, miny, maxx, maxy); + final double minx = getX(); + final double miny = getY(); + final double maxx = minx + getWidth(); + final double maxy = miny + getHeight(); + return new PathIterator() + { + /** Current coordinate. */ + private int current = (maxx >= minx && maxy >= miny) ? 6 : 0; + + public int getWindingRule() + { + return WIND_EVEN_ODD; + } + + public boolean isDone() + { + return current > 5; + } + + public void next() + { + current++; + } + + public int currentSegment(float[] coords) + { + switch (current) + { + case 1: + coords[0] = (float) maxx; + coords[1] = (float) miny; + break; + case 2: + coords[0] = (float) maxx; + coords[1] = (float) maxy; + break; + case 3: + coords[0] = (float) minx; + coords[1] = (float) maxy; + break; + case 0: + case 4: + coords[0] = (float) minx; + coords[1] = (float) miny; + break; + case 5: + return SEG_CLOSE; + default: + throw new NoSuchElementException("rect iterator out of bounds"); + } + if (at != null) + at.transform(coords, 0, coords, 0, 1); + return current == 0 ? SEG_MOVETO : SEG_LINETO; + } + + public int currentSegment(double[] coords) + { + switch (current) + { + case 1: + coords[0] = maxx; + coords[1] = miny; + break; + case 2: + coords[0] = maxx; + coords[1] = maxy; + break; + case 3: + coords[0] = minx; + coords[1] = maxy; + break; + case 0: + case 4: + coords[0] = minx; + coords[1] = miny; + break; + case 5: + return SEG_CLOSE; + default: + throw new NoSuchElementException("rect iterator out of bounds"); + } + if (at != null) + at.transform(coords, 0, coords, 0, 1); + return current == 0 ? SEG_MOVETO : SEG_LINETO; + } + }; } - public void add (Point2D p) + /** + * Return an iterator along the shape boundary. If the optional transform + * is provided, the iterator is transformed accordingly. Each call returns + * a new object, independent from others in use. This iterator is thread + * safe; modifications to the rectangle do not affect the results of this + * path instance. As the rectangle is already flat, the flatness parameter + * is ignored. + * + * @param transform an optional transform to apply to the iterator + * @param double the maximum distance for deviation from the real boundary + * @return a new iterator over the boundary + * @since 1.2 + */ + public PathIterator getPathIterator(AffineTransform at, double flatness) { - add (p.getX (), p.getY ()); + return getPathIterator(at); } - public void add (Rectangle2D r) + /** + * Return the hashcode for this rectangle. The formula is not documented, but + * appears to be the same as: + * <pre> + * long l = Double.doubleToLongBits(getX()) + * + 37 * Double.doubleToLongBits(getY()) + * + 43 * Double.doubleToLongBits(getWidth()) + * + 47 * Double.doubleToLongBits(getHeight()); + * return (int) ((l >> 32) ^ l); + * </pre> + * + * @return the hashcode + */ + public int hashCode() { - add (r.getMinX (), r.getMinY ()); - add (r.getMaxX (), r.getMaxY ()); + // Talk about a fun time reverse engineering this one! + long l = java.lang.Double.doubleToLongBits(getX()) + + 37 * java.lang.Double.doubleToLongBits(getY()) + + 43 * java.lang.Double.doubleToLongBits(getWidth()) + + 47 * java.lang.Double.doubleToLongBits(getHeight()); + return (int) ((l >> 32) ^ l); } - public PathIterator getPathIterator (AffineTransform at) + /** + * Tests this rectangle for equality against the specified object. This + * will be true if an only if the specified object is an instance of + * Rectangle2D with the same coordinates and dimensions. + * + * @param obj the object to test against for equality + * @return true if the specified object is equal to this one + */ + public boolean equals(Object obj) { - // We know the superclass just ignores the flatness parameter. - return getPathIterator (at, 0); + if (! (obj instanceof Rectangle2D)) + return false; + Rectangle2D r = (Rectangle2D) obj; + return r.getX() == getX() && r.getY() == getY() + && r.getWidth() == getWidth() && r.getHeight() == getHeight(); } + /** + * This class defines a rectangle in <code>double</code> precision. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ public static class Double extends Rectangle2D { - public double height; - public double width; + /** The x coordinate of the lower left corner. */ public double x; + + /** The y coordinate of the lower left corner. */ public double y; - public Double () + /** The width of the rectangle. */ + public double width; + + /** The height of the rectangle. */ + public double height; + + /** + * Create a rectangle at (0,0) with width 0 and height 0. + */ + public Double() { - height = width = x = y = 0; } - public Double (double x, double y, double w, double h) + /** + * Create a rectangle with the given values. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + */ + public Double(double x, double y, double w, double h) { this.x = x; this.y = y; - this.width = w; - this.height = h; + width = w; + height = h; } - public double getX () + /** + * Return the X coordinate. + * + * @return the value of x + */ + public double getX() { return x; } - public double getY () + /** + * Return the Y coordinate. + * + * @return the value of y + */ + public double getY() { return y; } - public double getWidth () + /** + * Return the width. + * + * @return the value of width + */ + public double getWidth() { return width; } - public double getHeight () + /** + * Return the height. + * + * @return the value of height + */ + public double getHeight() { return height; } - public boolean isEmpty () + /** + * Test if the rectangle is empty. + * + * @return true if width or height is not positive + */ + public boolean isEmpty() { return width <= 0 || height <= 0; } - public void setRect (double x, double y, double w, double h) + /** + * Set the contents of this rectangle to those specified. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + */ + public void setRect(double x, double y, double w, double h) { this.x = x; this.y = y; - this.width = w; - this.height = h; + width = w; + height = h; } - public void setRect (Rectangle2D r) + /** + * Set the contents of this rectangle to those specified. + * + * @param r the rectangle to copy + * @throws NullPointerException if r is null + */ + public void setRect(Rectangle2D r) { - this.x = r.getX (); - this.y = r.getY (); - this.width = r.getWidth (); - this.height = r.getHeight (); + x = r.getX(); + y = r.getY(); + width = r.getWidth(); + height = r.getHeight(); } - public int outcode (double x, double y) + /** + * Determine where the point lies with respect to this rectangle. The + * result will be the binary OR of the appropriate bit masks. + * + * @param x the x coordinate to check + * @param y the y coordinate to check + * @return the binary OR of the result + * @see #OUT_LEFT + * @see #OUT_TOP + * @see #OUT_RIGHT + * @see #OUT_BOTTOM + * @since 1.2 + */ + public int outcode(double x, double y) { - int code = 0; - if (x < this.x) - code |= OUT_LEFT; - else if (x >= this.x + this.width) - code |= OUT_RIGHT; - if (y < this.y) - code |= OUT_TOP; - else if (y >= this.y + this.height) - code |= OUT_BOTTOM; - return code; + int result = 0; + if (width <= 0) + result |= OUT_LEFT | OUT_RIGHT; + else if (x < this.x) + result |= OUT_LEFT; + else if (x > this.x + width) + result |= OUT_RIGHT; + if (height <= 0) + result |= OUT_BOTTOM | OUT_TOP; + else if (y < this.y) // Remember that +y heads top-to-bottom. + result |= OUT_TOP; + else if (y > this.y + height) + result |= OUT_BOTTOM; + return result; } - public Rectangle2D getBounds2D () + /** + * Returns the bounds of this rectangle. A pretty useless method, as this + * is already a rectangle. + * + * @return a copy of this rectangle + */ + public Rectangle2D getBounds2D() { - return new Rectangle2D.Double (x, y, width, height); + return new Double(x, y, width, height); } - public Rectangle2D createIntersection (Rectangle2D r) + /** + * Return a new rectangle which is the intersection of this and the given + * one. The result will be empty if there is no intersection. + * + * @param r the rectangle to be intersected + * @return the intersection + * @throws NullPointerException if r is null + */ + public Rectangle2D createIntersection(Rectangle2D r) { - Double res = new Double (); - intersect (this, r, res); + Double res = new Double(); + intersect(this, r, res); return res; } - public Rectangle2D createUnion (Rectangle2D r) + /** + * Return a new rectangle which is the union of this and the given one. + * + * @param r the rectangle to be merged + * @return the union + * @throws NullPointerException if r is null + */ + public Rectangle2D createUnion(Rectangle2D r) { - Double res = new Double (); - union (this, r, res); + Double res = new Double(); + union(this, r, res); return res; } - public String toString () + /** + * Returns a string representation of this rectangle. This is in the form + * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width + * + ",h=" + height + ']'</code>. + * + * @return a string representation of this rectangle + */ + public String toString() { - return "fixme"; + return getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width + + ",h=" + height + ']'; } - } - + } // class Double + + /** + * This class defines a rectangle in <code>float</code> precision. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ public static class Float extends Rectangle2D { - public float height; - public float width; + /** The x coordinate of the lower left corner. */ public float x; + + /** The y coordinate of the lower left corner. */ public float y; - public Float () + /** The width of the rectangle. */ + public float width; + + /** The height of the rectangle. */ + public float height; + + /** + * Create a rectangle at (0,0) with width 0 and height 0. + */ + public Float() { - height = width = x = y = 0; } - public Float (float x, float y, float w, float h) + /** + * Create a rectangle with the given values. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + */ + public Float(float x, float y, float w, float h) { this.x = x; this.y = y; - this.width = w; - this.height = h; + width = w; + height = h; } - public double getX () + /** + * Create a rectangle with the given values. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + */ + Float(double x, double y, double w, double h) + { + this.x = (float) x; + this.y = (float) y; + width = (float) w; + height = (float) h; + } + + /** + * Return the X coordinate. + * + * @return the value of x + */ + public double getX() { return x; } - public double getY () + /** + * Return the Y coordinate. + * + * @return the value of y + */ + public double getY() { return y; } - public double getWidth () + /** + * Return the width. + * + * @return the value of width + */ + public double getWidth() { return width; } - public double getHeight () + /** + * Return the height. + * + * @return the value of height + */ + public double getHeight() { return height; } - public boolean isEmpty () + /** + * Test if the rectangle is empty. + * + * @return true if width or height is not positive + */ + public boolean isEmpty() { return width <= 0 || height <= 0; } - public void setRect (double x, double y, double w, double h) + /** + * Set the contents of this rectangle to those specified. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + */ + public void setRect(float x, float y, float w, float h) { - this.x = (float) x; - this.y = (float) y; - this.width = (float) w; - this.height = (float) h; + this.x = x; + this.y = y; + width = w; + height = h; } - public void setRect (float x, float y, float w, float h) + /** + * Set the contents of this rectangle to those specified. + * + * @param x the x coordinate + * @param y the y coordinate + * @param w the width + * @param h the height + */ + public void setRect(double x, double y, double w, double h) { - this.x = x; - this.y = y; - this.width = w; - this.height = h; + this.x = (float) x; + this.y = (float) y; + width = (float) w; + height = (float) h; } - public void setRect (Rectangle2D r) + /** + * Set the contents of this rectangle to those specified. + * + * @param r the rectangle to copy + * @throws NullPointerException if r is null + */ + public void setRect(Rectangle2D r) { - this.x = (float) r.getX (); - this.y = (float) r.getY (); - this.width = (float) r.getWidth (); - this.height = (float) r.getHeight (); + x = (float) r.getX(); + y = (float) r.getY(); + width = (float) r.getWidth(); + height = (float) r.getHeight(); } - public int outcode (double x, double y) + /** + * Determine where the point lies with respect to this rectangle. The + * result will be the binary OR of the appropriate bit masks. + * + * @param x the x coordinate to check + * @param y the y coordinate to check + * @return the binary OR of the result + * @see #OUT_LEFT + * @see #OUT_TOP + * @see #OUT_RIGHT + * @see #OUT_BOTTOM + * @since 1.2 + */ + public int outcode(double x, double y) { - int code = 0; - if (x < this.x) - code |= OUT_LEFT; - else if (x >= this.x + this.width) - code |= OUT_RIGHT; - if (y < this.y) - code |= OUT_TOP; - else if (y >= this.y + this.height) - code |= OUT_BOTTOM; - return code; + int result = 0; + if (width <= 0) + result |= OUT_LEFT | OUT_RIGHT; + else if (x < this.x) + result |= OUT_LEFT; + else if (x > this.x + width) + result |= OUT_RIGHT; + if (height <= 0) + result |= OUT_BOTTOM | OUT_TOP; + else if (y < this.y) // Remember that +y heads top-to-bottom. + result |= OUT_TOP; + else if (y > this.y + height) + result |= OUT_BOTTOM; + return result; } - public Rectangle2D getBounds2D () + /** + * Returns the bounds of this rectangle. A pretty useless method, as this + * is already a rectangle. + * + * @return a copy of this rectangle + */ + public Rectangle2D getBounds2D() { - return new Rectangle2D.Float (x, y, width, height); + return new Float(x, y, width, height); } - public Rectangle2D createIntersection (Rectangle2D r) + /** + * Return a new rectangle which is the intersection of this and the given + * one. The result will be empty if there is no intersection. + * + * @param r the rectangle to be intersected + * @return the intersection + * @throws NullPointerException if r is null + */ + public Rectangle2D createIntersection(Rectangle2D r) { - Float res = new Float (); - intersect (this, r, res); + Float res = new Float(); + intersect(this, r, res); return res; } - public Rectangle2D createUnion (Rectangle2D r) + /** + * Return a new rectangle which is the union of this and the given one. + * + * @param r the rectangle to be merged + * @return the union + * @throws NullPointerException if r is null + */ + public Rectangle2D createUnion(Rectangle2D r) { - Float res = new Float (); - union (this, r, res); + Float res = new Float(); + union(this, r, res); return res; } - public String toString () + /** + * Returns a string representation of this rectangle. This is in the form + * <code>getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width + * + ",h=" + height + ']'</code>. + * + * @return a string representation of this rectangle + */ + public String toString() { - return "fixme"; + return getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width + + ",h=" + height + ']'; } - } -} + } // class Float +} // class Rectangle2D diff --git a/libjava/java/awt/geom/RectangularShape.java b/libjava/java/awt/geom/RectangularShape.java index 897512813a8..1801e80339d 100644 --- a/libjava/java/awt/geom/RectangularShape.java +++ b/libjava/java/awt/geom/RectangularShape.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* RectangularShape.java -- a rectangular frame for several generic shapes + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -34,77 +35,196 @@ 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.geom; -import java.awt.*; -import java.awt.geom.Rectangle2D; + +import java.awt.Rectangle; +import java.awt.Shape; /** + * This class provides a generic framework, and several helper methods, for + * subclasses which represent geometric objects inside a rectangular frame. + * This does not specify any geometry except for the bounding box. + * * @author Tom Tromey <tromey@cygnus.com> - * @date April 16, 2000 + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @see Arc2D + * @see Ellipse2D + * @see Rectangle2D + * @see RoundRectangle2D + * @status updated to 1.4 */ - public abstract class RectangularShape implements Shape, Cloneable { - protected RectangularShape () + /** + * Default constructor. + */ + protected RectangularShape() { } - public abstract double getX (); - public abstract double getY (); - public abstract double getWidth (); - public abstract double getHeight (); - - public double getMinX () - { - return Math.min (getX (), getX () + getWidth ()); + /** + * Get the x coordinate of the upper-left corner of the framing rectangle. + * + * @return the x coordinate + */ + public abstract double getX(); + + /** + * Get the y coordinate of the upper-left corner of the framing rectangle. + * + * @return the y coordinate + */ + public abstract double getY(); + + /** + * Get the width of the framing rectangle. + * + * @return the width + */ + public abstract double getWidth(); + + /** + * Get the height of the framing rectangle. + * + * @return the height + */ + public abstract double getHeight(); + + /** + * Get the minimum x coordinate in the frame. This is misnamed, or else + * Sun has a bug, because the implementation returns getX() even when + * getWidth() is negative. + * + * @return the minimum x coordinate + */ + public double getMinX() + { + return getX(); } - public double getMinY () + /** + * Get the minimum y coordinate in the frame. This is misnamed, or else + * Sun has a bug, because the implementation returns getY() even when + * getHeight() is negative. + * + * @return the minimum y coordinate + */ + public double getMinY() { - return Math.min (getY (), getY () + getHeight ()); + return getY(); } - public double getMaxX () - { - return Math.max (getX (), getX () + getWidth ()); + /** + * Get the maximum x coordinate in the frame. This is misnamed, or else + * Sun has a bug, because the implementation returns getX()+getWidth() even + * when getWidth() is negative. + * + * @return the maximum x coordinate + */ + public double getMaxX() + { + return getX() + getWidth(); } - public double getMaxY () + /** + * Get the maximum y coordinate in the frame. This is misnamed, or else + * Sun has a bug, because the implementation returns getY()+getHeight() even + * when getHeight() is negative. + * + * @return the maximum y coordinate + */ + public double getMaxY() { - return Math.max (getY (), getY () + getHeight ()); + return getY() + getHeight(); } - public double getCenterX () + /** + * Return the x coordinate of the center point of the framing rectangle. + * + * @return the central x coordinate + */ + public double getCenterX() { - return getX () + getWidth () / 2; + return getX() + getWidth() / 2; } - public double getCenterY () + /** + * Return the y coordinate of the center point of the framing rectangle. + * + * @return the central y coordinate + */ + public double getCenterY() { - return getY () + getHeight () / 2; + return getY() + getHeight() / 2; } - public Rectangle2D getFrame () + /** + * Return the frame around this object. Note that this may be a looser + * bounding box than getBounds2D. + * + * @return the frame, in double precision + * @see #setFrame(double, double, double, double) + */ + public Rectangle2D getFrame() { - return new Rectangle2D.Double (getX (), getY (), - getWidth (), getHeight ()); + return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight()); } - public abstract boolean isEmpty (); - public abstract void setFrame (double x, double y, double w, double h); - - public void setFrame (Point2D loc, Dimension2D size) + /** + * Test if the shape is empty, meaning that no points are inside it. + * + * @return true if the shape is empty + */ + public abstract boolean isEmpty(); + + /** + * Set the framing rectangle of this shape to the given coordinate and size. + * + * @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 abstract void setFrame(double x, double y, double w, double h); + + /** + * Set the framing rectangle of this shape to the given coordinate and size. + * + * @param p the new point + * @param d the new dimension + * @throws NullPointerException if p or d is null + * @see #getFrame() + */ + public void setFrame(Point2D p, Dimension2D d) { - setFrame (loc.getX (), loc.getY (), size.getWidth (), size.getHeight ()); + setFrame(p.getX(), p.getY(), d.getWidth(), d.getHeight()); } - public void setFrame (Rectangle2D r) + /** + * Set the framing rectangle of this shape to the given rectangle. + * + * @param r the new framing rectangle + * @throws NullPointerException if r is null + * @see #getFrame() + */ + public void setFrame(Rectangle2D r) { - setFrame (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); + setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - public void setFrameFromDiagonal (double x1, double y1, - double x2, double y2) + /** + * Set the framing rectangle of this shape using two points on a diagonal. + * The area will be positive. + * + * @param x1 the first x coordinate + * @param y1 the first y coordinate + * @param x2 the second x coordinate + * @param y2 the second y coordinate + */ + public void setFrameFromDiagonal(double x1, double y1, double x2, double y2) { if (x1 > x2) { @@ -118,206 +238,148 @@ public abstract class RectangularShape implements Shape, Cloneable y2 = y1; y1 = t; } - setFrame (x1, y1, x2 - x1, y2 - y1); + setFrame(x1, y1, x2 - x1, y2 - y1); } - public void setFrameFromDiagonal (Point2D p1, Point2D p2) + /** + * Set the framing rectangle of this shape using two points on a diagonal. + * The area will be positive. + * + * @param p1 the first point + * @param p2 the second point + * @throws NullPointerException if either point is null + */ + public void setFrameFromDiagonal(Point2D p1, Point2D p2) { - setFrameFromDiagonal (p1.getX (), p1.getY (), - p2.getX (), p2.getY ()); + setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY()); } - public void setFrameFromCenter (double centerX, double centerY, - double cornerX, double cornerY) + /** + * Set the framing rectangle of this shape using the center of the frame, + * and one of the four corners. The area will be positive. + * + * @param centerX the x coordinate at the center + * @param centerY the y coordinate at the center + * @param cornerX the x coordinate at a corner + * @param cornerY the y coordinate at a corner + */ + public void setFrameFromCenter(double centerX, double centerY, + double cornerX, double cornerY) { - double halfw = Math.abs (cornerX - centerX); - double halfh = Math.abs (cornerY - centerY); - setFrame (centerX - halfw, centerY - halfh, - 2 * halfw, 2 * halfh); + double halfw = Math.abs(cornerX - centerX); + double halfh = Math.abs(cornerY - centerY); + setFrame(centerX - halfw, centerY - halfh, halfw + halfw, halfh + halfh); } - public void setFrameFromCenter (Point2D center, Point2D corner) + /** + * Set the framing rectangle of this shape using the center of the frame, + * and one of the four corners. The area will be positive. + * + * @param center the center point + * @param corner a corner point + * @throws NullPointerException if either point is null + */ + public void setFrameFromCenter(Point2D center, Point2D corner) { - setFrameFromCenter (center.getX (), center.getY (), - corner.getX (), corner.getY ()); + setFrameFromCenter(center.getX(), center.getY(), + corner.getX(), corner.getY()); } - public boolean contains (Point2D p) + /** + * Tests if a point is inside the boundary of the shape. + * + * @param p the point to test + * @return true if the point is inside the shape + * @throws NullPointerException if p is null + * @see #contains(double, double) + */ + public boolean contains(Point2D p) { - double x = p.getX (); - double y = p.getY (); - double rx = getX (); - double ry = getY (); - double w = getWidth (); - double h = getHeight (); - return x >= rx && x < rx + w && y >= ry && y < ry + h; + return contains(p.getX(), p.getY()); } - public boolean intersects (Rectangle2D r) + /** + * Tests if a rectangle and this shape share common internal points. + * + * @param r the rectangle to test + * @return true if the rectangle intersects this shpae + * @throws NullPointerException if r is null + * @see #intersects(double, double, double, double) + */ + public boolean intersects(Rectangle2D r) { - double x = getX (); - double w = getWidth (); - double mx = r.getX (); - double mw = r.getWidth (); - if (x < mx || x >= mx + mw || x + w < mx || x + w >= mx + mw) - return false; - double y = getY (); - double h = getHeight (); - double my = r.getY (); - double mh = r.getHeight (); - return y >= my && y < my + mh && y + h >= my && y + h < my + mh; + return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - private boolean containsPoint (double x, double y) + /** + * Tests if the shape completely contains the given rectangle. + * + * @param r the rectangle to test + * @return true if r is contained in this shape + * @throws NullPointerException if r is null + * @see #contains(double, double, double, double) + */ + public boolean contains(Rectangle2D r) { - double mx = getX (); - double mw = getWidth (); - if (x < mx || x >= mx + mw) - return false; - double my = getY (); - double mh = getHeight (); - return y >= my && y < my + mh; + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - public boolean contains (Rectangle2D r) + /** + * Returns a bounding box for this shape, in integer format. Notice that you + * may get a tighter bound with getBounds2D. If the frame is empty, the + * box is the default empty box at the origin. + * + * @return a bounding box + */ + public Rectangle getBounds() { - return (containsPoint (r.getMinX (), r.getMinY ()) - && containsPoint (r.getMaxX (), r.getMaxY ())); + if (isEmpty()) + return new Rectangle(); + double x = getX(); + double y = getY(); + double maxx = Math.ceil(x + getWidth()); + double maxy = Math.ceil(y + getHeight()); + x = Math.floor(x); + y = Math.floor(y); + return new Rectangle((int) x, (int) y, (int) (maxx - x), (int) (maxy - y)); } - public Rectangle getBounds () + /** + * Return an iterator along the shape boundary. If the optional transform + * is provided, the iterator is transformed accordingly. The path is + * flattened until all segments differ from the curve by at most the value + * of the flatness parameter, within the limits of the default interpolation + * recursion limit of 1024 segments between actual points. Each call + * returns a new object, independent from others in use. The result is + * threadsafe if and only if the iterator returned by + * {@link #getPathIterator(AffineTransform)} is as well. + * + * @param transform an optional transform to apply to the iterator + * @param flatness the desired flatness + * @return a new iterator over the boundary + * @throws IllegalArgumentException if flatness is invalid + * @since 1.2 + */ + public PathIterator getPathIterator(AffineTransform at, double flatness) { - return new Rectangle ((int) getX (), (int) getY (), - (int) getWidth (), (int) getHeight ()); + return new FlatteningPathIterator(getPathIterator(at), flatness); } - public PathIterator getPathIterator (AffineTransform at, double flatness) - { - return at.new Iterator (new Iterator ()); - } - - public Object clone () + /** + * Create a new shape of the same run-time type with the same contents as + * this one. + * + * @return the clone + */ + public Object clone() { try - { - return super.clone (); - } - catch (CloneNotSupportedException _) {return null;} - } - - // This implements the PathIterator for all RectangularShape objects - // that don't override getPathIterator. - private class Iterator implements PathIterator - { - // Our current coordinate. - private int coord; - - private static final int START = 0; - private static final int END_PLUS_ONE = 5; - - public Iterator () - { - coord = START; - } - - public int currentSegment (double[] coords) - { - int r; - switch (coord) - { - case 0: - coords[0] = getX (); - coords[1] = getY (); - r = SEG_MOVETO; - break; - - case 1: - coords[0] = getX () + getWidth (); - coords[1] = getY (); - r = SEG_LINETO; - break; - - case 2: - coords[0] = getX () + getWidth (); - coords[1] = getY () + getHeight (); - r = SEG_LINETO; - break; - - case 3: - coords[0] = getX (); - coords[1] = getY () + getHeight (); - r = SEG_LINETO; - break; - - case 4: - r = SEG_CLOSE; - break; - - default: - // It isn't clear what to do if the caller calls us after - // isDone returns true. - r = SEG_CLOSE; - break; - } - - return r; - } - - public int currentSegment (float[] coords) - { - int r; - switch (coord) - { - case 0: - coords[0] = (float) getX (); - coords[1] = (float) getY (); - r = SEG_MOVETO; - break; - - case 1: - coords[0] = (float) (getX () + getWidth ()); - coords[1] = (float) getY (); - r = SEG_LINETO; - break; - - case 2: - coords[0] = (float) (getX () + getWidth ()); - coords[1] = (float) (getY () + getHeight ()); - r = SEG_LINETO; - break; - - case 3: - coords[0] = (float) getX (); - coords[1] = (float) (getY () + getHeight ()); - r = SEG_LINETO; - break; - - case 4: - default: - // It isn't clear what to do if the caller calls us after - // isDone returns true. We elect to keep returning - // SEG_CLOSE. - r = SEG_CLOSE; - break; - } - - return r; - } - - public int getWindingRule () - { - return WIND_NON_ZERO; - } - - public boolean isDone () - { - return coord == END_PLUS_ONE; - } - - public void next () - { - if (coord < END_PLUS_ONE) - ++coord; - } + { + return super.clone(); + } + catch (CloneNotSupportedException e) + { + throw (Error) new InternalError().initCause(e); // Impossible + } } -} +} // class RectangularShape diff --git a/libjava/java/awt/geom/RoundRectangle2D.java b/libjava/java/awt/geom/RoundRectangle2D.java index b518568c965..ec7e4615f0d 100644 --- a/libjava/java/awt/geom/RoundRectangle2D.java +++ b/libjava/java/awt/geom/RoundRectangle2D.java @@ -1,4 +1,5 @@ -/* Copyright (C) 2000, 2002 Free Software Foundation +/* RoundRectangle2D.java -- represents a rectangle with rounded corners + Copyright (C) 2000, 2002 Free Software Foundation This file is part of GNU Classpath. @@ -43,10 +44,10 @@ package java.awt.geom; public abstract class RoundRectangle2D extends RectangularShape { /** Return the arc height of this round rectangle. */ - public abstract double getArcHeight (); + public abstract double getArcHeight(); /** Return the arc width of this round rectangle. */ - public abstract double getArcWidth (); + public abstract double getArcWidth(); /** Set the values of this round rectangle * @param x The x coordinate @@ -56,13 +57,13 @@ public abstract class RoundRectangle2D extends RectangularShape * @param arcWidth The arc width * @param arcHeight The arc height */ - public abstract void setRoundRect (double x, double y, double w, double h, - double arcWidth, double arcHeight); + public abstract void setRoundRect(double x, double y, double w, double h, + double arcWidth, double arcHeight); /** Create a RoundRectangle2D. This is protected because this class * is abstract and cannot be instantiated. */ - protected RoundRectangle2D () + protected RoundRectangle2D() { } @@ -70,22 +71,22 @@ public abstract class RoundRectangle2D extends RectangularShape * @param x The x coordinate * @param y The y coordinate */ - public boolean contains (double x, double y) + public boolean contains(double x, double y) { - double mx = getX (); - double mw = getWidth (); + double mx = getX(); + double mw = getWidth(); if (x < mx || x >= mx + mw) return false; - double my = getY (); - double mh = getHeight (); + double my = getY(); + double mh = getHeight(); if (y < my || y >= my + mh) return false; // Now check to see if the point is in range of an arc. - double dy = Math.min (Math.abs (my - y), Math.abs (my + mh - y)); - double dx = Math.min (Math.abs (mx - x), Math.abs (mx + mw - x)); - double aw = getArcWidth (); - double ah = getArcHeight (); + double dy = Math.min(Math.abs(my - y), Math.abs(my + mh - y)); + double dx = Math.min(Math.abs(mx - x), Math.abs(mx + mw - x)); + double aw = getArcWidth(); + double ah = getArcHeight(); if (dx > aw || dy > ah) return true; @@ -105,18 +106,18 @@ public abstract class RoundRectangle2D extends RectangularShape * @param w The width * @param h The height */ - public boolean contains (double x, double y, double w, double h) + public boolean contains(double x, double y, double w, double h) { // We have to check all four points here (for ordinary rectangles // we can just check opposing corners). - return (contains (x, y) && contains (x + w, h) - && contains (x, y + h) && contains (x + w, y + h)); + return (contains(x, y) && contains(x + w, h) + && contains(x, y + h) && contains(x + w, y + h)); } /** Return a new path iterator which iterates over this rectangle. * @param at An affine transform to apply to the object */ - public PathIterator getPathIterator (AffineTransform at) + public PathIterator getPathIterator(AffineTransform at) { // FIXME. return null; @@ -128,15 +129,15 @@ public abstract class RoundRectangle2D extends RectangularShape * @param w The width * @param h The height */ - public boolean intersects (double x, double y, double w, double h) + public boolean intersects(double x, double y, double w, double h) { // Here we can use the same code we use for an ordinary rectangle. - double mx = getX (); - double mw = getWidth (); + double mx = getX(); + double mw = getWidth(); if (x < mx || x >= mx + mw || x + w < mx || x + w >= mx + mw) return false; - double my = getY (); - double mh = getHeight (); + double my = getY(); + double mh = getHeight(); return y >= my && y < my + mh && y + h >= my && y + h < my + mh; } @@ -146,48 +147,47 @@ public abstract class RoundRectangle2D extends RectangularShape * @param w The width * @param h The height */ - public void setFrame (double x, double y, double w, double h) + public void setFrame(double x, double y, double w, double h) { // This is a bit lame. - setRoundRect (x, y, w, h, getArcWidth (), getArcHeight ()); + setRoundRect(x, y, w, h, getArcWidth(), getArcHeight()); } /** Set the values of this round rectangle to be the same as those * of the argument. * @param rr The round rectangle to copy */ - public void setRoundRect (RoundRectangle2D rr) + public void setRoundRect(RoundRectangle2D rr) { - setRoundRect (rr.getX (), rr.getY (), rr.getWidth (), rr.getHeight (), - rr.getArcWidth (), rr.getArcHeight ()); + setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(), + rr.getArcWidth(), rr.getArcHeight()); } /** A subclass of RoundRectangle which keeps its parameters as - * floats. */ - public static class Float extends RoundRectangle2D + * doubles. */ + public static class Double extends RoundRectangle2D { /** The height of the corner arc. */ - public float archeight; + public double archeight; /** The width of the corner arc. */ - public float arcwidth; + public double arcwidth; /** The x coordinate of this object. */ - public float x; + public double x; /** The y coordinate of this object. */ - public float y; + public double y; /** The width of this object. */ - public float width; + public double width; /** The height of this object. */ - public float height; + public double height; /** Construct a new instance, with all parameters set to 0. */ - public Float () + public Double() { - this (0, 0, 0, 0, 0, 0); } /** Construct a new instance with the given arguments. @@ -198,8 +198,8 @@ public abstract class RoundRectangle2D extends RectangularShape * @param arcWidth The arc width * @param arcHeight The arc height */ - public Float (float x, float y, float w, float h, - float arcWidth, float arcHeight) + public Double(double x, double y, double w, double h, + double arcWidth, double arcHeight) { this.x = x; this.y = y; @@ -209,48 +209,48 @@ public abstract class RoundRectangle2D extends RectangularShape this.archeight = arcHeight; } - public double getArcHeight () + public double getArcHeight() { return archeight; } - public double getArcWidth () + public double getArcWidth() { return arcwidth; } - public Rectangle2D getBounds2D () + public Rectangle2D getBounds2D() { - return new Rectangle2D.Float (x, y, width, height); + return new Rectangle2D.Double(x, y, width, height); } - public double getX () + public double getX() { return x; } - public double getY () + public double getY() { return y; } - public double getWidth () + public double getWidth() { return width; } - public double getHeight () + public double getHeight() { return height; } - public boolean isEmpty () + public boolean isEmpty() { return width <= 0 || height <= 0; } - public void setRoundRect (float x, float y, float w, float h, - float arcWidth, float arcHeight) + public void setRoundRect(double x, double y, double w, double h, + double arcWidth, double arcHeight) { this.x = x; this.y = y; @@ -259,45 +259,33 @@ public abstract class RoundRectangle2D extends RectangularShape this.arcwidth = arcWidth; this.archeight = arcHeight; } - - public void setRoundRect (double x, double y, double w, double h, - double arcWidth, double arcHeight) - { - this.x = (float) x; - this.y = (float) y; - this.width = (float) w; - this.height = (float) h; - this.arcwidth = (float) arcWidth; - this.archeight = (float) arcHeight; - } - } + } // class Double /** A subclass of RoundRectangle which keeps its parameters as - * doubles. */ - public static class Double extends RoundRectangle2D + * floats. */ + public static class Float extends RoundRectangle2D { /** The height of the corner arc. */ - public double archeight; + public float archeight; /** The width of the corner arc. */ - public double arcwidth; + public float arcwidth; /** The x coordinate of this object. */ - public double x; + public float x; /** The y coordinate of this object. */ - public double y; + public float y; /** The width of this object. */ - public double width; + public float width; /** The height of this object. */ - public double height; + public float height; /** Construct a new instance, with all parameters set to 0. */ - public Double () + public Float() { - this (0, 0, 0, 0, 0, 0); } /** Construct a new instance with the given arguments. @@ -308,8 +296,8 @@ public abstract class RoundRectangle2D extends RectangularShape * @param arcWidth The arc width * @param arcHeight The arc height */ - public Double (double x, double y, double w, double h, - double arcWidth, double arcHeight) + public Float(float x, float y, float w, float h, + float arcWidth, float arcHeight) { this.x = x; this.y = y; @@ -319,48 +307,48 @@ public abstract class RoundRectangle2D extends RectangularShape this.archeight = arcHeight; } - public double getArcHeight () + public double getArcHeight() { return archeight; } - public double getArcWidth () + public double getArcWidth() { return arcwidth; } - public Rectangle2D getBounds2D () + public Rectangle2D getBounds2D() { - return new Rectangle2D.Double (x, y, width, height); + return new Rectangle2D.Float(x, y, width, height); } - public double getX () + public double getX() { return x; } - public double getY () + public double getY() { return y; } - public double getWidth () + public double getWidth() { return width; } - public double getHeight () + public double getHeight() { return height; } - public boolean isEmpty () + public boolean isEmpty() { return width <= 0 || height <= 0; } - public void setRoundRect (double x, double y, double w, double h, - double arcWidth, double arcHeight) + public void setRoundRect(float x, float y, float w, float h, + float arcWidth, float arcHeight) { this.x = x; this.y = y; @@ -369,5 +357,16 @@ public abstract class RoundRectangle2D extends RectangularShape this.arcwidth = arcWidth; this.archeight = arcHeight; } - } -} + + public void setRoundRect(double x, double y, double w, double h, + double arcWidth, double arcHeight) + { + this.x = (float) x; + this.y = (float) y; + this.width = (float) w; + this.height = (float) h; + this.arcwidth = (float) arcWidth; + this.archeight = (float) arcHeight; + } + } // class Float +} // class RoundRectangle2D diff --git a/libjava/java/awt/im/InputContext.java b/libjava/java/awt/im/InputContext.java new file mode 100644 index 00000000000..e4431f9c374 --- /dev/null +++ b/libjava/java/awt/im/InputContext.java @@ -0,0 +1,434 @@ +/* InputContext.java -- provides the context for text input + 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.im; + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Component; +import java.awt.im.spi.InputMethod; +import java.awt.im.spi.InputMethodDescriptor; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Locale; +import gnu.java.util.EmptyEnumeration; + +/** + * Provides a context for controlling input methods and keyboard layouts. + * This class provides the communication layer between the client component, + * and the various locale-dependent text entry input methods that can be used + * for the client. By default, there is one instance per Window, shared among + * all components, but this limits text entry to one component at a time. + * Thus, text components can create their own instance to allow text entry + * in multiple components at a time. + * + * <p>By using the interfaces of {@link java.awt.im.spi}, you can install + * extensions which allow additional input methods. Some of these may use + * platform native input methods, or keyboard layouts provided by the platform. + * Input methods are unavailable if none have been installed and the platform + * has no underlying native input methods. Extensions are installed as jar + * files, usually accessed in the default extension location or specified by + * the -extdir VM flag. The jar must contain a file named + * "META_INF/services/java.awt.im.spi.InputMethodDescriptor" which lists, + * one entry per line in UTF-8 encoding, each class in the jar that implements + * java.awt.im.spi.InputMethodDescriptor. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Component#getInputContext() + * @see Component#enableInputMethods(boolean) + * @since 1.2 + * @status updated to 1.4, but unverified + */ +public class InputContext +{ + /** + * The list of installed input method descriptors. + */ + private static final ArrayList descriptors = new ArrayList(); + static + { + Enumeration enum; + try + { + enum = ClassLoader.getSystemResources + ("META_INF/services/java.awt.im.spi.InputMethodDescriptor"); + } + catch (IOException ex) + { + // XXX Should we do something else? + enum = EmptyEnumeration.getInstance(); + } + while (enum.hasMoreElements()) + { + URL url = (URL) enum.nextElement(); + BufferedReader in; + String line; + try + { + in = new BufferedReader + (new InputStreamReader(url.openConnection().getInputStream(), + "UTF-8")); + line = in.readLine().trim(); + } + catch (IOException ignored) + { + continue; + } + outer: + while (line != null) + { + try + { + if (line.charAt(0) != '#') + { + Class c = Class.forName(line); + descriptors.add((InputMethodDescriptor) c.newInstance()); + } + line = in.readLine().trim(); + } + catch (IOException e) + { + continue outer; + } + catch (Exception ignored) + { + } + } + } + } + + /** The current input method; null if no input methods are installed. */ + private InputMethod im; + + /** Map of locales to the most recently selected input method. */ + private final HashMap recent = new HashMap(); + + /** The list of acceptable character subsets. */ + private Character.Subset[] subsets; + + /** + * Construct an InputContext. This is protected, so clients must use + * {@link #getInstance()} instead. + */ + protected InputContext() + { + } + + /** + * Returns a new InputContext. + * + * @return a new instance, initialized to the default locale if available + */ + public static InputContext getInstance() + { + InputContext ic = new InputContext(); + ic.selectInputMethod(Locale.getDefault()); + return ic; + } + + /** + * Attempts to select an input method or keyboard layout which supports the + * given locale. This returns true if a locale is available and was selected. + * The following steps are taken in choosing an input method:<ul> + * <li>If the currently selected input method or keyboard layout supports + * the requested locale, it remains selected.</li> + * <li>If there is no input method or keyboard layout available that + * supports the requested locale, the current input method or keyboard + * layout remains selected.</li> + * <li>If the user has previously selected an input method or keyboard + * layout for the requested locale from the user interface, then the most + * recently selected such input method or keyboard layout is reselected.</li> + * <li>Otherwise, an input method or keyboard layout that supports the + * requested locale is selected in an implementation dependent way. This + * implementation chooses the first input method which supports the requested + * locale based on the InputMethodDescriptors loaded from the extensions + * installed on the CLASSPATH.</li> + * </ul> + * + * <p>Before switching away from an input method, any currently uncommitted + * text is committed. Not all host operating systems provide API to + * determine the locale of the currently selected native input method or + * keyboard layout, and to select a native input method or keyboard layout + * by locale. For host operating systems that don't provide such API, + * selectInputMethod assumes that native input methods or keyboard layouts + * provided by the host operating system support only the system's default + * locale. + * + * <p>An example of where this may be called is in a multi-language document, + * when moving the insertion point between sections of different locale, so + * that the user may use the input method appropriate to that section of the + * document. + * + * @param locale the desired new locale + * @return true if the new locale is active + * @throws NullPointerException if locale is null + */ + public boolean selectInputMethod(Locale locale) + { + if (im != null && im.setLocale(locale)) + { + recent.put(locale, im); + return true; + } + InputMethod next = (InputMethod) recent.get(locale); + outer: + if (next != null) + for (int i = 0, limit = descriptors.size(); i < limit; i++) + { + InputMethodDescriptor d = (InputMethodDescriptor) descriptors.get(i); + Locale[] list; + try + { + list = d.getAvailableLocales(); + } + catch (AWTException ignored) + { + continue; + } + for (int j = list.length; --j >= 0; ) + if (locale.equals(list[j])) + { + try + { + next = d.createInputMethod(); + recent.put(locale, next); + } + catch (Exception ignored) + { + continue; + } + } + } + if (next == null) + return false; + // XXX I'm not sure if this does all the necessary steps in the switch. + if (im != null) + { + try + { + next.setCompositionEnabled(im.isCompositionEnabled()); + } + catch (UnsupportedOperationException ignored) + { + } + im.endComposition(); + im.deactivate(false); + im.hideWindows(); + } + im = next; + im.setLocale(locale); + im.setCharacterSubsets(subsets); + return true; + } + + /** + * Returns the current locale of the current input method or keyboard + * layout. Returns null if the input context does not have a current input + * method or keyboard layout or if the current input method's + * {@link InputMethod#getLocale()} method returns null. Not all host + * operating systems provide API to determine the locale of the currently + * selected native input method or keyboard layout. For host operating + * systems that don't provide such API, getLocale assumes that the current + * locale of all native input methods or keyboard layouts provided by the + * host operating system is the system's default locale. + * + * @return the locale of the current input method, or null + * @since 1.3 + */ + public Locale getLocale() + { + return im == null ? null : im.getLocale(); + } + + /** + * Sets the subsets of Unicode characters allowed to be input by the current + * input method, as well as subsequent input methods. The value of null + * implies all characters are legal. Applications should not rely on this + * behavior, since native host input methods may not allow restrictions. + * If no current input method is available, this has no immediate effect. + * + * @param subsets the set of Unicode subsets to accept, or null + */ + public void setCharacterSubsets(Character.Subset[] subsets) + { + this.subsets = subsets; + if (im != null) + im.setCharacterSubsets(subsets); + } + + /** + * Changes the enabled status of the current input method. An input method + * that is enabled for composition interprets incoming events for both + * composition and control purposes, while a disabled input method only + * interprets control commands (including commands to enable itself). + * + * @param enable whether to enable the input method + * @throws UnsupportedOperationException if there is no current input method, + * or the input method does not support enabling + * @see #isCompositionEnabled() + * @since 1.3 + */ + public void setCompositionEnabled(boolean enable) + { + if (im == null) + throw new UnsupportedOperationException(); + im.setCompositionEnabled(enable); + } + + /** + * Find out if the current input method is enabled. + * + * @return true if the current input method is enabled + * @throws UnsupportedOperationException if there is no current input method, + * or the input method does not support enabling + * @see #setCompositionEnabled(boolean) + * @since 1.3 + */ + public boolean isCompositionEnabled() + { + if (im == null) + throw new UnsupportedOperationException(); + return im.isCompositionEnabled(); + } + + /** + * Starts a reconversion operation in the current input method. The input + * method gets theh text to reconvert from the client component, using + * {@link InputMethodRequests#getSelectedText(Attribute[])}. Then the + * composed and committed text produced by the operation is sent back to + * the client using a sequence of InputMethodRequests. + * + * @throws UnsupportedOperationException if there is no current input method, + * or the input method does not support reconversion + * @throws UnsupportedOperationException if ther + * @since 1.3 + */ + public void reconvert() + { + if (im == null) + throw new UnsupportedOperationException(); + im.reconvert(); + } + + /** + * Dispatches an event to the current input method. This is called + * automatically by AWT. If no input method is available, then the event + * will never be consumed. + * + * @param event the event to dispatch + * @throws NullPointerException if event is null + */ + public void dispatchEvent(AWTEvent event) + { + if (im != null) + im.dispatchEvent(event); + } + + /** + * Notifies the input context that a client component has been removed from + * its containment hierarchy, or that input method support has been disabled + * for the component. This method is usually called from the client + * component's {@link Component#removeNotify()} method. Potentially pending + * input from input methods for this component is discarded. If no input + * methods are available, then this method has no effect. + * + * @param client the client component + * @throws NullPointerException if client is null + */ + public void removeNotify(Component client) + { + // XXX What to do with client information? + if (im != null) + { + im.deactivate(false); + im.removeNotify(); + } + } + + /** + * Ends any input composition that may currently be going on in this + * context. Depending on the platform and possibly user preferences, this + * may commit or delete uncommitted text. Any changes to the text are + * communicated to the active component using an input method event. If no + * input methods are available, then this method has no effect. This may + * be called for a variety of reasons, such as when the user moves the + * insertion point in the client text outside the range of the composed text, + * or when text is saved to file. + */ + public void endComposition() + { + if (im != null) + im.endComposition(); + } + + /** + * Disposes of the input context and release the resources used by it. + * Called automatically by AWT for the default input context of each + * Window. If no input methods are available, then this method has no + * effect. + */ + public void dispose() + { + if (im != null) + { + im.deactivate(false); + im.dispose(); + } + } + + /** + * Returns a control object from the current input method, or null. A + * control object provides implementation-dependent methods that control + * the behavior of the input method or obtain information from the input + * method. Clients have to compare the result against known input method + * control object types. If no input methods are available or the current + * input method does not provide an input method control object, then null + * is returned. + * + * @return the control object, or null + */ + public Object getInputMethodControlObject() + { + return im == null ? null : im.getControlObject(); + } +} // class InputContext diff --git a/libjava/java/awt/im/InputMethodHighlight.java b/libjava/java/awt/im/InputMethodHighlight.java new file mode 100644 index 00000000000..5398fc5de77 --- /dev/null +++ b/libjava/java/awt/im/InputMethodHighlight.java @@ -0,0 +1,185 @@ +/* InputMethodHighlight.java -- highlights the current text selection + 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.im; + +import java.util.Map; + +/** + * This describes the highlight attributes of text composed in an input method. + * The description includes an abstract level (whether text has been converted + * yet, and whether it is selected), and a concrete level (which style + * attributes are used in rendering). If no concrete level is defined, the + * renderer should use + * {@link Toolkit#mapInputMethodHighlight(InputMethodHighlight)}. An example + * of conversion state is kana -> kanji. + * + * <p>Instances of this class are typically used in + * AttributedCharacterIterators, and may be wrapped in Annotations to separate + * text segments. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see AttributedCharacterIterators + * @see Annotation + * @since 1.2 + * @status updated to 1.4 + */ +public class InputMethodHighlight +{ + /** Raw text state (before conversion). */ + public static final int RAW_TEXT = 0; + + /** Converted text state (after conversion). */ + public static final int CONVERTED_TEXT = 1; + + /** Default do-nothing highlighting for unselected raw text. */ + public static final InputMethodHighlight UNSELECTED_RAW_TEXT_HIGHLIGHT + = new InputMethodHighlight(false, RAW_TEXT); + + /** Default do-nothing highlighting for selected raw text. */ + public static final InputMethodHighlight SELECTED_RAW_TEXT_HIGHLIGHT + = new InputMethodHighlight(true, RAW_TEXT); + + /** Default do-nothing highlighting for unselected converted text. */ + public static final InputMethodHighlight UNSELECTED_CONVERTED_TEXT_HIGHLIGHT + = new InputMethodHighlight(false, CONVERTED_TEXT); + + /** Default do-nothing highlighting for selected converted text. */ + public static final InputMethodHighlight SELECTED_CONVERTED_TEXT_HIGHLIGHT + = new InputMethodHighlight(true, CONVERTED_TEXT); + + /** Whether the highlighting applies to selected text. */ + private final boolean selected; + + /** The state of highlighted text. */ + private final int state; + + /** Any variation on the highlighting style. */ + private final int variation; + + /** The unmodifiable map of rendering styles. */ + private final Map style; + + /** + * Create an input method highlight style, with variation 0 and null style + * mapping. + * + * @param selected whether the text range is selected + * @param state either {@link #RAW_TEXT} or {@link #CONVERTED_TEXT} + * @throws IllegalArgumentException if state is invalid + */ + public InputMethodHighlight(boolean selected, int state) + { + this(selected, state, 0, null); + } + + /** + * Create an input method highlight style, with null style mapping. + * + * @param selected whether the text range is selected + * @param state either {@link #RAW_TEXT} or {@link #CONVERTED_TEXT} + * @param variation the style variation + * @throws IllegalArgumentException if state is invalid + */ + public InputMethodHighlight(boolean selected, int state, int variation) + { + this(selected, state, variation, null); + } + + /** + * Create an input method highlight style. + * + * @param selected whether the text range is selected + * @param state either {@link #RAW_TEXT} or {@link #CONVERTED_TEXT} + * @param variation the style variation + * @param style an unmodifiable map of rendering styles, or null + * @throws IllegalArgumentException if state is invalid + * @since 1.3 + */ + public InputMethodHighlight(boolean selected, int state, int variation, + Map style) + { + if (state != RAW_TEXT && state != CONVERTED_TEXT) + throw new IllegalArgumentException(); + this.selected = selected; + this.state = state; + this.variation = variation; + this.style = style; + } + + /** + * Return whether the highlighting applies to selected text. + * + * @return the selection status + */ + public boolean isSelected() + { + return selected; + } + + /** + * Return the conversion state of the highlighted text. + * + * @return one of {@link #RAW_TEXT} or {@link #CONVERTED_TEXT} + */ + public int getState() + { + return state; + } + + /** + * Return the highlighting style variation. + * + * @return the variation + */ + public int getVariation() + { + return variation; + } + + /** + * Return the rendering style attributes map, or null if it should be the + * default mapping. + * + * @return the style map + * @since 1.3 + */ + public Map getSytle() + { + return style; + } +} // class InputMethodHighlight diff --git a/libjava/java/awt/im/InputMethodRequests.java b/libjava/java/awt/im/InputMethodRequests.java new file mode 100644 index 00000000000..88253ed6237 --- /dev/null +++ b/libjava/java/awt/im/InputMethodRequests.java @@ -0,0 +1,153 @@ +/* InputMethodRequests.java -- handles text insertion via input methods + 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.im; + +import java.awt.Rectangle; +import java.awt.font.TextHitInfo; +import java.text.AttributedCharacterIterator; +import java.text.AttributedCharacterIterator.Attribute; + +/** + * This interface handles requests made by input methods on text editing + * components. A component must specify a handler for input methods that + * implements this interface, and which supports one of two user interfaces: + * <ul><li><em>on-the-spot</em>: composed text is shown in place</li> + * <li><em>below-the-spot</em>: composed text is in a separate window, + * usually below the main text window, until it is committed into place at + * the insertion point, overwriting any selected text</li></ul> + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Component#getInputMethodRequests() + * @see InputMethodListener + * @since 1.2 + * @status updated to 1.4 + */ +public interface InputMethodRequests +{ + /** + * Gets the location of a given offset of the text. This can be used to + * position a composition window near the location of where the composed + * text will be inserted. + * + * <p>If the component has composed text (from the most recent + * InputMethodEvent), then offset 0 indicates the location of the first + * character of this composed text. Otherwise, the offset is ignored, and + * the location should be the beginning of the final line of selected + * text (in horizontal left-to-right text, like English, this would be the + * lower left corner of the selction; in vertical top-to-bottom text, like + * Chinese, this would be the top right corner of the selection). + * + * <p>The location returned is a 0-thickness caret (either horizontal or + * vertical, depending on text flow), mapped to absolute screen coordinates. + * + * @param offset offset within composed text, or null + * @return the screen location of the caret at the offset + */ + Rectangle getTextLocation(TextHitInfo offset); + + /** + * Get the text offset for the given screen coordinate. The offset is + * relative to the composed text, and the return is null if it is outside + * the range of composed text. For example, this can be used to find + * where a mouse click should pop up a text composition window. + * + * @param x the x screen coordinate + * @param y the y screen coordinate + * @return a text hit info describing the composed text offset + */ + TextHitInfo getLocationOffset(int x, int y); + + /** + * Gets the offset where the committed text exists in the text editing + * component. This can be used to examine the text surrounding the insert + * position. + * + * @return the offset of the insert position + */ + int getInsertPositionOffset(); + + /** + * Gets an interator which provides access to the text and its attributes, + * except for the uncommitted text. The input method may provide a list of + * attributes it is interested in; and the iterator need not provide + * information on the remaining attributes. If the attribute list is null, + * the iterator must list all attributes. + * + * @param beginIndex the index of the first character in the iteration + * @param endIndex the index of the last character in the iteration + * @param attributes a list of attributes interested in, or null + * @return an iterator over the region of text with its attributes + */ + AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex, + Attribute[] attributes); + + /** + * Gets the length of committed text. + * + * @return the number of committed characters + */ + int getCommittedTextLength(); + + /** + * Gets the latest committed text, and removes it from the component's text + * body. This allows an input method to provide an "Undo" command. In + * general, this should only be supported immediately after a commit, and + * not when other actions intervene; if not supported, simply return null. + * The input method may provide a list of attributes it is interested in; + * and the iterator need not provide information on the remaining attributes. + * If the attribute list is null, the iterator must list all attributes. + * + * @param attributes a list of attributes interested in, or null + * @return the latest committed text, or null + */ + AttributedCharacterIterator cancelLatestCommittedText + (Attribute[] attributes); + + /** + * Gets the currently selected text. One use of this is to implement a + * "Reconvert" feature in an input method, which modifies the selection + * based on the text in the composition window. The input method may + * provide a list of attributes it is interested in; and the iterator need + * not provide information on the remaining attributes. If the attribute + * list is null, the iterator must list all attributes. + * + * @param attributes a list of attributes interested in, or null + * @return the current selection + */ + AttributedCharacterIterator getSelectedText(Attribute[] attributes); +} // interface InputMethodRequests diff --git a/libjava/java/awt/im/InputSubset.java b/libjava/java/awt/im/InputSubset.java new file mode 100644 index 00000000000..10755fd49c7 --- /dev/null +++ b/libjava/java/awt/im/InputSubset.java @@ -0,0 +1,129 @@ +/* InputSubset.java -- subsets of Unicode important in text input + 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.im; + +/** + * Defines additional Unicode character blocks for use by input methods. + * These constants encompass several Unicode blocks, or portions thereof, for + * simplification over {@link Character.UnicodeBlock}. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @since 1.2 + * @status updated to 1.4 + */ +public final class InputSubset extends java.lang.Character.Subset +{ // XXX - FIXME Use fully qualified extends as gcj 3.1 workaround. + /** + * Constant for all Latin characters, including the characters in the + * BASIC_LATIN, LATIN_1_SUPPLEMENT, LATIN_EXTENDED_A, LATIN_EXTENDED_B + * Unicode character blocks. + */ + public static final InputSubset LATIN = new InputSubset("LATIN"); + + /** + * Constant for the digits included in the BASIC_LATIN Unicode character + * block. + */ + public static final InputSubset LATIN_DIGITS + = new InputSubset("LATIN_DIGITS"); + + /** + * Constant for all Han characters used in writing Traditional Chinese, + * including a subset of the CJK unified ideographs as well as Traditional + * Chinese Han characters that may be defined as surrogate characters. + */ + public static final InputSubset TRADITIONAL_HANZI + = new InputSubset("TRADITIONAL_HANZI"); + + /** + * Constant for all Han characters used in writing Simplified Chinese, + * including a subset of the CJK unified ideographs as well as Simplified + * Chinese Han characters that may be defined as surrogate characters. + */ + public static final InputSubset SIMPLIFIED_HANZI + = new InputSubset("SIMPLIFIED_HANZI"); + + /** + * Constant for all Han characters used in writing Japanese, including a + * subset of the CJK unified ideographs as well as Japanese Han characters + * that may be defined as surrogate characters. + */ + public static final InputSubset KANJI = new InputSubset("KANJI"); + + /** + * Constant for all Han characters used in writing Korean, including a + * subset of the CJK unified ideographs as well as Korean Han characters + * that may be defined as surrogate characters. + */ + public static final InputSubset HANJA = new InputSubset("HANJA"); + + /** + * Constant for the halfwidth katakana subset of the Unicode halfwidth and + * fullwidth forms character block. + */ + public static final InputSubset HALFWIDTH_KATAKANA + = new InputSubset("HALFWIDTH_KATAKANA"); + + /** + * Constant for the fullwidth ASCII variants subset of the Unicode + * halfwidth and fullwidth forms character block. + * + * @since 1.3 + */ + public static final InputSubset FULLWIDTH_LATIN + = new InputSubset("FULLWIDTH_LATIN"); + + /** + * Constant for the fullwidth digits included in the Unicode halfwidth and + * fullwidth forms character block. + * + * @since 1.3 + */ + public static final InputSubset FULLWIDTH_DIGITS + = new InputSubset("FULLWIDTH_DIGITS"); + + /** + * Construct a subset. + * + * @param name the subset name + */ + private InputSubset(String name) + { + super(name); + } +} // class InputSubset diff --git a/libjava/java/awt/image/BufferStrategy.java b/libjava/java/awt/image/BufferStrategy.java new file mode 100644 index 00000000000..88d4912307f --- /dev/null +++ b/libjava/java/awt/image/BufferStrategy.java @@ -0,0 +1,55 @@ +/* BufferStrategy.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.image; + +import java.awt.BufferCapabilities; +import java.awt.Graphics; + +/** STUBS ONLY */ +public abstract class BufferStrategy +{ + public BufferStrategy() + { + } + public abstract BufferCapabilities getCapabilities(); + public abstract Graphics getDrawGraphics(); + public abstract boolean contentsLost(); + public abstract boolean contentsRestored(); + public abstract void show(); +} // class BufferStrategy diff --git a/libjava/java/awt/image/BufferedImageOp.java b/libjava/java/awt/image/BufferedImageOp.java new file mode 100644 index 00000000000..b1b7575df7f --- /dev/null +++ b/libjava/java/awt/image/BufferedImageOp.java @@ -0,0 +1,55 @@ +/* BufferedImageOp.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.image; + +import java.awt.RenderingHints; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +/** + * NEEDS DOCUMENTATION + */ +public interface BufferedImageOp +{ + BufferedImage filter(BufferedImage src, BufferedImage dst); + Rectangle2D getBounds2D(BufferedImage src); + BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM); + Point2D getPoint2D(Point2D src, Point2D dst); + RenderingHints getRenderingHints(); +} // interface BufferedImageOp diff --git a/libjava/java/awt/image/ImagingOpException.java b/libjava/java/awt/image/ImagingOpException.java new file mode 100644 index 00000000000..28c3df132cc --- /dev/null +++ b/libjava/java/awt/image/ImagingOpException.java @@ -0,0 +1,66 @@ +/* ImagingOpException.java -- indicates an imaging filter failure + 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.image; + +/** + * This exception is thrown when <code>BufferedImageOp</code> or + * <code>RasterOp</code> filters cannot process an image. + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see BufferedImageOp + * @see RasterOp + * @status updated to 1.4 + */ +public class ImagingOpException extends RuntimeException +{ + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = 96598996116164315L; + + /** + * Create a new instance with a descriptive error message. + * + * @param message the descriptive error message + */ + public ImagingOpException(String message) + { + super(message); + } +} // class ImagingOpException diff --git a/libjava/java/awt/image/IndexColorModel.java b/libjava/java/awt/image/IndexColorModel.java index 34b9f7298f5..3e56f85e79f 100644 --- a/libjava/java/awt/image/IndexColorModel.java +++ b/libjava/java/awt/image/IndexColorModel.java @@ -1,355 +1,271 @@ -/* Copyright (C) 2000 Free Software Foundation +/* IndexColorModel.java -- Java class for interpreting Pixel objects + Copyright (C) 1999 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ +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. -package java.awt.image; +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. */ -import java.awt.Transparency; -import java.awt.color.ColorSpace; -import gnu.java.awt.Buffers; + +package java.awt.image; /** - * @author Rolf W. Rasmussen <rolfwr@ii.uib.no> + * + * @author C. Brian Jones (cbj@gnu.org) */ public class IndexColorModel extends ColorModel { - private byte[] r; - private byte[] g; - private byte[] b; - private byte[] a; - private int[] argb; - private byte[] cmap; - private int start; - private int transparent; - private int size; - - public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b) - { - super(bits, nArray(bits, 3), - ColorSpace.getInstance(ColorSpace.CS_sRGB), - false, // no transparency - false, // no premultiplied - Transparency.OPAQUE, - Buffers.smallestAppropriateTransferType(bits)); - this.r = r; - this.g = g; - this.b = b; - this.size = size; - } + private int map_size; + private boolean opaque; + private int trans = -1; - public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b, - int transparent) - { - super(bits, nArray(bits, 4), - ColorSpace.getInstance(ColorSpace.CS_sRGB), - true, // has transparency - false, - Transparency.BITMASK, - Buffers.smallestAppropriateTransferType(bits)); - this.r = r; - this.g = g; - this.b = b; - this.transparent = transparent; - this.size = size; - } + private int[] rgb; - public IndexColorModel(int bits, int size, byte[] r, byte[] g, byte[] b, - byte[] a) - { - super(bits, nArray(bits, 4), - ColorSpace.getInstance(ColorSpace.CS_sRGB), - true, // has transparency - false, - Transparency.BITMASK, - Buffers.smallestAppropriateTransferType(bits)); - this.r = r; - this.g = g; - this.b = b; - this.a = a; - this.size = size; - } + /** + * Each array much contain <code>size</code> elements. For each + * array, the i-th color is described by reds[i], greens[i], + * blues[i], alphas[i], unless alphas is not specified, then all the + * colors are opaque except for the transparent color. + * + * @param bits the number of bits needed to represent <code>size</code> colors + * @param size the number of colors in the color map + * @param reds the red component of all colors + * @param greens the green component of all colors + * @param blues the blue component of all colors + */ + public IndexColorModel(int bits, int size, byte[] reds, byte[] greens, + byte[] blues) { + this(bits, size, reds, greens, blues, (byte[])null); + } - public IndexColorModel(int bits, int size, byte[] cmap, int start, - boolean hasAlpha) - { - super(bits, nArray(bits, hasAlpha ? 4 : 3), - ColorSpace.getInstance(ColorSpace.CS_sRGB), - hasAlpha, - false, - hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE, - Buffers.smallestAppropriateTransferType(bits)); - this.cmap = cmap; - this.start = start; - this.size = size; - } + /** + * Each array much contain <code>size</code> elements. For each + * array, the i-th color is described by reds[i], greens[i], + * blues[i], alphas[i], unless alphas is not specified, then all the + * colors are opaque except for the transparent color. + * + * @param bits the number of bits needed to represent <code>size</code> colors + * @param size the number of colors in the color map + * @param reds the red component of all colors + * @param greens the green component of all colors + * @param blues the blue component of all colors + * @param trans the index of the transparent color + */ + public IndexColorModel(int bits, int size, byte[] reds, byte[] greens, + byte[] blues, int trans) { + this(bits, size, reds, greens, blues, (byte[])null); + this.trans = trans; + } - public IndexColorModel(int bits, int size, byte[] cmap, int start, - boolean hasAlpha, int transparent, - int transferType) - { - super(bits, nArray(bits, hasAlpha ? 4 : 3), - ColorSpace.getInstance(ColorSpace.CS_sRGB), - hasAlpha, - false, - hasAlpha ? - Transparency.TRANSLUCENT : - ((transparent < 0) ? - Transparency.OPAQUE : - Transparency.BITMASK), - transferType); - this.cmap = cmap; - this.start = start; - this.size = size; - } + /** + * Each array much contain <code>size</code> elements. For each + * array, the i-th color is described by reds[i], greens[i], + * blues[i], alphas[i], unless alphas is not specified, then all the + * colors are opaque except for the transparent color. + * + * @param bits the number of bits needed to represent <code>size</code> colors + * @param size the number of colors in the color map + * @param reds the red component of all colors + * @param greens the green component of all colors + * @param blues the blue component of all colors + * @param alphas the alpha component of all colors + */ + public IndexColorModel(int bits, int size, byte[] reds, byte[] greens, + byte[] blues, byte[] alphas) { + super(bits); + map_size = size; + opaque = (alphas == null); - public final int getMapSize() - { - return size; - } - - public final int getTransparentPixel() - { - return transparent; - } + rgb = new int[size]; + if (alphas == null) { + for (int i = 0; i < size; i++) { + rgb[i] = 0xff000000 | + ((reds[i] & 0xff) << 16) | + ((greens[i] & 0xff) << 8) | + (blues[i] & 0xff); + } + } + else { + for (int i = 0; i < size; i++) { + rgb[i] = ((alphas[i] & 0xff) << 24 | + ((reds[i] & 0xff) << 16) | + ((greens[i] & 0xff) << 8) | + (blues[i] & 0xff)); + } + } + } - public final void getReds(byte r[]) - { - if (this.r == null) calcRGBArrays(); - System.arraycopy(this.r, 0, r, 0, getMapSize()); - } - - public final void getGreens(byte g[]) - { - if (this.g == null) calcRGBArrays(); - System.arraycopy(this.g, 0, g, 0, getMapSize()); - } - - public final void getBlues(byte b[]) - { - if (this.b == null) calcRGBArrays(); - System.arraycopy(this.b, 0, b, 0, getMapSize()); - } + /** + * Each array much contain <code>size</code> elements. For each + * array, the i-th color is described by reds[i], greens[i], + * blues[i], alphas[i], unless alphas is not specified, then all the + * colors are opaque except for the transparent color. + * + * @param bits the number of bits needed to represent <code>size</code> colors + * @param size the number of colors in the color map + * @param cmap packed color components + * @param start the offset of the first color component in <code>cmap</code> + * @param hasAlpha <code>cmap</code> has alpha values + */ + public IndexColorModel(int bits, int size, byte[] cmap, int start, + boolean hasAlpha) { + this(bits, size, cmap, start, hasAlpha, -1); + } - public final void getAlphas(byte a[]) - { - if (this.a == null) calcAlphaArray(); - System.arraycopy(this.a, 0, a, 0, getMapSize()); - } + /** + * Each array much contain <code>size</code> elements. For each + * array, the i-th color is described by reds[i], greens[i], + * blues[i], alphas[i], unless alphas is not specified, then all the + * colors are opaque except for the transparent color. + * + * @param bits the number of bits needed to represent <code>size</code> colors + * @param size the number of colors in the color map + * @param cmap packed color components + * @param start the offset of the first color component in <code>cmap</code> + * @param hasAlpha <code>cmap</code> has alpha values + * @param trans the index of the transparent color + */ + public IndexColorModel(int bits, int size, byte[] cmap, int start, + boolean hasAlpha, int trans) { + super(bits); + map_size = size; + opaque = !hasAlpha; + this.trans = trans; + } - public final void getRGBs(int rgb[]) - { - if (this.argb == null) calcARGBArray(); - System.arraycopy(this.argb, 0, rgb, 0, getMapSize()); - } + public final int getMapSize() { + return map_size; + } - public int getRed(int pixel) - { - try - { - return r[pixel]; - } - catch (NullPointerException npe) - { - calcRGBArrays(); - return r[pixel]; - } - } + /** + * Get the index of the transparent color in this color model + */ + public final int getTransparentPixel() { + return trans; + } - public int getGreen(int pixel) - { - try - { - return g[pixel]; - } - catch (NullPointerException npe) - { - calcRGBArrays(); - return g[pixel]; - } - } + /** + * <br> + */ + public final void getReds(byte[] r) { + getComponents( r, 2 ); + } - public int getBlue(int pixel) - { - try - { - return b[pixel]; - } - catch (NullPointerException npe) - { - calcRGBArrays(); - return b[pixel]; - } - } - - public int getAlpha(int pixel) - { - try - { - return a[pixel]; - } - catch (NullPointerException npe) - { - calcAlphaArray(); - return a[pixel]; - } - } + /** + * <br> + */ + public final void getGreens(byte[] g) { + getComponents( g, 1 ); + } - private void calcRGBArrays() { - int j=0; - boolean hasAlpha = hasAlpha(); - r = new byte[size]; - g = new byte[size]; - b = new byte[size]; - if (hasAlpha) a = new byte[size]; - - for (int i=0; i<size; i++) - { - r[i] = cmap[j++]; - g[i] = cmap[j++]; - b[i] = cmap[j++]; - if (hasAlpha()) a[i] = cmap[j++]; - } - } + /** + * <br> + */ + public final void getBlues(byte[] b) { + getComponents( b, 0 ); + } - private void calcAlphaArray() - { - int transparency = getTransparency(); - switch (transparency) - { - case Transparency.OPAQUE: - case Transparency.BITMASK: - a = nArray((byte) 255, size); - if (transparency == Transparency.BITMASK) - a[transparent] = 0; - break; - case Transparency.TRANSLUCENT: - calcRGBArrays(); - } - } + /** + * <br> + */ + public final void getAlphas(byte[] a) { + getComponents( a, 3 ); + } - private void calcARGBArray() - { - int mapSize = getMapSize(); - argb = new int[mapSize]; - for (int p=0; p<mapSize; p++) argb[p] = getRGB(p); - } - - public int getRed(Object inData) - { - return getRed(getPixelFromArray(inData)); - } + private void getComponents( byte[] c, int ci ) + { + int i, max = ( map_size < c.length ) ? map_size : c.length; + for( i = 0; i < max; i++ ) + c[i] = (byte)(( generateMask( ci ) & rgb[i]) >> ( ci * pixel_bits) ); + } - public int getGreen(Object inData) - { - return getGreen(getPixelFromArray(inData)); - } + /** + * Get the red component of the given pixel. + * <br> + */ + public final int getRed(int pixel) { + if( pixel < map_size ) + return (int)(( generateMask( 2 ) & rgb[pixel]) >> (2 * pixel_bits ) ); + return 0; + } - public int getBlue(Object inData) - { - return getBlue(getPixelFromArray(inData)); - } - - public int getAlpha(Object inData) - { - return getAlpha(getPixelFromArray(inData)); - } + /** + * Get the green component of the given pixel. + * <br> + */ + public final int getGreen(int pixel) { + if( pixel < map_size ) + return (int)(( generateMask( 1 ) & rgb[pixel]) >> (1 * pixel_bits ) ); + return 0; + } - public int getRGB(Object inData) - { - return getRGB(getPixelFromArray(inData)); - } + /** + * Get the blue component of the given pixel. + * <br> + */ + public final int getBlue(int pixel) { + if( pixel < map_size ) + return (int)( generateMask( 0 ) & rgb[pixel]); + return 0; + } - public Object getDataElements(int rgb, Object pixel) - { - int av, rv, gv, bv; - // using 8 bit values - av = (rgb >>> 24) & 0xff; - rv = (rgb >>> 16) & 0xff; - gv = (rgb >>> 8) & 0xff; - bv = (rgb >>> 0) & 0xff; - - int pixelValue = getPixelValue(av, rv, gv, bv); + /** + * Get the alpha component of the given pixel. + * <br> + */ + public final int getAlpha(int pixel) { + if( pixel < map_size ) + return (int)(( generateMask( 3 ) & rgb[pixel]) >> (3 * pixel_bits ) ); + return 0; + } - /* In this color model, the whole pixel fits in the first element - of the array. */ - DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1); - buffer.setElem(0, pixelValue); - return Buffers.getData(buffer); - } + /** + * Get the RGB color value of the given pixel using the default + * RGB color model. + * <br> + * + * @param pixel a pixel value + */ + public final int getRGB(int pixel) { + if( pixel < map_size ) + return rgb[pixel]; + return 0; + } - private int getPixelValue(int av, int rv, int gv, int bv) - { - if (r == null) calcRGBArrays(); - if (a == null) calcAlphaArray(); - - int minDAlpha = 1<<8; - int minDRGB = (1<<8)*(1<<8)*3; - int pixelValue = -1; - for (int i=0; i<size; i++) - { - int dAlpha = Math.abs(av-(a[i]&0xff)); - if (dAlpha > minDAlpha) continue; - int dR = rv-(r[i]&0xff); - int dG = gv-(g[i]&0xff); - int dB = bv-(b[i]&0xff); - int dRGB = dR*dR + dG*dG + dB*dB; - - if (dRGB >= minDRGB) continue; - - pixelValue = i; - minDRGB = dRGB; - } - return pixelValue; - } + //pixel_bits is number of bits to be in generated mask + private int generateMask( int offset ) + { + return ( ( ( 2 << pixel_bits ) - 1 ) << ( pixel_bits * offset ) ); + } - public int[] getComponents(int pixel, int[] components, int offset) - { - int numComponents = getNumComponents(); - if (components == null) components = new int[offset + numComponents]; - components[offset++] = (r[pixel]&0xff); - components[offset++] = (g[pixel]&0xff); - components[offset++] = (b[pixel]&0xff); - if (hasAlpha()) components[offset++] = (a[pixel]&0xff); - return components; - } - - public final int[] getComponents(Object pixel, int[] components, - int offset) - { - return getComponents(getPixelFromArray(pixel), components, offset); - } - - public int getDataElement(int[] components, int offset) - { - int r = components[offset++]; - int g = components[offset++]; - int b = components[offset++]; - int a = hasAlpha() ? components[offset++] : 255; - - return getPixelValue(a, r, g, b); - } - - public Object getDataElements(int[] components, int offset, Object pixel) - { - int pixelValue = getDataElement(components, offset); - - /* In this color model, the whole pixel fits in the first element - of the array. */ - DataBuffer buffer = Buffers.createBuffer(transferType, pixel, 1); - buffer.setElem(0, pixelValue); - return Buffers.getData(buffer); - } - - public SampleModel createCompatibleSampleModel(int w, int h) - { - int[] bandOffsets = {0}; - return new ComponentSampleModel(transferType, w, h, - 1, // pixel stride - w, // scanline stride - bandOffsets); - } } + diff --git a/libjava/java/awt/image/MemoryImageSource.java b/libjava/java/awt/image/MemoryImageSource.java index d36d000437d..fce112a0656 100644 --- a/libjava/java/awt/image/MemoryImageSource.java +++ b/libjava/java/awt/image/MemoryImageSource.java @@ -312,7 +312,10 @@ public class MemoryImageSource implements ImageProducer int scansize) { - // FIXME + if( animated == true ) + { + //FIXME + } } public synchronized void newPixels(int newpix[], @@ -321,7 +324,10 @@ public class MemoryImageSource implements ImageProducer int scansize) { - // FIXME + if( animated == true ) + { + //FIXME + } } } diff --git a/libjava/java/awt/image/PixelGrabber.java b/libjava/java/awt/image/PixelGrabber.java index 65e831e9809..24dd6d3fc49 100644 --- a/libjava/java/awt/image/PixelGrabber.java +++ b/libjava/java/awt/image/PixelGrabber.java @@ -151,7 +151,7 @@ public class PixelGrabber implements ImageConsumer @return true if successful - @throws InterruptedExcpetion if interrupted by another thread. + @throws InterruptedException if interrupted by another thread. */ public boolean grabPixels() throws InterruptedException { @@ -163,7 +163,7 @@ public class PixelGrabber implements ImageConsumer @return true if successful - @throws InterruptedExcpetion if interrupted by another thread. + @throws InterruptedException if interrupted by another thread. or time runs out */ public synchronized boolean grabPixels(long ms) throws InterruptedException diff --git a/libjava/java/awt/image/RasterFormatException.java b/libjava/java/awt/image/RasterFormatException.java new file mode 100644 index 00000000000..3a29877476b --- /dev/null +++ b/libjava/java/awt/image/RasterFormatException.java @@ -0,0 +1,65 @@ +/* RasterFormatException.java -- indicates invalid layout in Raster + 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.image; + +/** + * This exception is thrown when there is invalid layout information in + * <code>Raster</code> + * + * @author Eric Blake <ebb9@email.byu.edu> + * @see Raster + * @status updated to 1.4 + */ +public class RasterFormatException extends RuntimeException +{ + /** + * Compatible with JDK 1.0+. + */ + private static final long serialVersionUID = 96598996116164315L; + + /** + * Create a new instance with a descriptive error message. + * + * @param message the descriptive error message + */ + public RasterFormatException(String message) + { + super(message); + } +} // class RasterFormatException diff --git a/libjava/java/awt/image/RenderedImage.java b/libjava/java/awt/image/RenderedImage.java new file mode 100644 index 00000000000..f38b44a94d2 --- /dev/null +++ b/libjava/java/awt/image/RenderedImage.java @@ -0,0 +1,70 @@ +/* RenderedImage.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.image; + +import java.awt.Rectangle; +import java.util.Vector; + +/** + * NEEDS DOCUMENTATION + */ +public interface RenderedImage +{ + Vector getSources(); + Object getProperty(String name); + String[] getPropertyNames(); + ColorModel getColorModel(); + SampleModel getSampleModel(); + int getWidth(); + int getHeight(); + int getMinX(); + int getMinY(); + int getNumXTiles(); + int getNumYTiles(); + int getMinTileX(); + int getMinTileY(); + int getTileWidth(); + int getTileHeight(); + int getTileGridXOffset(); + int getTileGridYOffset(); + Raster getTile(int x, int y); + Raster getData(); + Raster getData(Rectangle r); + WritableRaster copyData(WritableRaster raster); +} // interface RenderedImage diff --git a/libjava/java/awt/image/TileObserver.java b/libjava/java/awt/image/TileObserver.java new file mode 100644 index 00000000000..b76217870ea --- /dev/null +++ b/libjava/java/awt/image/TileObserver.java @@ -0,0 +1,47 @@ +/* TileObserver.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.image; + +/** + * NEEDS DOCUMENTATION + */ +public interface TileObserver +{ + void tileUpdate(WritableRenderedImage src, int x, int y, boolean writable); +} // interface TileObserver diff --git a/libjava/java/awt/image/VolatileImage.java b/libjava/java/awt/image/VolatileImage.java new file mode 100644 index 00000000000..7455c2b17be --- /dev/null +++ b/libjava/java/awt/image/VolatileImage.java @@ -0,0 +1,74 @@ +/* VolatileImage.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.image; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.ImageCapabilities; + +/** STUBS ONLY */ +public abstract class VolatileImage extends Image +{ + public static final int IMAGE_OK = 0; + public static final int IMAGE_RESTORED = 1; + public static final int IMAGE_INCOMPLETE = 2; + public VolatileImage() + { + } + public abstract BufferedImage getSnapshot(); + public abstract int getWidth(); + public abstract int getHeight(); + public ImageProducer getSource() + { + return getSnapshot().getSource(); + } + public void flush() + { + } + public Graphics getGraphics() + { + return createGraphics(); + } + public abstract Graphics2D createGraphics(); + public abstract int validate(GraphicsConfiguration gc); + public abstract boolean contentsLost(); + public abstract ImageCapabilities getCapabilities(); +} // class VolatileImage diff --git a/libjava/java/awt/image/WritableRenderedImage.java b/libjava/java/awt/image/WritableRenderedImage.java new file mode 100644 index 00000000000..657d6fdb6a0 --- /dev/null +++ b/libjava/java/awt/image/WritableRenderedImage.java @@ -0,0 +1,56 @@ +/* WritableRenderedImage.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.image; + +import java.awt.Point; + +/** + * NEEDS DOCUMENTATION + */ +public interface WritableRenderedImage extends RenderedImage +{ + void addTileObserver(TileObserver to); + void removeTileObserver(TileObserver to); + WritableRaster getWritableTile(int x, int y); + void releaseWritableTile(int x, int y); + boolean isTileWritable(int x, int y); + Point[] getWritableTileIndices(); + boolean hasTileWriters(); + void setData(Raster r); +} // interface WritableRenderedImage diff --git a/libjava/java/awt/print/Book.java b/libjava/java/awt/print/Book.java new file mode 100644 index 00000000000..19014bacf6c --- /dev/null +++ b/libjava/java/awt/print/Book.java @@ -0,0 +1,188 @@ +/* Book.java -- A mixed group of pages to print. + Copyright (C) 1999 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.print; + +import java.util.Vector; + +/** + * This class allows documents to be created with different paper types, + * page formatters, and painters. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class Book implements Pageable +{ + +/* + * Instance Variables + */ + +// Painter objects for the book +Vector printables = new Vector(); + +// Page formats for the book +Vector page_formats = new Vector(); + +/*************************************************************************/ + +/* + * Constructors + */ + +/** + * Initializes a new instance of <code>Book</code> that is empty. + */ +public +Book() +{ + ; +} + +/*************************************************************************/ + +/** + * Returns the number of pages in this book. + * + * @return The number of pages in this book. + */ +public int +getNumberOfPages() +{ + return(printables.size()); +} + +/*************************************************************************/ + +/** + * This method returns the <code>PageFormat</code> object for the + * specified page. + * + * @param page_numbers The number of the page to get information for, where + * page numbers start at 0. + * + * @return The <code>PageFormat</code> object for the specified page. + * + * @exception IndexOutOfBoundsException If the page number is not valid. + */ +public PageFormat +getPageFormat(int page_number) +{ + return((PageFormat)page_formats.elementAt(page_number)); +} + +/*************************************************************************/ + +/** + * This method returns the <code>Printable</code> object for the + * specified page. + * + * @param page_numbers The number of the page to get information for, where + * page numbers start at 0. + * + * @return The <code>Printable</code> object for the specified page. + * + * @exception IndexOutOfBoundsException If the page number is not valid. + */ +public Printable +getPrintable(int page_number) +{ + return((Printable)printables.elementAt(page_number)); +} + +/*************************************************************************/ + +/** + * This method appends a page to the end of the book. + * + * @param printable The <code>Printable</code> for this page. + * @param page_format The <code>PageFormat</code> for this page. + * + * @exception NullPointerException If either argument is <code>null</code>. + */ +public void +append(Printable printable, PageFormat page_format) +{ + append(printable, page_format, 1); +} + +/*************************************************************************/ + +/** + * This method appends the specified number of pages to the end of the book. + * Each one will be associated with the specified <code>Printable</code> + * and <code>PageFormat</code>. + * + * @param printable The <code>Printable</code> for this page. + * @param page_format The <code>PageFormat</code> for this page. + * @param num_pages The number of pages to append. + * + * @exception NullPointerException If any argument is <code>null</code>. + */ +public void +append(Printable painter, PageFormat page_format, int num_pages) +{ + for (int i = 0; i < num_pages; i++) + { + printables.addElement(painter); + page_formats.addElement(page_format); + } +} + +/*************************************************************************/ + +/** + * This method changes the <code>Printable</code> and <code>PageFormat</code> + * for the specified page. The page must already exist or an exception + * will be thrown. + * + * @param page_num The page number to alter. + * @param printable The new <code>Printable</code> for the page. + * @param page_format The new <code>PageFormat</code> for the page. + * + * @param IndexOutOfBoundsException If the specified page does not exist. + */ +public void +setPage(int page_num, Printable printable, PageFormat page_format) +{ + printables.setElementAt(printable, page_num); + page_formats.setElementAt(page_format, page_num); +} + +} // class Book + diff --git a/libjava/java/awt/print/PageFormat.java b/libjava/java/awt/print/PageFormat.java new file mode 100644 index 00000000000..7328ab5287e --- /dev/null +++ b/libjava/java/awt/print/PageFormat.java @@ -0,0 +1,293 @@ +/* PageFormat.java -- Information about the page format + Copyright (C) 1999 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.print; + +/** + * This class contains information about the desired page format to + * use for printing a particular set of pages. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class PageFormat implements Cloneable +{ + +/* + * Static Variables + */ + +/** + * A constant for a landscaped page orientation. Used by + * <code>getOrientation</code> and <code>setOrientation</code>. + */ +public static final int LANDSCAPE = 0; + +/** + * A constant for a portrait page orientation. Used by + * <code>getOrientation</code> and <code>setOrientation</code>. + */ +public static final int PORTRAIT = 1; + +/** + * A constant for a reversed landscaped page orientation. This is + * the orientation used by Macintosh's for landscape. The origin is + * in the upper right hand corner instead of the upper left. The + * X and Y axes are reversed. Used by <code>getOrientation</code> and + * <code>setOrientation</code>. + */ +public static final int REVERSE_LANDSCAPE = 2; + +/*************************************************************************/ + +/* + * Instance Variables + */ + +// The page orientation +private int orientation; + +// The paper type +private Paper paper; + +/*************************************************************************/ + +/* + * Constructors + */ + +/** + * This method creates a default page layout, which will be in portrait + * format. + */ +public +PageFormat() +{ + this.paper = new Paper(); + this.orientation = PORTRAIT; +} + +/*************************************************************************/ + +/* + * Instance Methods + */ + +/** + * This method returns the width of the page, in 1/72nd's of an inch. The + * "width" measured depends on orientation. + * + * @return The width of the page. + */ +public double +getWidth() +{ + return(paper.getWidth()); +} + +/*************************************************************************/ + +/** + * This method returns the height of the page, in 1/72nd's of an inch. + * The "height" measured depends on the orientation. + * + * @return The height of the page. + */ +public double +getHeight() +{ + return(paper.getHeight()); +} + +/*************************************************************************/ + +/** + * This method returns the X coordinate value of the upper leftmost + * drawable area of the paper. + * + * @return The upper leftmost imageable X coordinate. + */ +public double +getImageableX() +{ + return(paper.getImageableX()); +} + +/*************************************************************************/ + +/** + * This method returns the Y coordinate value of the upper leftmost + * drawable area of the paper. + * + * @return The upper leftmost imageable Y coordinate. + */ +public double +getImageableY() +{ + return(paper.getImageableY()); +} + +/*************************************************************************/ + +/** + * This method returns the imageable width of the paper, in 1/72nd's of + * an inch. + * + * @return The imageable width of the paper. + */ +public double +getImageableWidth() +{ + return(paper.getImageableWidth()); +} + +/*************************************************************************/ + +/** + * This method returns the imageable height of the paper, in 1/72nd's of + * an inch. + * + * @return The imageable height of the paper. + */ +public double +getImageableHeigth() +{ + return(paper.getImageableHeight()); +} + +/*************************************************************************/ + +/** + * Returns a copy of the <code>paper</code> object being used for this + * page format. + * + * @return A copy of the <code>Paper</code> object for this format. + */ +public Paper +getPaper() +{ + return((Paper)paper.clone()); +} + +/*************************************************************************/ + +/** + * Sets the <code>Paper</code> object to be used by this page format. + * + * @param paper The new <code>Paper</code> object for this page format. + */ +public void +setPaper(Paper paper) +{ + this.paper = paper; +} + +/*************************************************************************/ + +/** + * This method returns the current page orientation. The value returned + * will be one of the page orientation constants from this class. + * + * @return The current page orientation. + */ +public int +getOrientation() +{ + return(orientation); +} + +/*************************************************************************/ + +/** + * This method sets the page orientation for this format to the + * specified value. It must be one of the page orientation constants + * from this class or an exception will be thrown. + * + * @param orientation The new page orientation. + * + * @exception IllegalArgumentException If the specified page orientation + * value is not one of the constants from this class. + */ +public void +setOrientation(int orientation) throws IllegalArgumentException +{ + if ((orientation != PORTRAIT) && + (orientation != LANDSCAPE) && + (orientation != REVERSE_LANDSCAPE)) + throw new IllegalArgumentException("Bad page orientation value: " + + orientation); + + this.orientation = orientation; +} + +/*************************************************************************/ + +/** + * This method returns a matrix used for transforming user space + * coordinates to page coordinates. The value returned will be six + * doubles as described in <code>java.awt.geom.AffineTransform</code>. + * + * @return The transformation matrix for this page format. + */ +public double[] +getMatrix() +{ + throw new RuntimeException("Not implemented since I don't know what to do"); +} + +/*************************************************************************/ + +/** + * This method returns a copy of this object. + * + * @return A copy of this object. + */ +public Object +clone() +{ + try + { + return(super.clone()); + } + catch(CloneNotSupportedException e) + { + return(null); + } +} + +} // class PageFormat + diff --git a/libjava/java/awt/print/Pageable.java b/libjava/java/awt/print/Pageable.java new file mode 100644 index 00000000000..fc631c5ce7b --- /dev/null +++ b/libjava/java/awt/print/Pageable.java @@ -0,0 +1,113 @@ +/* Pageable.java -- Pages to be printed + Copyright (C) 1999 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.print; + +/** + * This interface represents pages that are to be printed. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface Pageable +{ + +/* + * Static Variables + */ + +/** + * This constant is returned when <code>getNumberOfPages()</code> + * cannot determine the number of pages available for printing. + */ +public static final int UNKNOWN_NUMBER_OF_PAGES = -1; + +/*************************************************************************/ + +/* + * Instance Methods + */ + +/** + * This method returns the number of pages this object contains, or + * <code>UNKNOWN_NUMBER_OF_PAGES</code> if it cannot determine the number + * of pages to be printed. + * + * @return The number of pages to be printed, or + * <code>UNKNOWN_NUMBER_OF_PAGES</code> if this is unknown. + */ +public abstract int +getNumberOfPages(); + +/*************************************************************************/ + +/** + * This method returns the <code>PageFormat</code> instance for the + * specified page. Page numbers start at zero. An exception is thrown if + * the requested page does not exist. + * + * @param pageIndex The index of the page to return the + * <code>PageFormat</code> for. + * + * @return The <code>PageFormat</code> for the requested page. + * + * @exception IndexOutOfBoundsException If the requested page number does + * not exist. + */ +public abstract PageFormat +getPageFormat(int pageIndex) throws IndexOutOfBoundsException; + +/*************************************************************************/ + +/** + * This method returns the <code>Printable</code> instance for the + * specified page. Page numbers start at zero. An exception is thrown if + * the requested page does not exist. + * + * @param pageIndex The index of the page to return the + * <code>Printable</code> for. + * + * @return The <code>Printable</code> for the requested page. + * + * @exception IndexOutOfBoundsException If the requested page number does + * not exist. + */ +public abstract Printable +getPrintable(int pageIndex) throws IndexOutOfBoundsException; + +} // interface Pageable + diff --git a/libjava/java/awt/print/Paper.java b/libjava/java/awt/print/Paper.java new file mode 100644 index 00000000000..cba4aec23d1 --- /dev/null +++ b/libjava/java/awt/print/Paper.java @@ -0,0 +1,236 @@ +/* Paper.java -- Information about a paper type. + Copyright (C) 1999 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.print; + +/** + * This class describes a particular type of paper. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class Paper +{ + +/* + * Instance Variables + */ + +// Height of the paper +private double height; + +// Width of the paper +private double width; + +// Upper left imageable X coordinate +private double imageableX; + +// Upper left imageable Y coordinate +private double imageableY; + +// Imageable width of the page +private double imageableWidth; + +// Imageable height of the page +private double imageableHeight; + +/*************************************************************************/ + +/* + * Constructor + */ + +/** + * This method creates a letter sized paper with one inch margins + */ +public +Paper() +{ + width = 8.5 * 72; + height = 11 * 72; + imageableX = 72; + imageableY = 72; + imageableWidth = width - (2 * 72); + imageableHeight = height - (2 * 72); +} + +/*************************************************************************/ + +/** + * This method returns the height of the paper in 1/72nds of an inch. + * + * @return The height of the paper in 1/72nds of an inch. + */ +public double +getHeight() +{ + return(height); +} + +/*************************************************************************/ + +/** + * Returns the width of the paper in 1/72nds of an inch. + * + * @return The width of the paper in 1/72nds of an inch. + */ +public double +getWidth() +{ + return(width); +} + +/*************************************************************************/ + +/** + * This method returns the X coordinate of the upper left hand corner + * of the imageable area of the paper. + * + * @return The X coordinate of the upper left hand corner of the imageable + * area of the paper. + */ +public double +getImageableX() +{ + return(imageableX); +} + +/*************************************************************************/ + +/** + * This method returns the Y coordinate of the upper left hand corner + * of the imageable area of the paper. + * + * @return The Y coordinate of the upper left hand corner of the imageable + * area of the paper. + */ +public double +getImageableY() +{ + return(imageableY); +} + +/*************************************************************************/ + +/** + * Returns the width of the imageable area of the paper. + * + * @return The width of the imageable area of the paper. + */ +public double +getImageableWidth() +{ + return(imageableWidth); +} + +/*************************************************************************/ + +/** + * Returns the height of the imageable area of the paper. + * + * @return The height of the imageable area of the paper. + */ +public double +getImageableHeight() +{ + return(imageableHeight); +} + +/*************************************************************************/ + +/** + * This method sets the size of the paper to the specified width and + * height, which are specified in 1/72nds of an inch. + * + * @param width The width of the paper in 1/72nds of an inch. + * @param height The height of the paper in 1/72nds of an inch. + */ +public void +setSize(double width, double height) +{ + this.width = width; + this.height = height; +} + +/*************************************************************************/ + +/** + * This method sets the imageable area of the paper by specifying the + * coordinates of the upper left hand corner of that area, and its + * length and height. All values are in 1/72nds of an inch. + * + * @param imageableX The X coordinate of the upper left hand corner of + * the imageable area, in 1/72nds of an inch. + * @param imageableY The Y coordinate of the upper left hand corner of + * the imageable area, in 1/72nds of an inch. + * @param imageableWidth The width of the imageable area of the paper, + * in 1/72nds of an inch. + * @param imageableHeight The heigth of the imageable area of the paper, + * in 1/72nds of an inch. + */ +public void +setImageableArea(double imageableX, double imageableY, + double imageableWidth, double imageableHeight) +{ + this.imageableX = imageableX; + this.imageableY = imageableY; + this.imageableWidth = imageableWidth; + this.imageableHeight = imageableHeight; +} + +/*************************************************************************/ + +/** + * This method creates a copy of this object. + * + * @return A copy of this object. + */ +public Object +clone() +{ + try + { + return(super.clone()); + } + catch(CloneNotSupportedException e) + { + return(null); + } +} + +} // class Paper + diff --git a/libjava/java/awt/print/Printable.java b/libjava/java/awt/print/Printable.java new file mode 100644 index 00000000000..8f3d0b64e9e --- /dev/null +++ b/libjava/java/awt/print/Printable.java @@ -0,0 +1,90 @@ +/* Printable.java -- Renders a page to the print device + Copyright (C) 1999 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.print; + +import java.awt.Graphics; + +/** + * This interface provides a mechanism for the actual printing of pages to the + * printer. The object implementing this interface performs the page + * rendering. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface Printable +{ + +/* + * Static Variables + */ + +/** + * This value is returned by the <code>print()</code> method to indicate + * that the requested page number does not exist. + */ +public static final int NO_SUCH_PAGE = 0; + +/** + * This value is returned by the <code>print()</code> method to indicate + * that the requested page exists and has been printed. + */ +public static final int PAGE_EXISTS = 1; + +/*************************************************************************/ + +/** + * This method prints the specified page to the specified graphics + * context in the specified format. The pages are numbered starting + * from zero. + * + * @param graphics The graphics context to render the pages on. + * @param format The format in which to print the page. + * @param page_number The page number to print, where numbers start at zero. + * + * @return <code>PAGE_EXISTS</code> if the requested page exists and was + * successfully printed, <code>NO_SUCH_PAGE</code> otherwise. + * + * @exception PrinterException If an error occurs during printing. + */ +public abstract int +print(Graphics graphics, PageFormat format, int page_number) + throws PrinterException; + +} // interface Printable + diff --git a/libjava/java/awt/print/PrinterAbortException.java b/libjava/java/awt/print/PrinterAbortException.java new file mode 100644 index 00000000000..133fdfe116d --- /dev/null +++ b/libjava/java/awt/print/PrinterAbortException.java @@ -0,0 +1,71 @@ +/* PrinterAbortException.java -- Indicates the print job was aborted + Copyright (C) 1999, 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.print; + +/** + * This exception is thrown when the print job is aborted, either by the + * user or by the application. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @status updated to 1.4 + */ +public class PrinterAbortException extends PrinterException +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 4725169026278854136L; + + /** + * Create a new instance with no detailed error message. + */ + public PrinterAbortException() + { + } + + /** + * Create a new instance with a descriptive error message. + * + * @param message the descriptive error message + */ + public PrinterAbortException(String message) + { + super(message); + } +} // class PrinterAbortException diff --git a/libjava/java/awt/print/PrinterException.java b/libjava/java/awt/print/PrinterException.java new file mode 100644 index 00000000000..9476d935674 --- /dev/null +++ b/libjava/java/awt/print/PrinterException.java @@ -0,0 +1,71 @@ +/* PrinterException.java -- generic problem in the printing subsystem + Copyright (C) 1999, 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.print; + +/** + * This is the generic toplevel exception for printing errors. Subclasses + * provide more detailed descriptions of the problem. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @status updated to 1.4 + */ +public class PrinterException extends Exception +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = -3757589981158265819L; + + /** + * Create a new instance with no detailed error message. + */ + public PrinterException() + { + } + + /** + * Create a new instance with a descriptive error message. + * + * @param message the descriptive error message + */ + public PrinterException(String message) + { + super(message); + } +} // class PrinterException diff --git a/libjava/java/awt/print/PrinterGraphics.java b/libjava/java/awt/print/PrinterGraphics.java new file mode 100644 index 00000000000..3615107f3fc --- /dev/null +++ b/libjava/java/awt/print/PrinterGraphics.java @@ -0,0 +1,61 @@ +/* PrinterGraphics.java -- Hook to return print job controller. + Copyright (C) 1999 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.print; + +/** + * This interface is implemented by the <code>Graphics</code> instance + * that is used for rendering pages. It provides a hook to return the + * object that is controlling the print job. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface PrinterGraphics +{ + +/** + * This method returns the instance of <code>PrinterJob</code> that is + * controlling this print job. + * + * @return The <code>PrinterJob</code> that is controlling this print job. + */ +public abstract PrinterJob +getPrinterJob(); + +} // interface PrinterGraphics + diff --git a/libjava/java/awt/print/PrinterIOException.java b/libjava/java/awt/print/PrinterIOException.java new file mode 100644 index 00000000000..31f6381dc0d --- /dev/null +++ b/libjava/java/awt/print/PrinterIOException.java @@ -0,0 +1,98 @@ +/* PrinterIOException.java -- The print job encountered an I/O error + Copyright (C) 1999, 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.print; + +import java.io.IOException; + +/** + * This exception is thrown when the print job encounters an I/O problem + * of some kind. + * + * @author Aaron M. Renn <arenn@urbanophile.com> + * @author Eric Blake <ebb9@email.byu.edu> + * @status updated to 1.4 + */ +public class PrinterIOException extends PrinterException +{ + /** + * Compatible with JDK 1.2+. + */ + private static final long serialVersionUID = 5850870712125932846L; + + /** + * The exception that caused this (duplicates Throwable). + * + * @serial the I/O exception that terminated the job + */ + private final IOException mException; + + /** + * Initializes a new instance with the given cause. + * + * @param mException the cause + */ + public PrinterIOException(IOException mException) + { + super(mException == null ? null : mException.toString()); + initCause(mException); + this.mException = mException; + } + + /** + * Gets the underlying <code>IOException</code> that caused this exception. + * This legacy method has been replaced by {@link #getCause()}. + * + * @return the cause + */ + public IOException getIOException() + { + return mException; + } + + /** + * Gets the cause. + * + * @return the cause + */ + public Throwable getCause() + { + return mException; + } +} // class PrinterIOException + diff --git a/libjava/java/awt/print/PrinterJob.java b/libjava/java/awt/print/PrinterJob.java new file mode 100644 index 00000000000..b9e558caa26 --- /dev/null +++ b/libjava/java/awt/print/PrinterJob.java @@ -0,0 +1,259 @@ +/* PrinterJob.java -- This job is the printer control class + Copyright (C) 1999 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.print; + +/** + * This class controls printing. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public abstract class PrinterJob +{ + +/* + * Class Methods + */ + +/** + * Creates a new print job. + * + * @return A <code>PrinterJob</code> object for the newly created print job. + */ +public static PrinterJob +getPrinterJob() +{ + // FIXME: Need to fix this to load a default implementation instance. + return(null); +} + +/*************************************************************************/ + +/* + * Constructors + */ + +/** + * Initializes a new instance of <code>PrinterJob</code>. + */ +public +PrinterJob() +{ + ; +} + +/*************************************************************************/ + +/* + * Instance Methods + */ + +/** + * Returns the number of copies to be printed. + * + * @return The number of copies to be printed. + */ +public abstract int +getCopies(); + +/*************************************************************************/ + +/** + * Sets the number of copies to be printed. + * + * @param copies The number of copies to be printed. + */ +public abstract void +setCopies(); + +/*************************************************************************/ + +/** + * Returns the name of the print job. + * + * @return The name of the print job. + */ +public abstract String +getJobName(); + +/*************************************************************************/ + +/** + * Sets the name of the print job. + * + * @param job_name The name of the print job. + */ +public abstract String +setJobName(String job_name); + +/*************************************************************************/ + +/** + * Returns the printing user name. + * + * @return The printing username. + */ +public abstract String +getUserName(); + +/*************************************************************************/ + +/** + * Cancels an in progress print job. + */ +public abstract void +cancel(); + +/*************************************************************************/ + +/** + * Tests whether or not this job has been cancelled. + * + * @param <code>true</code> if this job has been cancelled, <code>false</code> + * otherwise. + */ +public abstract boolean +isCancelled(); + +/*************************************************************************/ + +/** + * Returns an instance of the default page which will have the default + * paper and orientation. + * + * @return A default instance of <code>PageFormat</code>. + */ +public PageFormat +defaultPage() +{ + return(new PageFormat()); +} + +/*************************************************************************/ + +/** + * Clones the specified <code>PageFormat</code> object then alters the + * clone so that it represents the default page format. + * + * @param page_format The <code>PageFormat</code> to clone. + * + * @return A new default page format. + */ +public abstract PageFormat +defaultPage(PageFormat page_format); + +/*************************************************************************/ + +/** + * Displays a dialog box to the user which allows the page format + * attributes to be modified. + * + * @param page_format The <code>PageFormat</code> object to modify. + * + * @return The modified <code>PageFormat</code>. + */ +public abstract PageFormat +pageDialog(PageFormat page_format); + +/*************************************************************************/ + +/** + * Prints the pages. + */ +public abstract void +print(); + +/** + * Displays a dialog box to the user which allows the print job + * attributes to be modified. + * + * @return <code>false</code> if the user cancels the dialog box, + * <code>true</code> otherwise. + */ +public abstract boolean +printDialog(); + +/*************************************************************************/ + +/** + * This sets the pages that are to be printed. + * + * @param pageable The pages to be printed, which may not be <code>null</code>. + */ +public abstract void +setPageable(Pageable pageable); + +/*************************************************************************/ + +/** + * Sets this specified <code>Printable</code> as the one to use for + * rendering the pages on the print device. + * + * @param printable The <code>Printable</code> for the print job. + */ +public abstract void +setPrintable(Printable printable); + +/*************************************************************************/ + +/** + * Sets the <code>Printable</code> and the page format for the pages + * to be printed. + * + * @param printable The <code>Printable</code> for the print job. + * @param page_format The <code>PageFormat</code> for the print job. + */ +public abstract void +setPrintable(Printable printable, PageFormat page_format); + +/*************************************************************************/ + +/** + * Makes any alterations to the specified <code>PageFormat</code> + * necessary to make it work with the current printer. The alterations + * are made to a clone of the input object, which is then returned. + * + * @param page_format The <code>PageFormat</code> to validate. + * + * @return The validated <code>PageFormat</code>. + */ +public abstract PageFormat +validatePage(PageFormat page); + +} // class PrinterJob + |