summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/awt
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/awt')
-rw-r--r--libjava/classpath/java/awt/AWTEvent.java5
-rw-r--r--libjava/classpath/java/awt/BasicStroke.java123
-rw-r--r--libjava/classpath/java/awt/Canvas.java20
-rw-r--r--libjava/classpath/java/awt/CardLayout.java1
-rw-r--r--libjava/classpath/java/awt/CheckboxMenuItem.java20
-rw-r--r--libjava/classpath/java/awt/Choice.java20
-rw-r--r--libjava/classpath/java/awt/Component.java1039
-rw-r--r--libjava/classpath/java/awt/Container.java334
-rw-r--r--libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java36
-rw-r--r--libjava/classpath/java/awt/Cursor.java15
-rw-r--r--libjava/classpath/java/awt/DefaultKeyboardFocusManager.java140
-rw-r--r--libjava/classpath/java/awt/EventDispatchThread.java12
-rw-r--r--libjava/classpath/java/awt/FileDialog.java52
-rw-r--r--libjava/classpath/java/awt/FlowLayout.java10
-rw-r--r--libjava/classpath/java/awt/Font.java39
-rw-r--r--libjava/classpath/java/awt/Graphics2D.java12
-rw-r--r--libjava/classpath/java/awt/GridBagConstraints.java139
-rw-r--r--libjava/classpath/java/awt/GridBagLayout.java116
-rw-r--r--libjava/classpath/java/awt/GridLayout.java12
-rw-r--r--libjava/classpath/java/awt/Image.java38
-rw-r--r--libjava/classpath/java/awt/Insets.java7
-rw-r--r--libjava/classpath/java/awt/KeyboardFocusManager.java92
-rw-r--r--libjava/classpath/java/awt/Label.java434
-rw-r--r--libjava/classpath/java/awt/LightweightDispatcher.java44
-rw-r--r--libjava/classpath/java/awt/List.java38
-rw-r--r--libjava/classpath/java/awt/Menu.java20
-rw-r--r--libjava/classpath/java/awt/MenuBar.java22
-rw-r--r--libjava/classpath/java/awt/MenuComponent.java14
-rw-r--r--libjava/classpath/java/awt/MenuItem.java25
-rw-r--r--libjava/classpath/java/awt/MouseInfo.java95
-rw-r--r--libjava/classpath/java/awt/Point.java13
-rw-r--r--libjava/classpath/java/awt/PointerInfo.java84
-rw-r--r--libjava/classpath/java/awt/PopupMenu.java24
-rw-r--r--libjava/classpath/java/awt/ScrollPane.java32
-rw-r--r--libjava/classpath/java/awt/Shape.java12
-rw-r--r--libjava/classpath/java/awt/TextArea.java64
-rw-r--r--libjava/classpath/java/awt/TextComponent.java680
-rw-r--r--libjava/classpath/java/awt/TextField.java738
-rw-r--r--libjava/classpath/java/awt/Toolkit.java21
-rw-r--r--libjava/classpath/java/awt/Window.java128
-rw-r--r--libjava/classpath/java/awt/datatransfer/Clipboard.java8
-rw-r--r--libjava/classpath/java/awt/datatransfer/DataFlavor.java114
-rw-r--r--libjava/classpath/java/awt/dnd/DragGestureEvent.java97
-rw-r--r--libjava/classpath/java/awt/dnd/DragGestureRecognizer.java1
-rw-r--r--libjava/classpath/java/awt/dnd/DragSource.java124
-rw-r--r--libjava/classpath/java/awt/dnd/DragSourceContext.java191
-rw-r--r--libjava/classpath/java/awt/dnd/DropTarget.java70
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetContext.java37
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetDragEvent.java17
-rw-r--r--libjava/classpath/java/awt/dnd/DropTargetDropEvent.java5
-rw-r--r--libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java1
-rw-r--r--libjava/classpath/java/awt/event/KeyEvent.java21
-rw-r--r--libjava/classpath/java/awt/font/FontRenderContext.java10
-rw-r--r--libjava/classpath/java/awt/font/LineBreakMeasurer.java107
-rw-r--r--libjava/classpath/java/awt/font/TextLayout.java232
-rw-r--r--libjava/classpath/java/awt/font/TextMeasurer.java149
-rw-r--r--libjava/classpath/java/awt/geom/GeneralPath.java8
-rw-r--r--libjava/classpath/java/awt/image/BandedSampleModel.java342
-rw-r--r--libjava/classpath/java/awt/image/BufferedImage.java53
-rw-r--r--libjava/classpath/java/awt/image/BufferedImageOp.java58
-rw-r--r--libjava/classpath/java/awt/image/ByteLookupTable.java17
-rw-r--r--libjava/classpath/java/awt/image/ColorConvertOp.java15
-rw-r--r--libjava/classpath/java/awt/image/ColorModel.java29
-rw-r--r--libjava/classpath/java/awt/image/ComponentSampleModel.java13
-rw-r--r--libjava/classpath/java/awt/image/ConvolveOp.java178
-rw-r--r--libjava/classpath/java/awt/image/DataBuffer.java23
-rw-r--r--libjava/classpath/java/awt/image/Kernel.java62
-rw-r--r--libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java458
-rw-r--r--libjava/classpath/java/awt/image/Raster.java780
-rw-r--r--libjava/classpath/java/awt/image/RasterOp.java50
-rw-r--r--libjava/classpath/java/awt/image/SampleModel.java461
-rw-r--r--libjava/classpath/java/awt/image/ShortLookupTable.java39
-rw-r--r--libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java307
-rw-r--r--libjava/classpath/java/awt/image/WritableRaster.java346
-rw-r--r--libjava/classpath/java/awt/peer/ComponentPeer.java33
-rw-r--r--libjava/classpath/java/awt/peer/MouseInfoPeer.java61
-rw-r--r--libjava/classpath/java/awt/peer/WindowPeer.java5
77 files changed, 6400 insertions, 2892 deletions
diff --git a/libjava/classpath/java/awt/AWTEvent.java b/libjava/classpath/java/awt/AWTEvent.java
index d10433cb3c3..a6151b424c1 100644
--- a/libjava/classpath/java/awt/AWTEvent.java
+++ b/libjava/classpath/java/awt/AWTEvent.java
@@ -103,6 +103,11 @@ public abstract class AWTEvent extends EventObject
*/
byte[] bdata;
+ /**
+ * Indicates if this event is dispatched by the KeyboardFocusManager.
+ */
+ boolean isFocusManagerEvent = false;
+
/** Mask for selecting component events. */
public static final long COMPONENT_EVENT_MASK = 0x00001;
diff --git a/libjava/classpath/java/awt/BasicStroke.java b/libjava/classpath/java/awt/BasicStroke.java
index 3e259216fa7..160a3eb0f74 100644
--- a/libjava/classpath/java/awt/BasicStroke.java
+++ b/libjava/classpath/java/awt/BasicStroke.java
@@ -43,7 +43,6 @@ import gnu.java.awt.java2d.LineSegment;
import gnu.java.awt.java2d.QuadSegment;
import gnu.java.awt.java2d.Segment;
-import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
@@ -118,6 +117,7 @@ public class BasicStroke implements Stroke
/** The dash phase. */
private final float phase;
+ // The inner and outer paths of the stroke
private Segment start, end;
/**
@@ -260,7 +260,7 @@ public class BasicStroke implements Stroke
*/
public Shape createStrokedShape(Shape s)
{
- PathIterator pi = s.getPathIterator( new AffineTransform() );
+ PathIterator pi = s.getPathIterator(null);
if( dash == null )
return solidStroke( pi );
@@ -435,8 +435,8 @@ public class BasicStroke implements Stroke
else
addSegments(p);
- x = coords[0];
- y = coords[1];
+ x = coords[2];
+ y = coords[3];
break;
case PathIterator.SEG_CUBICTO:
@@ -452,17 +452,25 @@ public class BasicStroke implements Stroke
else
addSegments(p);
- x = coords[0];
- y = coords[1];
+ x = coords[4];
+ y = coords[5];
break;
case PathIterator.SEG_CLOSE:
- p = (new LineSegment(x, y, x0, y0)).getDisplacedSegments(width/2.0);
- addSegments(p);
+ if (x == x0 && y == y0)
+ {
+ joinSegments(new Segment[] { start.first, end.first });
+ }
+ else
+ {
+ p = (new LineSegment(x, y, x0, y0)).getDisplacedSegments(width / 2.0);
+ addSegments(p);
+ }
convertPath(output, start);
convertPath(output, end);
start = end = null;
pathOpen = false;
+ output.setWindingRule(GeneralPath.WIND_EVEN_ODD);
break;
}
pi.next();
@@ -499,7 +507,7 @@ public class BasicStroke implements Stroke
}
/**
- * Convert and add the linked list of Segments in s to a GeneralPath p.
+ * Append the Segments in s to the GeneralPath p
*/
private void convertPath(GeneralPath p, Segment s)
{
@@ -527,18 +535,28 @@ public class BasicStroke implements Stroke
p.closePath();
}
-
+
/**
- * Add to segments to start and end, joining the outer pair and
+ * Add the segments to start and end (the inner and outer edges of the stroke)
*/
private void addSegments(Segment[] segments)
{
- double[] p0 = start.last.last();
+ joinSegments(segments);
+ start.add(segments[0]);
+ end.add(segments[1]);
+ }
+
+ private void joinSegments(Segment[] segments)
+ {
+ double[] p0 = start.last.cp2();
double[] p1 = new double[]{start.last.P2.getX(), start.last.P2.getY()};
- double[] p2 = new double[]{segments[0].P1.getX(), segments[0].P1.getY()};
- double[] p3 = segments[0].first();
+ double[] p2 = new double[]{segments[0].first.P1.getX(), segments[0].first.P1.getY()};
+ double[] p3 = segments[0].cp1();
Point2D p;
+ p = lineIntersection(p0[0],p0[1],p1[0],p1[1],
+ p2[0],p2[1],p3[0],p3[1], false);
+
double det = (p1[0] - p0[0])*(p3[1] - p2[1]) -
(p3[0] - p2[0])*(p1[1] - p0[1]);
@@ -546,42 +564,14 @@ public class BasicStroke implements Stroke
{
// start and segment[0] form the 'inner' part of a join,
// connect the overlapping segments
- p = lineIntersection(p0[0],p0[1],p1[0],p1[1],p2[0],p2[1],p3[0],p3[1], false);
- if( p == null )
- {
- // Dodgy.
- start.add(new LineSegment(start.last.P2, segments[0].P1));
- p = new Point2D.Double((segments[0].P1.getX()+ start.last.P2.getX())/2.0,
- (segments[0].P1.getY()+ start.last.P2.getY())/2.0);
- }
- else
- segments[0].P1 = start.last.P2 = p;
-
- start.add( segments[0] );
- joinSegments(end, segments[1], p);
+ joinInnerSegments(start, segments[0], p);
+ joinOuterSegments(end, segments[1], p);
}
else
{
// end and segment[1] form the 'inner' part
- p0 = end.last.last();
- p1 = new double[]{end.last.P2.getX(), end.last.P2.getY()};
- p2 = new double[]{segments[1].P1.getX(), segments[1].P1.getY()};
- p3 = segments[1].first();
-
- p = lineIntersection(p0[0],p0[1],p1[0],p1[1],
- p2[0],p2[1],p3[0],p3[1], false);
- if( p == null )
- {
- // Dodgy.
- end.add(new LineSegment(end.last.P2, segments[1].P1));
- p = new Point2D.Double((segments[1].P1.getX()+ end.last.P2.getX())/2.0,
- (segments[1].P1.getY()+ end.last.P2.getY())/2.0);
- }
- else
- segments[1].P1 = end.last.P2 = p;
-
- end.add( segments[1] );
- joinSegments(start, segments[0], p);
+ joinInnerSegments(end, segments[1], p);
+ joinOuterSegments(start, segments[0], p);
}
}
@@ -602,7 +592,7 @@ public class BasicStroke implements Stroke
break;
case CAP_SQUARE:
- p0 = a.last.last();
+ p0 = a.last.cp2();
p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
dx = p1[0] - p0[0];
dy = p1[1] - p0[1];
@@ -617,7 +607,7 @@ public class BasicStroke implements Stroke
break;
case CAP_ROUND:
- p0 = a.last.last();
+ p0 = a.last.cp2();
p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
dx = p1[0] - p0[0];
dy = p1[1] - p0[1];
@@ -676,7 +666,7 @@ public class BasicStroke implements Stroke
* insideP is the inside intersection point of the join, needed for
* calculating miter lengths.
*/
- private void joinSegments(Segment a, Segment b, Point2D insideP)
+ private void joinOuterSegments(Segment a, Segment b, Point2D insideP)
{
double[] p0, p1;
double dx, dy, l;
@@ -685,10 +675,10 @@ public class BasicStroke implements Stroke
switch( join )
{
case JOIN_MITER:
- p0 = a.last.last();
+ p0 = a.last.cp2();
p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
double[] p2 = new double[]{b.P1.getX(), b.P1.getY()};
- double[] p3 = b.first();
+ double[] p3 = b.cp1();
Point2D p = lineIntersection(p0[0],p0[1],p1[0],p1[1],p2[0],p2[1],p3[0],p3[1], true);
if( p == null || insideP == null )
a.add(new LineSegment(a.last.P2, b.P1));
@@ -705,7 +695,7 @@ public class BasicStroke implements Stroke
break;
case JOIN_ROUND:
- p0 = a.last.last();
+ p0 = a.last.cp2();
p1 = new double[]{a.last.P2.getX(), a.last.P2.getY()};
dx = p1[0] - p0[0];
dy = p1[1] - p0[1];
@@ -715,7 +705,7 @@ public class BasicStroke implements Stroke
c1 = new Point2D.Double(p1[0] + dx, p1[1] + dy);
p0 = new double[]{b.P1.getX(), b.P1.getY()};
- p1 = b.first();
+ p1 = b.cp1();
dx = p0[0] - p1[0]; // backwards direction.
dy = p0[1] - p1[1];
@@ -730,6 +720,29 @@ public class BasicStroke implements Stroke
a.add(new LineSegment(a.last.P2, b.P1));
break;
}
- a.add(b);
}
-}
+
+ /**
+ * Join a and b segments, removing any overlap
+ */
+ private void joinInnerSegments(Segment a, Segment b, Point2D p)
+ {
+ double[] p0 = a.last.cp2();
+ double[] p1 = new double[] { a.last.P2.getX(), a.last.P2.getY() };
+ double[] p2 = new double[] { b.P1.getX(), b.P1.getY() };
+ double[] p3 = b.cp1();
+
+ if (p == null)
+ {
+ // Dodgy.
+ a.add(new LineSegment(a.last.P2, b.P1));
+ p = new Point2D.Double((b.P1.getX() + a.last.P2.getX()) / 2.0,
+ (b.P1.getY() + a.last.P2.getY()) / 2.0);
+ }
+ else
+ // This assumes segments a and b are single segments, which is
+ // incorrect - if they are a linked list of segments (ie, passed in
+ // from a flattening operation), this produces strange results!!
+ a.last.P2 = b.P1 = p;
+ }
+}
diff --git a/libjava/classpath/java/awt/Canvas.java b/libjava/classpath/java/awt/Canvas.java
index b599582ba93..843fded44db 100644
--- a/libjava/classpath/java/awt/Canvas.java
+++ b/libjava/classpath/java/awt/Canvas.java
@@ -68,6 +68,11 @@ public class Canvas
* Compatible with Sun's JDK.
*/
private static final long serialVersionUID = -2284879212465893870L;
+
+ /**
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_canvas_number;
/**
* The graphics configuration associated with the canvas.
@@ -343,4 +348,19 @@ public class Canvas
/* Call the paint method */
paint(graphics);
}
+
+ /**
+ * Generate a unique name for this <code>Canvas</code>.
+ *
+ * @return A unique name for this <code>Canvas</code>.
+ */
+ String generateName()
+ {
+ return "canvas" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_canvas_number++;
+ }
}
diff --git a/libjava/classpath/java/awt/CardLayout.java b/libjava/classpath/java/awt/CardLayout.java
index 8b3fea2ca23..fcb05215af9 100644
--- a/libjava/classpath/java/awt/CardLayout.java
+++ b/libjava/classpath/java/awt/CardLayout.java
@@ -350,6 +350,7 @@ public class CardLayout implements LayoutManager2, Serializable
}
}
((Component) target).setVisible (true);
+ parent.validate();
}
}
diff --git a/libjava/classpath/java/awt/CheckboxMenuItem.java b/libjava/classpath/java/awt/CheckboxMenuItem.java
index 197065f6535..2df621b71b7 100644
--- a/libjava/classpath/java/awt/CheckboxMenuItem.java
+++ b/libjava/classpath/java/awt/CheckboxMenuItem.java
@@ -63,6 +63,11 @@ public class CheckboxMenuItem extends MenuItem
* Static Variables
*/
+/**
+ * The number used to generate the name returned by getName.
+ */
+private static transient long next_chkmenuitem_number;
+
// Serialization constant
private static final long serialVersionUID = 6190621106981774043L;
@@ -352,6 +357,21 @@ paramString()
accessibleContext = new AccessibleAWTCheckboxMenuItem();
return accessibleContext;
}
+
+ /**
+ * Generate a unique name for this <code>CheckboxMenuItem</code>.
+ *
+ * @return A unique name for this <code>CheckboxMenuItem</code>.
+ */
+ String generateName()
+ {
+ return "chkmenuitem" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_chkmenuitem_number++;
+ }
} // class CheckboxMenuItem
diff --git a/libjava/classpath/java/awt/Choice.java b/libjava/classpath/java/awt/Choice.java
index 90a8d3141c8..f1da94bbeb8 100644
--- a/libjava/classpath/java/awt/Choice.java
+++ b/libjava/classpath/java/awt/Choice.java
@@ -63,6 +63,11 @@ public class Choice extends Component
* Static Variables
*/
+/**
+ * The number used to generate the name returned by getName.
+ */
+private static transient long next_choice_number;
+
// Serialization constant
private static final long serialVersionUID = -4075310674757313071L;
@@ -639,4 +644,19 @@ paramString()
accessibleContext = new AccessibleAWTChoice();
return accessibleContext;
}
+
+ /**
+ * Generate a unique name for this <code>Choice</code>.
+ *
+ * @return A unique name for this <code>Choice</code>.
+ */
+ String generateName()
+ {
+ return "choice" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_choice_number++;
+ }
} // class Choice
diff --git a/libjava/classpath/java/awt/Component.java b/libjava/classpath/java/awt/Component.java
index 3d3dcc319cc..44f277ac783 100644
--- a/libjava/classpath/java/awt/Component.java
+++ b/libjava/classpath/java/awt/Component.java
@@ -70,6 +70,7 @@ import java.awt.image.ImageProducer;
import java.awt.image.VolatileImage;
import java.awt.peer.ComponentPeer;
import java.awt.peer.LightweightPeer;
+import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
@@ -213,6 +214,12 @@ public abstract class Component
*/
static final Object treeLock = new String("AWT_TREE_LOCK");
+ /**
+ * The default maximum size.
+ */
+ private static final Dimension DEFAULT_MAX_SIZE
+ = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
+
// Serialized fields from the serialization spec.
/**
@@ -427,6 +434,24 @@ public abstract class Component
Dimension minSize;
/**
+ * Flag indicating whether the minimum size for the component has been set
+ * by a call to {@link #setMinimumSize(Dimension)} with a non-null value.
+ */
+ boolean minSizeSet;
+
+ /**
+ * The maximum size for the component.
+ * @see #setMaximumSize(Dimension)
+ */
+ Dimension maxSize;
+
+ /**
+ * A flag indicating whether the maximum size for the component has been set
+ * by a call to {@link #setMaximumSize(Dimension)} with a non-null value.
+ */
+ boolean maxSizeSet;
+
+ /**
* Cached information on the preferred size. Should have been transient.
*
* @serial ignore
@@ -434,6 +459,12 @@ public abstract class Component
Dimension prefSize;
/**
+ * Flag indicating whether the preferred size for the component has been set
+ * by a call to {@link #setPreferredSize(Dimension)} with a non-null value.
+ */
+ boolean prefSizeSet;
+
+ /**
* Set to true if an event is to be handled by this component, false if
* it is to be passed up the hierarcy.
*
@@ -563,6 +594,17 @@ public abstract class Component
transient BufferStrategy bufferStrategy;
/**
+ * The number of hierarchy listeners of this container plus all of its
+ * children. This is needed for efficient handling of HierarchyEvents.
+ * These must be propagated to all child components with HierarchyListeners
+ * attached. To avoid traversal of the whole subtree, we keep track of
+ * the number of HierarchyListeners here and only walk the paths that
+ * actually have listeners.
+ */
+ int numHierarchyListeners;
+ int numHierarchyBoundsListeners;
+
+ /**
* true if requestFocus was called on this component when its
* top-level ancestor was not focusable.
*/
@@ -607,16 +649,19 @@ public abstract class Component
}
/**
- * Sets the name of this component to the specified name.
+ * Sets the name of this component to the specified name (this is a bound
+ * property with the name 'name').
*
- * @param name the new name of this component
+ * @param name the new name (<code>null</code> permitted).
* @see #getName()
* @since 1.1
*/
public void setName(String name)
{
nameExplicitlySet = true;
+ String old = this.name;
this.name = name;
+ firePropertyChange("name", old, name);
}
/**
@@ -718,7 +763,9 @@ public abstract class Component
*/
public boolean isValid()
{
- return valid;
+ // Tests show that components are invalid as long as they are not showing, even after validate()
+ // has been called on them.
+ return peer != null && valid;
}
/**
@@ -804,9 +851,17 @@ public abstract class Component
*/
public void enable()
{
- this.enabled = true;
- if (peer != null)
- peer.setEnabled (true);
+ if (! enabled)
+ {
+ // Need to lock the tree here, because the peers are involved.
+ synchronized (getTreeLock())
+ {
+ enabled = true;
+ ComponentPeer p = peer;
+ if (p != null)
+ p.enable();
+ }
+ }
}
/**
@@ -831,9 +886,17 @@ public abstract class Component
*/
public void disable()
{
- this.enabled = false;
- if (peer != null)
- peer.setEnabled (false);
+ if (enabled)
+ {
+ // Need to lock the tree here, because the peers are involved.
+ synchronized (getTreeLock())
+ {
+ enabled = false;
+ ComponentPeer p = peer;
+ if (p != null)
+ p.disable();
+ }
+ }
}
/**
@@ -898,16 +961,38 @@ public abstract class Component
// and its children.
if(!isVisible())
{
- this.visible = true;
- // Avoid NullPointerExceptions by creating a local reference.
- ComponentPeer currentPeer=peer;
- if (currentPeer != null)
- currentPeer.show();
-
- // The JDK repaints the component before invalidating the parent.
- // So do we.
- if (isShowing() && isLightweight())
- repaint();
+ // Need to lock the tree here to avoid races and inconsistencies.
+ synchronized (getTreeLock())
+ {
+ visible = true;
+ // Avoid NullPointerExceptions by creating a local reference.
+ ComponentPeer currentPeer=peer;
+ if (currentPeer != null)
+ {
+ currentPeer.show();
+
+ // Fire HierarchyEvent.
+ fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
+ this, parent,
+ HierarchyEvent.SHOWING_CHANGED);
+
+ // The JDK repaints the component before invalidating the parent.
+ // So do we.
+ if (isLightweight())
+ repaint();
+ }
+
+ // Only post an event if this component actually has a listener
+ // or has this event explicitly enabled.
+ if (componentListener != null
+ || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
+ {
+ ComponentEvent ce =
+ new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
// Invalidate the parent if we have one. The component itself must
// not be invalidated. We also avoid NullPointerException with
// a local reference here.
@@ -915,9 +1000,6 @@ public abstract class Component
if (currentParent != null)
currentParent.invalidate();
- ComponentEvent ce =
- new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
- getToolkit().getSystemEventQueue().postEvent(ce);
}
}
@@ -945,27 +1027,45 @@ public abstract class Component
{
if (isVisible())
{
- // Avoid NullPointerExceptions by creating a local reference.
- ComponentPeer currentPeer=peer;
- if (currentPeer != null)
- currentPeer.setVisible(false);
- boolean wasShowing = isShowing();
- this.visible = false;
-
- // The JDK repaints the component before invalidating the parent.
- // So do we.
- if (wasShowing)
- repaint();
- // Invalidate the parent if we have one. The component itself must
+ // Need to lock the tree here to avoid races and inconsistencies.
+ synchronized (getTreeLock())
+ {
+ visible = false;
+
+ // Avoid NullPointerExceptions by creating a local reference.
+ ComponentPeer currentPeer=peer;
+ if (currentPeer != null)
+ {
+ currentPeer.hide();
+
+ // Fire hierarchy event.
+ fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
+ this, parent,
+ HierarchyEvent.SHOWING_CHANGED);
+ // The JDK repaints the component before invalidating the
+ // parent. So do we. This only applies for lightweights.
+ if (peer instanceof LightweightPeer)
+ repaint();
+ }
+
+ // Only post an event if this component actually has a listener
+ // or has this event explicitly enabled.
+ if (componentListener != null
+ || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
+ {
+ ComponentEvent ce =
+ new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
+ // Invalidate the parent if we have one. The component itself need
// not be invalidated. We also avoid NullPointerException with
// a local reference here.
Container currentParent = parent;
if (currentParent != null)
currentParent.invalidate();
- ComponentEvent ce =
- new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
- getToolkit().getSystemEventQueue().postEvent(ce);
}
}
@@ -1088,16 +1188,13 @@ public abstract class Component
*/
public void setFont(Font newFont)
{
- if((newFont != null && (font == null || !font.equals(newFont)))
- || newFont == null)
- {
- Font oldFont = font;
- font = newFont;
- if (peer != null)
- peer.setFont(font);
- firePropertyChange("font", oldFont, newFont);
- invalidate();
- }
+ Font oldFont = font;
+ font = newFont;
+ if (peer != null)
+ peer.setFont(font);
+ firePropertyChange("font", oldFont, newFont);
+ if (valid)
+ invalidate();
}
/**
@@ -1189,8 +1286,15 @@ public abstract class Component
throw new IllegalComponentStateException("component "
+ getClass().getName()
+ " not showing");
- // We know peer != null here.
- return peer.getLocationOnScreen();
+
+ // Need to lock the tree here. We get crazy races and explosions when
+ // the tree changes while we are trying to find the location of this
+ // component.
+ synchronized (getTreeLock())
+ {
+ // We know peer != null here.
+ return peer.getLocationOnScreen();
+ }
}
/**
@@ -1384,53 +1488,98 @@ public abstract class Component
*/
public void reshape(int x, int y, int width, int height)
{
- int oldx = this.x;
- int oldy = this.y;
- int oldwidth = this.width;
- int oldheight = this.height;
+ // We need to lock the tree here, otherwise we risk races and
+ // inconsistencies.
+ synchronized (getTreeLock())
+ {
+ int oldx = this.x;
+ int oldy = this.y;
+ int oldwidth = this.width;
+ int oldheight = this.height;
- if (this.x == x && this.y == y && this.width == width
- && this.height == height)
- return;
+ boolean resized = oldwidth != width || oldheight != height;
+ boolean moved = oldx != x || oldy != y;
- invalidate();
-
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- if (peer != null)
- peer.setBounds (x, y, width, height);
-
- // Erase old bounds and repaint new bounds for lightweights.
- if (isLightweight() && isShowing())
- {
- if (parent != null)
+ if (resized || moved)
{
- Rectangle oldBounds = new Rectangle(oldx, oldy, oldwidth,
- oldheight);
- Rectangle newBounds = new Rectangle(x, y, width, height);
- Rectangle destroyed = oldBounds.union(newBounds);
- if (!destroyed.isEmpty())
- parent.repaint(0, destroyed.x, destroyed.y, destroyed.width,
- destroyed.height);
+ // Update the fields.
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+
+ if (peer != null)
+ {
+ peer.setBounds (x, y, width, height);
+ if (resized)
+ invalidate();
+ if (parent != null && parent.valid)
+ parent.invalidate();
+ }
+
+ // Send some events to interested listeners.
+ notifyReshape(resized, moved);
+
+ // Repaint this component and the parent if appropriate.
+ if (parent != null && peer instanceof LightweightPeer
+ && isShowing())
+ {
+ // The parent repaints the area that we occupied before.
+ parent.repaint(oldx, oldy, oldwidth, oldheight);
+ // This component repaints the area that we occupy now.
+ repaint();
+ }
}
}
+ }
- // Only post event if this component is visible and has changed size.
- if (isShowing ()
- && (oldx != x || oldy != y))
+ private void notifyReshape(boolean resized, boolean moved)
+ {
+ // Only post an event if this component actually has a listener
+ // or has this event explicitly enabled.
+ if (componentListener != null
+ || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
{
- ComponentEvent ce = new ComponentEvent(this,
- ComponentEvent.COMPONENT_MOVED);
- getToolkit().getSystemEventQueue().postEvent(ce);
+ // Fire component event on this component.
+ if (moved)
+ {
+ ComponentEvent ce = new ComponentEvent(this,
+ ComponentEvent.COMPONENT_MOVED);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ if (resized)
+ {
+ ComponentEvent ce = new ComponentEvent(this,
+ ComponentEvent.COMPONENT_RESIZED);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
}
- if (isShowing ()
- && (oldwidth != width || oldheight != height))
+ else
{
- ComponentEvent ce = new ComponentEvent(this,
- ComponentEvent.COMPONENT_RESIZED);
- getToolkit().getSystemEventQueue().postEvent(ce);
+ // Otherwise we might need to notify child components when this is
+ // a Container.
+ if (this instanceof Container)
+ {
+ Container cont = (Container) this;
+ if (resized)
+ {
+ for (int i = 0; i < cont.getComponentCount(); i++)
+ {
+ Component child = cont.getComponent(i);
+ child.fireHierarchyEvent(HierarchyEvent.ANCESTOR_RESIZED,
+ this, parent, 0);
+ }
+ }
+ if (moved)
+ {
+ for (int i = 0; i < cont.getComponentCount(); i++)
+ {
+ Component child = cont.getComponent(i);
+ child.fireHierarchyEvent(HierarchyEvent.ANCESTOR_MOVED,
+ this, parent, 0);
+ }
+ }
+ }
}
}
@@ -1584,6 +1733,7 @@ public abstract class Component
*
* @return the component's preferred size
* @see #getMinimumSize()
+ * @see #setPreferredSize(Dimension)
* @see LayoutManager
*/
public Dimension getPreferredSize()
@@ -1592,6 +1742,40 @@ public abstract class Component
}
/**
+ * Sets the preferred size that will be returned by
+ * {@link #getPreferredSize()} always, and sends a
+ * {@link PropertyChangeEvent} (with the property name 'preferredSize') to
+ * all registered listeners.
+ *
+ * @param size the preferred size (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getPreferredSize()
+ */
+ public void setPreferredSize(Dimension size)
+ {
+ Dimension old = prefSizeSet ? prefSize : null;
+ prefSize = size;
+ prefSizeSet = (size != null);
+ firePropertyChange("preferredSize", old, size);
+ }
+
+ /**
+ * Returns <code>true</code> if the current preferred size is not
+ * <code>null</code> and was set by a call to
+ * {@link #setPreferredSize(Dimension)}, otherwise returns <code>false</code>.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ */
+ public boolean isPreferredSizeSet()
+ {
+ return prefSizeSet;
+ }
+
+ /**
* Returns the component's preferred size.
*
* @return the component's preferred size
@@ -1599,14 +1783,36 @@ public abstract class Component
*/
public Dimension preferredSize()
{
- if (prefSize == null)
+ // Create a new Dimension object, so that the application doesn't mess
+ // with the actual values.
+ return new Dimension(preferredSizeImpl());
+ }
+
+ /**
+ * The actual calculation is pulled out of preferredSize() so that
+ * we can call it from Container.preferredSize() and avoid creating a
+ * new intermediate Dimension object.
+ *
+ * @return the preferredSize of the component
+ */
+ Dimension preferredSizeImpl()
+ {
+ Dimension size = prefSize;
+ // Try to use a cached value.
+ if (size == null || !(valid || prefSizeSet))
{
- if (peer == null)
- prefSize = minimumSize();
- else
- prefSize = peer.getPreferredSize();
+ // We need to lock here, because the calculation depends on the
+ // component structure not changing.
+ synchronized (getTreeLock())
+ {
+ ComponentPeer p = peer;
+ if (p != null)
+ size = peer.preferredSize();
+ else
+ size = minimumSizeImpl();
+ }
}
- return prefSize;
+ return size;
}
/**
@@ -1614,6 +1820,7 @@ public abstract class Component
*
* @return the component's minimum size
* @see #getPreferredSize()
+ * @see #setMinimumSize(Dimension)
* @see LayoutManager
*/
public Dimension getMinimumSize()
@@ -1622,6 +1829,39 @@ public abstract class Component
}
/**
+ * Sets the minimum size that will be returned by {@link #getMinimumSize()}
+ * always, and sends a {@link PropertyChangeEvent} (with the property name
+ * 'minimumSize') to all registered listeners.
+ *
+ * @param size the minimum size (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getMinimumSize()
+ */
+ public void setMinimumSize(Dimension size)
+ {
+ Dimension old = minSizeSet ? minSize : null;
+ minSize = size;
+ minSizeSet = (size != null);
+ firePropertyChange("minimumSize", old, size);
+ }
+
+ /**
+ * Returns <code>true</code> if the current minimum size is not
+ * <code>null</code> and was set by a call to
+ * {@link #setMinimumSize(Dimension)}, otherwise returns <code>false</code>.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ */
+ public boolean isMinimumSizeSet()
+ {
+ return minSizeSet;
+ }
+
+ /**
* Returns the component's minimum size.
*
* @return the component's minimum size
@@ -1629,10 +1869,36 @@ public abstract class Component
*/
public Dimension minimumSize()
{
- if (minSize == null)
- minSize = (peer != null ? peer.getMinimumSize()
- : new Dimension(width, height));
- return minSize;
+ // Create a new Dimension object, so that the application doesn't mess
+ // with the actual values.
+ return new Dimension(minimumSizeImpl());
+ }
+
+ /**
+ * The actual calculation is pulled out of minimumSize() so that
+ * we can call it from Container.preferredSize() and
+ * Component.preferredSizeImpl and avoid creating a
+ * new intermediate Dimension object.
+ *
+ * @return the minimum size of the component
+ */
+ Dimension minimumSizeImpl()
+ {
+ Dimension size = minSize;
+ if (size == null || !(valid || minSizeSet))
+ {
+ // We need to lock here, because the calculation depends on the
+ // component structure not changing.
+ synchronized (getTreeLock())
+ {
+ ComponentPeer p = peer;
+ if (p != null)
+ size = peer.minimumSize();
+ else
+ size = size();
+ }
+ }
+ return size;
}
/**
@@ -1640,15 +1906,66 @@ public abstract class Component
*
* @return the component's maximum size
* @see #getMinimumSize()
+ * @see #setMaximumSize(Dimension)
* @see #getPreferredSize()
* @see LayoutManager
*/
public Dimension getMaximumSize()
{
- return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
+ return new Dimension(maximumSizeImpl());
+ }
+
+ /**
+ * This is pulled out from getMaximumSize(), so that we can access it
+ * from Container.getMaximumSize() without creating an additional
+ * intermediate Dimension object.
+ *
+ * @return the maximum size of the component
+ */
+ Dimension maximumSizeImpl()
+ {
+ Dimension size;
+ if (maxSizeSet)
+ size = maxSize;
+ else
+ size = DEFAULT_MAX_SIZE;
+ return size;
+ }
+
+ /**
+ * Sets the maximum size that will be returned by {@link #getMaximumSize()}
+ * always, and sends a {@link PropertyChangeEvent} (with the property name
+ * 'maximumSize') to all registered listeners.
+ *
+ * @param size the maximum size (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getMaximumSize()
+ */
+ public void setMaximumSize(Dimension size)
+ {
+ Dimension old = maxSizeSet ? maxSize : null;
+ maxSize = size;
+ maxSizeSet = (size != null);
+ firePropertyChange("maximumSize", old, size);
}
/**
+ * Returns <code>true</code> if the current maximum size is not
+ * <code>null</code> and was set by a call to
+ * {@link #setMaximumSize(Dimension)}, otherwise returns <code>false</code>.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ */
+ public boolean isMaximumSizeSet()
+ {
+ return maxSizeSet;
+ }
+
+ /**
* Returns the preferred horizontal alignment of this component. The value
* returned will be between {@link #LEFT_ALIGNMENT} and
* {@link #RIGHT_ALIGNMENT}, inclusive.
@@ -1716,11 +2033,25 @@ public abstract class Component
*/
public void invalidate()
{
- valid = false;
- prefSize = null;
- minSize = null;
- if (parent != null && parent.isValid())
- parent.invalidate();
+ // Need to lock here, to avoid races and other ugly stuff when doing
+ // layout or structure changes in other threads.
+ synchronized (getTreeLock())
+ {
+ // Invalidate.
+ valid = false;
+
+ // Throw away cached layout information.
+ if (! minSizeSet)
+ minSize = null;
+ if (! prefSizeSet)
+ prefSize = null;
+ if (! maxSizeSet)
+ maxSize = null;
+
+ // Also invalidate the parent, if it hasn't already been invalidated.
+ if (parent != null && parent.isValid())
+ parent.invalidate();
+ }
}
/**
@@ -1826,11 +2157,9 @@ public abstract class Component
}
/**
- * 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
+ * Updates this component. This is called for heavyweight components in
+ * response to {@link #repaint()}. The default implementation simply forwards
+ * to {@link #paint(Graphics)}. The coordinates of the graphics are
* relative to this component. Subclasses should call either
* <code>super.update(g)</code> or <code>paint(g)</code>.
*
@@ -1838,27 +2167,17 @@ public abstract class Component
*
* @see #paint(Graphics)
* @see #repaint()
- *
- * @specnote In contrast to what the spec says, tests show that the exact
- * behaviour is to clear the background on lightweight and
- * top-level components only. Heavyweight components are not
- * affected by this method and only call paint().
*/
public void update(Graphics g)
{
- // Tests show that the clearing of the background is only done in
- // two cases:
- // - If the component is lightweight (yes this is in contrast to the spec).
- // or
- // - If the component is a toplevel container.
- if (isLightweight() || getParent() == null)
- {
- Rectangle clip = g.getClipBounds();
- if (clip == null)
- g.clearRect(0, 0, width, height);
- else
- g.clearRect(clip.x, clip.y, clip.width, clip.height);
- }
+ // Note 1: We used to clear the background here for lightweights and
+ // toplevel components. Tests show that this is not what the JDK does
+ // here. Note that there is some special handling and background
+ // clearing code in Container.update(Graphics).
+
+ // Note 2 (for peer implementors): The JDK doesn't seem call update() for
+ // toplevel components, even when an UPDATE event is sent (as a result
+ // of repaint).
paint(g);
}
@@ -1934,11 +2253,46 @@ public abstract class Component
*/
public void repaint(long tm, int x, int y, int width, int height)
{
- if (isShowing())
+ // The repaint() call has previously been delegated to
+ // {@link ComponentPeer.repaint()}. Testing on the JDK using some
+ // dummy peers show that this methods is never called. I think it makes
+ // sense to actually perform the tasks below here, since it's pretty
+ // much peer independent anyway, and makes sure only heavyweights are
+ // bothered by this.
+ ComponentPeer p = peer;
+
+ // Let the nearest heavyweight parent handle repainting for lightweight
+ // components.
+ // This goes up the hierarchy until we hit
+ // a heavyweight component that handles this and translates the
+ // rectangle while doing so.
+
+ // We perform some boundary checking to restrict the paint
+ // region to this component.
+ int px = (x < 0 ? 0 : x);
+ int py = (y < 0 ? 0 : y);
+ int pw = width;
+ int ph = height;
+ Component par = this;
+ while (par != null && p instanceof LightweightPeer)
+ {
+ px += par.x;
+ py += par.y;
+ // We perform some boundary checking to restrict the paint
+ // region to this component.
+ pw = Math.min(pw, par.width);
+ ph = Math.min(ph, par.height);
+ par = par.parent;
+ p = par.peer;
+ }
+
+ // Now send an UPDATE event to the heavyweight component that we've found.
+ if (par != null && par.isVisible() && p != null && pw > 0 && ph > 0)
{
- ComponentPeer p = peer;
- if (p != null)
- p.repaint(tm, x, y, width, height);
+ assert ! (p instanceof LightweightPeer);
+ PaintEvent pe = new PaintEvent(par, PaintEvent.UPDATE,
+ new Rectangle(px, py, pw, ph));
+ getToolkit().getSystemEventQueue().postEvent(pe);
}
}
@@ -1957,10 +2311,7 @@ public abstract class Component
}
/**
- * 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.
+ * Prints this component, including all sub-components.
*
* @param g the graphics context of the print device
*
@@ -1968,7 +2319,9 @@ public abstract class Component
*/
public void printAll(Graphics g)
{
- paintAll(g);
+ if( peer != null )
+ peer.print( g );
+ paintAll( g );
}
/**
@@ -2318,6 +2671,17 @@ public abstract class Component
}
/**
+ * By default, no old mouse events should be ignored.
+ * This can be overridden by subclasses.
+ *
+ * @return false, no mouse events are ignored.
+ */
+ static boolean ignoreOldMouseEvents()
+ {
+ return false;
+ }
+
+ /**
* AWT 1.0 event handler.
*
* This method simply calls handleEvent and returns the result.
@@ -2449,6 +2813,14 @@ public abstract class Component
hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener);
if (hierarchyListener != null)
enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
+
+ // Need to lock the tree, otherwise we might end up inconsistent.
+ synchronized (getTreeLock())
+ {
+ numHierarchyListeners++;
+ if (parent != null)
+ parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK, 1);
+ }
}
/**
@@ -2464,6 +2836,15 @@ public abstract class Component
public synchronized void removeHierarchyListener(HierarchyListener listener)
{
hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
+
+ // Need to lock the tree, otherwise we might end up inconsistent.
+ synchronized (getTreeLock())
+ {
+ numHierarchyListeners--;
+ if (parent != null)
+ parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
+ -1);
+ }
}
/**
@@ -2499,6 +2880,16 @@ public abstract class Component
AWTEventMulticaster.add(hierarchyBoundsListener, listener);
if (hierarchyBoundsListener != null)
enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
+
+ // Need to lock the tree, otherwise we might end up inconsistent.
+ synchronized (getTreeLock())
+ {
+ numHierarchyBoundsListeners++;
+ if (parent != null)
+ parent.updateHierarchyListenerCount
+ (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
+ 1);
+ }
}
/**
@@ -2516,6 +2907,16 @@ public abstract class Component
{
hierarchyBoundsListener =
AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
+
+ // Need to lock the tree, otherwise we might end up inconsistent.
+ synchronized (getTreeLock())
+ {
+ numHierarchyBoundsListeners--;
+ if (parent != null)
+ parent.updateHierarchyListenerCount
+ (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
+ -1);
+ }
}
/**
@@ -2534,6 +2935,40 @@ public abstract class Component
}
/**
+ * Fires a HierarchyEvent or HierarchyChangeEvent on this component.
+ *
+ * @param id the event id
+ * @param changed the changed component
+ * @param parent the parent
+ * @param flags the event flags
+ */
+ void fireHierarchyEvent(int id, Component changed, Container parent,
+ long flags)
+ {
+ boolean enabled = false;
+ switch (id)
+ {
+ case HierarchyEvent.HIERARCHY_CHANGED:
+ enabled = hierarchyListener != null
+ || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0;
+ break;
+ case HierarchyEvent.ANCESTOR_MOVED:
+ case HierarchyEvent.ANCESTOR_RESIZED:
+ enabled = hierarchyBoundsListener != null
+ || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0;
+ break;
+ default:
+ assert false : "Should not reach here";
+ }
+ if (enabled)
+ {
+ HierarchyEvent ev = new HierarchyEvent(this, id, changed, parent,
+ flags);
+ dispatchEvent(ev);
+ }
+ }
+
+ /**
* 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.
@@ -3435,18 +3870,24 @@ public abstract class Component
*/
public void addNotify()
{
- if (peer == null)
- peer = getToolkit().createComponent(this);
- else if (parent != null && parent.isLightweight())
- new HeavyweightInLightweightListener(parent);
- /* Now that all the children has gotten their peers, we should
+ // We need to lock the tree here to avoid races and inconsistencies.
+ synchronized (getTreeLock())
+ {
+ if (peer == null)
+ peer = getToolkit().createComponent(this);
+ else if (parent != null && parent.isLightweight())
+ new HeavyweightInLightweightListener(parent);
+ /* 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
+ 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,
etc. */
+ if (dropTarget != null)
+ dropTarget.addNotify(peer);
+ }
}
/**
@@ -3460,17 +3901,21 @@ public abstract class Component
*/
public void removeNotify()
{
- // We null our peer field before disposing of it, such that if we're
- // not the event dispatch thread and the dispatch thread is awoken by
- // the dispose call, there will be no race checking the peer's null
- // status.
-
- ComponentPeer tmp = peer;
- peer = null;
- if (tmp != null)
+ // We need to lock the tree here to avoid races and inconsistencies.
+ synchronized (getTreeLock())
{
- tmp.hide();
- tmp.dispose();
+ // We null our peer field before disposing of it, such that if we're
+ // not the event dispatch thread and the dispatch thread is awoken by
+ // the dispose call, there will be no race checking the peer's null
+ // status.
+
+ ComponentPeer tmp = peer;
+ peer = null;
+ if (tmp != null)
+ {
+ tmp.hide();
+ tmp.dispose();
+ }
}
}
@@ -3791,56 +4236,7 @@ public abstract class Component
*/
public void requestFocus ()
{
- if (isDisplayable ()
- && isShowing ()
- && isFocusable ())
- {
- synchronized (getTreeLock ())
- {
- // Find this Component's top-level ancestor.
- Container parent = (this instanceof Container) ? (Container) this
- : getParent();
- while (parent != null
- && !(parent instanceof Window))
- parent = parent.getParent ();
-
- if (parent == null)
- return;
-
- Window toplevel = (Window) parent;
- if (toplevel.isFocusableWindow ())
- {
- if (peer != null && !isLightweight())
- // This call will cause a FOCUS_GAINED event to be
- // posted to the system event queue if the native
- // windowing system grants the focus request.
- peer.requestFocus ();
- else
- {
- // Either our peer hasn't been created yet or we're a
- // lightweight component. In either case we want to
- // post a FOCUS_GAINED event.
- EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
- synchronized (eq)
- {
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
- Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
- if (currentFocusOwner != null)
- {
- eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
- false, this));
- eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false,
- currentFocusOwner));
- }
- else
- eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, false));
- }
- }
- }
- else
- pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED);
- }
- }
+ requestFocusImpl(false, true);
}
/**
@@ -3880,61 +4276,7 @@ public abstract class Component
*/
protected boolean requestFocus (boolean temporary)
{
- if (isDisplayable ()
- && isShowing ()
- && isFocusable ())
- {
- synchronized (getTreeLock ())
- {
- // Find this Component's top-level ancestor.
- Container parent = getParent ();
-
- while (parent != null
- && !(parent instanceof Window))
- parent = parent.getParent ();
-
- Window toplevel = (Window) parent;
- if (toplevel.isFocusableWindow ())
- {
- if (peer != null && !isLightweight())
- // This call will cause a FOCUS_GAINED event to be
- // posted to the system event queue if the native
- // windowing system grants the focus request.
- peer.requestFocus ();
- else
- {
- // Either our peer hasn't been created yet or we're a
- // lightweight component. In either case we want to
- // post a FOCUS_GAINED event.
- EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
- synchronized (eq)
- {
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
- Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
- if (currentFocusOwner != null)
- {
- eq.postEvent (new FocusEvent(currentFocusOwner,
- FocusEvent.FOCUS_LOST,
- temporary, this));
- eq.postEvent (new FocusEvent(this,
- FocusEvent.FOCUS_GAINED,
- temporary,
- currentFocusOwner));
- }
- else
- eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
- }
- }
- }
- else
- // FIXME: need to add a focus listener to our top-level
- // ancestor, so that we can post this event when it becomes
- // the focused window.
- pendingFocusRequest = new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary);
- }
- }
- // Always return true.
- return true;
+ return requestFocusImpl(temporary, true);
}
/**
@@ -3962,7 +4304,7 @@ public abstract class Component
*/
public boolean requestFocusInWindow ()
{
- return requestFocusInWindow (false);
+ return requestFocusImpl(false, false);
}
/**
@@ -3993,65 +4335,84 @@ public abstract class Component
*/
protected boolean requestFocusInWindow (boolean temporary)
{
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
-
- Window focusedWindow = manager.getFocusedWindow ();
+ return requestFocusImpl(temporary, false);
+ }
- if (isDisplayable ()
- && isShowing ()
- && isFocusable ())
+ /**
+ * Helper method for all 4 requestFocus variants.
+ *
+ * @param temporary indicates if the focus change is temporary
+ * @param focusWindow indicates if the window focus may be changed
+ *
+ * @return <code>false</code> if the request has been definitely denied,
+ * <code>true</code> otherwise
+ */
+ private boolean requestFocusImpl(boolean temporary, boolean focusWindow)
+ {
+ boolean retval = false;
+
+ // Don't try to focus non-focusable and non-visible components.
+ if (isFocusable() && isVisible())
{
- if (focusedWindow != null)
+ ComponentPeer myPeer = peer;
+ if (peer != null)
{
- synchronized (getTreeLock ())
+ // Find Window ancestor and find out if we're showing while
+ // doing this.
+ boolean showing = true;
+ Component window = this;
+ while (! (window instanceof Window))
{
- Container parent = getParent ();
-
- while (parent != null
- && !(parent instanceof Window))
- parent = parent.getParent ();
-
- Window toplevel = (Window) parent;
-
- // Check if top-level ancestor is currently focused window.
- if (focusedWindow == toplevel)
+ if (! window.isVisible())
+ showing = false;
+ window = window.parent;
+ }
+ // Don't allow focus when there is no window or the window
+ // is not focusable.
+ if (window != null && ((Window) window).isFocusableWindow()
+ && showing)
+ {
+ // Search for nearest heavy ancestor (including this
+ // component).
+ Component heavyweightParent = this;
+ while (heavyweightParent.peer instanceof LightweightPeer)
+ heavyweightParent = heavyweightParent.parent;
+
+ // Don't allow focus on lightweight components without
+ // visible heavyweight ancestor
+ if (heavyweightParent != null && heavyweightParent.isVisible())
{
- if (peer != null
- && !isLightweight()
- && !(this instanceof Window))
- // This call will cause a FOCUS_GAINED event to be
- // posted to the system event queue if the native
- // windowing system grants the focus request.
- peer.requestFocus ();
- else
+ // Don't allow focus when heavyweightParent has no peer.
+ myPeer = heavyweightParent.peer;
+ if (myPeer != null)
{
- // Either our peer hasn't been created yet or we're a
- // lightweight component. In either case we want to
- // post a FOCUS_GAINED event.
- EventQueue eq = Toolkit.getDefaultToolkit ().getSystemEventQueue ();
- synchronized (eq)
+ // Register lightweight focus request.
+ if (heavyweightParent != this)
+ {
+ KeyboardFocusManager
+ .addLightweightFocusRequest(heavyweightParent,
+ this);
+ }
+
+ // Try to focus the component.
+ long time = EventQueue.getMostRecentEventTime();
+ boolean success = myPeer.requestFocus(this, temporary,
+ focusWindow,
+ time);
+ if (! success)
{
- Component currentFocusOwner = manager.getGlobalPermanentFocusOwner ();
- if (currentFocusOwner != null)
- {
- eq.postEvent (new FocusEvent(currentFocusOwner, FocusEvent.FOCUS_LOST,
- temporary, this));
- eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary,
- currentFocusOwner));
- }
- else
- eq.postEvent (new FocusEvent(this, FocusEvent.FOCUS_GAINED, temporary));
+ // Dequeue key events if focus request failed.
+ KeyboardFocusManager kfm =
+ KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ kfm.dequeueKeyEvents(time, this);
}
+ retval = success;
}
}
- else
- return false;
}
}
-
- return true;
}
- return false;
+ return retval;
}
/**
@@ -4552,7 +4913,7 @@ p * <li>the set of backward traversal keys
Object newValue)
{
if (changeSupport != null)
- changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+ changeSupport.firePropertyChange(propertyName, oldValue, newValue);
}
/**
@@ -4693,14 +5054,12 @@ p * <li>the set of backward traversal keys
* {@link #applyComponentOrientation(ComponentOrientation)} affects the
* entire hierarchy.
*
- * @param o the new orientation
- * @throws NullPointerException if o is null
+ * @param o the new orientation (<code>null</code> is accepted)
* @see #getComponentOrientation()
*/
public void setComponentOrientation(ComponentOrientation o)
{
- if (o == null)
- throw new NullPointerException();
+
ComponentOrientation oldOrientation = orientation;
orientation = o;
firePropertyChange("componentOrientation", oldOrientation, o);
@@ -4709,7 +5068,7 @@ p * <li>the set of backward traversal keys
/**
* Determines the text layout orientation used by this component.
*
- * @return the component orientation
+ * @return the component orientation (this can be <code>null</code>)
* @see #setComponentOrientation(ComponentOrientation)
*/
public ComponentOrientation getComponentOrientation()
@@ -4864,7 +5223,7 @@ p * <li>the set of backward traversal keys
if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
oldMods |= Event.ALT_MASK;
- if (e instanceof MouseEvent)
+ if (e instanceof MouseEvent && !ignoreOldMouseEvents())
{
if (id == MouseEvent.MOUSE_PRESSED)
oldID = Event.MOUSE_DOWN;
@@ -5045,52 +5404,26 @@ p * <li>the set of backward traversal keys
void dispatchEventImpl(AWTEvent e)
{
- // This boolean tells us not to process focus events when the focus
- // opposite component is the same as the focus component.
- boolean ignoreFocus =
- (e instanceof FocusEvent &&
- ((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent());
-
- if (eventTypeEnabled (e.id))
+ // Retarget focus events before dispatching it to the KeyboardFocusManager
+ // in order to handle lightweight components properly.
+ boolean dispatched = false;
+ if (! e.isFocusManagerEvent)
{
- if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE
- && !ignoreFocus)
- processEvent(e);
-
- // the trick we use to communicate between dispatch and redispatch
- // is to have KeyboardFocusManager.redispatch synchronize on the
- // object itself. we then do not redispatch to KeyboardFocusManager
- // if we are already holding the lock.
- if (! Thread.holdsLock(e))
+ e = KeyboardFocusManager.retargetFocusEvent(e);
+ dispatched = KeyboardFocusManager.getCurrentKeyboardFocusManager()
+ .dispatchEvent(e);
+ }
+
+ if (! dispatched)
+ {
+ if (eventTypeEnabled (e.id))
{
- switch (e.id)
- {
- case WindowEvent.WINDOW_GAINED_FOCUS:
- case WindowEvent.WINDOW_LOST_FOCUS:
- case KeyEvent.KEY_PRESSED:
- case KeyEvent.KEY_RELEASED:
- case KeyEvent.KEY_TYPED:
- case FocusEvent.FOCUS_GAINED:
- case FocusEvent.FOCUS_LOST:
- if (KeyboardFocusManager
- .getCurrentKeyboardFocusManager()
- .dispatchEvent(e))
- return;
- case MouseEvent.MOUSE_PRESSED:
- // A mouse click on an enabled lightweight component
- // which has not yet been marked as consumed by any
- // other mouse listener results in a focus traversal
- // to that component.
- if (isLightweight()
- && isEnabled() && !e.isConsumed())
- requestFocus();
- break;
- }
+ if (e.id != PaintEvent.PAINT && e.id != PaintEvent.UPDATE)
+ processEvent(e);
}
+ if (peer != null)
+ peer.handleEvent(e);
}
-
- if (peer != null)
- peer.handleEvent(e);
}
/**
diff --git a/libjava/classpath/java/awt/Container.java b/libjava/classpath/java/awt/Container.java
index 85a68ce13c2..409d164a13c 100644
--- a/libjava/classpath/java/awt/Container.java
+++ b/libjava/classpath/java/awt/Container.java
@@ -42,6 +42,7 @@ package java.awt;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
+import java.awt.event.HierarchyEvent;
import java.awt.event.KeyEvent;
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
@@ -88,14 +89,16 @@ public class Container extends Component
Dimension maxSize;
/**
- * Keeps track if the Container was cleared during a paint/update.
+ * @since 1.4
*/
- private boolean backCleared;
+ boolean focusCycleRoot;
/**
- * @since 1.4
+ * Indicates if this container provides a focus traversal policy.
+ *
+ * @since 1.5
*/
- boolean focusCycleRoot;
+ private boolean focusTraversalPolicyProvider;
int containerSerializedDataVersion;
@@ -341,7 +344,7 @@ public class Container extends Component
if (component == null)
component = new Component[4]; // FIXME, better initial size?
-
+
// This isn't the most efficient implementation. We could do less
// copying when growing the array. It probably doesn't matter.
if (ncomponents >= component.length)
@@ -362,6 +365,16 @@ public class Container extends Component
++ncomponents;
}
+ // Update the counter for Hierarchy(Bounds)Listeners.
+ int childHierarchyListeners = comp.numHierarchyListeners;
+ if (childHierarchyListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
+ childHierarchyListeners);
+ int childHierarchyBoundsListeners = comp.numHierarchyBoundsListeners;
+ if (childHierarchyBoundsListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
+ childHierarchyListeners);
+
// Notify the layout manager.
if (layoutMgr != null)
{
@@ -388,6 +401,10 @@ public class Container extends Component
ContainerListener[] listeners = getContainerListeners();
for (int i = 0; i < listeners.length; i++)
listeners[i].componentAdded(ce);
+
+ // Notify hierarchy listeners.
+ comp.fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, comp,
+ this, HierarchyEvent.PARENT_CHANGED);
}
}
@@ -412,6 +429,16 @@ public class Container extends Component
ncomponents - index - 1);
component[--ncomponents] = null;
+ // Update the counter for Hierarchy(Bounds)Listeners.
+ int childHierarchyListeners = r.numHierarchyListeners;
+ if (childHierarchyListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
+ -childHierarchyListeners);
+ int childHierarchyBoundsListeners = r.numHierarchyBoundsListeners;
+ if (childHierarchyBoundsListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
+ -childHierarchyListeners);
+
invalidate();
if (layoutMgr != null)
@@ -423,10 +450,14 @@ public class Container extends Component
{
// Post event to notify of removing the component.
ContainerEvent ce = new ContainerEvent(this,
- ContainerEvent.COMPONENT_REMOVED,
- r);
+ ContainerEvent.COMPONENT_REMOVED,
+ r);
getToolkit().getSystemEventQueue().postEvent(ce);
}
+
+ // Notify hierarchy listeners.
+ r.fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, r,
+ this, HierarchyEvent.PARENT_CHANGED);
}
}
@@ -517,7 +548,8 @@ public class Container extends Component
public void setLayout(LayoutManager mgr)
{
layoutMgr = mgr;
- invalidate();
+ if (valid)
+ invalidate();
}
/**
@@ -572,19 +604,22 @@ public class Container extends Component
*/
void invalidateTree()
{
- super.invalidate(); // Clean cached layout state.
- for (int i = 0; i < ncomponents; i++)
+ synchronized (getTreeLock())
{
- Component comp = component[i];
- comp.invalidate();
- if (comp instanceof Container)
- ((Container) comp).invalidateTree();
- }
+ super.invalidate(); // Clean cached layout state.
+ for (int i = 0; i < ncomponents; i++)
+ {
+ Component comp = component[i];
+ comp.invalidate();
+ if (comp instanceof Container)
+ ((Container) comp).invalidateTree();
+ }
- if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
- {
- LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
- lm2.invalidateLayout(this);
+ if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
+ {
+ LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
+ lm2.invalidateLayout(this);
+ }
}
}
@@ -671,21 +706,25 @@ public class Container extends Component
*/
public Dimension preferredSize()
{
- synchronized(treeLock)
- {
- if(valid && prefSize != null)
- return new Dimension(prefSize);
- LayoutManager layout = getLayout();
- if (layout != null)
+ Dimension size = prefSize;
+ // Try to return cached value if possible.
+ if (size == null || !(prefSizeSet || valid))
+ {
+ // Need to lock here.
+ synchronized (getTreeLock())
{
- Dimension layoutSize = layout.preferredLayoutSize(this);
- if(valid)
- prefSize = layoutSize;
- return new Dimension(layoutSize);
+ LayoutManager l = layoutMgr;
+ if (l != null)
+ prefSize = l.preferredLayoutSize(this);
+ else
+ prefSize = super.preferredSizeImpl();
+ size = prefSize;
}
- else
- return super.preferredSize ();
}
+ if (size != null)
+ return new Dimension(size);
+ else
+ return size;
}
/**
@@ -707,17 +746,25 @@ public class Container extends Component
*/
public Dimension minimumSize()
{
- if(valid && minSize != null)
- return new Dimension(minSize);
-
- LayoutManager layout = getLayout();
- if (layout != null)
+ Dimension size = minSize;
+ // Try to return cached value if possible.
+ if (size == null || !(minSizeSet || valid))
{
- minSize = layout.minimumLayoutSize (this);
- return minSize;
- }
+ // Need to lock here.
+ synchronized (getTreeLock())
+ {
+ LayoutManager l = layoutMgr;
+ if (l != null)
+ minSize = l.minimumLayoutSize(this);
+ else
+ minSize = super.minimumSizeImpl();
+ size = minSize;
+ }
+ }
+ if (size != null)
+ return new Dimension(size);
else
- return super.minimumSize ();
+ return size;
}
/**
@@ -727,18 +774,25 @@ public class Container extends Component
*/
public Dimension getMaximumSize()
{
- if (valid && maxSize != null)
- return new Dimension(maxSize);
-
- LayoutManager layout = getLayout();
- if (layout != null && layout instanceof LayoutManager2)
+ Dimension size = maxSize;
+ // Try to return cached value if possible.
+ if (size == null || !(maxSizeSet || valid))
{
- LayoutManager2 lm2 = (LayoutManager2) layout;
- maxSize = lm2.maximumLayoutSize(this);
- return maxSize;
+ // Need to lock here.
+ synchronized (getTreeLock())
+ {
+ LayoutManager l = layoutMgr;
+ if (l instanceof LayoutManager2)
+ maxSize = ((LayoutManager2) l).maximumLayoutSize(this);
+ else
+ maxSize = super.maximumSizeImpl();
+ size = maxSize;
+ }
}
+ if (size != null)
+ return new Dimension(size);
else
- return super.getMaximumSize();
+ return size;
}
/**
@@ -754,8 +808,11 @@ public class Container extends Component
float alignmentX = 0.0F;
if (layout != null && layout instanceof LayoutManager2)
{
- LayoutManager2 lm2 = (LayoutManager2) layout;
- alignmentX = lm2.getLayoutAlignmentX(this);
+ synchronized (getTreeLock())
+ {
+ LayoutManager2 lm2 = (LayoutManager2) layout;
+ alignmentX = lm2.getLayoutAlignmentX(this);
+ }
}
else
alignmentX = super.getAlignmentX();
@@ -775,8 +832,11 @@ public class Container extends Component
float alignmentY = 0.0F;
if (layout != null && layout instanceof LayoutManager2)
{
- LayoutManager2 lm2 = (LayoutManager2) layout;
- alignmentY = lm2.getLayoutAlignmentY(this);
+ synchronized (getTreeLock())
+ {
+ LayoutManager2 lm2 = (LayoutManager2) layout;
+ alignmentY = lm2.getLayoutAlignmentY(this);
+ }
}
else
alignmentY = super.getAlignmentY();
@@ -794,13 +854,10 @@ public class Container extends Component
*/
public void paint(Graphics g)
{
- if (!isShowing())
- return;
-
- // Visit heavyweights if the background was cleared
- // for this container.
- visitChildren(g, GfxPaintVisitor.INSTANCE, !backCleared);
- backCleared = false;
+ if (isShowing())
+ {
+ visitChildren(g, GfxPaintVisitor.INSTANCE, true);
+ }
}
/**
@@ -830,14 +887,15 @@ public class Container extends Component
// that overrides isLightweight() to return false, the background is
// also not cleared. So we do a check on !(peer instanceof LightweightPeer)
// instead.
- ComponentPeer p = peer;
- if (p != null && ! (p instanceof LightweightPeer))
+ if (isShowing())
{
- g.clearRect(0, 0, getWidth(), getHeight());
- backCleared = true;
+ ComponentPeer p = peer;
+ if (! (p instanceof LightweightPeer))
+ {
+ g.clearRect(0, 0, getWidth(), getHeight());
+ }
+ paint(g);
}
-
- paint(g);
}
/**
@@ -1173,8 +1231,11 @@ public class Container extends Component
*/
public void addNotify()
{
- super.addNotify();
- addNotifyContainerChildren();
+ synchronized (getTreeLock())
+ {
+ super.addNotify();
+ addNotifyContainerChildren();
+ }
}
/**
@@ -1549,6 +1610,42 @@ public class Container extends Component
}
/**
+ * Set to <code>true</code> if this container provides a focus traversal
+ * policy, <code>false</code> when the root container's focus
+ * traversal policy should be used.
+ *
+ * @return <code>true</code> if this container provides a focus traversal
+ * policy, <code>false</code> when the root container's focus
+ * traversal policy should be used
+ *
+ * @see #setFocusTraversalPolicyProvider(boolean)
+ *
+ * @since 1.5
+ */
+ public final boolean isFocusTraversalPolicyProvider()
+ {
+ return focusTraversalPolicyProvider;
+ }
+
+ /**
+ * Set to <code>true</code> if this container provides a focus traversal
+ * policy, <code>false</code> when the root container's focus
+ * traversal policy should be used.
+ *
+ * @param b <code>true</code> if this container provides a focus traversal
+ * policy, <code>false</code> when the root container's focus
+ * traversal policy should be used
+ *
+ * @see #isFocusTraversalPolicyProvider()
+ *
+ * @since 1.5
+ */
+ public final void setFocusTraversalPolicyProvider(boolean b)
+ {
+ focusTraversalPolicyProvider = b;
+ }
+
+ /**
* Check whether this Container is a focus cycle root.
*
* @return true if this is a focus cycle root, false otherwise
@@ -1594,7 +1691,16 @@ public class Container extends Component
public void applyComponentOrientation (ComponentOrientation orientation)
{
if (orientation == null)
- throw new NullPointerException ();
+ throw new NullPointerException();
+
+ setComponentOrientation(orientation);
+ for (int i = 0; i < ncomponents; i++)
+ {
+ if (component[i] instanceof Container)
+ ((Container) component[i]).applyComponentOrientation(orientation);
+ else
+ component[i].setComponentOrientation(orientation);
+ }
}
public void addPropertyChangeListener (PropertyChangeListener listener)
@@ -1646,24 +1752,27 @@ public class Container extends Component
if (comp == this)
throw new IllegalArgumentException("cannot add component to itself");
- // FIXME: Implement reparenting.
- if ( comp.getParent() != this)
- throw new AssertionError("Reparenting is not implemented yet");
- else
+ synchronized (getTreeLock())
{
- // Find current component index.
- int currentIndex = getComponentZOrder(comp);
- if (currentIndex < index)
- {
- System.arraycopy(component, currentIndex + 1, component,
- currentIndex, index - currentIndex);
- }
+ // FIXME: Implement reparenting.
+ if ( comp.getParent() != this)
+ throw new AssertionError("Reparenting is not implemented yet");
else
{
- System.arraycopy(component, index, component, index + 1,
- currentIndex - index);
+ // Find current component index.
+ int currentIndex = getComponentZOrder(comp);
+ if (currentIndex < index)
+ {
+ System.arraycopy(component, currentIndex + 1, component,
+ currentIndex, index - currentIndex);
+ }
+ else
+ {
+ System.arraycopy(component, index, component, index + 1,
+ currentIndex - index);
+ }
+ component[index] = comp;
}
- component[index] = comp;
}
}
@@ -1682,19 +1791,22 @@ public class Container extends Component
*/
public final int getComponentZOrder(Component comp)
{
- int index = -1;
- if (component != null)
+ synchronized (getTreeLock())
{
- for (int i = 0; i < component.length; i++)
+ int index = -1;
+ if (component != null)
{
- if (component[i] == comp)
+ for (int i = 0; i < ncomponents; i++)
{
- index = i;
- break;
+ if (component[i] == comp)
+ {
+ index = i;
+ break;
+ }
}
}
+ return index;
}
- return index;
}
// Hidden helper methods.
@@ -1850,6 +1962,48 @@ public class Container extends Component
}
}
+ /**
+ * Fires hierarchy events to the children of this container and this
+ * container itself. This overrides {@link Component#fireHierarchyEvent}
+ * in order to forward this event to all children.
+ */
+ void fireHierarchyEvent(int id, Component changed, Container parent,
+ long flags)
+ {
+ // Only propagate event if there is actually a listener waiting for it.
+ if ((id == HierarchyEvent.HIERARCHY_CHANGED && numHierarchyListeners > 0)
+ || ((id == HierarchyEvent.ANCESTOR_MOVED
+ || id == HierarchyEvent.ANCESTOR_RESIZED)
+ && numHierarchyBoundsListeners > 0))
+ {
+ for (int i = 0; i < ncomponents; i++)
+ component[i].fireHierarchyEvent(id, changed, parent, flags);
+ super.fireHierarchyEvent(id, changed, parent, flags);
+ }
+ }
+
+ /**
+ * Adjusts the number of hierarchy listeners of this container and all of
+ * its parents. This is called by the add/remove listener methods and
+ * structure changing methods in Container.
+ *
+ * @param type the type, either {@link AWTEvent#HIERARCHY_BOUNDS_EVENT_MASK}
+ * or {@link AWTEvent#HIERARCHY_EVENT_MASK}
+ * @param delta the number of listeners added or removed
+ */
+ void updateHierarchyListenerCount(long type, int delta)
+ {
+ if (type == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)
+ numHierarchyBoundsListeners += delta;
+ else if (type == AWTEvent.HIERARCHY_EVENT_MASK)
+ numHierarchyListeners += delta;
+ else
+ assert false : "Should not reach here";
+
+ if (parent != null)
+ parent.updateHierarchyListenerCount(type, delta);
+ }
+
private void addNotifyContainerChildren()
{
synchronized (getTreeLock ())
diff --git a/libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java b/libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java
index 23b4ac2e8d3..14afd364876 100644
--- a/libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java
+++ b/libjava/classpath/java/awt/ContainerOrderFocusTraversalPolicy.java
@@ -346,28 +346,30 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
|| !root.isDisplayable ())
return null;
- if (root.visible && root.isDisplayable() && root.enabled
- && root.focusable)
+ if (accept(root))
return root;
- Component[] componentArray = root.getComponents ();
-
- for (int i = 0; i < componentArray.length; i++)
+ int ncomponents = root.getComponentCount();
+ for (int i = 0; i < ncomponents; i++)
{
- Component component = componentArray [i];
-
- if (component.visible && component.isDisplayable() && component.enabled
- && component.focusable)
- return component;
-
- if (component instanceof Container)
+ Component component = root.getComponent(i);
+ if (component instanceof Container
+ && !((Container) component).isFocusCycleRoot())
{
- Component result = getFirstComponent ((Container) component);
-
- if (result != null
- && (result.visible && result.isDisplayable() && result.enabled && result.focusable))
- return result;
+ Component first = null;
+ Container cont = (Container) component;
+ if (cont.isFocusTraversalPolicyProvider())
+ {
+ FocusTraversalPolicy childPol = cont.getFocusTraversalPolicy();
+ first = childPol.getFirstComponent(cont);
+ }
+ else
+ first = getFirstComponent(cont);
+ if (first != null)
+ return first;
}
+ else if (accept(component))
+ return component;
}
return null;
diff --git a/libjava/classpath/java/awt/Cursor.java b/libjava/classpath/java/awt/Cursor.java
index 0ff987cd9ed..4d339b7211a 100644
--- a/libjava/classpath/java/awt/Cursor.java
+++ b/libjava/classpath/java/awt/Cursor.java
@@ -116,6 +116,16 @@ public class Cursor implements java.io.Serializable
*/
public static final int MOVE_CURSOR = 13;
+ private static String[] NAMES = { "Default Cursor", "Crosshair Cursor",
+ "Text Cursor", "Wait Cursor",
+ "Southwest Resize Cursor",
+ "Southeast Resize Cursor",
+ "Northwest Resize Cursor",
+ "Northeast Resize Cursor",
+ "North Resize Cursor", "South Resize Cursor",
+ "West Resize Cursor", "East Resize Cursor",
+ "Hand Cursor", "Move Cursor" };
+
public static final int CUSTOM_CURSOR = 0xFFFFFFFF;
private static final int PREDEFINED_COUNT = 14;
@@ -142,7 +152,10 @@ public class Cursor implements java.io.Serializable
throw new IllegalArgumentException ("invalid cursor " + type);
this.type = type;
- // FIXME: lookup and set name?
+
+ name = NAMES[type];
+
+ // FIXME: lookup?
}
/** This constructor is used internally only.
diff --git a/libjava/classpath/java/awt/DefaultKeyboardFocusManager.java b/libjava/classpath/java/awt/DefaultKeyboardFocusManager.java
index 037cb834c40..9fea99b7839 100644
--- a/libjava/classpath/java/awt/DefaultKeyboardFocusManager.java
+++ b/libjava/classpath/java/awt/DefaultKeyboardFocusManager.java
@@ -163,7 +163,13 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager
if (e.id == WindowEvent.WINDOW_ACTIVATED)
setGlobalActiveWindow (target);
else if (e.id == WindowEvent.WINDOW_GAINED_FOCUS)
- setGlobalFocusedWindow (target);
+ {
+ setGlobalFocusedWindow (target);
+ FocusTraversalPolicy p = target.getFocusTraversalPolicy();
+ Component toFocus = p.getInitialComponent(target);
+ if (toFocus != null)
+ toFocus.requestFocusInWindow();
+ }
else if (e.id != WindowEvent.WINDOW_LOST_FOCUS
&& e.id != WindowEvent.WINDOW_DEACTIVATED)
return false;
@@ -173,51 +179,18 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager
}
else if (e instanceof FocusEvent)
{
- Component target = (Component) e.getSource ();
+ FocusEvent fe = (FocusEvent) e;
+ Component target = fe.getComponent ();
+ boolean retval = false;
if (e.id == FocusEvent.FOCUS_GAINED)
{
- if (! (target instanceof Window))
- {
- if (((FocusEvent) e).isTemporary ())
- setGlobalFocusOwner (target);
- else
- setGlobalPermanentFocusOwner (target);
- }
-
- // Keep track of this window's focus owner.
-
- // Find the target Component's top-level ancestor. target
- // may be a window.
- Container parent = target.getParent ();
-
- while (parent != null
- && !(parent instanceof Window))
- parent = parent.getParent ();
-
- // If the parent is null and target is not a window, then target is an
- // unanchored component and so we don't want to set the focus owner.
- if (! (parent == null && ! (target instanceof Window)))
- {
- Window toplevel = parent == null ?
- (Window) target : (Window) parent;
-
- Component focusOwner = getFocusOwner ();
- if (focusOwner != null
- && ! (focusOwner instanceof Window))
- toplevel.setFocusOwner (focusOwner);
- }
+ retval = handleFocusGained(fe);
}
else if (e.id == FocusEvent.FOCUS_LOST)
{
- if (((FocusEvent) e).isTemporary ())
- setGlobalFocusOwner (null);
- else
- setGlobalPermanentFocusOwner (null);
+ retval = handleFocusLost(fe);
}
-
- redispatchEvent(target, e);
-
return true;
}
else if (e instanceof KeyEvent)
@@ -256,6 +229,95 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager
return false;
}
+ /**
+ * Handles FOCUS_GAINED events in {@link #dispatchEvent(AWTEvent)}.
+ *
+ * @param fe the focus event
+ */
+ private boolean handleFocusGained(FocusEvent fe)
+ {
+ Component target = fe.getComponent ();
+
+ // If old focus owner != new focus owner, notify old focus
+ // owner that it has lost focus.
+ Component oldFocusOwner = getGlobalFocusOwner();
+ if (oldFocusOwner != null && oldFocusOwner != target)
+ {
+ FocusEvent lost = new FocusEvent(oldFocusOwner,
+ FocusEvent.FOCUS_LOST,
+ fe.isTemporary(), target);
+ oldFocusOwner.dispatchEvent(lost);
+ }
+
+ setGlobalFocusOwner (target);
+ if (target != getGlobalFocusOwner())
+ {
+ // Focus transfer was rejected, like when the target is not
+ // focusable.
+ dequeueKeyEvents(-1, target);
+ // FIXME: Restore focus somehow.
+ }
+ else
+ {
+ if (! fe.isTemporary())
+ {
+ setGlobalPermanentFocusOwner (target);
+ if (target != getGlobalPermanentFocusOwner())
+ {
+ // Focus transfer was rejected, like when the target is not
+ // focusable.
+ dequeueKeyEvents(-1, target);
+ // FIXME: Restore focus somehow.
+ }
+ else
+ {
+ redispatchEvent(target, fe);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Handles FOCUS_LOST events for {@link #dispatchEvent(AWTEvent)}.
+ *
+ * @param fe the focus event
+ *
+ * @return if the event has been handled
+ */
+ private boolean handleFocusLost(FocusEvent fe)
+ {
+ Component currentFocus = getGlobalFocusOwner();
+ if (currentFocus != fe.getOppositeComponent())
+ {
+ setGlobalFocusOwner(null);
+ if (getGlobalFocusOwner() != null)
+ {
+ // TODO: Is this possible? If so, then we should try to restore
+ // the focus.
+ }
+ else
+ {
+ if (! fe.isTemporary())
+ {
+ setGlobalPermanentFocusOwner(null);
+ if (getGlobalPermanentFocusOwner() != null)
+ {
+ // TODO: Is this possible? If so, then we should try to
+ // restore the focus.
+ }
+ else
+ {
+ fe.setSource(currentFocus);
+ redispatchEvent(currentFocus, fe);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
private boolean enqueueKeyEvent (KeyEvent e)
{
Iterator i = delayRequests.iterator ();
diff --git a/libjava/classpath/java/awt/EventDispatchThread.java b/libjava/classpath/java/awt/EventDispatchThread.java
index 7cb8af831bf..074a84975ac 100644
--- a/libjava/classpath/java/awt/EventDispatchThread.java
+++ b/libjava/classpath/java/awt/EventDispatchThread.java
@@ -82,17 +82,7 @@ class EventDispatchThread extends Thread
try
{
AWTEvent evt = queue.getNextEvent();
-
- KeyboardFocusManager manager;
- manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
-
- // Try to dispatch this event to the current keyboard focus
- // manager. It will dispatch all FocusEvents, all
- // WindowEvents related to focus, and all KeyEvents,
- // returning true. Otherwise, it returns false and we
- // dispatch the event normally.
- if (!manager.dispatchEvent (evt))
- queue.dispatchEvent(evt);
+ queue.dispatchEvent(evt);
}
catch (ThreadDeath death)
{
diff --git a/libjava/classpath/java/awt/FileDialog.java b/libjava/classpath/java/awt/FileDialog.java
index 7f2723e7e9a..f02d06be2c9 100644
--- a/libjava/classpath/java/awt/FileDialog.java
+++ b/libjava/classpath/java/awt/FileDialog.java
@@ -101,6 +101,58 @@ private int mode;
* Constructors
*/
+ /**
+ * Initializes a new instance of <code>FileDialog</code> with the specified
+ * parent. This dialog will have no title and will be for loading a file.
+ *
+ * @param parent The parent dialog for this.
+ *
+ * @since 1.5
+ */
+ public FileDialog(Dialog parent)
+ {
+ this(parent, "", LOAD);
+ }
+
+ /**
+ * Initialized a new instance of <code>FileDialog</code> with the
+ * specified parent and title. This dialog will be for opening a file.
+ *
+ * @param parent The parent dialog for this.
+ * @param title The title for this dialog.
+ *
+ * @since 1.5
+ */
+ public FileDialog(Dialog parent, String title)
+ {
+ this(parent, title, LOAD);
+ }
+
+ /**
+ * Initialized a new instance of <code>FileDialog</code> with the specified
+ * parent, title, and mode.
+ *
+ * @param parent The parent dialog for this.
+ * @param title The title for this dialog.
+ * @param mode The mode of the dialog, either <code>LOAD</code> or
+ * <code>SAVE</code>.
+ * @throws IllegalArgumentException - if illegal mode, if
+ * GraphicsEnvironment.isHeadless or if parent is null.
+ *
+ * @since 1.5
+ */
+ public FileDialog(Dialog parent, String title, int mode)
+ {
+ super(parent, title, true);
+
+ // Other IllegalArgumentException cases are taken care of in Window.java
+ if (mode != LOAD && mode != SAVE)
+ throw new IllegalArgumentException (
+ "Mode argument must be either LOAD or SAVE");
+
+ setMode(mode);
+ }
+
/**
* Initializes a new instance of <code>FileDialog</code> with the
* specified parent. This dialog will have no title and will be for
diff --git a/libjava/classpath/java/awt/FlowLayout.java b/libjava/classpath/java/awt/FlowLayout.java
index 7d0771d915b..8c99195289a 100644
--- a/libjava/classpath/java/awt/FlowLayout.java
+++ b/libjava/classpath/java/awt/FlowLayout.java
@@ -276,26 +276,24 @@ public class FlowLayout implements LayoutManager, Serializable
}
/**
- * Sets the horizontal gap between components to the specified value.
- *
+ * Sets the horizontal gap between lines of components to the specified value.
+ * No Exception is thrown if hgap < 0.
+ *
* @param hgap The new horizontal gap between components.
*/
public void setHgap (int hgap)
{
- if (hgap < 0)
- throw new IllegalArgumentException ("horizontal gap must be nonnegative");
this.hgap = hgap;
}
/**
* Sets the vertical gap between lines of components to the specified value.
+ * No Exception is thrown if vgap < 0.
*
* @param vgap The new vertical gap.
*/
public void setVgap (int vgap)
{
- if (vgap < 0)
- throw new IllegalArgumentException ("vertical gap must be nonnegative");
this.vgap = vgap;
}
diff --git a/libjava/classpath/java/awt/Font.java b/libjava/classpath/java/awt/Font.java
index a52f63408da..1c22ce7b48f 100644
--- a/libjava/classpath/java/awt/Font.java
+++ b/libjava/classpath/java/awt/Font.java
@@ -48,6 +48,8 @@ import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.peer.FontPeer;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
@@ -114,7 +116,14 @@ public class Font implements Serializable
* @since 1.3
*/
public static final int TRUETYPE_FONT = 0;
-
+
+ /**
+ * Indicates to <code>createFont</code> that the supplied font data
+ * is in Type1 format.
+ *
+ * @since 1.5
+ */
+ public static final int TYPE1_FONT = 1;
/**
* A flag for <code>layoutGlyphVector</code>, indicating that the
@@ -576,6 +585,34 @@ public class Font implements Serializable
}
/**
+ * Creates a new font from a File object.
+ *
+ * @see #layoutGlyphVector(FontRenderContext, char[], int, int, int)
+ *
+ * @param fontFormat - Integer code indicating the format the font data is
+ * in.Currently this can only be {@link #TRUETYPE_FONT}.
+ * @param file - a {@link File} from which font data will be read.
+ *
+ * @return A new {@link Font} of the format indicated.
+ *
+ * @throws IllegalArgumentException if <code>fontType</code> is not
+ * recognized.
+ * @throws NullPointerException if <code>file</code> is <code>null</code>.
+ * @throws FontFormatException if data in the file is invalid or cannot be read..
+ * @throws SecurityException if the caller has no read permission for the file.
+ * @throws IOException if the file cannot be read
+ *
+ * @since 1.5
+ */
+ public static Font createFont (int fontFormat, File file)
+ throws FontFormatException, IOException
+ {
+ if( file == null )
+ throw new NullPointerException("Null file argument");
+ return tk().createFont(fontFormat, new FileInputStream( file ));
+ }
+
+ /**
* Maps characters to glyphs in a one-to-one relationship, returning a new
* {@link GlyphVector} with a mapped glyph for each input character. This
* sort of mapping is often sufficient for some scripts such as Roman, but
diff --git a/libjava/classpath/java/awt/Graphics2D.java b/libjava/classpath/java/awt/Graphics2D.java
index b3ecbc58a98..ada13edc512 100644
--- a/libjava/classpath/java/awt/Graphics2D.java
+++ b/libjava/classpath/java/awt/Graphics2D.java
@@ -53,23 +53,21 @@ import java.util.Map;
/**
* An abstract class defining a device independent two-dimensional vector
* graphics API. Concrete subclasses implement this API for output of
- * vector graphics to: (*)
+ * vector graphics to:
* <p>
* <ul>
* <li>a {@link javax.swing.JComponent} - in the
* {@link javax.swing.JComponent#paint(Graphics)} method, the incoming
* {@link Graphics} should always be an instance of
- * <code>Graphics2D</code> (*);</li>
+ * <code>Graphics2D</code>;</li>
* <li>a {@link BufferedImage} - see
- * {@link BufferedImage#createGraphics()} (*);</li>
+ * {@link BufferedImage#createGraphics()};</li>
* <li>a {@link java.awt.print.PrinterJob} - in the
* {@link Printable#print(Graphics, PageFormat, int)} method, the incoming
- * {@link Graphics} should always be an instance of <code>Graphics2D</code>
- * (*).</li>
+ * {@link Graphics} should always be an instance of
+ * <code>Graphics2D</code>.</li>
* </ul>
* <p>
- * (*) Support for this API is not fully implemented in GNU Classpath yet.
- * <p>
* Third party libraries provide support for output to other formats via this
* API, including encapsulated postscript (EPS), portable document format (PDF),
* and scalable vector graphics (SVG).
diff --git a/libjava/classpath/java/awt/GridBagConstraints.java b/libjava/classpath/java/awt/GridBagConstraints.java
index 8d8b4fae534..a6a64c3bb8b 100644
--- a/libjava/classpath/java/awt/GridBagConstraints.java
+++ b/libjava/classpath/java/awt/GridBagConstraints.java
@@ -48,62 +48,99 @@ public class GridBagConstraints implements Cloneable, Serializable
{
static final long serialVersionUID = -1000070633030801713L;
- /** Fill in both directions. */
- public static final int BOTH = 1;
- /** Don't fill. */
+ // Fill values.
+ /**
+ * Don't fill.
+ */
public static final int NONE = 0;
- /** Fill horizontally. */
+
+ /**
+ * Fill in both directions.
+ */
+ public static final int BOTH = 1;
+
+ /**
+ * Fill horizontally.
+ */
public static final int HORIZONTAL = 2;
- /** Fill vertically. */
+
+ /**
+ * Fill vertically.
+ */
public static final int VERTICAL = 3;
- /** Position in the center. */
+ // Anchor values.
+ /**
+ * Position in the center.
+ */
public static final int CENTER = 10;
- /** Position to the east. */
- public static final int EAST = 13;
- /** Position to the north. */
+
+ /**
+ * Position to the north.
+ */
public static final int NORTH = 11;
- /** Position to the northeast. */
+
+ /**
+ * Position to the northeast.
+ */
public static final int NORTHEAST = 12;
- /** Position to the northwest. */
- public static final int NORTHWEST = 18;
- /** Position to the south. */
- public static final int SOUTH = 15;
- /** Position to the southeast. */
+
+ /**
+ * Position to the east.
+ */
+ public static final int EAST = 13;
+
+ /**
+ * Position to the southeast.
+ */
public static final int SOUTHEAST = 14;
- /** Position to the southwest. */
+
+ /**
+ * Position to the south.
+ */
+ public static final int SOUTH = 15;
+
+ /**
+ * Position to the southwest.
+ */
public static final int SOUTHWEST = 16;
- /** Position to the west. */
+
+ /**
+ * Position to the west.
+ */
public static final int WEST = 17;
- /** Occupy all remaining cells except last cell. */
+ /**
+ * Position to the northwest.
+ */
+ public static final int NORTHWEST = 18;
+
+ // gridx and gridy values.
+ /**
+ * Occupy all remaining cells except last cell.
+ */
public static final int RELATIVE = -1;
- /** Occupy all remaining cells. */
- public static final int REMAINDER = 0;
/**
- * Position to where the first text line would end. Equals to NORTHEAST for
- * horizontal left-to-right orientations.
+ * Occupy all remaining cells.
*/
- public static final int FIRST_LINE_END = 24;
+ public static final int REMAINDER = 0;
/**
- * Position to where the first text line would start. Equals to NORTHWEST for
- * horizontal left-to-right orientations.
+ * Position to where a page starts. Equals NORTH for horizontal orientations.
*/
- public static final int FIRST_LINE_START = 23;
+ public static final int PAGE_START = 19;
/**
- * Position to where the last text line would end. Equals to SOUTHEAST for
- * horizontal left-to-right orientations.
+ * Position to where a page ends. Equals SOUTH for horizontal orientations.
*/
- public static final int LAST_LINE_END = 26;
+ public static final int PAGE_END = 20;
/**
- * Position to where the last text line would start. Equals to SOUTHWEST for
- * horizontal left-to-right orientations.
+ * Position to where a text line would start. Equals to WEST for
+ * left-to-right orientations.
*/
- public static final int LAST_LINE_START = 25;
+ public static final int LINE_START = 21;
/**
* Position to where a text line would end. Equals to EAST for
@@ -112,20 +149,28 @@ public class GridBagConstraints implements Cloneable, Serializable
public static final int LINE_END = 22;
/**
- * Position to where a text line would start. Equals to WEST for
- * left-to-right orientations.
+ * Position to where the first text line would start. Equals to NORTHWEST for
+ * horizontal left-to-right orientations.
*/
- public static final int LINE_START = 21;
+ public static final int FIRST_LINE_START = 23;
/**
- * Position to where a page ends. Equals SOUTH for horizontal orientations.
+ * Position to where the first text line would end. Equals to NORTHEAST for
+ * horizontal left-to-right orientations.
*/
- public static final int PAGE_END = 20;
+ public static final int FIRST_LINE_END = 24;
/**
- * Position to where a page starts. Equals NORTH for horizontal orientations.
+ * Position to where the last text line would start. Equals to SOUTHWEST for
+ * horizontal left-to-right orientations.
*/
- public static final int PAGE_START = 19;
+ public static final int LAST_LINE_START = 25;
+
+ /**
+ * Position to where the last text line would end. Equals to SOUTHEAST for
+ * horizontal left-to-right orientations.
+ */
+ public static final int LAST_LINE_END = 26;
public int anchor;
public int fill;
@@ -139,7 +184,9 @@ public class GridBagConstraints implements Cloneable, Serializable
public double weightx;
public double weighty;
- /** Create a copy of this object. */
+ /**
+ * Create a copy of this object.
+ */
public Object clone ()
{
try
@@ -155,8 +202,10 @@ public class GridBagConstraints implements Cloneable, Serializable
}
}
- /** Create a new GridBagConstraints object with the default
- * parameters. */
+ /**
+ * Create a new GridBagConstraints object with the default
+ * parameters.
+ */
public GridBagConstraints ()
{
this.anchor = CENTER;
@@ -172,8 +221,10 @@ public class GridBagConstraints implements Cloneable, Serializable
this.weighty = 0;
}
- /** Create a new GridBagConstraints object with the indicated
- * parameters. */
+ /**
+ * Create a new GridBagConstraints object with the indicated
+ * parameters.
+ */
public GridBagConstraints (int gridx, int gridy,
int gridwidth, int gridheight,
double weightx, double weighty,
diff --git a/libjava/classpath/java/awt/GridBagLayout.java b/libjava/classpath/java/awt/GridBagLayout.java
index f827d21ca6a..d84b7d6df6c 100644
--- a/libjava/classpath/java/awt/GridBagLayout.java
+++ b/libjava/classpath/java/awt/GridBagLayout.java
@@ -1,5 +1,5 @@
/* GridBagLayout - Layout manager for components according to GridBagConstraints
- Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,6 @@ exception statement from your version. */
package java.awt;
-import gnu.classpath.NotImplementedException;
-
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
@@ -322,13 +320,24 @@ public class GridBagLayout
}
/**
- * Obsolete.
+ * Move and resize a rectangle according to a set of grid bag
+ * constraints. The x, y, width and height fields of the
+ * rectangle argument are adjusted to the new values.
+ *
+ * @param constraints position and size constraints
+ * @param r rectangle to be moved and resized
*/
- protected void AdjustForGravity (GridBagConstraints gbc, Rectangle rect)
- throws NotImplementedException
+ protected void AdjustForGravity (GridBagConstraints constraints,
+ Rectangle r)
{
- // FIXME
- throw new Error ("Not implemented");
+ Insets insets = constraints.insets;
+ if (insets != null)
+ {
+ r.x += insets.left;
+ r.y += insets.top;
+ r.width -= insets.left + insets.right;
+ r.height -= insets.top + insets.bottom;
+ }
}
/**
@@ -353,10 +362,9 @@ public class GridBagLayout
// layoutInfo. So we wait until after this for loop to set
// layoutInfo.
Component lastComp = null;
- int cellx = 0;
- int celly = 0;
- int cellw = 0;
- int cellh = 0;
+
+ Rectangle cell = new Rectangle();
+
for (int i = 0; i < components.length; i++)
{
Component component = components[i];
@@ -370,29 +378,23 @@ public class GridBagLayout
if (lastComp != null
&& constraints.gridheight == GridBagConstraints.REMAINDER)
- celly += cellh;
+ cell.y += cell.height;
else
- celly = sumIntArray(info.rowHeights, constraints.gridy);
+ cell.y = sumIntArray(info.rowHeights, constraints.gridy);
if (lastComp != null
&& constraints.gridwidth == GridBagConstraints.REMAINDER)
- cellx += cellw;
+ cell.x += cell.width;
else
- cellx = sumIntArray(info.colWidths, constraints.gridx);
+ cell.x = sumIntArray(info.colWidths, constraints.gridx);
- cellw = sumIntArray(info.colWidths, constraints.gridx
- + constraints.gridwidth) - cellx;
- cellh = sumIntArray(info.rowHeights, constraints.gridy
- + constraints.gridheight) - celly;
-
- Insets insets = constraints.insets;
- if (insets != null)
- {
- cellx += insets.left;
- celly += insets.top;
- cellw -= insets.left + insets.right;
- cellh -= insets.top + insets.bottom;
- }
+ cell.width = sumIntArray(info.colWidths, constraints.gridx
+ + constraints.gridwidth) - cell.x;
+ cell.height = sumIntArray(info.rowHeights, constraints.gridy
+ + constraints.gridheight) - cell.y;
+
+ // Adjust for insets.
+ AdjustForGravity( constraints, cell );
// Note: Documentation says that padding is added on both sides, but
// visual inspection shows that the Sun implementation only adds it
@@ -403,14 +405,14 @@ public class GridBagLayout
switch (constraints.fill)
{
case GridBagConstraints.HORIZONTAL:
- dim.width = cellw;
+ dim.width = cell.width;
break;
case GridBagConstraints.VERTICAL:
- dim.height = cellh;
+ dim.height = cell.height;
break;
case GridBagConstraints.BOTH:
- dim.width = cellw;
- dim.height = cellh;
+ dim.width = cell.width;
+ dim.height = cell.height;
break;
}
@@ -420,40 +422,40 @@ public class GridBagLayout
switch (constraints.anchor)
{
case GridBagConstraints.NORTH:
- x = cellx + (cellw - dim.width) / 2;
- y = celly;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y;
break;
case GridBagConstraints.SOUTH:
- x = cellx + (cellw - dim.width) / 2;
- y = celly + cellh - dim.height;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y + cell.height - dim.height;
break;
case GridBagConstraints.WEST:
- x = cellx;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
case GridBagConstraints.EAST:
- x = cellx + cellw - dim.width;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
case GridBagConstraints.NORTHEAST:
- x = cellx + cellw - dim.width;
- y = celly;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y;
break;
case GridBagConstraints.NORTHWEST:
- x = cellx;
- y = celly;
+ x = cell.x;
+ y = cell.y;
break;
case GridBagConstraints.SOUTHEAST:
- x = cellx + cellw - dim.width;
- y = celly + cellh - dim.height;
+ x = cell.x + cell.width - dim.width;
+ y = cell.y + cell.height - dim.height;
break;
case GridBagConstraints.SOUTHWEST:
- x = cellx;
- y = celly + cellh - dim.height;
+ x = cell.x;
+ y = cell.y + cell.height - dim.height;
break;
default:
- x = cellx + (cellw - dim.width) / 2;
- y = celly + (cellh - dim.height) / 2;
+ x = cell.x + (cell.width - dim.width) / 2;
+ y = cell.y + (cell.height - dim.height) / 2;
break;
}
component.setBounds(info.pos_x + x, info.pos_y + y, dim.width,
@@ -1082,10 +1084,18 @@ public class GridBagLayout
}
/**
+ * Move and resize a rectangle according to a set of grid bag
+ * constraints. The x, y, width and height fields of the
+ * rectangle argument are adjusted to the new values.
+ *
+ * @param constraints position and size constraints
+ * @param r rectangle to be moved and resized
+ *
* @since 1.4
*/
- protected void adjustForGravity (GridBagConstraints gbc, Rectangle rect)
+ protected void adjustForGravity (GridBagConstraints constraints,
+ Rectangle r)
{
- AdjustForGravity (gbc, rect);
+ AdjustForGravity (constraints, r);
}
}
diff --git a/libjava/classpath/java/awt/GridLayout.java b/libjava/classpath/java/awt/GridLayout.java
index 80d96414249..a6836681da5 100644
--- a/libjava/classpath/java/awt/GridLayout.java
+++ b/libjava/classpath/java/awt/GridLayout.java
@@ -254,14 +254,11 @@ public class GridLayout implements LayoutManager, Serializable
this.cols = newCols;
}
- /** Set the horizontal gap
+ /** Set the horizontal gap. An Exception is not thrown if hgap < 0.
* @param hgap The horizontal gap
- * @exception IllegalArgumentException If the hgap value is less than zero.
*/
public void setHgap (int hgap)
{
- if (hgap < 0)
- throw new IllegalArgumentException ("horizontal gap must be nonnegative");
this.hgap = hgap;
}
@@ -280,21 +277,18 @@ public class GridLayout implements LayoutManager, Serializable
this.rows = newRows;
}
- /** Set the vertical gap.
+ /** Set the vertical gap. An Exception is not thrown if vgap < 0.
* @param vgap The vertical gap
- * @exception IllegalArgumentException If the vgap value is less than zero.
*/
public void setVgap (int vgap)
{
- if (vgap < 0)
- throw new IllegalArgumentException ("vertical gap must be nonnegative");
this.vgap = vgap;
}
/** Return String description of this object. */
public String toString ()
{
- return ("[" + getClass ().getName ()
+ return (getClass ().getName () + "["
+ ",hgap=" + hgap + ",vgap=" + vgap
+ ",rows=" + rows + ",cols=" + cols
+ "]");
diff --git a/libjava/classpath/java/awt/Image.java b/libjava/classpath/java/awt/Image.java
index 6ade302a147..8a1cc0f0039 100644
--- a/libjava/classpath/java/awt/Image.java
+++ b/libjava/classpath/java/awt/Image.java
@@ -1,5 +1,5 @@
/* Image.java -- superclass for images
- Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -50,7 +50,7 @@ import java.awt.image.ReplicateScaleFilter;
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @since 1.0
- * @status updated to 1.4
+ * @status updated to 1.5
*/
public abstract class Image
{
@@ -102,6 +102,12 @@ public abstract class Image
public static final int SCALE_AREA_AVERAGING = 16;
/**
+ * The acceleration priority of the image
+ * @since 1.5
+ */
+ protected float accelerationPriority;
+
+ /**
* A default constructor for subclasses.
*/
public Image()
@@ -205,4 +211,32 @@ public abstract class Image
* includes the actual image data.
*/
public abstract void flush();
+
+ /**
+ * Sets the acceleration priority of the image.
+ * This is a value from 0 (lowest) to 1 (highest), which may
+ * be used as a hint for image acceleration.
+ * E.g. higher priority images may be stored in video memory.
+ * @param priority - the priority
+ * @throws IllegalArgumentException if priority is not >= 0 and <= 1.
+ *
+ * @since 1.5
+ */
+ public void setAccelerationPriority(float priority)
+ {
+ if( priority < 0f || priority > 1f)
+ throw new IllegalArgumentException("Invalid priority value.");
+ accelerationPriority = priority;
+ }
+
+ /**
+ * Returns the acceleration priority of the image.
+ *
+ * @see #setAccelerationPriority(float)
+ * @since 1.5
+ */
+ public float getAccelerationPriority()
+ {
+ return accelerationPriority;
+ }
} // class Image
diff --git a/libjava/classpath/java/awt/Insets.java b/libjava/classpath/java/awt/Insets.java
index 6d5bd122e9d..762b6975b3f 100644
--- a/libjava/classpath/java/awt/Insets.java
+++ b/libjava/classpath/java/awt/Insets.java
@@ -1,5 +1,5 @@
/* Insets.java -- information about a container border
- Copyright (C) 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -149,14 +149,13 @@ public class Insets implements Cloneable, Serializable
/**
* 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 + ')';
+ return getClass().getName() + "[top=" + top + ",left=" + left
+ + ",bottom=" + bottom + ",right=" + right + ']';
}
/**
diff --git a/libjava/classpath/java/awt/KeyboardFocusManager.java b/libjava/classpath/java/awt/KeyboardFocusManager.java
index 371ea9bdf8a..eacbceb7d50 100644
--- a/libjava/classpath/java/awt/KeyboardFocusManager.java
+++ b/libjava/classpath/java/awt/KeyboardFocusManager.java
@@ -304,10 +304,7 @@ public abstract class KeyboardFocusManager
*/
public Component getFocusOwner ()
{
- Component owner = (Component) getObject (currentFocusOwners);
- if (owner == null)
- owner = (Component) getObject (currentPermanentFocusOwners);
- return owner;
+ return (Component) getObject (currentFocusOwners);
}
/**
@@ -323,10 +320,7 @@ public abstract class KeyboardFocusManager
*/
protected Component getGlobalFocusOwner ()
{
- // Check if there is a temporary focus owner.
- Component focusOwner = (Component) getGlobalObject (currentFocusOwners);
-
- return (focusOwner == null) ? getGlobalPermanentFocusOwner () : focusOwner;
+ return (Component) getGlobalObject(currentFocusOwners, true);
}
/**
@@ -409,7 +403,7 @@ public abstract class KeyboardFocusManager
*/
protected Component getGlobalPermanentFocusOwner ()
{
- return (Component) getGlobalObject (currentPermanentFocusOwners);
+ return (Component) getGlobalObject (currentPermanentFocusOwners, true);
}
/**
@@ -455,7 +449,7 @@ public abstract class KeyboardFocusManager
*/
protected Window getGlobalFocusedWindow ()
{
- return (Window) getGlobalObject (currentFocusedWindows);
+ return (Window) getGlobalObject (currentFocusedWindows, true);
}
/**
@@ -497,7 +491,7 @@ public abstract class KeyboardFocusManager
*/
protected Window getGlobalActiveWindow()
{
- return (Window) getGlobalObject (currentActiveWindows);
+ return (Window) getGlobalObject (currentActiveWindows, true);
}
/**
@@ -663,7 +657,7 @@ public abstract class KeyboardFocusManager
*/
protected Container getGlobalCurrentFocusCycleRoot ()
{
- return (Container) getGlobalObject (currentFocusCycleRoots);
+ return (Container) getGlobalObject (currentFocusCycleRoots, true);
}
/**
@@ -1105,11 +1099,9 @@ public abstract class KeyboardFocusManager
*/
public final void redispatchEvent (Component target, AWTEvent e)
{
- synchronized (e)
- {
- e.setSource (target);
- target.dispatchEvent (e);
- }
+ e.isFocusManagerEvent = true;
+ target.dispatchEvent (e);
+ e.isFocusManagerEvent = false;
}
/**
@@ -1355,17 +1347,19 @@ public abstract class KeyboardFocusManager
* @see #getGlobalActiveWindow()
* @see #getGlobalCurrentFocusCycleRoot()
*/
- private Object getGlobalObject (Map globalMap)
+ private Object getGlobalObject (Map globalMap, boolean checkThread)
{
- ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
- KeyboardFocusManager managerForCallingThread
- = (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
-
- if (this != managerForCallingThread)
- throw new SecurityException ("Attempted to retrieve an object from a "
- + "keyboard focus manager that isn't "
- + "associated with the current thread group.");
+ if (checkThread)
+ {
+ ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+ KeyboardFocusManager managerForCallingThread =
+ (KeyboardFocusManager) currentKeyboardFocusManagers.get(currentGroup);
+ if (this != managerForCallingThread)
+ throw new SecurityException ("Attempted to retrieve an object from a "
+ + "keyboard focus manager that isn't "
+ + "associated with the current thread group.");
+ }
synchronized (globalMap)
{
Collection globalObjects = globalMap.values ();
@@ -1406,7 +1400,7 @@ public abstract class KeyboardFocusManager
synchronized (globalMap)
{
// Save old object.
- Object oldObject = getGlobalObject (globalMap);
+ Object oldObject = getGlobalObject(globalMap, false);
// Nullify old object.
Collection threadGroups = globalMap.keySet ();
@@ -1436,4 +1430,48 @@ public abstract class KeyboardFocusManager
}
}
}
+
+
+ /**
+ * Maps focus requests from heavyweight to lightweight components.
+ */
+ private static HashMap focusRequests = new HashMap();
+
+ /**
+ * Retargets focus events that come from the peer (which only know about
+ * heavyweight components) to go to the correct lightweight component
+ * if appropriate.
+ *
+ * @param ev the event to check
+ *
+ * @return the retargetted event
+ */
+ static AWTEvent retargetFocusEvent(AWTEvent ev)
+ {
+ if (ev instanceof FocusEvent)
+ {
+ FocusEvent fe = (FocusEvent) ev;
+ Component target = fe.getComponent();
+ if (focusRequests.containsKey(target))
+ {
+ Component lightweight = (Component) focusRequests.get(target);
+ ev = new FocusEvent(lightweight, fe.id, fe.isTemporary());
+ focusRequests.remove(target);
+ }
+ }
+ return ev;
+ }
+
+ /**
+ * Adds a lightweight focus request for a heavyweight component.
+ *
+ * @param heavyweight the heavyweight from which we will receive a focus
+ * event soon
+ * @param lightweight the lightweight that ultimately receives the request
+ */
+ static void addLightweightFocusRequest(Component heavyweight,
+ Component lightweight)
+ {
+ focusRequests.put(heavyweight, lightweight);
+ }
}
diff --git a/libjava/classpath/java/awt/Label.java b/libjava/classpath/java/awt/Label.java
index d6db329106f..71614da6482 100644
--- a/libjava/classpath/java/awt/Label.java
+++ b/libjava/classpath/java/awt/Label.java
@@ -1,5 +1,6 @@
/* Label.java -- Java label widget
- Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, Free Software
+ Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,275 +46,250 @@ import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
/**
- * This component is used for displaying simple text strings that cannot
- * be edited by the user.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- * @author Tom Tromey (tromey@cygnus.com)
- * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
- */
+ * This component is used for displaying simple text strings that cannot
+ * be edited by the user.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
public class Label extends Component implements Accessible
{
-/*
- * Static Variables
- */
-
-/**
- * Alignment constant aligning the text to the left of its window.
- */
-public static final int LEFT = 0;
-
-/**
- * Alignment constant aligning the text in the center of its window.
- */
-public static final int CENTER = 1;
-
-/**
- * Alignment constant aligning the text to the right of its window.
- */
-public static final int RIGHT = 2;
-
-// Serialization version constant:
-private static final long serialVersionUID = 3094126758329070636L;
-
-/*************************************************************************/
+ /**
+ * Alignment constant aligning the text to the left of its window.
+ */
+ public static final int LEFT = 0;
-/*
- * Instance Variables
- */
+ /**
+ * Alignment constant aligning the text in the center of its window.
+ */
+ public static final int CENTER = 1;
-/**
- * @serial Indicates the alignment of the text within this label's window.
- * This is one of the constants in this class. The default value is
- * <code>LEFT</code>.
- */
-private int alignment;
+ /**
+ * Alignment constant aligning the text to the right of its window.
+ */
+ public static final int RIGHT = 2;
-/**
- * @serial The text displayed in the label
- */
-private String text;
+ // Serialization version constant:
+ private static final long serialVersionUID = 3094126758329070636L;
-/*************************************************************************/
+ /**
+ * @serial Indicates the alignment of the text within this label's window.
+ * This is one of the constants in this class. The default value is
+ * <code>LEFT</code>.
+ */
+ private int alignment;
-/*
- * Constructors
- */
+ /**
+ * @serial The text displayed in the label
+ */
+ private String text;
-/**
- * Initializes a new instance of <code>Label</code> with no text.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
- */
-public
-Label()
-{
- this("", LEFT);
-}
+ /**
+ * Initializes a new instance of <code>Label</code> with no text.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public Label()
+ {
+ this("", LEFT);
+ }
-/*************************************************************************/
+ /**
+ * Initializes a new instance of <code>Label</code> with the specified
+ * text that is aligned to the left.
+ *
+ * @param text The text of the label.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public Label(String text)
+ {
+ this(text, LEFT);
+ }
-/**
- * Initializes a new instance of <code>Label</code> with the specified
- * text that is aligned to the left.
- *
- * @param text The text of the label.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
- */
-public
-Label(String text)
-{
- this(text, LEFT);
-}
+ /**
+ * Initializes a new instance of <code>Label</code> with the specified
+ * text and alignment.
+ *
+ * @param text The text of the label.
+ * @param alignment The desired alignment for the text in this label,
+ * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
+ * <code>RIGHT</code>.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ */
+ public Label(String text, int alignment)
+ {
+ setAlignment(alignment);
+ setText(text);
-/*************************************************************************/
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException();
+ }
-/**
- * Initializes a new instance of <code>Label</code> with the specified
- * text and alignment.
- *
- * @param text The text of the label.
- * @param alignment The desired alignment for the text in this label,
- * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
- * <code>RIGHT</code>.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
- */
-public
-Label(String text, int alignment)
-{
- setAlignment (alignment);
- setText (text);
+ /**
+ * Returns the constant indicating the alignment of the text in this
+ * label. The value returned will be one of the alignment constants
+ * from this class.
+ *
+ * @return The alignment of the text in the label.
+ */
+ public int getAlignment()
+ {
+ return(alignment);
+ }
- if (GraphicsEnvironment.isHeadless())
- throw new HeadlessException ();
-}
+ /**
+ * Sets the text alignment of this label to the specified value.
+ *
+ * @param alignment The desired alignment for the text in this label,
+ * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
+ * <code>RIGHT</code>.
+ */
+ public synchronized void setAlignment(int alignment)
+ {
+ if (alignment != CENTER && alignment != LEFT && alignment != RIGHT)
+ throw new IllegalArgumentException("invalid alignment: " + alignment);
+ this.alignment = alignment;
+ if (peer != null)
+ {
+ LabelPeer lp = (LabelPeer) peer;
+ lp.setAlignment(alignment);
+ }
+ }
-/*************************************************************************/
+ /**
+ * Returns the text displayed in this label.
+ *
+ * @return The text for this label.
+ */
+ public String getText()
+ {
+ return text;
+ }
-/*
- * Instance Variables
- */
+ /**
+ * Sets the text in this label to the specified value.
+ *
+ * @param text The new text for this label.
+ */
+ public synchronized void setText(String text)
+ {
+ if ((this.text == null && text != null)
+ || (this.text != null && ! this.text.equals(text)))
+ {
+ this.text = text;
+
+ if (peer != null)
+ {
+ LabelPeer lp = (LabelPeer) peer;
+ lp.setText(text);
+ }
+ invalidate();
+ }
+ }
-/**
- * Returns the constant indicating the alignment of the text in this
- * label. The value returned will be one of the alignment constants
- * from this class.
- *
- * @return The alignment of the text in the label.
- */
-public int
-getAlignment()
-{
- return(alignment);
-}
+ /**
+ * Notifies this label that it has been added to a container, causing
+ * the peer to be created. This method is called internally by the AWT
+ * system.
+ */
+ public void addNotify()
+ {
+ if (peer == null)
+ peer = getToolkit().createLabel(this);
+ super.addNotify();
+ }
-/*************************************************************************/
+ /**
+ * Returns a parameter string useful for debugging.
+ *
+ * @return A debugging string.
+ */
+ protected String paramString()
+ {
+ return ("text=" + getText() + ",alignment=" +
+ getAlignment() + "," + super.paramString());
+ }
-/**
- * Sets the text alignment of this label to the specified value.
- *
- * @param alignment The desired alignment for the text in this label,
- * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
- * <code>RIGHT</code>.
- */
-public synchronized void
-setAlignment(int alignment)
-{
- if (alignment != CENTER && alignment != LEFT && alignment != RIGHT)
- throw new IllegalArgumentException ("invalid alignment: " + alignment);
- this.alignment = alignment;
- if (peer != null)
+ /**
+ * This class provides accessibility support for the label.
+ */
+ protected class AccessibleAWTLabel
+ extends AccessibleAWTComponent
+ {
+ /**
+ * For compatability with Sun's JDK 1.4.2 rev. 5
+ */
+ private static final long serialVersionUID = -3568967560160480438L;
+
+ /**
+ * Constructor for the accessible label.
+ */
+ public AccessibleAWTLabel()
{
- LabelPeer lp = (LabelPeer) peer;
- lp.setAlignment (alignment);
}
-}
-
-/*************************************************************************/
-
-/**
- * Returns the text displayed in this label.
- *
- * @return The text for this label.
- */
-public String
-getText()
-{
- return(text);
-}
-
-/*************************************************************************/
-/**
- * Sets the text in this label to the specified value.
- *
- * @param text The new text for this label.
- */
-public synchronized void
-setText(String text)
-{
- if ((this.text == null && text != null)
- || (this.text != null && ! this.text.equals(text)))
+ /**
+ * Returns the accessible name for the label. This is
+ * the text used in the label.
+ *
+ * @return a <code>String</code> containing the accessible
+ * name for this label.
+ */
+ public String getAccessibleName()
{
- this.text = text;
-
- if (peer != null)
- {
- LabelPeer lp = (LabelPeer) peer;
- lp.setText (text);
- }
- invalidate();
+ return getText();
}
-}
-
-/*************************************************************************/
-
-/**
- * Notifies this label that it has been added to a container, causing
- * the peer to be created. This method is called internally by the AWT
- * system.
- */
-public void
-addNotify()
-{
- if (peer == null)
- peer = getToolkit ().createLabel (this);
- super.addNotify ();
-}
-/*************************************************************************/
-
-/**
- * Returns a parameter string useful for debugging.
- *
- * @return A debugging string.
- */
-protected String
-paramString()
-{
- return ("text=" + getText() + ",alignment=" +
- getAlignment() + "," + super.paramString());
-}
+ /**
+ * Returns the accessible role for the label.
+ *
+ * @return an instance of <code>AccessibleRole</code>, describing
+ * the role of the label.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.LABEL;
+ }
-/**
- * This class provides accessibility support for the label.
- */
-protected class AccessibleAWTLabel
- extends AccessibleAWTComponent
-{
- /**
- * For compatability with Sun's JDK 1.4.2 rev. 5
- */
- private static final long serialVersionUID = -3568967560160480438L;
+ }
/**
- * Constructor for the accessible label.
+ * Gets the AccessibleContext associated with this <code>Label</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
*/
- public AccessibleAWTLabel()
+ public AccessibleContext getAccessibleContext()
{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ accessibleContext = new AccessibleAWTLabel();
+ return accessibleContext;
}
/**
- * Returns the accessible name for the label. This is
- * the text used in the label.
+ * Generate a unique name for this button.
*
- * @return a <code>String</code> containing the accessible
- * name for this label.
+ * @return A unique name for this button.
*/
- public String getAccessibleName()
+ String generateName()
{
- return getText();
+ return "label" + getUniqueLong();
}
-
+
/**
- * Returns the accessible role for the label.
- *
- * @return an instance of <code>AccessibleRole</code>, describing
- * the role of the label.
+ * The number used to generate the name returned by getName.
*/
- public AccessibleRole getAccessibleRole()
+ private static transient long nextLabelNumber;
+
+ private static synchronized long getUniqueLong()
{
- return AccessibleRole.LABEL;
+ return nextLabelNumber++;
}
}
-/**
- * Gets the AccessibleContext associated with this <code>Label</code>.
- * The context is created, if necessary.
- *
- * @return the associated context
- */
-public AccessibleContext getAccessibleContext()
-{
- /* Create the context if this is the first request */
- if (accessibleContext == null)
- accessibleContext = new AccessibleAWTLabel();
- return accessibleContext;
-}
-
-} // class Label
-
diff --git a/libjava/classpath/java/awt/LightweightDispatcher.java b/libjava/classpath/java/awt/LightweightDispatcher.java
index 7e33bd4e9ce..3ea3f90a643 100644
--- a/libjava/classpath/java/awt/LightweightDispatcher.java
+++ b/libjava/classpath/java/awt/LightweightDispatcher.java
@@ -152,8 +152,11 @@ class LightweightDispatcher
target = findTarget(parent, loc);
while (target == null && parent != null)
{
- if (parent.getMouseListeners().length > 0
- || parent.getMouseMotionListeners().length > 0)
+ if (parent.mouseListener != null
+ || parent.mouseMotionListener != null
+ || (parent.eventMask
+ & (AWTEvent.MOUSE_EVENT_MASK
+ | AWTEvent.MOUSE_MOTION_EVENT_MASK)) != 0)
{
target = parent;
}
@@ -175,24 +178,22 @@ class LightweightDispatcher
new MouseEvent(lastTarget, MouseEvent.MOUSE_EXITED,
ev.getWhen(), ev.getModifiers(), p1.x, p1.y,
ev.getClickCount(), ev.isPopupTrigger());
+ //System.err.println("event: " + mouseExited);
lastTarget.dispatchEvent(mouseExited);
}
- // If a target exists dispatch the MOUSE_ENTERED event only if
- // there is currently no component from which a drag operation
- // started (dragTarget == null) or the target is that component
- // (dragTarget == target)
- // That way a user can click and hold on a button (putting it into
- // the armed state), move the cursor above other buttons without
- // affecting their rollover state and get back to the initial
- // button.
- if (target != null && (dragTarget == null || dragTarget == target))
+ // If a target exists dispatch the MOUSE_ENTERED event.
+ // Experimenting shows that the MOUSE_ENTERED is also dispatched
+ // when the mouse is dragging.
+ if (target != null)
{
Point p = convertPointToChild(window, ev.getPoint(), target);
MouseEvent mouseEntered =
- new MouseEvent(target, MouseEvent.MOUSE_ENTERED, ev.getWhen(),
+ new MouseEvent(target,
+ MouseEvent.MOUSE_ENTERED, ev.getWhen(),
ev.getModifiers(), p.x, p.y, ev.getClickCount(),
ev.isPopupTrigger());
+ //System.err.println("event: " + mouseEntered);
target.dispatchEvent(mouseEntered);
}
}
@@ -219,7 +220,11 @@ class LightweightDispatcher
// it was released.
if (dragTarget != null && dragButton == ev.getButton())
{
- target = dragTarget;
+ // Only post MOUSE_RELEASED to dragTarget (set in
+ // MOUSE_PRESSED) when the dragTarget is actually visible.
+ // Otherwise post the event to the normal target.
+ if (dragTarget.isVisible())
+ target = dragTarget;
dragTarget = null;
}
@@ -287,18 +292,21 @@ class LightweightDispatcher
*/
private Component findTarget(Container c, Point loc)
{
- Component[] children = c.getComponents();
+ int numComponents = c.getComponentCount();
Component target = null;
if (c != null)
{
- for (int i = 0; i < children.length; i++)
+ for (int i = 0; i < numComponents; i++)
{
- Component child = children[i];
+ Component child = c.getComponent(i);
if (child.isShowing())
{
if (child.contains(loc.x - child.getX(), loc.y - child.getY())
- && (child.getMouseListeners().length > 0
- || child.getMouseMotionListeners().length > 0))
+ && (child.mouseListener != null
+ || child.mouseMotionListener != null
+ || (child.eventMask
+ & (AWTEvent.MOUSE_EVENT_MASK
+ | AWTEvent.MOUSE_MOTION_EVENT_MASK)) != 0))
{
target = child;
break;
diff --git a/libjava/classpath/java/awt/List.java b/libjava/classpath/java/awt/List.java
index b28e2016d2e..86270234345 100644
--- a/libjava/classpath/java/awt/List.java
+++ b/libjava/classpath/java/awt/List.java
@@ -66,6 +66,11 @@ public class List extends Component
* Static Variables
*/
+/**
+ * The number used to generate the name returned by getName.
+ */
+private static transient long next_list_number;
+
// Serialization constant
private static final long serialVersionUID = -3304312411574666869L;
@@ -161,7 +166,11 @@ List(int rows)
public
List(int rows, boolean multipleMode)
{
- this.rows = rows;
+ if (rows == 0)
+ this.rows = 4;
+ else
+ this.rows = rows;
+
this.multipleMode = multipleMode;
selected = new int[0];
@@ -645,13 +654,13 @@ clear()
* @param item The new item value.
* @param index The index of the item to replace.
*
- * @exception IllegalArgumentException If the index is not valid.
+ * @exception ArrayIndexOutOfBoundsException If the index is not valid.
*/
public synchronized void
-replaceItem(String item, int index) throws IllegalArgumentException
+replaceItem(String item, int index) throws ArrayIndexOutOfBoundsException
{
if ((index < 0) || (index >= items.size()))
- throw new IllegalArgumentException("Bad list index: " + index);
+ throw new ArrayIndexOutOfBoundsException("Bad list index: " + index);
items.insertElementAt(item, index + 1);
items.removeElementAt (index);
@@ -818,15 +827,11 @@ isSelected(int index)
/**
* This method ensures that the item at the specified index is visible.
*
- * @exception IllegalArgumentException If the specified index is out of
- * range.
+ * @param index The index of the item to be made visible.
*/
public synchronized void
makeVisible(int index) throws IllegalArgumentException
{
- if ((index < 0) || (index >= items.size()))
- throw new IllegalArgumentException("Bad list index: " + index);
-
visibleIndex = index;
if (peer != null)
{
@@ -1266,4 +1271,19 @@ paramString()
accessibleContext = new AccessibleAWTList();
return accessibleContext;
}
+
+ /**
+ * Generate a unique name for this <code>List</code>.
+ *
+ * @return A unique name for this <code>List</code>.
+ */
+ String generateName()
+ {
+ return "list" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_list_number++;
+ }
} // class List
diff --git a/libjava/classpath/java/awt/Menu.java b/libjava/classpath/java/awt/Menu.java
index 6daec72cf44..f900d929574 100644
--- a/libjava/classpath/java/awt/Menu.java
+++ b/libjava/classpath/java/awt/Menu.java
@@ -58,6 +58,11 @@ public class Menu extends MenuItem implements MenuContainer, Serializable
* Static Variables
*/
+/**
+ * The number used to generate the name returned by getName.
+ */
+private static transient long next_menu_number;
+
// Serialization Constant
private static final long serialVersionUID = -8809584163345499784L;
@@ -485,5 +490,20 @@ paramString()
accessibleContext = new AccessibleAWTMenu();
return accessibleContext;
}
+
+ /**
+ * Generate a unique name for this <code>Menu</code>.
+ *
+ * @return A unique name for this <code>Menu</code>.
+ */
+ String generateName()
+ {
+ return "menu" + getUniqueLong();
+ }
+ private static synchronized long getUniqueLong()
+ {
+ return next_menu_number++;
+ }
+
} // class Menu
diff --git a/libjava/classpath/java/awt/MenuBar.java b/libjava/classpath/java/awt/MenuBar.java
index 3c6b915649f..bd658cde6e3 100644
--- a/libjava/classpath/java/awt/MenuBar.java
+++ b/libjava/classpath/java/awt/MenuBar.java
@@ -60,10 +60,15 @@ public class MenuBar extends MenuComponent
implements MenuContainer, Serializable, Accessible
{
-//Serialization Constant
+ // Serialization Constant
private static final long serialVersionUID = -4930327919388951260L;
/**
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_menubar_number;
+
+ /**
* @serial The menu used for providing help information
*/
private Menu helpMenu;
@@ -331,6 +336,21 @@ public class MenuBar extends MenuComponent
accessibleContext = new AccessibleAWTMenuBar();
return accessibleContext;
}
+
+ /**
+ * Generate a unique name for this <code>MenuBar</code>.
+ *
+ * @return A unique name for this <code>MenuBar</code>.
+ */
+ String generateName()
+ {
+ return "menubar" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_menubar_number++;
+ }
/**
* This class provides accessibility support for AWT menu bars.
diff --git a/libjava/classpath/java/awt/MenuComponent.java b/libjava/classpath/java/awt/MenuComponent.java
index 9bb875069e0..163092685e7 100644
--- a/libjava/classpath/java/awt/MenuComponent.java
+++ b/libjava/classpath/java/awt/MenuComponent.java
@@ -200,8 +200,22 @@ public abstract class MenuComponent implements Serializable
*/
public String getName()
{
+ if (name == null && ! nameExplicitlySet)
+ name = generateName();
return name;
}
+
+ /**
+ * Subclasses should override this to return unique component names like
+ * "menuitem0".
+ *
+ * @return the generated name for this menu component
+ */
+ String generateName()
+ {
+ // MenuComponent is abstract.
+ return null;
+ }
/**
* Sets the name of this component to the specified name.
diff --git a/libjava/classpath/java/awt/MenuItem.java b/libjava/classpath/java/awt/MenuItem.java
index a7ac79643be..7cbc9219f54 100644
--- a/libjava/classpath/java/awt/MenuItem.java
+++ b/libjava/classpath/java/awt/MenuItem.java
@@ -63,9 +63,15 @@ public class MenuItem extends MenuComponent
/*
* Static Variables
*/
+
+
+ /**
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_menuitem_number;
-// Serialization Constant
-private static final long serialVersionUID = -21757335363267194L;
+ // Serialization Constant
+ private static final long serialVersionUID = - 21757335363267194L;
/*************************************************************************/
@@ -599,4 +605,19 @@ public AccessibleContext getAccessibleContext()
return accessibleContext;
}
+/**
+ * Generate a unique name for this <code>MenuItem</code>.
+ *
+ * @return A unique name for this <code>MenuItem</code>.
+ */
+String generateName()
+{
+ return "menuitem" + getUniqueLong();
+}
+
+private static synchronized long getUniqueLong()
+{
+ return next_menuitem_number++;
+}
+
} // class MenuItem
diff --git a/libjava/classpath/java/awt/MouseInfo.java b/libjava/classpath/java/awt/MouseInfo.java
new file mode 100644
index 00000000000..957b6bccbef
--- /dev/null
+++ b/libjava/classpath/java/awt/MouseInfo.java
@@ -0,0 +1,95 @@
+/* MouseInfo.java -- utility methods for mice.
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.awt.ClasspathToolkit;
+import java.awt.peer.MouseInfoPeer;
+
+/**
+ * MouseInfo is a class containing utility functions for mouse information.
+ *
+ * @author Sven de Marothy
+ * @since 1.5
+ */
+public class MouseInfo
+{
+ private static MouseInfoPeer peer;
+
+ /**
+ * Returns a PointerInfo object containing information about the current
+ * location of the mouse pointer
+ *
+ * @throws HeadlessException if the current GraphicsEnvironment is headless.
+ * @return a PointerInfo object.
+ */
+ public static PointerInfo getPointerInfo() throws HeadlessException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission( new AWTPermission("watchMousePointer") );
+
+ if( GraphicsEnvironment.isHeadless() )
+ throw new HeadlessException();
+
+ if( peer == null )
+ peer = Toolkit.getDefaultToolkit().getMouseInfoPeer();
+
+ Point p = new Point();
+ int screen = peer.fillPointWithCoords( p );
+
+ GraphicsDevice[] gds = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ getScreenDevices();
+
+ return new PointerInfo( gds[ screen ], p );
+ }
+
+ /**
+ * Returns the number of mouse buttons, or -1 if no mouse is connected.
+ * (mentioned in the 1.5 release notes)
+ *
+ * @throws HeadlessException if the current GraphicsEnvironment is headless.
+ * @return an integer number of buttons.
+ */
+ public static int getNumberOfButtons() throws HeadlessException
+ {
+ if( GraphicsEnvironment.isHeadless() )
+ throw new HeadlessException();
+ return ((ClasspathToolkit)Toolkit.getDefaultToolkit()).
+ getMouseNumberOfButtons();
+ }
+}
diff --git a/libjava/classpath/java/awt/Point.java b/libjava/classpath/java/awt/Point.java
index 31b72e2cc75..64bc07eaf72 100644
--- a/libjava/classpath/java/awt/Point.java
+++ b/libjava/classpath/java/awt/Point.java
@@ -1,5 +1,5 @@
/* Point.java -- represents a point in 2-D space
- Copyright (C) 1999, 2002 Free Software Foundation
+ Copyright (C) 1999, 2002, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -83,7 +83,7 @@ public class Point extends Point2D implements Serializable
/**
* Initializes a new instance of <code>Point</code> representing the
- * coordiates (0,0).
+ * coordinates (0, 0).
*
* @since 1.1
*/
@@ -93,7 +93,7 @@ public class Point extends Point2D implements Serializable
/**
* Initializes a new instance of <code>Point</code> with coordinates
- * identical to the coordinates of the specified points.
+ * identical to the coordinates of the specified point.
*
* @param p the point to copy the coordinates from
* @throws NullPointerException if p is null
@@ -178,15 +178,16 @@ public class Point extends Point2D implements Serializable
/**
* Sets this object's coordinates to the specified values. This method
- * performs normal casting from double to int, so you may lose precision.
+ * rounds to the nearest integer coordinates by adding 0.5 and calling
+ * {@link Math#floor(double)}.
*
* @param x the new X coordinate
* @param y the new Y coordinate
*/
public void setLocation(double x, double y)
{
- this.x = (int) x;
- this.y = (int) y;
+ this.x = (int) Math.floor(x + 0.5);
+ this.y = (int) Math.floor(y + 0.5);
}
/**
diff --git a/libjava/classpath/java/awt/PointerInfo.java b/libjava/classpath/java/awt/PointerInfo.java
new file mode 100644
index 00000000000..14d44a69b3f
--- /dev/null
+++ b/libjava/classpath/java/awt/PointerInfo.java
@@ -0,0 +1,84 @@
+/* PointerInfo.java -- mouse pointer data
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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;
+
+/**
+ * PointerInfo represents information about the mouse pointer,
+ * i.e. its GraphicsDevice and location.
+ *
+ * PointerInfo objects cannot be instantiated directly, but are
+ * retrieved from MouseInfo.getPointerInfo(). PointerInfo objects
+ * are immutable and will not be updated for future mouse motions.
+ *
+ * @since 1.5
+ * @author Sven de Marothy
+ */
+public class PointerInfo
+{
+ private GraphicsDevice gd;
+ private Point p;
+
+ /**
+ * Package-private constructor used by MouseInfo.
+ */
+ PointerInfo( GraphicsDevice gd, Point p )
+ {
+ this.gd = gd;
+ this.p = p;
+ }
+
+ /**
+ * Returns the GraphicsDevice on which the mouse pointer was located
+ *
+ * @return a GraphicsDevice object.
+ */
+ public GraphicsDevice getDevice()
+ {
+ return gd;
+ }
+
+ /**
+ * Returns the coordinates of the mouse pointer.
+ *
+ * @return a Point object containing the pointer coordinates.
+ */
+ public Point getLocation()
+ {
+ return p;
+ }
+}
diff --git a/libjava/classpath/java/awt/PopupMenu.java b/libjava/classpath/java/awt/PopupMenu.java
index 540fffda718..9268678026d 100644
--- a/libjava/classpath/java/awt/PopupMenu.java
+++ b/libjava/classpath/java/awt/PopupMenu.java
@@ -55,8 +55,13 @@ public class PopupMenu extends Menu
* Static Variables
*/
-// Serialization Constant
-private static final long serialVersionUID = -4620452533522760060L;
+ /**
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_popup_number;
+
+ // Serialization Constant
+ private static final long serialVersionUID = - 4620452533522760060L;
/*************************************************************************/
@@ -166,6 +171,21 @@ show(Component component, int x, int y)
accessibleContext = new AccessibleAWTPopupMenu();
return accessibleContext;
}
+
+ /**
+ * Generate a unique name for this <code>PopupMenu</code>.
+ *
+ * @return A unique name for this <code>PopupMenu</code>.
+ */
+ String generateName()
+ {
+ return "popup" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_popup_number++;
+ }
} // class PopupMenu
diff --git a/libjava/classpath/java/awt/ScrollPane.java b/libjava/classpath/java/awt/ScrollPane.java
index 525d9d3e7da..65ce484b88d 100644
--- a/libjava/classpath/java/awt/ScrollPane.java
+++ b/libjava/classpath/java/awt/ScrollPane.java
@@ -46,6 +46,7 @@ import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
+
/**
* This widget provides a scrollable region that allows a single
* subcomponent to be viewed through a smaller window.
@@ -76,6 +77,11 @@ public static final int SCROLLBARS_ALWAYS = 1;
*/
public static final int SCROLLBARS_NEVER = 2;
+/**
+ * The number used to generate the name returned by getName.
+ */
+private static transient long next_scrollpane_number;
+
// Serialization constant
private static final long serialVersionUID = 7956609840827222915L;
@@ -221,7 +227,7 @@ getVAdjustable()
* @return The viewport size.
*/
public Dimension getViewportSize ()
-{
+{
Dimension viewsize = getSize ();
Insets insets = getInsets ();
@@ -231,9 +237,9 @@ public Dimension getViewportSize ()
Component[] list = getComponents();
if ((list == null) || (list.length <= 0))
return viewsize;
-
+
Dimension dim = list[0].getPreferredSize();
-
+
if (dim.width <= 0 && dim.height <= 0)
return viewsize;
@@ -276,7 +282,7 @@ public Dimension getViewportSize ()
needHorizontal = true;
else if (dim.width > (viewsize.width - vScrollbarWidth))
mayNeedHorizontal = true;
-
+
if (needVertical && mayNeedHorizontal)
needHorizontal = true;
@@ -288,7 +294,7 @@ public Dimension getViewportSize ()
if (needVertical)
viewsize.width -= vScrollbarWidth;
-
+
return viewsize;
}
@@ -613,5 +619,21 @@ paramString()
accessibleContext = new AccessibleAWTScrollPane();
return accessibleContext;
}
+
+ /**
+ * Generate a unique name for this <code>ScrollPane</code>.
+ *
+ * @return A unique name for this <code>ScrollPane</code>.
+ */
+ String generateName()
+ {
+ return "scrollpane" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_scrollpane_number++;
+ }
+
} // class ScrollPane
diff --git a/libjava/classpath/java/awt/Shape.java b/libjava/classpath/java/awt/Shape.java
index bd8a4343528..d76bbaba69d 100644
--- a/libjava/classpath/java/awt/Shape.java
+++ b/libjava/classpath/java/awt/Shape.java
@@ -1,5 +1,5 @@
/* Shape.java -- the classic Object-Oriented shape interface
- Copyright (C) 1999, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -176,7 +176,8 @@ public interface Shape
* 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 transform an optional transform to apply to the
+ * iterator (<code>null</code> permitted).
* @return a new iterator over the boundary
* @since 1.2
*/
@@ -185,7 +186,7 @@ public interface Shape
/**
* 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
+ * iterator. The flatness parameter 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.
*
@@ -194,10 +195,11 @@ public interface Shape
* 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 transform an optional transform to apply to the
+ * iterator (<code>null</code> permitted).
* @param flatness 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/classpath/java/awt/TextArea.java b/libjava/classpath/java/awt/TextArea.java
index b04cdc89204..7e3463ab849 100644
--- a/libjava/classpath/java/awt/TextArea.java
+++ b/libjava/classpath/java/awt/TextArea.java
@@ -125,9 +125,11 @@ public class TextArea extends TextComponent implements java.io.Serializable
* the specified text. Conceptually the <code>TextArea</code> has 0
* rows and 0 columns but its initial bounds are defined by its peer
* or by the container in which it is packed. Both horizontal and
- * veritcal scrollbars will be displayed.
+ * veritcal scrollbars will be displayed. The TextArea initially contains
+ * the specified text. If text specified as <code>null<code>, it will
+ * be set to "".
*
- * @param text The text to display in this text area.
+ * @param text The text to display in this text area (<code>null</code> permitted).
*
* @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
*/
@@ -156,9 +158,10 @@ public class TextArea extends TextComponent implements java.io.Serializable
* Initialize a new instance of <code>TextArea</code> that can
* display the specified number of rows and columns of text, without
* the need to scroll. The TextArea initially contains the
- * specified text.
+ * specified text. If text specified as <code>null<code>, it will
+ * be set to "".
*
- * @param text The text to display in this text area.
+ * @param text The text to display in this text area (<code>null</code> permitted).
* @param rows The number of rows in this text area.
* @param columns The number of columns in this text area.
*
@@ -174,9 +177,10 @@ public class TextArea extends TextComponent implements java.io.Serializable
* contains the specified text. The TextArea can display the
* specified number of rows and columns of text, without the need to
* scroll. This constructor allows specification of the scroll bar
- * display policy.
+ * display policy. The TextArea initially contains the specified text.
+ * If text specified as <code>null<code>, it will be set to "".
*
- * @param text The text to display in this text area.
+ * @param text The text to display in this text area (<code>null</code> permitted).
* @param rows The number of rows in this text area.
* @param columns The number of columns in this text area.
* @param scrollbarVisibility The scroll bar display policy. One of
@@ -192,18 +196,20 @@ public class TextArea extends TextComponent implements java.io.Serializable
if (GraphicsEnvironment.isHeadless ())
throw new HeadlessException ();
- if (rows < 0 || columns < 0)
- throw new IllegalArgumentException ("Bad row or column value");
-
- if (scrollbarVisibility != SCROLLBARS_BOTH
- && scrollbarVisibility != SCROLLBARS_VERTICAL_ONLY
- && scrollbarVisibility != SCROLLBARS_HORIZONTAL_ONLY
- && scrollbarVisibility != SCROLLBARS_NONE)
- throw new IllegalArgumentException ("Bad scrollbar visibility value");
+ if (rows < 0)
+ this.rows = 0;
+ else
+ this.rows = rows;
+
+ if (columns < 0)
+ this.columns = 0;
+ else
+ this.columns = columns;
- this.rows = rows;
- this.columns = columns;
- this.scrollbarVisibility = scrollbarVisibility;
+ if (scrollbarVisibility < 0 || scrollbarVisibility > 4)
+ this.scrollbarVisibility = SCROLLBARS_BOTH;
+ else
+ this.scrollbarVisibility = scrollbarVisibility;
// TextAreas need to receive tab key events so we override the
// default forward and backward traversal key sets.
@@ -478,6 +484,8 @@ public class TextArea extends TextComponent implements java.io.Serializable
if (peer != null)
peer.insert (str, peer.getText().length ());
+ else
+ setText(getText() + str);
}
/**
@@ -504,10 +512,19 @@ public class TextArea extends TextComponent implements java.io.Serializable
*/
public void insertText (String str, int pos)
{
+ String tmp1 = null;
+ String tmp2 = null;
+
TextAreaPeer peer = (TextAreaPeer) getPeer ();
if (peer != null)
peer.insert (str, pos);
+ else
+ {
+ tmp1 = getText().substring(0, pos);
+ tmp2 = getText().substring(pos, getText().length());
+ setText(tmp1 + str + tmp2);
+ }
}
/**
@@ -544,10 +561,19 @@ public class TextArea extends TextComponent implements java.io.Serializable
*/
public void replaceText (String str, int start, int end)
{
- TextAreaPeer peer = (TextAreaPeer) getPeer ();
+ String tmp1 = null;
+ String tmp2 = null;
+
+ TextAreaPeer peer = (TextAreaPeer) getPeer();
if (peer != null)
- peer.replaceRange (str, start, end);
+ peer.replaceRange(str, start, end);
+ else
+ {
+ tmp1 = getText().substring(0, start);
+ tmp2 = getText().substring(end, getText().length());
+ setText(tmp1 + str + tmp2);
+ }
}
/**
diff --git a/libjava/classpath/java/awt/TextComponent.java b/libjava/classpath/java/awt/TextComponent.java
index f08e59c9fc9..f811122f2b2 100644
--- a/libjava/classpath/java/awt/TextComponent.java
+++ b/libjava/classpath/java/awt/TextComponent.java
@@ -1,5 +1,5 @@
/* TextComponent.java -- Widgets for entering text
- Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -54,54 +54,45 @@ import javax.accessibility.AccessibleText;
import javax.swing.text.AttributeSet;
/**
- * This class provides common functionality for widgets than
- * contain text.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- */
+ * This class provides common functionality for widgets than
+ * contain text.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
public class TextComponent extends Component
implements Serializable, Accessible
{
-/*
- * Static Variables
- */
-
-// Constant for serialization
-private static final long serialVersionUID = -2214773872412987419L;
+ private static final long serialVersionUID = -2214773872412987419L;
-/*
- * Instance Variables
- */
-
-/**
- * @serial Indicates whether or not this component is editable.
- * This is package-private to avoid an accessor method.
- */
-boolean editable;
+ /**
+ * @serial Indicates whether or not this component is editable.
+ * This is package-private to avoid an accessor method.
+ */
+ boolean editable;
-/**
- * @serial The starting position of the selected text region.
- * This is package-private to avoid an accessor method.
- */
-int selectionStart;
+ /**
+ * @serial The starting position of the selected text region.
+ * This is package-private to avoid an accessor method.
+ */
+ int selectionStart;
-/**
- * @serial The ending position of the selected text region.
- * This is package-private to avoid an accessor method.
- */
-int selectionEnd;
+ /**
+ * @serial The ending position of the selected text region.
+ * This is package-private to avoid an accessor method.
+ */
+ int selectionEnd;
-/**
- * @serial The text in the component
- * This is package-private to avoid an accessor method.
- */
-String text;
+ /**
+ * @serial The text in the component
+ * This is package-private to avoid an accessor method.
+ */
+ String text;
-/**
- * A list of listeners that will receive events from this object.
- */
-protected transient TextListener textListener;
+ /**
+ * A list of listeners that will receive events from this object.
+ */
+ protected transient TextListener textListener;
protected class AccessibleAWTTextComponent
extends AccessibleAWTComponent
@@ -318,360 +309,298 @@ protected transient TextListener textListener;
}
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
-TextComponent(String text)
-{
- this.text = text;
- this.editable = true;
-}
-
-/*************************************************************************/
-/*
- * Instance Methods
- */
-
-/**
- * Returns the text in this component
- *
- * @return The text in this component.
- */
-public synchronized String
-getText()
-{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
- if (tcp != null)
- text = tcp.getText();
+ TextComponent(String text)
+ {
+ if (text == null)
+ this.text = "";
+ else
+ this.text = text;
+
+ this.editable = true;
+ }
- return(text);
-}
-/*************************************************************************/
+ /**
+ * Returns the text in this component
+ *
+ * @return The text in this component.
+ */
+ public synchronized String getText()
+ {
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
+ if (tcp != null)
+ text = tcp.getText();
-/**
- * Sets the text in this component to the specified string.
- *
- * @param text The new text for this component.
- */
-public synchronized void
-setText(String text)
-{
- if (text == null)
- text = "";
+ return(text);
+ }
- this.text = text;
+ /**
+ * Sets the text in this component to the specified string.
+ *
+ * @param text The new text for this component.
+ */
+ public synchronized void setText(String text)
+ {
+ if (text == null)
+ text = "";
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
- if (tcp != null)
- tcp.setText(text);
- setCaretPosition(0);
-}
+ this.text = text;
-/*************************************************************************/
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
+ if (tcp != null)
+ tcp.setText(text);
+ setCaretPosition(0);
+ }
-/**
- * Returns a string that contains the text that is currently selected.
- *
- * @return The currently selected text region.
- */
-public synchronized String
-getSelectedText()
-{
- String alltext = getText();
- int start = getSelectionStart();
- int end = getSelectionEnd();
+ /**
+ * Returns a string that contains the text that is currently selected.
+ *
+ * @return The currently selected text region.
+ */
+ public synchronized String getSelectedText()
+ {
+ String alltext = getText();
+ int start = getSelectionStart();
+ int end = getSelectionEnd();
- return(alltext.substring(start, end));
-}
-
-/*************************************************************************/
-
-/**
- * Returns the starting position of the selected text region.
- * If the text is not selected then caret position is returned.
- *
- * @return The starting position of the selected text region.
- */
-public synchronized int
-getSelectionStart()
-{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
- if (tcp != null)
- selectionStart = tcp.getSelectionStart();
-
- return(selectionStart);
-}
-
-/*************************************************************************/
-
-/**
- * Sets the starting position of the selected region to the
- * specified value. If the specified value is out of range, then it
- * will be silently changed to the nearest legal value.
- *
- * @param selectionStart The new start position for selected text.
- */
-public synchronized void
-setSelectionStart(int selectionStart)
-{
- select(selectionStart, getSelectionEnd());
-}
-
-/*************************************************************************/
-
-/**
- * Returns the ending position of the selected text region.
- * If the text is not selected, then caret position is returned
- *
- * @return The ending position of the selected text region.
- */
-public synchronized int
-getSelectionEnd()
-{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
- if (tcp != null)
- selectionEnd = tcp.getSelectionEnd();
-
- return(selectionEnd);
-}
+ return(alltext.substring(start, end));
+ }
-/*************************************************************************/
+ /**
+ * Returns the starting position of the selected text region.
+ * If the text is not selected then caret position is returned.
+ *
+ * @return The starting position of the selected text region.
+ */
+ public synchronized int getSelectionStart()
+ {
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
+ if (tcp != null)
+ selectionStart = tcp.getSelectionStart();
-/**
- * Sets the ending position of the selected region to the
- * specified value. If the specified value is out of range, then it
- * will be silently changed to the nearest legal value.
- *
- * @param selectionEnd The new start position for selected text.
- */
-public synchronized void
-setSelectionEnd(int selectionEnd)
-{
- select(getSelectionStart(), selectionEnd);
-}
+ return(selectionStart);
+ }
-/*************************************************************************/
+ /**
+ * Sets the starting position of the selected region to the
+ * specified value. If the specified value is out of range, then it
+ * will be silently changed to the nearest legal value.
+ *
+ * @param selectionStart The new start position for selected text.
+ */
+ public synchronized void setSelectionStart(int selectionStart)
+ {
+ select(selectionStart, getSelectionEnd());
+ }
-/**
- * This method sets the selected text range to the text between the
- * specified start and end positions. Illegal values for these
- * positions are silently fixed.
- *
- * @param selectionStart The new start position for the selected text.
- * @param selectionEnd The new end position for the selected text.
- */
-public synchronized void
-select(int selectionStart, int selectionEnd)
-{
- if (selectionStart < 0)
- selectionStart = 0;
+ /**
+ * Returns the ending position of the selected text region.
+ * If the text is not selected, then caret position is returned
+ *
+ * @return The ending position of the selected text region.
+ */
+ public synchronized int getSelectionEnd()
+ {
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
+ if (tcp != null)
+ selectionEnd = tcp.getSelectionEnd();
- if (selectionStart > getText().length())
- selectionStart = text.length();
+ return(selectionEnd);
+ }
- if (selectionEnd > text.length())
- selectionEnd = text.length();
+ /**
+ * Sets the ending position of the selected region to the
+ * specified value. If the specified value is out of range, then it
+ * will be silently changed to the nearest legal value.
+ *
+ * @param selectionEnd The new start position for selected text.
+ */
+ public synchronized void setSelectionEnd(int selectionEnd)
+ {
+ select(getSelectionStart(), selectionEnd);
+ }
- if (selectionStart > selectionEnd)
- selectionStart = selectionEnd;
+ /**
+ * This method sets the selected text range to the text between the
+ * specified start and end positions. Illegal values for these
+ * positions are silently fixed.
+ *
+ * @param selectionStart The new start position for the selected text.
+ * @param selectionEnd The new end position for the selected text.
+ */
+ public synchronized void select(int selectionStart, int selectionEnd)
+ {
+ if (selectionStart < 0)
+ selectionStart = 0;
- this.selectionStart = selectionStart;
- this.selectionEnd = selectionEnd;
+ if (selectionStart > getText().length())
+ selectionStart = text.length();
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
- if (tcp != null)
- tcp.select(selectionStart, selectionEnd);
-}
+ if (selectionEnd > text.length())
+ selectionEnd = text.length();
-/*************************************************************************/
+ if (selectionStart > selectionEnd)
+ selectionStart = selectionEnd;
-/**
- * Selects all of the text in the component.
- */
-public synchronized void
-selectAll()
-{
- select(0, getText().length());
-}
-
-/*************************************************************************/
+ this.selectionStart = selectionStart;
+ this.selectionEnd = selectionEnd;
+
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
+ if (tcp != null)
+ tcp.select(selectionStart, selectionEnd);
+ }
-/**
- * Returns the current caret position in the text.
- *
- * @return The caret position in the text.
- */
-public synchronized int
-getCaretPosition()
-{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
- if (tcp != null)
- return(tcp.getCaretPosition());
- else
- return(0);
-}
+ /**
+ * Selects all of the text in the component.
+ */
+ public synchronized void selectAll()
+ {
+ select(0, getText().length());
+ }
-/*************************************************************************/
+ /**
+ * Returns the current caret position in the text.
+ *
+ * @return The caret position in the text.
+ */
+ public synchronized int getCaretPosition()
+ {
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
+ if (tcp != null)
+ return(tcp.getCaretPosition());
+ else
+ return(0);
+ }
-/**
- * Sets the caret position to the specified value.
- *
- * @param caretPosition The new caret position.
- *
- * @exception IllegalArgumentException If the value supplied for position
- * is less than zero.
- *
- * @since 1.1
- */
-public synchronized void
-setCaretPosition(int caretPosition)
-{
- if (caretPosition < 0)
- throw new IllegalArgumentException ();
+ /**
+ * Sets the caret position to the specified value.
+ *
+ * @param caretPosition The new caret position.
+ *
+ * @exception IllegalArgumentException If the value supplied for position
+ * is less than zero.
+ *
+ * @since 1.1
+ */
+ public synchronized void setCaretPosition(int caretPosition)
+ {
+ if (caretPosition < 0)
+ throw new IllegalArgumentException();
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
- if (tcp != null)
- tcp.setCaretPosition(caretPosition);
-}
-
-/*************************************************************************/
-
-/**
- * Tests whether or not this component's text can be edited.
- *
- * @return <code>true</code> if the text can be edited, <code>false</code>
- * otherwise.
- */
-public boolean
-isEditable()
-{
- return(editable);
-}
-
-/*************************************************************************/
-
-/**
- * Sets whether or not this component's text can be edited.
- *
- * @param editable <code>true</code> to enable editing of the text,
- * <code>false</code> to disable it.
- */
-public synchronized void
-setEditable(boolean editable)
-{
- this.editable = editable;
-
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
- if (tcp != null)
- tcp.setEditable(editable);
-}
-
-/*************************************************************************/
-
-/**
- * Notifies the component that it should destroy its native peer.
- */
-public void
-removeNotify()
-{
- super.removeNotify();
-}
-
-/*************************************************************************/
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
+ if (tcp != null)
+ tcp.setCaretPosition(caretPosition);
+ }
-/**
- * Adds a new listener to the list of text listeners for this
- * component.
- *
- * @param listener The listener to be added.
- */
-public synchronized void
-addTextListener(TextListener listener)
-{
- textListener = AWTEventMulticaster.add(textListener, listener);
+ /**
+ * Tests whether or not this component's text can be edited.
+ *
+ * @return <code>true</code> if the text can be edited, <code>false</code>
+ * otherwise.
+ */
+ public boolean isEditable()
+ {
+ return(editable);
+ }
- enableEvents(AWTEvent.TEXT_EVENT_MASK);
-}
+ /**
+ * Sets whether or not this component's text can be edited.
+ *
+ * @param editable <code>true</code> to enable editing of the text,
+ * <code>false</code> to disable it.
+ */
+ public synchronized void setEditable(boolean editable)
+ {
+ this.editable = editable;
-/*************************************************************************/
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
+ if (tcp != null)
+ tcp.setEditable(editable);
+ }
-/**
- * Removes the specified listener from the list of listeners
- * for this component.
- *
- * @param listener The listener to remove.
- */
-public synchronized void
-removeTextListener(TextListener listener)
-{
- textListener = AWTEventMulticaster.remove(textListener, listener);
-}
+ /**
+ * Notifies the component that it should destroy its native peer.
+ */
+ public void removeNotify()
+ {
+ super.removeNotify();
+ }
-/*************************************************************************/
+ /**
+ * Adds a new listener to the list of text listeners for this
+ * component.
+ *
+ * @param listener The listener to be added.
+ */
+ public synchronized void addTextListener(TextListener listener)
+ {
+ textListener = AWTEventMulticaster.add(textListener, listener);
-/**
- * Processes the specified event for this component. Text events are
- * processed by calling the <code>processTextEvent()</code> method.
- * All other events are passed to the superclass method.
- *
- * @param event The event to process.
- */
-protected void
-processEvent(AWTEvent event)
-{
- if (event instanceof TextEvent)
- processTextEvent((TextEvent)event);
- else
- super.processEvent(event);
-}
+ enableEvents(AWTEvent.TEXT_EVENT_MASK);
+ }
-/*************************************************************************/
+ /**
+ * Removes the specified listener from the list of listeners
+ * for this component.
+ *
+ * @param listener The listener to remove.
+ */
+ public synchronized void removeTextListener(TextListener listener)
+ {
+ textListener = AWTEventMulticaster.remove(textListener, listener);
+ }
-/**
- * Processes the specified text event by dispatching it to any listeners
- * that are registered. Note that this method will only be called
- * if text event's are enabled. This will be true if there are any
- * registered listeners, or if the event has been specifically
- * enabled using <code>enableEvents()</code>.
- *
- * @param event The text event to process.
- */
-protected void
-processTextEvent(TextEvent event)
-{
- if (textListener != null)
- textListener.textValueChanged(event);
-}
+ /**
+ * Processes the specified event for this component. Text events are
+ * processed by calling the <code>processTextEvent()</code> method.
+ * All other events are passed to the superclass method.
+ *
+ * @param event The event to process.
+ */
+ protected void processEvent(AWTEvent event)
+ {
+ if (event instanceof TextEvent)
+ processTextEvent((TextEvent)event);
+ else
+ super.processEvent(event);
+ }
-void
-dispatchEventImpl(AWTEvent e)
-{
- if (e.id <= TextEvent.TEXT_LAST
- && e.id >= TextEvent.TEXT_FIRST
- && (textListener != null
- || (eventMask & AWTEvent.TEXT_EVENT_MASK) != 0))
- processEvent(e);
- else
- super.dispatchEventImpl(e);
-}
+ /**
+ * Processes the specified text event by dispatching it to any listeners
+ * that are registered. Note that this method will only be called
+ * if text event's are enabled. This will be true if there are any
+ * registered listeners, or if the event has been specifically
+ * enabled using <code>enableEvents()</code>.
+ *
+ * @param event The text event to process.
+ */
+ protected void processTextEvent(TextEvent event)
+ {
+ if (textListener != null)
+ textListener.textValueChanged(event);
+ }
-/*************************************************************************/
+ void dispatchEventImpl(AWTEvent e)
+ {
+ if (e.id <= TextEvent.TEXT_LAST
+ && e.id >= TextEvent.TEXT_FIRST
+ && (textListener != null
+ || (eventMask & AWTEvent.TEXT_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+ }
-/**
- * Returns a debugging string.
- *
- * @return A debugging string.
- */
-protected String
-paramString()
-{
- return(getClass().getName() + "(text=" + getText() + ")");
-}
+ /**
+ * Returns a debugging string.
+ *
+ * @return A debugging string.
+ */
+ protected String paramString()
+ {
+ return(getClass().getName() + "(text=" + getText() + ")");
+ }
/**
* Returns an array of all the objects currently registered as FooListeners
@@ -681,20 +610,20 @@ paramString()
* @exception ClassCastException If listenerType doesn't specify a class or
* interface that implements java.util.EventListener.
*/
- public EventListener[] getListeners (Class listenerType)
+ public EventListener[] getListeners(Class listenerType)
{
if (listenerType == TextListener.class)
- return AWTEventMulticaster.getListeners (textListener, listenerType);
+ return AWTEventMulticaster.getListeners(textListener, listenerType);
- return super.getListeners (listenerType);
+ return super.getListeners(listenerType);
}
/**
* Returns all text listeners registered to this object.
*/
- public TextListener[] getTextListeners ()
+ public TextListener[] getTextListeners()
{
- return (TextListener[]) getListeners (TextListener.class);
+ return (TextListener[]) getListeners(TextListener.class);
}
/**
@@ -712,30 +641,35 @@ paramString()
}
- /*******************************/
// Provide AccessibleAWTTextComponent access to several peer functions that
// aren't publicly exposed. This is package-private to avoid an accessor
// method.
- synchronized int
- getIndexAtPoint(Point p)
+ synchronized int getIndexAtPoint(Point p)
{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
return tcp.getIndexAtPoint(p.x, p.y);
return -1;
}
- synchronized Rectangle
- getCharacterBounds(int i)
+ synchronized Rectangle getCharacterBounds(int i)
{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
return tcp.getCharacterBounds(i);
return null;
}
-
-
+ /**
+ * All old mouse events for this component should
+ * be ignored.
+ *
+ * @return true to ignore all old mouse events.
+ */
+ static boolean ignoreOldMouseEvents()
+ {
+ return true;
+ }
} // class TextComponent
diff --git a/libjava/classpath/java/awt/TextField.java b/libjava/classpath/java/awt/TextField.java
index 23d3d918ff4..b76f393a0b6 100644
--- a/libjava/classpath/java/awt/TextField.java
+++ b/libjava/classpath/java/awt/TextField.java
@@ -1,5 +1,5 @@
/* TextField.java -- A one line text entry field
- Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,450 +48,369 @@ import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleStateSet;
/**
- * This class implements a single line text entry field widget
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- */
-public class TextField extends TextComponent
-{
-
-/*
- * Static Variables
- */
-
-// Serialization constant
-private static final long serialVersionUID = -2966288784432217853L;
-
-/*************************************************************************/
-
-/*
- * Instance Variables
- */
-
-/**
- * @serial The number of columns in the text entry field.
- */
-private int columns;
-
-/**
- * @serial The character that is echoed when doing protected input
- */
-private char echoChar;
-
-// List of registered ActionListener's for this object.
-private ActionListener action_listeners;
-
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
-/**
- * Initializes a new instance of <code>TextField</code> that is empty
- * and has one column.
+ * This class implements a single line text entry field widget
*
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
- */
-public
-TextField()
-{
- this("", 1);
-}
-
-/*************************************************************************/
-
-/**
- * Initializes a new instance of <code>TextField</code> containing
- * the specified text. The number of columns will be equal to the
- * length of the text string.
- *
- * @param text The text to display in the field.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
- */
-public
-TextField(String text)
-{
- this(text, text.length());
-}
-
-/*************************************************************************/
-
-/**
- * Initializes a new instance of <code>TextField</code> that is empty
- * and has the specified number of columns.
- *
- * @param columns The number of columns in the text field.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
- */
-public
-TextField(int columns)
-{
- this("", columns);
-}
-
-/*************************************************************************/
-
-/**
- * Initializes a new instance of <code>TextField</code> with the
- * specified text and number of columns.
- *
- * @param text The text to display in the field.
- * @param columns The number of columns in the field.
- *
- * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
- */
-public
-TextField(String text, int columns)
-{
- super(text);
- this.columns = columns;
-
- if (GraphicsEnvironment.isHeadless())
- throw new HeadlessException ();
-}
-
-/*************************************************************************/
-
-/*
- * Instance Methods
+ * @author Aaron M. Renn (arenn@urbanophile.com)
*/
-
-/**
- * Returns the number of columns in the field.
- *
- * @return The number of columns in the field.
- */
-public int
-getColumns()
-{
- return(columns);
-}
-
-/*************************************************************************/
-
-/**
- * Sets the number of columns in this field to the specified value.
- *
- * @param columns The new number of columns in the field.
- *
- * @exception IllegalArgumentException If columns is less than zero.
- */
-public synchronized void
-setColumns(int columns)
-{
- if (columns < 0)
- throw new IllegalArgumentException("Value is less than zero: " +
- columns);
-
- this.columns = columns;
- // FIXME: How to we communicate this to our peer?
-}
-
-/*************************************************************************/
-
-/**
- * Returns the character that is echoed to the screen when a text
- * field is protected (such as when a password is being entered).
- *
- * @return The echo character for this text field.
- */
-public char
-getEchoChar()
-{
- return(echoChar);
-}
-
-/*************************************************************************/
-
-/**
- * Sets the character that is echoed when protected input such as
- * a password is displayed.
- *
- * @param echoChar The new echo character.
- */
-public void
-setEchoChar(char echoChar)
+public class TextField extends TextComponent
{
- setEchoCharacter (echoChar);
-}
-
-/*************************************************************************/
+
+ /**
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long next_textfield_number;
-/**
- * Sets the character that is echoed when protected input such as
- * a password is displayed.
- *
- * @param echoChar The new echo character.
- *
- * @deprecated This method is deprecated in favor of
- * <code>setEchoChar()</code>
- */
-public void
-setEchoCharacter(char echoChar)
-{
- this.echoChar = echoChar;
+
+ private static final long serialVersionUID = -2966288784432217853L;
- TextFieldPeer peer = (TextFieldPeer) getPeer ();
- if (peer != null)
- peer.setEchoChar (echoChar);
-}
-/*************************************************************************/
+ /**
+ * @serial The number of columns in the text entry field.
+ */
+ private int columns;
-/**
- * Tests whether or not this text field has an echo character set
- * so that characters the user type are not echoed to the screen.
- *
- * @return <code>true</code> if an echo character is set,
- * <code>false</code> otherwise.
- */
-public boolean
-echoCharIsSet()
-{
- if (echoChar == '\u0000')
- return(false);
- else
- return(true);
-}
+ /**
+ * @serial The character that is echoed when doing protected input
+ */
+ private char echoChar;
-/*************************************************************************/
+ // List of registered ActionListener's for this object.
+ private ActionListener action_listeners;
-/**
- * Returns the minimum size for this text field.
- *
- * @return The minimum size for this text field.
- */
-public Dimension
-getMinimumSize()
-{
- return getMinimumSize (getColumns ());
-}
+ /**
+ * Initializes a new instance of <code>TextField</code> that is empty
+ * and has one column.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+ public TextField()
+ {
+ this("", 0);
+ }
-/*************************************************************************/
+ /**
+ * Initializes a new instance of <code>TextField</code> containing
+ * the specified text. The number of columns will be equal to the
+ * length of the text string.
+ *
+ * @param text The text to display in the field.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+ public TextField(String text)
+ {
+ this(text, (text == null) ? 0 : text.length());
+ }
-/**
- * Returns the minimum size of a text field with the specified number
- * of columns.
- *
- * @param columns The number of columns to get the minimum size for.
- */
-public Dimension
-getMinimumSize(int columns)
-{
- return minimumSize (columns);
-}
+ /**
+ * Initializes a new instance of <code>TextField</code> that is empty
+ * and has the specified number of columns.
+ *
+ * @param columns The number of columns in the text field.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+ public TextField(int columns)
+ {
+ this("", columns);
+ }
-/*************************************************************************/
+ /**
+ * Initializes a new instance of <code>TextField</code> with the
+ * specified text and number of columns.
+ *
+ * @param text The text to display in the field.
+ * @param columns The number of columns in the field.
+ *
+ * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
+ */
+ public TextField(String text, int columns)
+ {
+ super(text);
+
+ if (columns < 0)
+ this.columns = 0;
+ else
+ this.columns = columns;
-/**
- * Returns the minimum size for this text field.
- *
- * @return The minimum size for this text field.
- *
- * @deprecated This method is deprecated in favor of
- * <code>getMinimumSize()</code>.
- */
-public Dimension
-minimumSize()
-{
- return minimumSize (getColumns ());
-}
+ if (GraphicsEnvironment.isHeadless())
+ throw new HeadlessException ();
+ }
-/*************************************************************************/
+ /**
+ * Returns the number of columns in the field.
+ *
+ * @return The number of columns in the field.
+ */
+ public int getColumns()
+ {
+ return(columns);
+ }
-/**
- * Returns the minimum size of a text field with the specified number
- * of columns.
- *
- * @param columns The number of columns to get the minimum size for.
- *
- * @deprecated This method is deprecated in favor of
- * <code>getMinimumSize(int)</code>.
- */
-public Dimension
-minimumSize(int columns)
-{
- TextFieldPeer peer = (TextFieldPeer) getPeer ();
- if (peer == null)
- return null; // FIXME: What do we do if there is no peer?
+ /**
+ * Sets the number of columns in this field to the specified value.
+ *
+ * @param columns The new number of columns in the field.
+ *
+ * @exception IllegalArgumentException If columns is less than zero.
+ */
+ public synchronized void setColumns(int columns)
+ {
+ if (columns < 0)
+ throw new IllegalArgumentException("Value is less than zero: " +
+ columns);
- return peer.getMinimumSize (columns);
-}
+ this.columns = columns;
+ // FIXME: How to we communicate this to our peer?
+ }
-/*************************************************************************/
+ /**
+ * Returns the character that is echoed to the screen when a text
+ * field is protected (such as when a password is being entered).
+ *
+ * @return The echo character for this text field.
+ */
+ public char getEchoChar()
+ {
+ return(echoChar);
+ }
-/**
- * Returns the preferred size for this text field.
- *
- * @return The preferred size for this text field.
- */
-public Dimension
-getPreferredSize()
-{
- return getPreferredSize (getColumns ());
-}
+ /**
+ * Sets the character that is echoed when protected input such as
+ * a password is displayed.
+ *
+ * @param echoChar The new echo character.
+ */
+ public void setEchoChar(char echoChar)
+ {
+ setEchoCharacter(echoChar);
+ }
-/*************************************************************************/
+ /**
+ * Sets the character that is echoed when protected input such as
+ * a password is displayed.
+ *
+ * @param echoChar The new echo character.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>setEchoChar()</code>
+ */
+ public void setEchoCharacter(char echoChar)
+ {
+ this.echoChar = echoChar;
-/**
- * Returns the preferred size of a text field with the specified number
- * of columns.
- *
- * @param columns The number of columns to get the preferred size for.
- */
-public Dimension
-getPreferredSize(int columns)
-{
- return preferredSize (columns);
-}
+ TextFieldPeer peer = (TextFieldPeer) getPeer ();
+ if (peer != null)
+ peer.setEchoChar (echoChar);
+ }
-/*************************************************************************/
+ /**
+ * Tests whether or not this text field has an echo character set
+ * so that characters the user type are not echoed to the screen.
+ *
+ * @return <code>true</code> if an echo character is set,
+ * <code>false</code> otherwise.
+ */
+ public boolean echoCharIsSet()
+ {
+ if (echoChar == '\u0000')
+ return(false);
+ else
+ return(true);
+ }
-/**
- * Returns the preferred size for this text field.
- *
- * @return The preferred size for this text field.
- *
- * @deprecated This method is deprecated in favor of
- * <code>getPreferredSize()</code>.
- */
-public Dimension
-preferredSize()
-{
- return preferredSize (getColumns ());
-}
+ /**
+ * Returns the minimum size for this text field.
+ *
+ * @return The minimum size for this text field.
+ */
+ public Dimension getMinimumSize()
+ {
+ return getMinimumSize (getColumns ());
+ }
-/*************************************************************************/
+ /**
+ * Returns the minimum size of a text field with the specified number
+ * of columns.
+ *
+ * @param columns The number of columns to get the minimum size for.
+ */
+ public Dimension getMinimumSize(int columns)
+ {
+ return minimumSize(columns);
+ }
-/**
- * Returns the preferred size of a text field with the specified number
- * of columns.
- *
- * @param columns The number of columns to get the preferred size for.
- *
- * @deprecated This method is deprecated in favor of
- * <code>getPreferredSize(int)</code>.
- */
-public Dimension
-preferredSize(int columns)
-{
- TextFieldPeer peer = (TextFieldPeer) getPeer ();
- if (peer == null)
- return new Dimension (0, 0);
+ /**
+ * Returns the minimum size for this text field.
+ *
+ * @return The minimum size for this text field.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMinimumSize()</code>.
+ */
+ public Dimension minimumSize()
+ {
+ return minimumSize(getColumns ());
+ }
- return peer.getPreferredSize (columns);
-}
+ /**
+ * Returns the minimum size of a text field with the specified number
+ * of columns.
+ *
+ * @param columns The number of columns to get the minimum size for.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getMinimumSize(int)</code>.
+ */
+ public Dimension minimumSize(int columns)
+ {
+ TextFieldPeer peer = (TextFieldPeer) getPeer ();
+ if (peer == null)
+ return null; // FIXME: What do we do if there is no peer?
-/*************************************************************************/
+ return peer.getMinimumSize (columns);
+ }
-/**
- * Notifies this object that it should create its native peer.
- */
-public void
-addNotify()
-{
- if (getPeer() != null)
- return;
+ /**
+ * Returns the preferred size for this text field.
+ *
+ * @return The preferred size for this text field.
+ */
+ public Dimension getPreferredSize()
+ {
+ return getPreferredSize(getColumns ());
+ }
- setPeer((ComponentPeer)getToolkit().createTextField(this));
- super.addNotify();
-}
+ /**
+ * Returns the preferred size of a text field with the specified number
+ * of columns.
+ *
+ * @param columns The number of columns to get the preferred size for.
+ */
+ public Dimension getPreferredSize(int columns)
+ {
+ return preferredSize(columns);
+ }
-/*************************************************************************/
+ /**
+ * Returns the preferred size for this text field.
+ *
+ * @return The preferred size for this text field.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getPreferredSize()</code>.
+ */
+ public Dimension preferredSize()
+ {
+ return preferredSize(getColumns ());
+ }
-/**
- * Addes a new listener to the list of action listeners for this
- * object.
- *
- * @param listener The listener to add to the list.
- */
-public synchronized void
-addActionListener(ActionListener listener)
-{
- action_listeners = AWTEventMulticaster.add(action_listeners, listener);
+ /**
+ * Returns the preferred size of a text field with the specified number
+ * of columns.
+ *
+ * @param columns The number of columns to get the preferred size for.
+ *
+ * @deprecated This method is deprecated in favor of
+ * <code>getPreferredSize(int)</code>.
+ */
+ public Dimension preferredSize(int columns)
+ {
+ TextFieldPeer peer = (TextFieldPeer) getPeer ();
+ if (peer == null)
+ return new Dimension (0, 0);
- enableEvents(AWTEvent.ACTION_EVENT_MASK);
-}
+ return peer.getPreferredSize (columns);
+ }
-/*************************************************************************/
+ /**
+ * Notifies this object that it should create its native peer.
+ */
+ public void addNotify()
+ {
+ if (getPeer() != null)
+ return;
-/**
- * Removes the specified listener from the list of action listeners
- * for this object.
- *
- * @param listener The listener to remove from the list.
- */
-public synchronized void
-removeActionListener(ActionListener listener)
-{
- action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
-}
+ setPeer((ComponentPeer)getToolkit().createTextField(this));
+ super.addNotify();
+ }
-/*************************************************************************/
+ /**
+ * Addes a new listener to the list of action listeners for this
+ * object.
+ *
+ * @param listener The listener to add to the list.
+ */
+ public synchronized void addActionListener(ActionListener listener)
+ {
+ action_listeners = AWTEventMulticaster.add(action_listeners, listener);
-/**
- * Processes the specified event. If the event is an instance of
- * <code>ActionEvent</code> then <code>processActionEvent()</code> is
- * called to process it, otherwise the event is sent to the
- * superclass.
- *
- * @param event The event to process.
- */
-protected void
-processEvent(AWTEvent event)
-{
- if (event instanceof ActionEvent)
- processActionEvent((ActionEvent)event);
- else
- super.processEvent(event);
-}
+ enableEvents(AWTEvent.ACTION_EVENT_MASK);
+ }
-/*************************************************************************/
+ /**
+ * Removes the specified listener from the list of action listeners
+ * for this object.
+ *
+ * @param listener The listener to remove from the list.
+ */
+ public synchronized void removeActionListener(ActionListener listener)
+ {
+ action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
+ }
-/**
- * Processes an action event by calling any registered listeners.
- * Note to subclasses: This method is not called unless action events
- * are enabled on this object. This will be true if any listeners
- * are registered, or if action events were specifically enabled
- * using <code>enableEvents()</code>.
- *
- * @param event The event to process.
- */
-protected void
-processActionEvent(ActionEvent event)
-{
- if (action_listeners != null)
- action_listeners.actionPerformed(event);
-}
+ /**
+ * Processes the specified event. If the event is an instance of
+ * <code>ActionEvent</code> then <code>processActionEvent()</code> is
+ * called to process it, otherwise the event is sent to the
+ * superclass.
+ *
+ * @param event The event to process.
+ */
+ protected void processEvent(AWTEvent event)
+ {
+ if (event instanceof ActionEvent)
+ processActionEvent((ActionEvent)event);
+ else
+ super.processEvent(event);
+ }
-void
-dispatchEventImpl(AWTEvent e)
-{
- if (e.id <= ActionEvent.ACTION_LAST
- && e.id >= ActionEvent.ACTION_FIRST
- && (action_listeners != null
- || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
- processEvent(e);
- else
- super.dispatchEventImpl(e);
-}
+ /**
+ * Processes an action event by calling any registered listeners.
+ * Note to subclasses: This method is not called unless action events
+ * are enabled on this object. This will be true if any listeners
+ * are registered, or if action events were specifically enabled
+ * using <code>enableEvents()</code>.
+ *
+ * @param event The event to process.
+ */
+ protected void processActionEvent(ActionEvent event)
+ {
+ if (action_listeners != null)
+ action_listeners.actionPerformed(event);
+ }
-/*************************************************************************/
+ void dispatchEventImpl(AWTEvent e)
+ {
+ if (e.id <= ActionEvent.ACTION_LAST
+ && e.id >= ActionEvent.ACTION_FIRST
+ && (action_listeners != null
+ || (eventMask & AWTEvent.ACTION_EVENT_MASK) != 0))
+ processEvent(e);
+ else
+ super.dispatchEventImpl(e);
+ }
-/**
+ /**
* Returns a debug string for this object.
*
* @return A debug string for this object.
*/
-protected String
-paramString()
-{
- return(getClass().getName() + "(columns=" + getColumns() + ",echoChar=" +
- getEchoChar());
-}
+ protected String paramString()
+ {
+ return(getClass().getName() + "(columns=" + getColumns() + ",echoChar=" +
+ getEchoChar());
+ }
/**
* Returns an array of all the objects currently registered as FooListeners
@@ -521,6 +440,21 @@ paramString()
{
return (ActionListener[]) getListeners (ActionListener.class);
}
+
+ /**
+ * Generate a unique name for this <code>TextField</code>.
+ *
+ * @return A unique name for this <code>TextField</code>.
+ */
+ String generateName()
+ {
+ return "textfield" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_textfield_number++;
+ }
protected class AccessibleAWTTextField extends AccessibleAWTTextComponent
{
@@ -541,4 +475,4 @@ paramString()
return new AccessibleAWTTextField();
}
-} // class TextField
+}
diff --git a/libjava/classpath/java/awt/Toolkit.java b/libjava/classpath/java/awt/Toolkit.java
index 282e50d2c50..2842091c139 100644
--- a/libjava/classpath/java/awt/Toolkit.java
+++ b/libjava/classpath/java/awt/Toolkit.java
@@ -70,6 +70,7 @@ import java.awt.peer.ListPeer;
import java.awt.peer.MenuBarPeer;
import java.awt.peer.MenuItemPeer;
import java.awt.peer.MenuPeer;
+import java.awt.peer.MouseInfoPeer;
import java.awt.peer.PanelPeer;
import java.awt.peer.PopupMenuPeer;
import java.awt.peer.ScrollPanePeer;
@@ -332,6 +333,18 @@ public abstract class Toolkit
protected abstract MenuItemPeer createMenuItem(MenuItem target);
/**
+ * Returns a MouseInfoPeer.
+ * The default implementation of this method throws
+ * UnsupportedOperationException.
+ *
+ * Toolkit implementations should overload this if possible, however.
+ */
+ protected MouseInfoPeer getMouseInfoPeer()
+ {
+ throw new UnsupportedOperationException("No mouse info peer.");
+ }
+
+ /**
* Creates a peer object for the specified <code>FileDialog</code>.
*
* @param target The <code>FileDialog</code> to create the peer for.
@@ -695,6 +708,14 @@ public abstract class Toolkit
public PrintJob getPrintJob(Frame frame, String title,
JobAttributes jobAttr, PageAttributes pageAttr)
{
+ // FIXME: it is possible this check may be removed
+ // if this method, when written, always delegates to
+ // getPrintJob(Frame, String, Properties).
+ SecurityManager sm;
+ sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPrintJobAccess();
+
return null;
}
diff --git a/libjava/classpath/java/awt/Window.java b/libjava/classpath/java/awt/Window.java
index 8bc4715aed5..8885821811d 100644
--- a/libjava/classpath/java/awt/Window.java
+++ b/libjava/classpath/java/awt/Window.java
@@ -39,8 +39,6 @@ exception statement from your version. */
package java.awt;
import java.awt.event.ComponentEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowListener;
@@ -80,6 +78,8 @@ public class Window extends Container implements Accessible
private int state = 0;
/** @since 1.4 */
private boolean focusableWindowState = true;
+ /** @since 1.5 */
+ private boolean alwaysOnTop = false;
// A list of other top-level windows owned by this window.
private transient Vector ownedWindows = new Vector();
@@ -130,7 +130,6 @@ public class Window extends Container implements Accessible
// cycle roots.
focusCycleRoot = true;
setLayout(new BorderLayout());
- addWindowFocusListener();
GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
graphicsConfiguration = g.getDefaultScreenDevice().getDefaultConfiguration();
@@ -142,67 +141,6 @@ public class Window extends Container implements Accessible
graphicsConfiguration = gc;
}
- private void addWindowFocusListener()
- {
- addWindowFocusListener(new WindowAdapter()
- {
- public void windowGainedFocus(WindowEvent event)
- {
- EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
- if (windowFocusOwner != null)
- {
- synchronized (eq)
- {
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- Component currentFocusOwner = manager.getGlobalPermanentFocusOwner();
- if (currentFocusOwner != null)
- {
- eq.postEvent(new FocusEvent(currentFocusOwner,
- FocusEvent.FOCUS_LOST, false,
- windowFocusOwner));
- eq.postEvent(new FocusEvent(windowFocusOwner,
- FocusEvent.FOCUS_GAINED, false,
- currentFocusOwner));
- }
- else
- eq.postEvent(new FocusEvent(windowFocusOwner,
- FocusEvent.FOCUS_GAINED, false));
- }
- }
- else
- eq.postEvent(new FocusEvent(Window.this, FocusEvent.FOCUS_GAINED,
- false));
- }
-
- public void windowLostFocus(WindowEvent event)
- {
- EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
- if (windowFocusOwner != null)
- {
- synchronized (eq)
- {
- KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
- Component currentFocusOwner = manager.getGlobalPermanentFocusOwner();
- if (currentFocusOwner != null)
- {
- eq.postEvent(new FocusEvent(currentFocusOwner,
- FocusEvent.FOCUS_GAINED, false,
- windowFocusOwner));
- eq.postEvent(new FocusEvent(windowFocusOwner,
- FocusEvent.FOCUS_LOST, false,
- currentFocusOwner));
- }
- else
- eq.postEvent(new FocusEvent(windowFocusOwner,
- FocusEvent.FOCUS_LOST, false));
- }
- }
- else
- eq.postEvent(new FocusEvent(Window.this, FocusEvent.FOCUS_LOST, false));
- }
- });
- }
-
/**
* Initializes a new instance of <code>Window</code> with the specified
* parent. The window will initially be invisible.
@@ -420,13 +358,17 @@ public class Window extends Container implements Accessible
/**
* Sends this window to the back so that all other windows display in
* front of it.
+ *
+ * If the window is set to be always-on-top, this will remove its
+ * always-on-top status.
*/
public void toBack()
{
if (peer != null)
{
- WindowPeer wp = (WindowPeer) peer;
- wp.toBack();
+ if( alwaysOnTop )
+ setAlwaysOnTop( false );
+ ( (WindowPeer) peer ).toBack();
}
}
@@ -437,10 +379,7 @@ public class Window extends Container implements Accessible
public void toFront()
{
if (peer != null)
- {
- WindowPeer wp = (WindowPeer) peer;
- wp.toFront();
- }
+ ( (WindowPeer) peer ).toFront();
}
/**
@@ -1236,6 +1175,55 @@ public class Window extends Container implements Accessible
}
/**
+ * Returns whether the Windows is an always-on-top window,
+ * meaning whether the window can be obscured by other windows or not.
+ *
+ * @return <code>true</code> if the windows is always-on-top,
+ * <code>false</code> otherwise.
+ * @since 1.5
+ */
+ public final boolean isAlwaysOnTop()
+ {
+ return alwaysOnTop;
+ }
+
+ /**
+ * Sets the always-on-top state of this window (if supported).
+ *
+ * Setting a window to always-on-top means it will not be obscured
+ * by any other windows (with the exception of other always-on-top
+ * windows). Not all platforms may support this.
+ *
+ * If an window's always-on-top status is changed to false, the window
+ * will remain at the front but not be anchored there.
+ *
+ * Calling toBack() on an always-on-top window will change its
+ * always-on-top status to false.
+ *
+ * @since 1.5
+ */
+ public final void setAlwaysOnTop(boolean alwaysOnTop)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission( new AWTPermission("setWindowAlwaysOnTop") );
+
+ if( this.alwaysOnTop == alwaysOnTop )
+ return;
+
+ if( alwaysOnTop )
+ toFront();
+
+ firePropertyChange("alwaysOnTop", this.alwaysOnTop, alwaysOnTop );
+ this.alwaysOnTop = alwaysOnTop;
+
+ if (peer != null)
+ ( (WindowPeer) peer).updateAlwaysOnTop();
+ else
+ System.out.println("Null peer?!");
+ }
+
+ /**
* Generate a unique name for this window.
*
* @return A unique name for this window.
diff --git a/libjava/classpath/java/awt/datatransfer/Clipboard.java b/libjava/classpath/java/awt/datatransfer/Clipboard.java
index 5fa1d1ab134..2029e2c351b 100644
--- a/libjava/classpath/java/awt/datatransfer/Clipboard.java
+++ b/libjava/classpath/java/awt/datatransfer/Clipboard.java
@@ -1,5 +1,5 @@
/* Clipboard.java -- Class for transferring data via cut and paste.
- Copyright (C) 1999, 2001, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -182,6 +182,9 @@ public class Clipboard
public void addFlavorListener(FlavorListener listener)
{
+ if (listener == null)
+ return;
+
synchronized(listeners)
{
listeners.add(listener);
@@ -190,6 +193,9 @@ public class Clipboard
public void removeFlavorListener(FlavorListener listener)
{
+ if (listener == null)
+ return;
+
synchronized(listeners)
{
listeners.remove(listener);
diff --git a/libjava/classpath/java/awt/datatransfer/DataFlavor.java b/libjava/classpath/java/awt/datatransfer/DataFlavor.java
index 5944c2eb7ec..0228cd5786d 100644
--- a/libjava/classpath/java/awt/datatransfer/DataFlavor.java
+++ b/libjava/classpath/java/awt/datatransfer/DataFlavor.java
@@ -1,5 +1,5 @@
/* DataFlavor.java -- A type of data to transfer via the clipboard.
- Copyright (C) 1999, 2001, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,6 +47,7 @@ import java.io.InputStreamReader;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Reader;
+import java.io.Serializable;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
@@ -197,31 +198,37 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
throw new ClassNotFoundException(className);
}
- private static Class getRepresentationClassFromMime(String mimeString,
+ private static Class getRepresentationClassFromMimeThrows(String mimeString,
ClassLoader classLoader)
+ throws ClassNotFoundException
{
String classname = getParameter("class", mimeString);
if (classname != null)
- {
- try
- {
- return tryToLoadClass(classname, classLoader);
- }
- catch(Exception e)
- {
- IllegalArgumentException iae;
- iae = new IllegalArgumentException("mimeString: "
- + mimeString
- + " classLoader: "
- + classLoader);
- iae.initCause(e);
- throw iae;
- }
- }
+ return tryToLoadClass(classname, classLoader);
else
return java.io.InputStream.class;
}
-
+
+ // Same as above, but wraps any ClassNotFoundExceptions
+ private static Class getRepresentationClassFromMime(String mimeString,
+ ClassLoader classLoader)
+ {
+ try
+ {
+ return getRepresentationClassFromMimeThrows(mimeString, classLoader);
+ }
+ catch(ClassNotFoundException cnfe)
+ {
+ IllegalArgumentException iae;
+ iae = new IllegalArgumentException("mimeString: "
+ + mimeString
+ + " classLoader: "
+ + classLoader);
+ iae.initCause(cnfe);
+ throw iae;
+ }
+ }
+
/**
* Returns the value of the named MIME type parameter, or <code>null</code>
* if the parameter does not exist. Given the parameter name and the mime
@@ -240,7 +247,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
String value = mimeString.substring(idx + paramName.length() + 1);
- idx = value.indexOf(" ");
+ idx = value.indexOf(";");
if (idx == -1)
return(value);
else
@@ -328,6 +335,14 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
{
this.representationClass = representationClass;
this.mimeType = mimeType;
+
+ // Do some simple validity checks
+ String type = getPrimaryType() + "/" + getSubType();
+ if (type.indexOf(' ') != -1
+ || type.indexOf('=') != -1
+ || type.indexOf(';') != -1)
+ throw new IllegalArgumentException(mimeType);
+
if (humanPresentableName != null)
this.humanPresentableName = humanPresentableName;
else
@@ -375,7 +390,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
ClassLoader classLoader)
throws ClassNotFoundException
{
- this(getRepresentationClassFromMime(mimeType, classLoader),
+ this(getRepresentationClassFromMimeThrows(mimeType, classLoader),
mimeType, humanPresentableName);
}
@@ -417,7 +432,8 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public DataFlavor(String mimeType) throws ClassNotFoundException
{
- this(mimeType, null);
+ this(getRepresentationClassFromMimeThrows(mimeType, null),
+ mimeType, null);
}
/**
@@ -567,7 +583,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isRepresentationClassInputStream()
{
- return representationClass.getName().equals("java.io.InputStream");
+ return InputStream.class.isAssignableFrom(representationClass);
}
/**
@@ -579,17 +595,7 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isRepresentationClassSerializable()
{
- Class[] interfaces = representationClass.getInterfaces();
-
- int i = 0;
- while (i < interfaces.length)
- {
- if (interfaces[i].getName().equals("java.io.Serializable"))
- return true;
- ++i;
- }
-
- return false;
+ return Serializable.class.isAssignableFrom(representationClass);
}
/**
@@ -634,8 +640,10 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
*/
public boolean isFlavorJavaFileListType()
{
- if (mimeType.equals(javaFileListFlavor.mimeType)
- && representationClass.equals(javaFileListFlavor.representationClass))
+ if (getPrimaryType().equals(javaFileListFlavor.getPrimaryType())
+ && getSubType().equals(javaFileListFlavor.getSubType())
+ && javaFileListFlavor.representationClass
+ .isAssignableFrom(representationClass))
return true;
return false ;
@@ -666,7 +674,11 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
/**
* This method test the specified <code>DataFlavor</code> for equality
* against this object. This will be true if the MIME type and
- * representation type are the equal.
+ * representation class are the equal. If the primary type is 'text'
+ * then also the value of the charset parameter is compared. In such a
+ * case when the charset parameter isn't given then the charset is
+ * assumed to be equal to the default charset of the platform. All
+ * other parameters are ignored.
*
* @param flavor The <code>DataFlavor</code> to test against.
*
@@ -677,12 +689,34 @@ public class DataFlavor implements java.io.Externalizable, Cloneable
{
if (flavor == null)
return false;
-
- if (! this.mimeType.toLowerCase().equals(flavor.mimeType.toLowerCase()))
+
+ String primary = getPrimaryType();
+ if (! primary.equals(flavor.getPrimaryType()))
return false;
-
+
+ String sub = getSubType();
+ if (! sub.equals(flavor.getSubType()))
+ return false;
+
if (! this.representationClass.equals(flavor.representationClass))
return false;
+
+ if (primary.equals("text"))
+ if (! isRepresentationClassCharBuffer()
+ && ! isRepresentationClassReader()
+ && representationClass != java.lang.String.class
+ && ! (representationClass.isArray()
+ && representationClass.getComponentType() == Character.TYPE))
+ {
+ String charset = getParameter("charset");
+ String otherset = flavor.getParameter("charset");
+ String defaultset = Charset.defaultCharset().name();
+
+ if (charset == null || charset.equals(defaultset))
+ return (otherset == null || otherset.equals(defaultset));
+
+ return charset.equals(otherset);
+ }
return true;
}
diff --git a/libjava/classpath/java/awt/dnd/DragGestureEvent.java b/libjava/classpath/java/awt/dnd/DragGestureEvent.java
index 9f2bc7c98b8..351ae540072 100644
--- a/libjava/classpath/java/awt/dnd/DragGestureEvent.java
+++ b/libjava/classpath/java/awt/dnd/DragGestureEvent.java
@@ -48,13 +48,6 @@ 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
{
/**
@@ -66,52 +59,121 @@ public class DragGestureEvent extends EventObject
private Component component;
private final Point origin;
private final int action;
+ private List events;
+ private DragGestureRecognizer dgr;
+ /**
+ * Constructs a new DragGestureEvent.
+ * @param dgr - DragGestureRecognizer firing this event
+ * @param action - user's preferred action
+ * @param origin - origin of the drag
+ * @param events - List of events that make up the gesture
+ * @throws IllegalArgumentException - if input parameters are null
+ */
public DragGestureEvent(DragGestureRecognizer dgr, int action, Point origin,
List events)
- {
+ {
super(dgr);
- if (origin == null || events == null)
+ if (origin == null || events == null || dgr == null)
throw new IllegalArgumentException();
+
this.origin = origin;
this.action = action;
+ this.events = events;
+ this.dgr = dgr;
+ this.component = dgr.getComponent();
+ this.dragSource = dgr.getDragSource();
}
+ /**
+ * Returns the source casted as a DragGestureRecognizer.
+ *
+ * @return the source casted as a DragGestureRecognizer.
+ */
public DragGestureRecognizer getSourceAsDragGestureRecognizer()
{
- return (DragGestureRecognizer) source;
+ return (DragGestureRecognizer) getSource();
}
+
+ /**
+ * Returns the Component corresponding to this.
+ *
+ * @return the Component corresponding to this.
+ */
public Component getComponent()
{
- return null;
+ return component;
}
+
+ /**
+ * Gets the DragSource corresponding to this.
+ *
+ * @return the DragSource corresponding to this.
+ */
public DragSource getDragSource()
{
- return null;
+ return dragSource;
}
+
+ /**
+ * Returns the origin of the drag.
+ *
+ * @return the origin of the drag.
+ */
public Point getDragOrigin()
{
return origin;
}
+
+ /**
+ * Gets an iterator representation of the List of events.
+ *
+ * @return an iterator representation of the List of events.
+ */
public Iterator iterator()
{
- return null;
+ return events.iterator();
}
+
+ /**
+ * Gets an array representation of the List of events.
+ *
+ * @return an array representation of the List of events.
+ */
public Object[] toArray()
{
- return null;
+ return events.toArray();
}
+
+ /**
+ * Gets an array representation of the List of events.
+ *
+ * @param array - the array to store the events in.
+ * @return an array representation of the List of events.
+ */
public Object[] toArray(Object[] array)
{
- return array;
+ return events.toArray(array);
}
+
+ /**
+ * Gets the user's preferred action.
+ *
+ * @return the user's preferred action.
+ */
public int getDragAction()
{
- return 0;
+ return action;
}
+
+ /**
+ * Get the event that triggered this gesture.
+ *
+ * @return the event that triggered this gesture.
+ */
public InputEvent getTriggerEvent()
{
- return null;
+ return dgr.getTriggerEvent();
}
/**
@@ -152,5 +214,6 @@ public class DragGestureEvent extends EventObject
public void startDrag(Cursor dragCursor, Image dragImage, Point imageOffset,
Transferable trans, DragSourceListener l)
{
+ dragSource.startDrag(this, dragCursor, dragImage, imageOffset, trans, l);
}
} // class DragGestureEvent
diff --git a/libjava/classpath/java/awt/dnd/DragGestureRecognizer.java b/libjava/classpath/java/awt/dnd/DragGestureRecognizer.java
index 145a24a3850..32bbc56da5d 100644
--- a/libjava/classpath/java/awt/dnd/DragGestureRecognizer.java
+++ b/libjava/classpath/java/awt/dnd/DragGestureRecognizer.java
@@ -131,6 +131,7 @@ public abstract class DragGestureRecognizer implements Serializable
throws NotImplementedException
{
events = new ArrayList();
+ // FIXME: Not implemented fully.
}
/**
diff --git a/libjava/classpath/java/awt/dnd/DragSource.java b/libjava/classpath/java/awt/dnd/DragSource.java
index 05eb6709d47..48fa2388ee2 100644
--- a/libjava/classpath/java/awt/dnd/DragSource.java
+++ b/libjava/classpath/java/awt/dnd/DragSource.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package java.awt.dnd;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.Cursor;
import java.awt.GraphicsEnvironment;
@@ -70,9 +72,12 @@ public class DragSource implements Serializable
public static final Cursor DefaultLinkNoDrop = null;
private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap ();
-
private transient DragSourceListener dragSourceListener;
private transient DragSourceMotionListener dragSourceMotionListener;
+
+ private static DragSource ds;
+ private DragSourceContextPeer peer;
+ private DragSourceContext context;
/**
* Initializes the drag source.
@@ -82,19 +87,34 @@ public class DragSource implements Serializable
public DragSource()
{
if (GraphicsEnvironment.isHeadless())
- throw new HeadlessException ();
+ {
+ ds = null;
+ throw new HeadlessException();
+ }
}
/**
+ * Gets the default drag source.
+ *
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
public static DragSource getDefaultDragSource()
{
- return new DragSource();
+ if (GraphicsEnvironment.isHeadless())
+ {
+ ds = null;
+ throw new HeadlessException();
+ }
+
+ if (ds == null)
+ ds = new DragSource();
+ return ds;
}
public static boolean isDragImageSupported()
+ throws NotImplementedException
{
+ // FIXME: Implement this
return false;
}
@@ -110,6 +130,43 @@ public class DragSource implements Serializable
Transferable trans, DragSourceListener dsl,
FlavorMap map)
{
+ // http://www.javaworld.com/javaworld/jw-03-1999/jw-03-dragndrop.html
+
+ // This function creates a DragSourceContext object. This object tracks the
+ // state of the operation by listening to a native peer. In this situation,
+ // the DragSource may be obtained from the event or by an instance variable.
+ // This function also creates a new DragSourceContextPeer.
+
+ // This function sends the same message to the context, which then forwards
+ // it to the peer, passing itself as a parameter. Now, the native system has
+ // access to the Transferable through the context.
+
+ // FIXME: Add check to determine if dragging.
+
+ try
+ {
+ flavorMap = map;
+
+ if (peer == null)
+ peer = Toolkit.getDefaultToolkit().createDragSourceContextPeer(trigger);
+
+ if (context == null)
+ context = createDragSourceContext(peer, trigger,
+ dragCursor,
+ dragImage,
+ imageOffset, trans,
+ dsl);
+
+ if (peer == null)
+ throw new InvalidDnDOperationException();
+
+ peer.startDrag(context, dragCursor, dragImage, imageOffset);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidDnDOperationException("Drag and Drop system is "
+ + "unable to initiate a drag operation.");
+ }
}
/**
@@ -156,7 +213,7 @@ public class DragSource implements Serializable
/**
* Creates the DragSourceContext to handle this drag.
*
- * @exception IllegalArgumentException FIXME
+ * @exception IllegalArgumentException
* @exception NullPointerException If dscp, dgl, dragImage or t is null.
*/
protected DragSourceContext
@@ -164,7 +221,7 @@ public class DragSource implements Serializable
Cursor cursor, Image image, Point offset,
Transferable t, DragSourceListener dsl)
{
- return null;
+ return new DragSourceContext(peer, dge, cursor, image, offset, t, dsl);
}
public FlavorMap getFlavorMap()
@@ -172,42 +229,22 @@ public class DragSource implements Serializable
return flavorMap;
}
- /**
- * Dummy DragGestureRecognizer when Toolkit doesn't support drag and drop.
- */
- static class NoDragGestureRecognizer extends DragGestureRecognizer
- {
- NoDragGestureRecognizer(DragSource ds, Component c, int actions,
- DragGestureListener dgl)
- {
- super(ds, c, actions, dgl);
- }
-
- protected void registerListeners() { }
- protected void unregisterListeners() { }
- }
-
- public DragGestureRecognizer
- createDragGestureRecognizer(Class recognizer, Component c, int actions,
- DragGestureListener dgl)
+ public DragGestureRecognizer createDragGestureRecognizer(Class recognizer,
+ Component c,
+ int actions,
+ DragGestureListener dgl)
{
- DragGestureRecognizer dgr;
- dgr = Toolkit.getDefaultToolkit ()
- .createDragGestureRecognizer (recognizer, this, c, actions,
- dgl);
-
- if (dgr == null)
- dgr = new NoDragGestureRecognizer(this, c, actions, dgl);
-
- return dgr;
+ return Toolkit.getDefaultToolkit().createDragGestureRecognizer(recognizer,
+ this, c,
+ actions, dgl);
}
- public DragGestureRecognizer
- createDefaultDragGestureRecognizer(Component c, int actions,
- DragGestureListener dgl)
+ public DragGestureRecognizer createDefaultDragGestureRecognizer(Component c,
+ int actions,
+ DragGestureListener dgl)
{
- return createDragGestureRecognizer (MouseDragGestureRecognizer.class, c,
- actions, dgl);
+ return createDragGestureRecognizer(MouseDragGestureRecognizer.class, c,
+ actions, dgl);
}
/**
@@ -275,4 +312,17 @@ public class DragSource implements Serializable
// Return an empty EventListener array.
return new EventListener [0];
}
+
+ /**
+ * TODO
+ * @return
+ *
+ * @since 1.5
+ */
+ public static int getDragThreshold()
+ throws NotImplementedException
+ {
+ // FIXME: Not implemented.
+ return 4;
+ }
} // class DragSource
diff --git a/libjava/classpath/java/awt/dnd/DragSourceContext.java b/libjava/classpath/java/awt/dnd/DragSourceContext.java
index 88607b090ea..1fee5c0c304 100644
--- a/libjava/classpath/java/awt/dnd/DragSourceContext.java
+++ b/libjava/classpath/java/awt/dnd/DragSourceContext.java
@@ -70,8 +70,8 @@ public class DragSourceContext
private Transferable transferable;
private DragGestureEvent trigger;
private DragSourceListener dragSourceListener;
- private boolean useCustomCursor; // FIXME: currently unused but needed for serialization.
- private int sourceActions; // FIXME: currently unused but needed for serialization.
+ private boolean useCustomCursor;
+ private int sourceActions;
private Image image;
private Point offset;
@@ -82,16 +82,17 @@ public class DragSourceContext
* are null, the drag action for the trigger event is DnDConstants.ACTION_NONE
* or if the source actions for the DragGestureRecognizer associated with the
* trigger event are equal to DnDConstants.ACTION_NONE.
- * @exception NullPointerException If peer or trigger is null.
+ * @exception NullPointerException If peer, trans or trigger is null or if the
+ * image is not null but the offset is.
*/
public DragSourceContext (DragSourceContextPeer peer,
DragGestureEvent trigger, Cursor cursor,
Image image, Point offset, Transferable trans,
DragSourceListener dsl)
- throws NotImplementedException
- {
+ {
if (peer == null
- || trigger == null)
+ || trigger == null || trans == null
+ || (image != null && offset == null))
throw new NullPointerException ();
if (trigger.getComponent () == null
@@ -108,37 +109,77 @@ public class DragSourceContext
this.offset = offset;
this.transferable = trans;
this.dragSourceListener = dsl;
+ this.sourceActions = trigger.getSourceAsDragGestureRecognizer().getSourceActions();
- throw new Error ("not implemented");
+ setCursor(cursor);
+ updateCurrentCursor(trigger.getDragAction(), sourceActions, DEFAULT);
}
+ /**
+ * Returns the DragSource object associated with the
+ * DragGestureEvent.
+ *
+ * @return the DragSource associated with the trigger.
+ */
public DragSource getDragSource()
{
return trigger.getDragSource ();
}
+ /**
+ * Returns the component associated with this.
+ *
+ * @return the component associated with the trigger.
+ */
public Component getComponent()
{
return trigger.getComponent ();
}
+ /**
+ * Gets the trigger associated with this.
+ *
+ * @return the trigger.
+ */
public DragGestureEvent getTrigger()
{
return trigger;
}
+ /**
+ * Returns the source actions for the DragGestureRecognizer.
+ *
+ * @return the source actions for DragGestureRecognizer.
+ */
public int getSourceActions()
{
- return trigger.getSourceAsDragGestureRecognizer ().getSourceActions ();
+ if (sourceActions == 0)
+ sourceActions = trigger.getSourceAsDragGestureRecognizer().getSourceActions();
+ return sourceActions;
}
- public void setCursor (Cursor cursor)
- throws NotImplementedException
+ /**
+ * Sets the cursor for this drag operation to the specified cursor.
+ *
+ * @param cursor c - the Cursor to use, or null to use the default drag
+ * cursor.
+ */
+ public void setCursor(Cursor cursor)
{
+ if (cursor == null)
+ useCustomCursor = false;
+ else
+ useCustomCursor = true;
this.cursor = cursor;
- // FIXME: Check if we need to do more here
+ peer.setCursor(cursor);
}
+ /**
+ * Returns the current cursor or null if the default
+ * drag cursor is used.
+ *
+ * @return the current cursor or null.
+ */
public Cursor getCursor()
{
return cursor;
@@ -165,48 +206,160 @@ public class DragSourceContext
dragSourceListener = null;
}
+ /**
+ * This function tells the peer that the DataFlavors have been modified.
+ */
public void transferablesFlavorsChanged()
- throws NotImplementedException
{
+ peer.transferablesFlavorsChanged();
}
+ /**
+ * Calls dragEnter on the listeners registered with this
+ * and with the DragSource.
+ *
+ * @param e - the DragSourceDragEvent
+ */
public void dragEnter(DragSourceDragEvent e)
- throws NotImplementedException
{
+ if (dragSourceListener != null)
+ dragSourceListener.dragEnter(e);
+
+ DragSource ds = getDragSource();
+ DragSourceListener[] dsl = ds.getDragSourceListeners();
+ for (int i = 0; i < dsl.length; i++)
+ dsl[i].dragEnter(e);
+
+ updateCurrentCursor(e.getDropAction(), e.getTargetActions(), ENTER);
}
+ /**
+ * Calls dragOver on the listeners registered with this
+ * and with the DragSource.
+ *
+ * @param e - the DragSourceDragEvent
+ */
public void dragOver(DragSourceDragEvent e)
- throws NotImplementedException
{
+ if (dragSourceListener != null)
+ dragSourceListener.dragOver(e);
+
+ DragSource ds = getDragSource();
+ DragSourceListener[] dsl = ds.getDragSourceListeners();
+ for (int i = 0; i < dsl.length; i++)
+ dsl[i].dragOver(e);
+
+ updateCurrentCursor(e.getDropAction(), e.getTargetActions(), OVER);
}
-
+
+ /**
+ * Calls dragExit on the listeners registered with this
+ * and with the DragSource.
+ *
+ * @param e - the DragSourceEvent
+ */
public void dragExit(DragSourceEvent e)
- throws NotImplementedException
{
+ if (dragSourceListener != null)
+ dragSourceListener.dragExit(e);
+
+ DragSource ds = getDragSource();
+ DragSourceListener[] dsl = ds.getDragSourceListeners();
+ for (int i = 0; i < dsl.length; i++)
+ dsl[i].dragExit(e);
+
+ updateCurrentCursor(0, 0, DEFAULT);
}
+ /**
+ * Calls dropActionChanged on the listeners registered with this
+ * and with the DragSource.
+ *
+ * @param e - the DragSourceDragEvent
+ */
public void dropActionChanged(DragSourceDragEvent e)
- throws NotImplementedException
{
+ if (dragSourceListener != null)
+ dragSourceListener.dropActionChanged(e);
+
+ DragSource ds = getDragSource();
+ DragSourceListener[] dsl = ds.getDragSourceListeners();
+ for (int i = 0; i < dsl.length; i++)
+ dsl[i].dropActionChanged(e);
+
+ updateCurrentCursor(e.getDropAction(), e.getTargetActions(), CHANGED);
}
+ /**
+ * Calls dragDropEnd on the listeners registered with this
+ * and with the DragSource.
+ *
+ * @param e - the DragSourceDropEvent
+ */
public void dragDropEnd(DragSourceDropEvent e)
- throws NotImplementedException
{
+ if (dragSourceListener != null)
+ dragSourceListener.dragDropEnd(e);
+
+ DragSource ds = getDragSource();
+ DragSourceListener[] dsl = ds.getDragSourceListeners();
+ for (int i = 0; i < dsl.length; i++)
+ dsl[i].dragDropEnd(e);
}
+ /**
+ * Calls dragMouseMoved on the listeners registered with the DragSource.
+ *
+ * @param e - the DragSourceDragEvent
+ */
public void dragMouseMoved(DragSourceDragEvent e)
- throws NotImplementedException
{
+ DragSource ds = getDragSource();
+ DragSourceMotionListener[] dsml = ds.getDragSourceMotionListeners();
+ for (int i = 0; i < dsml.length; i++)
+ dsml[i].dragMouseMoved(e);
}
+ /**
+ * Returns the Transferable set with this object.
+ *
+ * @return the transferable.
+ */
public Transferable getTransferable()
{
return transferable;
}
+ /**
+ * This function sets the drag cursor for the specified operation, actions and
+ * status if the default drag cursor is active. Otherwise, the cursor is not
+ * updated in any way.
+ *
+ * @param dropOp - the current operation.
+ * @param targetAct - the supported actions.
+ * @param status - the status of the cursor (constant).
+ */
protected void updateCurrentCursor(int dropOp, int targetAct, int status)
throws NotImplementedException
{
+ // FIXME: Not implemented fully
+ if (!useCustomCursor)
+ {
+ Cursor cursor = null;
+ switch (status)
+ {
+ case ENTER:
+ break;
+ case CHANGED:
+ break;
+ case OVER:
+ break;
+ default:
+ break;
+ }
+
+ this.cursor = cursor;
+ peer.setCursor(cursor);
+ }
}
} // class DragSourceContext
diff --git a/libjava/classpath/java/awt/dnd/DropTarget.java b/libjava/classpath/java/awt/dnd/DropTarget.java
index b0d4c2ae7a1..a3650567f09 100644
--- a/libjava/classpath/java/awt/dnd/DropTarget.java
+++ b/libjava/classpath/java/awt/dnd/DropTarget.java
@@ -38,13 +38,18 @@ exception statement from your version. */
package java.awt.dnd;
+import gnu.classpath.NotImplementedException;
+
import java.awt.Component;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.datatransfer.FlavorMap;
+import java.awt.dnd.peer.DropTargetPeer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.peer.ComponentPeer;
+import java.awt.peer.LightweightPeer;
import java.io.Serializable;
import java.util.EventListener;
import java.util.TooManyListenersException;
@@ -79,19 +84,25 @@ public class DropTarget
}
protected void stop ()
+ throws NotImplementedException
{
+ // FIXME: implement this
}
public void actionPerformed (ActionEvent e)
+ throws NotImplementedException
{
+ // FIXME: implement this
}
}
private Component component;
private FlavorMap flavorMap;
private int actions;
+ private DropTargetPeer peer;
private DropTargetContext dropTargetContext;
private DropTargetListener dropTargetListener;
+ private DropTarget.DropTargetAutoScroller autoscroller;
private boolean active = true;
/**
@@ -150,12 +161,15 @@ public class DropTarget
if (GraphicsEnvironment.isHeadless ())
throw new HeadlessException ();
- component = c;
- actions = i;
+ setComponent(c);
+ setDefaultActions(i);
dropTargetListener = dtl;
flavorMap = fm;
setActive (b);
+
+ if (c != null)
+ c.setDropTarget(this);
}
/**
@@ -211,33 +225,46 @@ public class DropTarget
public void addDropTargetListener (DropTargetListener dtl)
throws TooManyListenersException
{
+ if (dropTargetListener != null)
+ throw new TooManyListenersException ();
+
dropTargetListener = dtl;
}
public void removeDropTargetListener(DropTargetListener dtl)
{
- // FIXME: Do we need to do something with dtl ?
- dropTargetListener = null;
+ if (dropTargetListener != null)
+ dropTargetListener = null;
}
public void dragEnter(DropTargetDragEvent dtde)
{
+ if (dropTargetListener != null)
+ dropTargetListener.dragEnter(dtde);
}
public void dragOver(DropTargetDragEvent dtde)
{
+ if (dropTargetListener != null)
+ dropTargetListener.dragOver(dtde);
}
public void dropActionChanged(DropTargetDragEvent dtde)
{
+ if (dropTargetListener != null)
+ dropTargetListener.dropActionChanged(dtde);
}
public void dragExit(DropTargetEvent dte)
{
+ if (dropTargetListener != null)
+ dropTargetListener.dragExit(dte);
}
public void drop(DropTargetDropEvent dtde)
{
+ if (dropTargetListener != null)
+ dropTargetListener.drop(dtde);
}
public FlavorMap getFlavorMap()
@@ -250,12 +277,29 @@ public class DropTarget
flavorMap = fm;
}
- public void addNotify(java.awt.peer.ComponentPeer peer)
+ public void addNotify(ComponentPeer p)
{
+ Component c = component;
+ while (c != null && p instanceof LightweightPeer)
+ {
+ p = c.getPeer();
+ c = c.getParent();
+ }
+
+ if (p instanceof DropTargetPeer)
+ {
+ peer = ((DropTargetPeer) p);
+ peer.addDropTarget(this);
+ }
+ else
+ peer = null;
}
- public void removeNotify(java.awt.peer.ComponentPeer peer)
+ public void removeNotify(ComponentPeer p)
{
+ ((DropTargetPeer) peer).removeDropTarget(this);
+ peer = null;
+ p = null;
}
public DropTargetContext getDropTargetContext()
@@ -268,24 +312,34 @@ public class DropTarget
protected DropTargetContext createDropTargetContext()
{
- return new DropTargetContext (this);
+ if (dropTargetContext == null)
+ dropTargetContext = new DropTargetContext (this);
+
+ return dropTargetContext;
}
protected DropTarget.DropTargetAutoScroller createDropTargetAutoScroller
(Component c, Point p)
{
- return new DropTarget.DropTargetAutoScroller (c, p);
+ if (autoscroller == null)
+ autoscroller = new DropTarget.DropTargetAutoScroller (c, p);
+
+ return autoscroller;
}
protected void initializeAutoscrolling(Point p)
{
+ createDropTargetAutoScroller (component, p);
}
protected void updateAutoscroll(Point dragCursorLocn)
{
+ if (autoscroller != null)
+ autoscroller.updateLocation(dragCursorLocn);
}
protected void clearAutoscroll()
{
+ autoscroller = null;
}
} // class DropTarget
diff --git a/libjava/classpath/java/awt/dnd/DropTargetContext.java b/libjava/classpath/java/awt/dnd/DropTargetContext.java
index 4a26d904880..31945c34bb1 100644
--- a/libjava/classpath/java/awt/dnd/DropTargetContext.java
+++ b/libjava/classpath/java/awt/dnd/DropTargetContext.java
@@ -37,12 +37,11 @@ exception statement from your version. */
package java.awt.dnd;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.dnd.peer.DropTargetContextPeer;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
@@ -86,7 +85,7 @@ public class DropTargetContext implements Serializable
private DropTarget dropTarget;
private int targetActions;
- private java.awt.dnd.peer.DropTargetContextPeer dtcp;
+ private DropTargetContextPeer dtcp;
// package private
DropTargetContext(DropTarget dropTarget)
@@ -104,7 +103,7 @@ public class DropTargetContext implements Serializable
return dropTarget.getComponent();
}
- public void addNotify(java.awt.dnd.peer.DropTargetContextPeer dtcp)
+ public void addNotify(DropTargetContextPeer dtcp)
{
this.dtcp = dtcp;
}
@@ -130,39 +129,39 @@ public class DropTargetContext implements Serializable
* @exception InvalidDnDOperationException If a drop is not outstanding.
*/
public void dropComplete(boolean success)
- throws NotImplementedException
{
- // FIXME: implement this
+ if (dtcp != null)
+ dtcp.dropComplete(success);
}
protected void acceptDrag(int dragOperation)
- throws NotImplementedException
{
- // FIXME: implement this
+ if (dtcp != null)
+ dtcp.acceptDrag(dragOperation);
}
protected void rejectDrag()
- throws NotImplementedException
{
- // FIXME: implement this
+ if (dtcp != null)
+ dtcp.rejectDrag();
}
protected void acceptDrop(int dropOperation)
- throws NotImplementedException
{
- // FIXME: implement this
+ if (dtcp != null)
+ dtcp.acceptDrop(dropOperation);
}
protected void rejectDrop()
- throws NotImplementedException
{
- // FIXME: implement this
+ if (dtcp != null)
+ dtcp.rejectDrop();
}
protected DataFlavor[] getCurrentDataFlavors()
- throws NotImplementedException
{
- // FIXME: implement this
+ if (dtcp != null)
+ dtcp.getTransferDataFlavors();
return null;
}
@@ -182,9 +181,11 @@ public class DropTargetContext implements Serializable
* @exception InvalidDnDOperationException If a drag is not outstanding.
*/
protected Transferable getTransferable()
- throws InvalidDnDOperationException, NotImplementedException
+ throws InvalidDnDOperationException
{
- // FIXME: implement this
+ // FIXME: Implement this
+ if (dtcp != null)
+ return dtcp.getTransferable();
return null;
}
diff --git a/libjava/classpath/java/awt/dnd/DropTargetDragEvent.java b/libjava/classpath/java/awt/dnd/DropTargetDragEvent.java
index 6cdc3a292be..89bf1778a71 100644
--- a/libjava/classpath/java/awt/dnd/DropTargetDragEvent.java
+++ b/libjava/classpath/java/awt/dnd/DropTargetDragEvent.java
@@ -40,6 +40,7 @@ package java.awt.dnd;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
import java.util.List;
/**
@@ -114,8 +115,7 @@ public class DropTargetDragEvent extends DropTargetEvent
public int getDropAction()
{
- return 0;
- //return dropAction & ((DropTargetContext) source).getTargetActions();
+ return dropAction & ((DropTargetContext) source).getTargetActions();
}
public Point getLocation ()
@@ -137,4 +137,17 @@ public class DropTargetDragEvent extends DropTargetEvent
{
context.rejectDrag ();
}
+
+ /**
+ * TODO
+ *
+ * @return
+ *
+ * @since 1.5
+ */
+ public Transferable getTransferable()
+ {
+ // FIXME: Not implemented
+ return null;
+ }
} // class DropTargetDragEvent
diff --git a/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java b/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java
index a745bd256f8..9754bb11ef5 100644
--- a/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java
+++ b/libjava/classpath/java/awt/dnd/DropTargetDropEvent.java
@@ -37,8 +37,6 @@ exception statement from your version. */
package java.awt.dnd;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
@@ -161,9 +159,8 @@ public class DropTargetDropEvent extends DropTargetEvent
}
public void dropComplete(boolean success)
- throws NotImplementedException
{
- // FIXME: implement this
+ context.dropComplete(success);
}
public boolean isLocalTransfer()
diff --git a/libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java b/libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java
index 2fd9767e03d..4a75610bf61 100644
--- a/libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java
+++ b/libjava/classpath/java/awt/dnd/InvalidDnDOperationException.java
@@ -59,6 +59,7 @@ public class InvalidDnDOperationException extends IllegalStateException
*/
public InvalidDnDOperationException()
{
+ super();
}
/**
diff --git a/libjava/classpath/java/awt/event/KeyEvent.java b/libjava/classpath/java/awt/event/KeyEvent.java
index d4b93ba3e0b..42084d7333e 100644
--- a/libjava/classpath/java/awt/event/KeyEvent.java
+++ b/libjava/classpath/java/awt/event/KeyEvent.java
@@ -993,6 +993,27 @@ public class KeyEvent extends InputEvent
public static final int VK_ALT_GRAPH = 65406;
/**
+ * The 'begin' key VK_BEGIN
+ *
+ * @since 1.5
+ */
+ public static final int VK_BEGIN = 65368;
+
+ /**
+ * The context-menu key VK_CONTEXT_MENU
+ *
+ * @since 1.5
+ */
+ public static final int VK_CONTEXT_MENU = 525;
+
+ /**
+ * The 'Windows' key VK_WINDOWS
+ *
+ * @since 1.5
+ */
+ public static final int VK_WINDOWS = 524;
+
+ /**
* The virtual key VK_UNDEFINED. This is used for key typed events, which
* do not have a virtual key.
*/
diff --git a/libjava/classpath/java/awt/font/FontRenderContext.java b/libjava/classpath/java/awt/font/FontRenderContext.java
index 78564a647da..c50e5e5092a 100644
--- a/libjava/classpath/java/awt/font/FontRenderContext.java
+++ b/libjava/classpath/java/awt/font/FontRenderContext.java
@@ -83,7 +83,15 @@ public class FontRenderContext
public boolean equals (FontRenderContext rhs)
{
- return (affineTransform.equals (rhs.getTransform ())
+ if (rhs == null)
+ return false;
+
+ if (affineTransform == null && rhs.affineTransform != null
+ || affineTransform != null && rhs.affineTransform == null)
+ return false;
+
+ return ((affineTransform == rhs.affineTransform
+ || affineTransform.equals (rhs.getTransform ()))
&& isAntiAliased == rhs.isAntiAliased ()
&& usesFractionalMetrics == rhs.usesFractionalMetrics ());
}
diff --git a/libjava/classpath/java/awt/font/LineBreakMeasurer.java b/libjava/classpath/java/awt/font/LineBreakMeasurer.java
index c2a6d45d9f5..816c7745c2b 100644
--- a/libjava/classpath/java/awt/font/LineBreakMeasurer.java
+++ b/libjava/classpath/java/awt/font/LineBreakMeasurer.java
@@ -41,57 +41,41 @@ package java.awt.font;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.BreakIterator;
-import java.awt.font.TextLayout;
-import java.awt.font.FontRenderContext;
import java.awt.Shape;
public final class LineBreakMeasurer
{
private AttributedCharacterIterator text;
private int position;
- private FontRenderContext frc;
- private TextLayout totalLayout;
+ private TextMeasurer tm;
private int numChars;
public LineBreakMeasurer(AttributedCharacterIterator text,
BreakIterator breakIter, FontRenderContext frc)
{
- this.text = text;
- this.frc = frc;
- position = 0;
- totalLayout = new TextLayout(text, frc);
- numChars = totalLayout.getCharacterCount();
+ this( text, frc );
}
public LineBreakMeasurer(AttributedCharacterIterator text,
FontRenderContext frc)
{
this.text = text;
- this.frc = frc;
position = 0;
- totalLayout = new TextLayout(text, frc);
- numChars = totalLayout.getCharacterCount();
+ numChars = text.getEndIndex();
+ tm = new TextMeasurer( text, frc );
}
public void deleteChar(AttributedCharacterIterator newParagraph,
int deletePos)
{
- totalLayout = new TextLayout(newParagraph, frc);
- if( deletePos < 0 || deletePos > totalLayout.getCharacterCount() )
- throw new NullPointerException("Invalid deletePos:"+deletePos);
- numChars = totalLayout.getCharacterCount();
- text = newParagraph;
+ tm.deleteChar( newParagraph, deletePos );
position = 0;
}
public void insertChar(AttributedCharacterIterator newParagraph,
int insertPos)
{
- totalLayout = new TextLayout(newParagraph, frc);
- if( insertPos < 0 || insertPos > totalLayout.getCharacterCount() )
- throw new NullPointerException("Invalid insertPos:"+insertPos);
- numChars = totalLayout.getCharacterCount();
- text = newParagraph;
+ tm.insertChar( newParagraph, insertPos );
position = 0;
}
@@ -104,11 +88,9 @@ public final class LineBreakMeasurer
boolean requireNextWord)
{
int next = nextOffset( wrappingWidth, offsetLimit, requireNextWord );
- AttributedCharacterIterator aci = (new AttributedString( text,
- position, next )
- ).getIterator();
+ TextLayout tl = tm.getLayout( position, next );
position = next;
- return new TextLayout( aci, frc );
+ return tl;
}
public int nextOffset(float wrappingWidth)
@@ -119,69 +101,40 @@ public final class LineBreakMeasurer
public int nextOffset(float wrappingWidth, int offsetLimit,
boolean requireNextWord)
{
- Shape s = totalLayout.getBlackBoxBounds( position, offsetLimit );
- double remainingLength = s.getBounds2D().getWidth();
+ int guessOffset = tm.getLineBreakIndex(position, wrappingWidth);
+ if( offsetLimit > numChars )
+ offsetLimit = numChars;
- int guessOffset = (int)( ( (double)wrappingWidth / (double)remainingLength)
- * ( (double)numChars - (double)position ) );
- guessOffset += position;
if( guessOffset > offsetLimit )
- guessOffset = offsetLimit;
-
- s = totalLayout.getBlackBoxBounds( position, guessOffset );
- double guessLength = s.getBounds2D().getWidth();
-
- boolean makeSmaller = ( guessLength > wrappingWidth );
- int inc = makeSmaller ? -1 : 1;
- boolean keepGoing = true;
-
- do
{
- guessOffset = guessOffset + inc;
- if( guessOffset <= position || guessOffset > offsetLimit )
- {
- keepGoing = false;
- }
- else
- {
- s = totalLayout.getBlackBoxBounds( position, guessOffset );
- guessLength = s.getBounds2D().getWidth();
- if( makeSmaller && ( guessLength <= wrappingWidth) )
- keepGoing = false;
- if( !makeSmaller && ( guessLength >= wrappingWidth) )
- keepGoing = false;
- }
+ text.setIndex( offsetLimit );
+ return offsetLimit;
}
- while( keepGoing );
- if( !makeSmaller )
- guessOffset--;
+ text.setIndex( guessOffset );
- if( guessOffset >= offsetLimit )
- return offsetLimit;
+ // If we're on a breaking character, return directly
+ if( Character.isWhitespace( text.current() ) )
+ return guessOffset;
- text.setIndex( guessOffset );
+ // Otherwise jump forward or backward to the last such char.
if( !requireNextWord )
- {
- char c = text.previous();
- while( !Character.isWhitespace( c ) && c != '-' &&
- guessOffset > position )
- {
- guessOffset--;
- c = text.previous();
- }
- }
+ while( !Character.isWhitespace( text.previous() ) &&
+ guessOffset > position )
+ guessOffset--;
else
+ while( !Character.isWhitespace( text.next() ) &&
+ guessOffset < offsetLimit )
+ guessOffset++;
+
+ if( guessOffset > offsetLimit )
{
- char c = text.next();
- while( !Character.isWhitespace( c ) && c != '-' &&
- guessOffset < offsetLimit )
- {
- guessOffset++;
- c = text.next();
- }
+ text.setIndex( offsetLimit );
+ return offsetLimit;
}
+ text.setIndex( guessOffset );
+
return guessOffset;
}
diff --git a/libjava/classpath/java/awt/font/TextLayout.java b/libjava/classpath/java/awt/font/TextLayout.java
index 4f8c1c644c1..b1473f25564 100644
--- a/libjava/classpath/java/awt/font/TextLayout.java
+++ b/libjava/classpath/java/awt/font/TextLayout.java
@@ -43,13 +43,12 @@ import gnu.classpath.NotImplementedException;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
-import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
+import java.text.CharacterIterator;
import java.text.AttributedCharacterIterator;
-import java.text.AttributedString;
import java.text.Bidi;
import java.util.Map;
@@ -73,6 +72,12 @@ public final class TextLayout implements Cloneable
private int[][] runIndices;
/**
+ * Character indices.
+ * Fixt index is the glyphvector, second index is the (first) glyph.
+ */
+ private int[][] charIndices;
+
+ /**
* Base directionality, determined from the first char.
*/
private boolean leftToRight;
@@ -85,7 +90,7 @@ public final class TextLayout implements Cloneable
/**
* The default caret policy.
*/
- static TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
+ public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy();
/**
* Constructs a TextLayout.
@@ -139,6 +144,7 @@ public final class TextLayout implements Cloneable
Font.LAYOUT_LEFT_TO_RIGHT :
Font.LAYOUT_RIGHT_TO_LEFT );
}
+ setCharIndices();
}
public TextLayout (String string, Map attributes, FontRenderContext frc)
@@ -147,9 +153,97 @@ public final class TextLayout implements Cloneable
}
public TextLayout (AttributedCharacterIterator text, FontRenderContext frc)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ // FIXME: Very rudimentary.
+ this(getText(text), getFont(text), frc);
+ }
+
+ /**
+ * Package-private constructor to make a textlayout from an existing one.
+ * This is used by TextMeasurer for returning sub-layouts, and it
+ * saves a lot of time in not having to relayout the text.
+ */
+ TextLayout(TextLayout t, int startIndex, int endIndex)
+ {
+ font = t.font;
+ frc = t.frc;
+ boundsCache = null;
+ lm = t.lm;
+ leftToRight = t.leftToRight;
+
+ if( endIndex > t.getCharacterCount() )
+ endIndex = t.getCharacterCount();
+ string = t.string.substring( startIndex, endIndex );
+
+ int startingRun = t.charIndices[startIndex][0];
+ int nRuns = 1 + t.charIndices[endIndex - 1][0] - startingRun;
+ runIndices = new int[ nRuns ][2];
+
+ runs = new GlyphVector[ nRuns ];
+ for( int i = 0; i < nRuns; i++ )
+ {
+ GlyphVector run = t.runs[ i + startingRun ];
+ // Copy only the relevant parts of the first and last runs.
+ int beginGlyphIndex = (i > 0) ? 0 : t.charIndices[startIndex][1];
+ int numEntries = ( i < nRuns - 1) ? run.getNumGlyphs() :
+ 1 + t.charIndices[endIndex - 1][1] - beginGlyphIndex;
+
+ int[] codes = run.getGlyphCodes(beginGlyphIndex, numEntries, null);
+ runs[ i ] = font.createGlyphVector( frc, codes );
+ runIndices[ i ][0] = t.runIndices[i + startingRun][0] - startIndex;
+ runIndices[ i ][1] = t.runIndices[i + startingRun][1] - startIndex;
+ }
+ runIndices[ nRuns - 1 ][1] = endIndex - 1;
+
+ setCharIndices();
+ determineWhiteSpace();
+ }
+
+ private void setCharIndices()
+ {
+ charIndices = new int[ getCharacterCount() ][2];
+ int i = 0;
+ int currentChar = 0;
+ for(int run = 0; run < runs.length; run++)
+ {
+ currentChar = -1;
+ for( int gi = 0; gi < runs[ run ].getNumGlyphs(); gi++)
+ {
+ if( runs[ run ].getGlyphCharIndex( gi ) != currentChar )
+ {
+ charIndices[ i ][0] = run;
+ charIndices[ i ][1] = gi;
+ currentChar = runs[ run ].getGlyphCharIndex( gi );
+ i++;
+ }
+ }
+ }
+ }
+
+ private static String getText(AttributedCharacterIterator iter)
+ {
+ StringBuffer sb = new StringBuffer();
+ int idx = iter.getIndex();
+ for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next())
+ sb.append(c);
+ iter.setIndex( idx );
+ return sb.toString();
+ }
+
+ private static Font getFont(AttributedCharacterIterator iter)
+ {
+ Font f = (Font)iter.getAttribute(TextAttribute.FONT);
+ if( f == null )
+ {
+ int size;
+ Float i = (Float)iter.getAttribute(TextAttribute.SIZE);
+ if( i != null )
+ size = (int)i.floatValue();
+ else
+ size = 14;
+ f = new Font("Dialog", Font.PLAIN, size );
+ }
+ return f;
}
/**
@@ -179,10 +273,14 @@ public final class TextLayout implements Cloneable
gotDirection = true;
break;
}
+ determineWhiteSpace();
+ }
+ private void determineWhiteSpace()
+ {
// Determine if there's whitespace in the thing.
// Ignore trailing chars.
- i = string.length() - 1;
+ int i = string.length() - 1;
hasWhitespace = false;
while( i >= 0 && Character.isWhitespace( string.charAt(i) ) )
i--;
@@ -251,56 +349,42 @@ public final class TextLayout implements Cloneable
public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint)
{
- if( firstEndpoint < 0 || secondEndpoint > getCharacterCount() )
+ if( secondEndpoint - firstEndpoint <= 0 )
+ return new Rectangle2D.Float(); // Hmm?
+
+ if( firstEndpoint < 0 || secondEndpoint > getCharacterCount())
return new Rectangle2D.Float();
GeneralPath gp = new GeneralPath();
- int i = 0; // run index
- double advance = 0;
-
- // go to first run
- while( runIndices[i + 1][1] < firstEndpoint )
- {
- advance += runs[i].getLogicalBounds().getWidth();
- i++;
- }
+
+ int ri = charIndices[ firstEndpoint ][0];
+ int gi = charIndices[ firstEndpoint ][1];
- int j = 0; // index into the run.
- if( runIndices[i][1] - runIndices[i][0] > 1 )
+ double advance = 0;
+
+ for( int i = 0; i < ri; i++ )
+ advance += runs[i].getLogicalBounds().getWidth();
+
+ for( int i = ri; i <= charIndices[ secondEndpoint - 1 ][0]; i++ )
{
- while( runs[i].getGlyphCharIndex( j + 1 ) <
- (firstEndpoint - runIndices[i][0] ) )j++;
- }
-
- gp.append(runs[i].getGlyphVisualBounds( j ), false);
- boolean keepGoing = true;;
+ int dg;
+ if( i == charIndices[ secondEndpoint - 1 ][0] )
+ dg = charIndices[ secondEndpoint - 1][1];
+ else
+ dg = runs[i].getNumGlyphs() - 1;
- do
- {
- while( j < runs[i].getNumGlyphs() &&
- runs[i].getGlyphCharIndex( j ) + runIndices[i][0] <
- secondEndpoint )
+ for( int j = 0; j <= dg; j++ )
{
Rectangle2D r2 = (runs[i].getGlyphVisualBounds( j )).
getBounds2D();
Point2D p = runs[i].getGlyphPosition( j );
- r2.setRect( advance + p.getX(), r2.getY(),
+ r2.setRect( advance + r2.getX(), r2.getY(),
r2.getWidth(), r2.getHeight() );
gp.append(r2, false);
- j++;
}
- if( j >= runs[i].getNumGlyphs() )
- {
- advance += runs[i].getLogicalBounds().getWidth();
- i++;
- j = 0;
- }
- else
- keepGoing = false;
+ advance += runs[i].getLogicalBounds().getWidth();
}
- while( keepGoing );
-
return gp;
}
@@ -384,55 +468,42 @@ public final class TextLayout implements Cloneable
public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint,
Rectangle2D bounds)
{
- if( firstEndpoint < 0 || secondEndpoint > getCharacterCount() )
+ if( secondEndpoint - firstEndpoint <= 0 )
+ return new Rectangle2D.Float(); // Hmm?
+
+ if( firstEndpoint < 0 || secondEndpoint > getCharacterCount())
return new Rectangle2D.Float();
- int i = 0; // run index
- double advance = 0;
+ Rectangle2D r = null;
+ int ri = charIndices[ firstEndpoint ][0];
+ int gi = charIndices[ firstEndpoint ][1];
- // go to first run
- if( i > 0 )
- while( runIndices[i + 1][1] < firstEndpoint )
- {
- advance += runs[i].getLogicalBounds().getWidth();
- i++;
- }
+ double advance = 0;
+
+ for( int i = 0; i < ri; i++ )
+ advance += runs[i].getLogicalBounds().getWidth();
- int j = 0; // index into the run.
- if( runIndices[i][1] - runIndices[i][0] > 1 )
+ for( int i = ri; i <= charIndices[ secondEndpoint - 1 ][0]; i++ )
{
- while( runs[i].getGlyphCharIndex( j + 1 ) <
- (firstEndpoint - runIndices[i][0] ) )j++;
- }
-
- Rectangle2D r = (runs[i].getGlyphLogicalBounds( j )).getBounds2D();
- boolean keepGoing = true;;
+ int dg; // last index in this run to use.
+ if( i == charIndices[ secondEndpoint - 1 ][0] )
+ dg = charIndices[ secondEndpoint - 1][1];
+ else
+ dg = runs[i].getNumGlyphs() - 1;
- do
- {
- while( j < runs[i].getNumGlyphs() &&
- runs[i].getGlyphCharIndex( j ) + runIndices[i][0] <
- secondEndpoint )
+ for(; gi <= dg; gi++ )
{
- Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( j )).
+ Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( gi )).
getBounds2D();
- Point2D p = runs[i].getGlyphPosition( j );
- r2.setRect( advance + p.getX(), r2.getY(),
- r2.getWidth(), r2.getHeight() );
- r = r.createUnion( r2 );
- j++;
+ if( r == null )
+ r = r2;
+ else
+ r = r.createUnion(r2);
}
+ gi = 0; // reset glyph index into run for next run.
- if( j >= runs[i].getNumGlyphs() )
- {
- advance += runs[i].getLogicalBounds().getWidth();
- i++;
- j = 0;
- }
- else
- keepGoing = false;
+ advance += runs[i].getLogicalBounds().getWidth();
}
- while( keepGoing );
return r;
}
@@ -593,8 +664,9 @@ public final class TextLayout implements Cloneable
}
public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds)
+ throws NotImplementedException
{
- return hitTestChar( x, y, getBounds() );
+ throw new Error ("not implemented");
}
public boolean isLeftToRight ()
diff --git a/libjava/classpath/java/awt/font/TextMeasurer.java b/libjava/classpath/java/awt/font/TextMeasurer.java
index 18c286c57c1..00cab8a878d 100644
--- a/libjava/classpath/java/awt/font/TextMeasurer.java
+++ b/libjava/classpath/java/awt/font/TextMeasurer.java
@@ -1,5 +1,5 @@
/* TextMeasurer.java
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,67 +38,154 @@ exception statement from your version. */
package java.awt.font;
-import gnu.classpath.NotImplementedException;
-
import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.awt.Shape;
/**
- * @author Michael Koch
+ * TextMeasurer is a small utility class for measuring the length of laid-out
+ * text objects.
+ *
+ * @author Sven de Marothy
* @since 1.3
*/
public final class TextMeasurer implements Cloneable
{
- private AttributedCharacterIterator ci;
+ private AttributedCharacterIterator text;
private FontRenderContext frc;
-
+ private TextLayout totalLayout;
+ private int numChars;
+
+ /**
+ * Creates a TextMeasurer from a given text in the form of an
+ * <code>AttributedCharacterIterator</code> and a
+ * <code>FontRenderContext</code>.
+ */
public TextMeasurer (AttributedCharacterIterator text, FontRenderContext frc)
{
- this.ci = text;
+ this.text = text;
this.frc = frc;
+ totalLayout = new TextLayout( text, frc );
+ numChars = totalLayout.getCharacterCount();
}
+ /**
+ * Clones the TextMeasurer object
+ */
protected Object clone ()
{
- try
- {
- return super.clone ();
- }
- catch (CloneNotSupportedException e)
- {
- // This may never occur
- throw new InternalError ();
- }
+ return new TextMeasurer( text, frc );
}
+ /**
+ * Update the text if a character is deleted at the position deletePos
+ * @param newParagraph - the updated paragraph.
+ * @param deletePos - the deletion position
+ */
public void deleteChar (AttributedCharacterIterator newParagraph,
int deletePos)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ totalLayout = new TextLayout(newParagraph, frc);
+ if( deletePos < 0 || deletePos > totalLayout.getCharacterCount() )
+ throw new NullPointerException("Invalid deletePos:"+deletePos);
+ numChars = totalLayout.getCharacterCount();
+ text = newParagraph;
+ }
+
+ /**
+ * Update the text if a character is inserted at the position insertPos
+ * @param newParagraph - the updated paragraph.
+ * @param insertPos - the insertion position
+ */
+ public void insertChar (AttributedCharacterIterator newParagraph,
+ int insertPos)
+ {
+ totalLayout = new TextLayout(newParagraph, frc);
+ if( insertPos < 0 || insertPos > totalLayout.getCharacterCount() )
+ throw new NullPointerException("Invalid insertPos:"+insertPos);
+ numChars = totalLayout.getCharacterCount();
+ text = newParagraph;
}
+ /***
+ * Returns the total advance between two positions in the paragraph.
+ * Characters from start to limit-1 (inclusive) are included in this count.
+ *
+ * @param start - the starting character index.
+ * @param limit - the limiting index.
+ */
public float getAdvanceBetween (int start, int limit)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ Shape s = totalLayout.getLogicalHighlightShape( start, limit );
+ return (float)s.getBounds2D().getWidth();
}
+ /**
+ * Returns a <code>TextLayout</code> object corresponding to the characters
+ * from text to limit.
+ * @param start - the starting character index.
+ * @param limit - the limiting index.
+ */
public TextLayout getLayout (int start, int limit)
- throws NotImplementedException
{
- throw new Error ("not implemented");
+ if( start >= limit )
+ throw new IllegalArgumentException("Start position must be < limit.");
+ return new TextLayout( totalLayout, start, limit );
}
+ /**
+ * Returns the line-break index from a given starting index and a maximum
+ * advance. The index returned is the first character outside the given
+ * advance (or the limit of the string, if all remaining characters fit.)
+ *
+ * @param start - the starting index.
+ * @param maxAdvance - the maximum advance allowed.
+ * @return the index of the first character beyond maxAdvance, or the
+ * index of the last character + 1.
+ */
public int getLineBreakIndex (int start, float maxAdvance)
- throws NotImplementedException
- {
- throw new Error ("not implemented");
- }
+ {
+ if( start < 0 )
+ throw new IllegalArgumentException("Start parameter must be > 0.");
+
+ double remainingLength = getAdvanceBetween( start, numChars );
+
+ int guessOffset = (int)( ( (double)maxAdvance / (double)remainingLength)
+ * ( (double)numChars - (double)start ) );
+ guessOffset += start;
+ if( guessOffset > numChars )
+ guessOffset = numChars;
+
+ double guessLength = getAdvanceBetween( start, guessOffset );
+ boolean makeSmaller = ( guessLength > maxAdvance );
+ int inc = makeSmaller ? -1 : 1;
+ boolean keepGoing = true;
+
+ do
+ {
+ guessOffset = guessOffset + inc;
+ if( guessOffset <= start || guessOffset > numChars )
+ {
+ keepGoing = false;
+ }
+ else
+ {
+ guessLength = getAdvanceBetween( start, guessOffset );
+ if( makeSmaller && ( guessLength <= maxAdvance) )
+ keepGoing = false;
+ if( !makeSmaller && ( guessLength >= maxAdvance) )
+ keepGoing = false;
+ }
+ }
+ while( keepGoing );
- public void insertChar (AttributedCharacterIterator newParagraph,
- int insertPos)
- throws NotImplementedException
- {
- throw new Error ("not implemented");
+ // Return first index that doesn't fit.
+ if( !makeSmaller )
+ guessOffset--;
+
+ if( guessOffset > numChars )
+ return numChars;
+
+ return guessOffset;
}
}
diff --git a/libjava/classpath/java/awt/geom/GeneralPath.java b/libjava/classpath/java/awt/geom/GeneralPath.java
index 123833b118b..e0ca8e18357 100644
--- a/libjava/classpath/java/awt/geom/GeneralPath.java
+++ b/libjava/classpath/java/awt/geom/GeneralPath.java
@@ -65,8 +65,8 @@ import java.awt.Shape;
* &#x2019;up&#x2019;
* direction, one in the &#x2019;down&#x2019; direction) Point <b>B</b> in
* the image is inside (one intersection &#x2019;down&#x2019;)
- * Point <b>C</b> in the image is outside (two intersections
- * &#x2019;down&#x2019;)
+ * Point <b>C</b> in the image is inside (two intersections in the
+ * &#x2019;down&#x2019; direction)
*
* @see Line2D
* @see CubicCurve2D
@@ -247,10 +247,12 @@ public final class GeneralPath implements Shape, Cloneable
/**
* Closes the current subpath by drawing a line
- * back to the point of the last moveTo.
+ * back to the point of the last moveTo, unless the path is already closed.
*/
public void closePath()
{
+ if (index >= 1 && types[index - 1] == PathIterator.SEG_CLOSE)
+ return;
ensureSize(index + 1);
types[index] = PathIterator.SEG_CLOSE;
xpoints[index] = xpoints[subpath];
diff --git a/libjava/classpath/java/awt/image/BandedSampleModel.java b/libjava/classpath/java/awt/image/BandedSampleModel.java
index 24d315a1c35..afe62bdc4bd 100644
--- a/libjava/classpath/java/awt/image/BandedSampleModel.java
+++ b/libjava/classpath/java/awt/image/BandedSampleModel.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004, 2005, Free Software Foundation
+/* Copyright (C) 2004, 2005, 2006, Free Software Foundation
This file is part of GNU Classpath.
@@ -36,10 +36,11 @@ exception statement from your version. */
package java.awt.image;
+import gnu.java.awt.Buffers;
+
/**
- * MultiPixelPackedSampleModel provides a single band model that supports
- * multiple pixels in a single unit. Pixels have 2^n bits and 2^k pixels fit
- * per data element.
+ * A sample model that reads each sample value from a separate band in the
+ * {@link DataBuffer}.
*
* @author Jerry Quinn (jlquinn@optonline.net)
*/
@@ -61,17 +62,61 @@ public final class BandedSampleModel extends ComponentSampleModel
return result;
}
+ /**
+ * Creates a new <code>BandedSampleModel</code>.
+ *
+ * @param dataType the data buffer type.
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ * @param numBands the number of bands.
+ */
public BandedSampleModel(int dataType, int w, int h, int numBands)
{
this(dataType, w, h, w, createBankArray(numBands), new int[numBands]);
}
+ /**
+ * Creates a new <code>BandedSampleModel</code>.
+ *
+ * @param dataType the data buffer type.
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ * @param scanlineStride the number of data elements from a pixel in one
+ * row to the corresponding pixel in the next row.
+ * @param bankIndices the bank indices.
+ * @param bandOffsets the band offsets.
+ */
public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
int[] bankIndices, int[] bandOffsets)
{
super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
}
+
+ /**
+ * Creates a new data buffer that is compatible with this sample model.
+ *
+ * @return The new data buffer.
+ */
+ public DataBuffer createDataBuffer()
+ {
+ int size = scanlineStride * height;
+ return Buffers.createBuffer(getDataType(), size, numBanks);
+ }
+ /**
+ * Creates a new <code>SampleModel</code> that is compatible with this
+ * model and has the specified width and height.
+ *
+ * @param w the width (in pixels, must be greater than zero).
+ * @param h the height (in pixels, must be greater than zero).
+ *
+ * @return The new sample model.
+ *
+ * @throws IllegalArgumentException if <code>w</code> or <code>h</code> is
+ * not greater than zero.
+ * @throws IllegalArgumentException if <code>w * h</code> exceeds
+ * <code>Integer.MAX_VALUE</code>.
+ */
public SampleModel createCompatibleSampleModel(int w, int h)
{
// NOTE: blackdown 1.4.1 sets all offsets to 0. Sun's 1.4.2 docs
@@ -80,32 +125,32 @@ public final class BandedSampleModel extends ComponentSampleModel
// Compress offsets so minimum is 0, others w*scanlineStride
int[] newoffsets = new int[bandOffsets.length];
int[] order = new int[bandOffsets.length];
- for (int i=0; i < bandOffsets.length; i++)
+ for (int i = 0; i < bandOffsets.length; i++)
order[i] = i;
// FIXME: This is N^2, but not a big issue, unless there's a lot of
// bands...
- for (int i=0; i < bandOffsets.length; i++)
- for (int j=i+1; j < bandOffsets.length; i++)
- if (bankIndices[order[i]] > bankIndices[order[j]]
- || (bankIndices[order[i]] == bankIndices[order[j]]
- && bandOffsets[order[i]] > bandOffsets[order[j]]))
- {
- int t = order[i]; order[i] = order[j]; order[j] = t;
- }
+ for (int i = 0; i < bandOffsets.length; i++)
+ for (int j = i + 1; j < bandOffsets.length; j++)
+ if (bankIndices[order[i]] > bankIndices[order[j]]
+ || (bankIndices[order[i]] == bankIndices[order[j]]
+ && bandOffsets[order[i]] > bandOffsets[order[j]]))
+ {
+ int t = order[i]; order[i] = order[j]; order[j] = t;
+ }
int bank = 0;
int offset = 0;
- for (int i=0; i < bandOffsets.length; i++)
+ for (int i = 0; i < bandOffsets.length; i++)
{
- if (bankIndices[order[i]] != bank)
- {
- bank = bankIndices[order[i]];
- offset = 0;
- }
- newoffsets[order[i]] = offset;
- offset += w * scanlineStride;
+ if (bankIndices[order[i]] != bank)
+ {
+ bank = bankIndices[order[i]];
+ offset = 0;
+ }
+ newoffsets[order[i]] = offset;
+ offset += w * scanlineStride;
}
- return new BandedSampleModel(dataType, w, h, scanlineStride, bankIndices, newoffsets);
+ return new BandedSampleModel(dataType, w, h, w, bankIndices, newoffsets);
}
@@ -117,7 +162,7 @@ public final class BandedSampleModel extends ComponentSampleModel
+" many bands");
int[] newoff = new int[bands.length];
int[] newbanks = new int[bands.length];
- for (int i=0; i < bands.length; i++)
+ for (int i = 0; i < bands.length; i++)
{
int b = bands[i];
newoff[i] = bandOffsets[b];
@@ -134,57 +179,64 @@ public final class BandedSampleModel extends ComponentSampleModel
* Extracts the pixel at x, y from data and stores samples into the array
* obj. If obj is null, a new array of getTransferType() is created.
*
- * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
- * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
- * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param x The x-coordinate of the pixel rectangle to store in
+ * <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in
+ * <code>obj</code>.
+ * @param obj The primitive array to store the pixels into or null to force
+ * creation.
* @param data The DataBuffer that is the source of the pixel data.
* @return The primitive array containing the pixel data.
- * @see java.awt.image.SampleModel#getDataElements(int, int, java.lang.Object, java.awt.image.DataBuffer)
+ * @see java.awt.image.SampleModel#getDataElements(int, int,
+ * java.lang.Object, java.awt.image.DataBuffer)
*/
- public Object getDataElements(int x, int y, Object obj,
- DataBuffer data)
+ public Object getDataElements(int x, int y, Object obj, DataBuffer data)
{
+ if (x < 0 || y < 0)
+ throw new ArrayIndexOutOfBoundsException(
+ "x and y must not be less than 0.");
int pixel = getSample(x, y, 0, data);
switch (getTransferType())
{
case DataBuffer.TYPE_BYTE:
{
- byte[] b = (byte[])obj;
+ byte[] b = (byte[]) obj;
if (b == null) b = new byte[numBands];
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
b[i] = (byte)getSample(x, y, i, data);
return b;
}
case DataBuffer.TYPE_SHORT:
case DataBuffer.TYPE_USHORT:
{
- short[] b = (short[])obj;
+ short[] b = (short[]) obj;
if (b == null) b = new short[numBands];
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
b[i] = (short)getSample(x, y, i, data);
return b;
}
case DataBuffer.TYPE_INT:
{
- int[] b = (int[])obj;
+ int[] b = (int[]) obj;
if (b == null) b = new int[numBands];
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
b[i] = getSample(x, y, i, data);
return b;
}
case DataBuffer.TYPE_FLOAT:
{
- float[] b = (float[])obj;
+ float[] b = (float[]) obj;
if (b == null) b = new float[numBands];
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
b[i] = getSampleFloat(x, y, i, data);
return b;
}
case DataBuffer.TYPE_DOUBLE:
{
- double[] b = (double[])obj;
- if (b == null) b = new double[numBands];
- for (int i=0; i < numBands; i++)
+ double[] b = (double[]) obj;
+ if (b == null)
+ b = new double[numBands];
+ for (int i = 0; i < numBands; i++)
b[i] = getSample(x, y, i, data);
return b;
}
@@ -195,10 +247,27 @@ public final class BandedSampleModel extends ComponentSampleModel
}
}
+ /**
+ * Returns all the samples for the pixel at location <code>(x, y)</code>
+ * stored in the specified data buffer.
+ *
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ * @param iArray an array that will be populated with the sample values and
+ * returned as the result. The size of this array should be equal to the
+ * number of bands in the model. If the array is <code>null</code>, a new
+ * array is created.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The samples for the specified pixel.
+ *
+ * @see #setPixel(int, int, int[], DataBuffer)
+ */
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
- if (iArray == null) iArray = new int[numBands];
- for (int i=0; i < numBands; i++)
+ if (iArray == null)
+ iArray = new int[numBands];
+ for (int i = 0; i < numBands; i++)
iArray[i] = getSample(x, y, i, data);
return iArray;
@@ -228,7 +297,11 @@ public final class BandedSampleModel extends ComponentSampleModel
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
- if (iArray == null) iArray = new int[w*h*numBands];
+ if (x < 0 || y < 0)
+ throw new ArrayIndexOutOfBoundsException(
+ "x and y must not be less than 0.");
+ if (iArray == null)
+ iArray = new int[w * h * numBands];
int outOffset = 0;
int maxX = x + w;
int maxY = y + h;
@@ -247,18 +320,64 @@ public final class BandedSampleModel extends ComponentSampleModel
return iArray;
}
+ /**
+ * Returns a sample value for the pixel at (x, y) in the specified data
+ * buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int getSample(int x, int y, int b, DataBuffer data)
{
int offset = bandOffsets[b] + y * scanlineStride + x;
return data.getElem(bankIndices[b], offset);
}
+ /**
+ * Returns a sample value for the pixel at (x, y) in the specified data
+ * buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ *
+ * @see #getSample(int, int, int, DataBuffer)
+ */
public float getSampleFloat(int x, int y, int b, DataBuffer data)
{
int offset = bandOffsets[b] + y * scanlineStride + x;
return data.getElemFloat(bankIndices[b], offset);
}
+ /**
+ * Returns the sample value for the pixel at (x, y) in the specified data
+ * buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ *
+ * @see #getSample(int, int, int, DataBuffer)
+ */
public double getSampleDouble(int x, int y, int b, DataBuffer data)
{
int offset = bandOffsets[b] + y * scanlineStride + x;
@@ -288,7 +407,11 @@ public final class BandedSampleModel extends ComponentSampleModel
public int[] getSamples(int x, int y, int w, int h, int b, int[] iArray,
DataBuffer data)
{
- if (iArray == null) iArray = new int[w*h];
+ if (x < 0 || y < 0)
+ throw new ArrayIndexOutOfBoundsException(
+ "x and y must not be less than 0.");
+ if (iArray == null)
+ iArray = new int[w * h];
int outOffset = 0;
int maxX = x + w;
int maxY = y + h;
@@ -304,7 +427,6 @@ public final class BandedSampleModel extends ComponentSampleModel
return iArray;
}
-
/**
* Set the pixel at x, y to the value in the first element of the primitive
* array obj.
@@ -338,7 +460,7 @@ public final class BandedSampleModel extends ComponentSampleModel
{
DataBufferByte out = (DataBufferByte) data;
byte[] in = (byte[]) obj;
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
return;
}
@@ -346,7 +468,7 @@ public final class BandedSampleModel extends ComponentSampleModel
{
DataBufferShort out = (DataBufferShort) data;
short[] in = (short[]) obj;
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
return;
}
@@ -354,7 +476,7 @@ public final class BandedSampleModel extends ComponentSampleModel
{
DataBufferUShort out = (DataBufferUShort) data;
short[] in = (short[]) obj;
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
return;
}
@@ -362,7 +484,7 @@ public final class BandedSampleModel extends ComponentSampleModel
{
DataBufferInt out = (DataBufferInt) data;
int[] in = (int[]) obj;
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
return;
}
@@ -370,7 +492,7 @@ public final class BandedSampleModel extends ComponentSampleModel
{
DataBufferFloat out = (DataBufferFloat) data;
float[] in = (float[]) obj;
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
return;
}
@@ -378,7 +500,7 @@ public final class BandedSampleModel extends ComponentSampleModel
{
DataBufferDouble out = (DataBufferDouble) data;
double[] in = (double[]) obj;
- for (int i=0; i < numBands; i++)
+ for (int i = 0; i < numBands; i++)
out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[i];
return;
}
@@ -388,26 +510,54 @@ public final class BandedSampleModel extends ComponentSampleModel
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
- String msg = "While writing data elements" +
- ", x="+x+", y="+y+
- ", width="+width+", height="+height+
- ", scanlineStride="+scanlineStride+
- ", offset="+offset+
- ", data.getSize()="+data.getSize()+
- ", data.getOffset()="+data.getOffset()+
- ": " +
- aioobe;
+ String msg = "While writing data elements"
+ + ", x=" + x + ", y=" + y
+ + ", width=" + width + ", height=" + height
+ + ", scanlineStride=" + scanlineStride
+ + ", offset=" + offset
+ + ", data.getSize()=" + data.getSize()
+ + ", data.getOffset()=" + data.getOffset()
+ + ": " + aioobe;
throw new ArrayIndexOutOfBoundsException(msg);
}
}
+ /**
+ * Sets the samples for the pixel at (x, y) in the specified data buffer to
+ * the specified values.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
- for (int b=0; b < numBands; b++)
+ for (int b = 0; b < numBands; b++)
data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x,
iArray[b]);
}
+ /**
+ * Sets the sample values for the pixels in the region specified by
+ * (x, y, w, h) in the specified data buffer. The array is
+ * ordered by pixels (that is, all the samples for the first pixel are
+ * grouped together, followed by all the samples for the second pixel, and so
+ * on).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param iArray the pixel sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
@@ -417,7 +567,7 @@ public final class BandedSampleModel extends ComponentSampleModel
for (int ww = 0; ww < w; ww++)
{
int offset = y * scanlineStride + (x + ww);
- for (int b=0; b < numBands; b++)
+ for (int b = 0; b < numBands; b++)
data.setElem(bankIndices[b], bandOffsets[b] + offset,
iArray[inOffset++]);
}
@@ -425,24 +575,83 @@ public final class BandedSampleModel extends ComponentSampleModel
}
}
+ /**
+ * Sets the sample value for band <code>b</code> of the pixel at location
+ * <code>(x, y)</code> in the specified data buffer.
+ *
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ * @param b the band index.
+ * @param s the sample value.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @see #getSample(int, int, int, DataBuffer)
+ */
public void setSample(int x, int y, int b, int s, DataBuffer data)
{
data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
}
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the
+ * specified data buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public void setSample(int x, int y, int b, float s, DataBuffer data)
{
- data.setElemFloat(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
+ data.setElemFloat(bankIndices[b], bandOffsets[b] + y * scanlineStride + x,
+ s);
}
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the
+ * specified data buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public void setSample(int x, int y, int b, double s, DataBuffer data)
{
- data.setElemDouble(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
+ data.setElemDouble(bankIndices[b], bandOffsets[b] + y * scanlineStride + x,
+ s);
}
+ /**
+ * Sets the sample values for one band for the pixels in the region
+ * specified by (x, y, w, h) in the specified data buffer.
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param iArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setSamples(int x, int y, int w, int h, int b, int[] iArray,
DataBuffer data)
{
+ if (x < 0 || y < 0)
+ throw new ArrayIndexOutOfBoundsException(
+ "x and y must not be less than 0.");
int inOffset = 0;
switch (getTransferType())
@@ -537,9 +746,10 @@ public final class BandedSampleModel extends ComponentSampleModel
result.append(getClass().getName());
result.append("[");
result.append("scanlineStride=").append(scanlineStride);
- for(int i=0; i < bitMasks.length; i+=1)
+ for(int i = 0; i < bitMasks.length; i+=1)
{
- result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+ result.append(", mask[").append(i).append("]=0x").append(
+ Integer.toHexString(bitMasks[i]));
}
result.append("]");
diff --git a/libjava/classpath/java/awt/image/BufferedImage.java b/libjava/classpath/java/awt/image/BufferedImage.java
index 77b8d6cc174..76848db0833 100644
--- a/libjava/classpath/java/awt/image/BufferedImage.java
+++ b/libjava/classpath/java/awt/image/BufferedImage.java
@@ -100,11 +100,33 @@ public class BufferedImage extends Image
Vector observers;
/**
- * Creates a new buffered image.
+ * Creates a new <code>BufferedImage</code> with the specified width, height
+ * and type. Valid <code>type</code> values are:
*
- * @param w the width.
- * @param h the height.
- * @param type the image type (see the constants defined by this class).
+ * <ul>
+ * <li>{@link #TYPE_INT_RGB}</li>
+ * <li>{@link #TYPE_INT_ARGB}</li>
+ * <li>{@link #TYPE_INT_ARGB_PRE}</li>
+ * <li>{@link #TYPE_INT_BGR}</li>
+ * <li>{@link #TYPE_3BYTE_BGR}</li>
+ * <li>{@link #TYPE_4BYTE_ABGR}</li>
+ * <li>{@link #TYPE_4BYTE_ABGR_PRE}</li>
+ * <li>{@link #TYPE_USHORT_565_RGB}</li>
+ * <li>{@link #TYPE_USHORT_555_RGB}</li>
+ * <li>{@link #TYPE_BYTE_GRAY}</li>
+ * <li>{@link #TYPE_USHORT_GRAY}</li>
+ * <li>{@link #TYPE_BYTE_BINARY}</li>
+ * <li>{@link #TYPE_BYTE_INDEXED}</li>
+ * </ul>
+ *
+ * @param w the width (must be > 0).
+ * @param h the height (must be > 0).
+ * @param type the image type (see the list of valid types above).
+ *
+ * @throws IllegalArgumentException if <code>w</code> or <code>h</code> is
+ * less than or equal to zero.
+ * @throws IllegalArgumentException if <code>type</code> is not one of the
+ * specified values.
*/
public BufferedImage(int w, int h, int type)
{
@@ -181,13 +203,15 @@ public class BufferedImage extends Image
case TYPE_4BYTE_ABGR_PRE:
bits = bits4;
break;
- case TYPE_BYTE_GRAY:
- bits = bits1byte;
- break;
- case TYPE_USHORT_GRAY:
- bits = bits1ushort;
- dataType = DataBuffer.TYPE_USHORT;
- break;
+ case TYPE_BYTE_GRAY:
+ bits = bits1byte;
+ cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ break;
+ case TYPE_USHORT_GRAY:
+ bits = bits1ushort;
+ cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ dataType = DataBuffer.TYPE_USHORT;
+ break;
}
cm = new ComponentColorModel(cs, bits, alpha, premultiplied,
alpha ?
@@ -203,6 +227,8 @@ public class BufferedImage extends Image
String msg2 = "type not implemented yet";
throw new UnsupportedOperationException(msg2);
// FIXME: build color-cube and create color model
+ default:
+ throw new IllegalArgumentException("Unknown image type " + type);
}
init(cm,
@@ -504,7 +530,10 @@ public class BufferedImage extends Image
int[] pixels = getRGB(x, y,
width, height,
(int[])null, offset, stride);
- ColorModel model = getColorModel();
+ // We already convert the color to RGB in the getRGB call, so
+ // we pass a simple RGB color model to the consumers.
+ ColorModel model = new DirectColorModel(32, 0xff0000, 0xff00, 0xff,
+ 0xff000000);
consumers.add(ic);
diff --git a/libjava/classpath/java/awt/image/BufferedImageOp.java b/libjava/classpath/java/awt/image/BufferedImageOp.java
index 2ecbec056a0..f6a24c976ab 100644
--- a/libjava/classpath/java/awt/image/BufferedImageOp.java
+++ b/libjava/classpath/java/awt/image/BufferedImageOp.java
@@ -1,5 +1,5 @@
/* BufferedImageOp.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,13 +43,65 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
- * NEEDS DOCUMENTATION
+ * An operation that is performed on one <code>BufferedImage</code> (the
+ * source) producing a new <code>BufferedImage</code> (the destination).
*/
public interface BufferedImageOp
{
+ /**
+ * Performs an operation on the source image, returning the result in a
+ * <code>BufferedImage</code>. If <code>dest</code> is <code>null</code>, a
+ * new <code>BufferedImage</code> will be created by calling the
+ * {@link #createCompatibleDestImage} method. If <code>dest</code>
+ * is not <code>null</code>, the result is written to <code>dest</code> then
+ * returned (this avoids creating a new <code>BufferedImage</code> each
+ * time this method is called).
+ *
+ * @param src the source image.
+ * @param dst the destination image (<code>null</code> permitted).
+ *
+ * @return The filterd image.
+ */
BufferedImage filter(BufferedImage src, BufferedImage dst);
+
+ /**
+ * Returns the bounds of the destination image on the basis of this
+ * <code>BufferedImageOp</code> being applied to the specified source image.
+ *
+ * @param src the source image.
+ *
+ * @return The destination bounds.
+ */
Rectangle2D getBounds2D(BufferedImage src);
+
+ /**
+ * Returns a new <code>BufferedImage</code> that can be used by this
+ * <code>BufferedImageOp</code> as the destination image when filtering
+ * the specified source image.
+ *
+ * @param src the source image.
+ * @param dstCM the color model for the destination image.
+ *
+ * @return A new image that can be used as the destination image.
+ */
BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM);
+
+ /**
+ * Returns the point on the destination image that corresponds to the given
+ * point on the source image.
+ *
+ * @param src the source point.
+ * @param dst the destination point (<code>null</code> permitted).
+ *
+ * @return The destination point.
+ */
Point2D getPoint2D(Point2D src, Point2D dst);
+
+ /**
+ * Returns the rendering hints for this operation.
+ *
+ * @return The rendering hints.
+ */
RenderingHints getRenderingHints();
-} // interface BufferedImageOp
+
+}
diff --git a/libjava/classpath/java/awt/image/ByteLookupTable.java b/libjava/classpath/java/awt/image/ByteLookupTable.java
index df02d0a1bf7..ecc0023aff6 100644
--- a/libjava/classpath/java/awt/image/ByteLookupTable.java
+++ b/libjava/classpath/java/awt/image/ByteLookupTable.java
@@ -1,5 +1,5 @@
/* ByteLookupTable.java -- Java class for a pixel translation table.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -60,14 +60,20 @@ public class ByteLookupTable extends LookupTable
* components.
*
* @param offset Offset to be subtracted.
- * @param data Array of lookup tables.
+ * @param data Array of lookup tables (<code>null</code> not permitted).
* @exception IllegalArgumentException if offset &lt; 0 or data.length &lt; 1.
*/
public ByteLookupTable(int offset, byte[][] data)
throws IllegalArgumentException
{
super(offset, data.length);
- this.data = data;
+
+ // tests show that Sun's implementation creates a new array to store the
+ // references from the incoming 'data' array - not sure why, but we'll
+ // match that behaviour just in case it matters...
+ this.data = new byte[data.length][];
+ for (int i = 0; i < data.length; i++)
+ this.data[i] = data[i];
}
/**
@@ -77,13 +83,16 @@ public class ByteLookupTable extends LookupTable
* table. The same table is applied to all pixel components.
*
* @param offset Offset to be subtracted.
- * @param data Lookup table for all components.
+ * @param data Lookup table for all components (<code>null</code> not
+ * permitted).
* @exception IllegalArgumentException if offset &lt; 0.
*/
public ByteLookupTable(int offset, byte[] data)
throws IllegalArgumentException
{
super(offset, 1);
+ if (data == null)
+ throw new NullPointerException("Null 'data' argument.");
this.data = new byte[][] {data};
}
diff --git a/libjava/classpath/java/awt/image/ColorConvertOp.java b/libjava/classpath/java/awt/image/ColorConvertOp.java
index 18609e0c4b0..1f85a5ecd99 100644
--- a/libjava/classpath/java/awt/image/ColorConvertOp.java
+++ b/libjava/classpath/java/awt/image/ColorConvertOp.java
@@ -1,5 +1,5 @@
-/* ColorModel.java --
- Copyright (C) 2004 Free Software Foundation
+/* ColorConvertOp.java --
+ Copyright (C) 2004, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -177,8 +177,7 @@ public class ColorConvertOp implements BufferedImageOp, RasterOp
ColorModel scm = src.getColorModel();
for (int i = 0; i < spaces.length; i++)
{
- ColorModel cm = scm.cloneColorModel(spaces[i]);
- BufferedImage tmp = createCompatibleDestImage(src, cm);
+ BufferedImage tmp = createCompatibleDestImage(src, scm);
copyimage(src, tmp);
src = tmp;
}
@@ -189,6 +188,7 @@ public class ColorConvertOp implements BufferedImageOp, RasterOp
// Apply final conversion
copyimage(src, dst);
+
return dst;
}
@@ -287,7 +287,12 @@ public class ColorConvertOp implements BufferedImageOp, RasterOp
private void copyimage(BufferedImage src, BufferedImage dst)
{
Graphics2D gg = dst.createGraphics();
- gg.setRenderingHints(hints);
+
+ // If no hints are set there is no need to call
+ // setRenderingHints on the Graphics2D object.
+ if (hints != null)
+ gg.setRenderingHints(hints);
+
gg.drawImage(src, 0, 0, null);
gg.dispose();
}
diff --git a/libjava/classpath/java/awt/image/ColorModel.java b/libjava/classpath/java/awt/image/ColorModel.java
index e2f5378b4da..9e559db37d8 100644
--- a/libjava/classpath/java/awt/image/ColorModel.java
+++ b/libjava/classpath/java/awt/image/ColorModel.java
@@ -1,5 +1,5 @@
/* ColorModel.java --
- Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
+ Copyright (C) 1999, 2000, 2002, 2003, 2004, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -43,7 +43,6 @@ import gnu.java.awt.Buffers;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
-import java.lang.reflect.Constructor;
import java.util.Arrays;
/**
@@ -163,32 +162,6 @@ public abstract class ColorModel implements Transparency
this.transparency = transparency;
this.transferType = transferType;
}
-
- // This is a hook for ColorConvertOp to create a colormodel with
- // a new colorspace
- ColorModel cloneColorModel(ColorSpace cspace)
- {
- Class cls = this.getClass();
- ColorModel cm;
- try {
- // This constructor will exist.
- Constructor ctor =
- cls.getConstructor(new Class[]{int.class, int[].class,
- ColorSpace.class, boolean.class,
- boolean.class, int.class, int.class});
- cm = (ColorModel)ctor.
- newInstance(new Object[]{new Integer(pixel_bits),
- bits, cspace, Boolean.valueOf(hasAlpha),
- Boolean.valueOf(isAlphaPremultiplied),
- new Integer(transparency),
- new Integer(transferType)});
- }
- catch (Exception e)
- {
- throw new IllegalArgumentException();
- }
- return cm;
- }
public void finalize()
{
diff --git a/libjava/classpath/java/awt/image/ComponentSampleModel.java b/libjava/classpath/java/awt/image/ComponentSampleModel.java
index b4e9450b060..bccabbbcadb 100644
--- a/libjava/classpath/java/awt/image/ComponentSampleModel.java
+++ b/libjava/classpath/java/awt/image/ComponentSampleModel.java
@@ -272,9 +272,7 @@ public class ComponentSampleModel extends SampleModel
// Maybe this value should be precalculated in the constructor?
int highestOffset = 0;
for (int b = 0; b < numBands; b++)
- {
- highestOffset = Math.max(highestOffset, bandOffsets[b]);
- }
+ highestOffset = Math.max(highestOffset, bandOffsets[b]);
int size = pixelStride * (width - 1) + scanlineStride * (height - 1)
+ highestOffset + 1;
@@ -678,6 +676,9 @@ public class ComponentSampleModel extends SampleModel
*/
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
+ if (x < 0 || x >= width || y < 0 || y >= height)
+ throw new ArrayIndexOutOfBoundsException("Pixel (" + x + ", " + y
+ + ") is out of bounds.");
int offset = pixelStride * x + scanlineStride * y;
if (iArray == null)
iArray = new int[numBands];
@@ -736,10 +737,16 @@ public class ComponentSampleModel extends SampleModel
*
* @return The sample value.
*
+ * @throws ArrayIndexOutOfBoundsException if <code>(x, y)</code> is outside
+ * the bounds <code>[0, 0, width, height]</code>.
+ *
* @see #setSample(int, int, int, int, DataBuffer)
*/
public int getSample(int x, int y, int b, DataBuffer data)
{
+ if (x < 0 || x >= width || y < 0 || y >= height)
+ throw new ArrayIndexOutOfBoundsException("Sample (" + x + ", " + y
+ + ") is out of bounds.");
return data.getElem(bankIndices[b], getOffset(x, y, b));
}
diff --git a/libjava/classpath/java/awt/image/ConvolveOp.java b/libjava/classpath/java/awt/image/ConvolveOp.java
index 1f73f75b233..ffb834874fa 100644
--- a/libjava/classpath/java/awt/image/ConvolveOp.java
+++ b/libjava/classpath/java/awt/image/ConvolveOp.java
@@ -1,5 +1,5 @@
/* ConvolveOp.java --
- Copyright (C) 2004, 2005 Free Software Foundation -- ConvolveOp
+ Copyright (C) 2004, 2005, 2006, Free Software Foundation -- ConvolveOp
This file is part of GNU Classpath.
@@ -42,7 +42,6 @@ import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
-import java.util.Arrays;
/**
* Convolution filter.
@@ -190,112 +189,101 @@ public class ConvolveOp implements BufferedImageOp, RasterOp
* @see java.awt.image.RasterOp#filter(java.awt.image.Raster,
* java.awt.image.WritableRaster)
*/
- public final WritableRaster filter(Raster src, WritableRaster dest) {
+ public final WritableRaster filter(Raster src, WritableRaster dest)
+ {
if (src == dest)
- throw new IllegalArgumentException();
- if (src.getWidth() < kernel.getWidth() ||
- src.getHeight() < kernel.getHeight())
- throw new ImagingOpException(null);
-
+ throw new IllegalArgumentException("src == dest is not allowed.");
+ if (kernel.getWidth() > src.getWidth()
+ || kernel.getHeight() > src.getHeight())
+ throw new ImagingOpException("The kernel is too large.");
if (dest == null)
dest = createCompatibleDestRaster(src);
- else if (src.numBands != dest.numBands)
- throw new ImagingOpException(null);
+ else if (src.getNumBands() != dest.getNumBands())
+ throw new ImagingOpException("src and dest have different band counts.");
- // Deal with bottom edge
- if (edge == EDGE_ZERO_FILL)
- {
- float[] zeros = new float[src.getNumBands() * src.getWidth()
- * (kernel.getYOrigin() - 1)];
- Arrays.fill(zeros, 0);
- dest.setPixels(src.getMinX(), src.getMinY(), src.getWidth(),
- kernel.getYOrigin() - 1, zeros);
- }
- else
- {
- float[] vals = new float[src.getNumBands() * src.getWidth()
- * (kernel.getYOrigin() - 1)];
- src.getPixels(src.getMinX(), src.getMinY(), src.getWidth(),
- kernel.getYOrigin() - 1, vals);
- dest.setPixels(src.getMinX(), src.getMinY(), src.getWidth(),
- kernel.getYOrigin() - 1, vals);
- }
+ // calculate the borders that the op can't reach...
+ int kWidth = kernel.getWidth();
+ int kHeight = kernel.getHeight();
+ int left = kernel.getXOrigin();
+ int right = Math.max(kWidth - left - 1, 0);
+ int top = kernel.getYOrigin();
+ int bottom = Math.max(kHeight - top - 1, 0);
- // Handle main section
+ // process the region that is reachable...
+ int regionW = src.width - left - right;
+ int regionH = src.height - top - bottom;
float[] kvals = kernel.getKernelData(null);
+ float[] tmp = new float[kWidth * kHeight];
- float[] tmp = new float[kernel.getWidth() * kernel.getHeight()];
- for (int y = src.getMinY() + kernel.getYOrigin();
- y < src.getMinY() + src.getHeight() - kernel.getYOrigin() / 2; y++)
- {
- // Handle unfiltered edge pixels at start of line
- float[] t1 = new float[(kernel.getXOrigin() - 1) * src.getNumBands()];
- if (edge == EDGE_ZERO_FILL)
- Arrays.fill(t1, 0);
- else
- src.getPixels(src.getMinX(), y, kernel.getXOrigin() - 1, 1, t1);
- dest.setPixels(src.getMinX(), y, kernel.getXOrigin() - 1, 1, t1);
-
- for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ for (int x = 0; x < regionW; x++)
{
- // FIXME: This needs a much more efficient implementation
- for (int b = 0; b < src.getNumBands(); b++)
- {
- float v = 0;
- src.getSamples(x, y, kernel.getWidth(), kernel.getHeight(), b, tmp);
- for (int i=0; i < tmp.length; i++)
- v += tmp[i] * kvals[i];
- dest.setSample(x, y, b, v);
- }
+ for (int y = 0; y < regionH; y++)
+ {
+ // FIXME: This needs a much more efficient implementation
+ for (int b = 0; b < src.getNumBands(); b++)
+ {
+ float v = 0;
+ src.getSamples(x, y, kWidth, kHeight, b, tmp);
+ for (int i = 0; i < tmp.length; i++)
+ v += tmp[tmp.length - i - 1] * kvals[i];
+ // FIXME: in the above line, I've had to reverse the order of
+ // the samples array to make the tests pass. I haven't worked
+ // out why this is necessary.
+ dest.setSample(x + kernel.getXOrigin(), y + kernel.getYOrigin(),
+ b, v);
+ }
+ }
}
-
- // Handle unfiltered edge pixels at end of line
- float[] t2 = new float[(kernel.getWidth() / 2) * src.getNumBands()];
- if (edge == EDGE_ZERO_FILL)
- Arrays.fill(t2, 0);
- else
- src.getPixels(src.getMinX() + src.getWidth()
- - (kernel.getWidth() / 2),
- y, kernel.getWidth() / 2, 1, t2);
- dest.setPixels(src.getMinX() + src.getWidth() - (kernel.getWidth() / 2),
- y, kernel.getWidth() / 2, 1, t2);
- }
- for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
- for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++)
+
+ // fill in the top border
+ fillEdge(src, dest, 0, 0, src.width, top, edge);
+
+ // fill in the bottom border
+ fillEdge(src, dest, 0, src.height - bottom, src.width, bottom, edge);
+
+ // fill in the left border
+ fillEdge(src, dest, 0, top, left, regionH, edge);
+
+ // fill in the right border
+ fillEdge(src, dest, src.width - right, top, right, regionH, edge);
+
+ return dest;
+ }
+
+ /**
+ * Fills a range of pixels (typically at the edge of a raster) with either
+ * zero values (if <code>edgeOp</code> is <code>EDGE_ZERO_FILL</code>) or the
+ * corresponding pixel values from the source raster (if <code>edgeOp</code>
+ * is <code>EDGE_NO_OP</code>). This utility method is called by the
+ * {@link #fillEdge(Raster, WritableRaster, int, int, int, int, int)} method.
+ *
+ * @param src the source raster.
+ * @param dest the destination raster.
+ * @param x the x-coordinate of the top left pixel in the range.
+ * @param y the y-coordinate of the top left pixel in the range.
+ * @param w the width of the pixel range.
+ * @param h the height of the pixel range.
+ * @param edgeOp indicates how to determine the values for the range
+ * (either {@link #EDGE_ZERO_FILL} or {@link #EDGE_NO_OP}).
+ */
+ private void fillEdge(Raster src, WritableRaster dest, int x, int y, int w,
+ int h, int edgeOp)
+ {
+ if (w <= 0)
+ return;
+ if (h <= 0)
+ return;
+ if (edgeOp == EDGE_ZERO_FILL) // fill region with zeroes
{
-
+ float[] zeros = new float[src.getNumBands() * w * h];
+ dest.setPixels(x, y, w, h, zeros);
}
- for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
- for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++)
+ else // copy pixels from source
{
-
+ float[] pixels = new float[src.getNumBands() * w * h];
+ src.getPixels(x, y, w, h, pixels);
+ dest.setPixels(x, y, w, h, pixels);
}
-
- // Handle top edge
- if (edge == EDGE_ZERO_FILL)
- {
- float[] zeros = new float[src.getNumBands() * src.getWidth() *
- (kernel.getHeight() / 2)];
- Arrays.fill(zeros, 0);
- dest.setPixels(src.getMinX(),
- src.getHeight() + src.getMinY() - (kernel.getHeight() / 2),
- src.getWidth(), kernel.getHeight() / 2, zeros);
- }
- else
- {
- float[] vals = new float[src.getNumBands() * src.getWidth() *
- (kernel.getHeight() / 2)];
- src.getPixels(src.getMinX(),
- src.getHeight() + src.getMinY()
- - (kernel.getHeight() / 2),
- src.getWidth(), kernel.getHeight() / 2, vals);
- dest.setPixels(src.getMinX(),
- src.getHeight() + src.getMinY()
- - (kernel.getHeight() / 2),
- src.getWidth(), kernel.getHeight() / 2, vals);
- }
-
- return dest;
}
/* (non-Javadoc)
diff --git a/libjava/classpath/java/awt/image/DataBuffer.java b/libjava/classpath/java/awt/image/DataBuffer.java
index 9e4f714180a..5a2cfd3b0e5 100644
--- a/libjava/classpath/java/awt/image/DataBuffer.java
+++ b/libjava/classpath/java/awt/image/DataBuffer.java
@@ -114,8 +114,7 @@ public abstract class DataBuffer
*/
protected DataBuffer(int dataType, int size)
{
- this.dataType = dataType;
- this.size = size;
+ this(dataType, size, 1);
}
/**
@@ -132,9 +131,7 @@ public abstract class DataBuffer
* @param numBanks the number of data banks.
*/
protected DataBuffer(int dataType, int size, int numBanks) {
- this(dataType, size);
- banks = numBanks;
- offsets = new int[numBanks];
+ this(dataType, size, numBanks, 0);
}
/**
@@ -153,11 +150,14 @@ public abstract class DataBuffer
* @param offset the offset to the first element for all banks.
*/
protected DataBuffer(int dataType, int size, int numBanks, int offset) {
- this(dataType, size, numBanks);
-
- java.util.Arrays.fill(offsets, offset);
-
+ banks = numBanks;
+ this.dataType = dataType;
+ this.size = size;
this.offset = offset;
+
+ offsets = new int[ numBanks ];
+ for(int i = 0; i < numBanks; i++ )
+ offsets[i] = offset;
}
/**
@@ -179,10 +179,11 @@ public abstract class DataBuffer
* <code>numBanks != offsets.length</code>.
*/
protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
- this(dataType, size);
if (numBanks != offsets.length)
throw new ArrayIndexOutOfBoundsException();
-
+
+ this.dataType = dataType;
+ this.size = size;
banks = numBanks;
this.offsets = offsets;
diff --git a/libjava/classpath/java/awt/image/Kernel.java b/libjava/classpath/java/awt/image/Kernel.java
index f7c29c3cde9..8361c0cf97d 100644
--- a/libjava/classpath/java/awt/image/Kernel.java
+++ b/libjava/classpath/java/awt/image/Kernel.java
@@ -1,5 +1,5 @@
/* Kernel.java -- Java class for an image processing kernel
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,21 +44,32 @@ package java.awt.image;
* values representing a 2-dimensional array in row-major order.
*
* @author Jerry Quinn (jlquinn@optonline.net)
- * @version 1.0
*/
public class Kernel implements Cloneable
{
+ /** The kernel width. */
private final int width;
+
+ /** The kernel height. */
private final int height;
+
+ /** Internal storage for the kernel's values. */
private final float[] data;
/**
- * Creates a new <code>Kernel</code> instance.
+ * Creates a new <code>Kernel</code> instance with the specified dimensions
+ * and values. The first <code>width * height</code> values in the specified
+ * <code>data</code> array are copied to internal storage.
*
- * @param width The 2D width of data.
- * @param height The 2D height of data.
- * @param data The source data array.
- * @exception IllegalArgumentException if width * height < data.length.
+ * @param width the kernel width.
+ * @param height the kernel height.
+ * @param data the source data array (<code>null</code> not permitted).
+ *
+ * @throws IllegalArgumentException if <code>data.length</code> is less than
+ * <code>width * height</code>.
+ * @throws IllegalArgumentException if <code>width</code> or
+ * <code>height</code> is less than zero.
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
*/
public Kernel(int width, int height, float[] data)
throws IllegalArgumentException
@@ -72,7 +83,10 @@ public class Kernel implements Cloneable
}
/**
- * Return the X origin: (width - 1) / 2
+ * Returns the x-origin for the kernel, which is calculated as
+ * <code>(width - 1) / 2</code>.
+ *
+ * @return The x-origin for the kernel.
*/
public final int getXOrigin()
{
@@ -80,7 +94,10 @@ public class Kernel implements Cloneable
}
/**
- * Return the Y origin: (height - 1) / 2
+ * Returns the y-origin for the kernel, which is calculated as
+ * <code>(height - 1) / 2</code>.
+ *
+ * @return The y-origin for the kernel.
*/
public final int getYOrigin()
{
@@ -88,6 +105,8 @@ public class Kernel implements Cloneable
}
/**
+ * Returns the kernel width (as supplied to the constructor).
+ *
* @return The kernel width.
*/
public final int getWidth()
@@ -96,6 +115,8 @@ public class Kernel implements Cloneable
}
/**
+ * Returns the kernel height (as supplied to the constructor).
+ *
* @return The kernel height.
*/
public final int getHeight()
@@ -104,20 +125,25 @@ public class Kernel implements Cloneable
}
/**
- * Return the kernel data.
+ * Returns an array containing a copy of the kernel data. If the
+ * <code>data</code> argument is non-<code>null</code>, the kernel values
+ * are copied into it and then <code>data</code> is returned as the result.
+ * If the <code>data</code> argument is <code>null</code>, this method
+ * allocates a new array then populates and returns it.
*
- * If data is null, allocates a new array and returns it. Otherwise, the
- * kernel values are copied into data.
- *
- * @param data Array to copy values into, or null.
+ * @param data an array to copy the return values into (if
+ * <code>null</code>, a new array is allocated).
+ *
* @return The array with copied values.
- * @exception IllegalArgumentException if data != null and too small.
+ *
+ * @throws IllegalArgumentException if <code>data.length</code> is less than
+ * the kernel's <code>width * height</code>.
*/
public final float[] getKernelData(float[] data)
throws IllegalArgumentException
{
if (data == null)
- return (float[])this.data.clone();
+ return (float[]) this.data.clone();
if (data.length < this.data.length)
throw new IllegalArgumentException();
@@ -127,13 +153,15 @@ public class Kernel implements Cloneable
}
/**
+ * Returns a clone of this kernel.
+ *
* @return a clone of this Kernel.
*/
public Object clone()
{
try
{
- return super.clone();
+ return super.clone();
}
catch (CloneNotSupportedException e)
{
diff --git a/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java b/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java
index 18a6e555205..8732e57659e 100644
--- a/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java
+++ b/libjava/classpath/java/awt/image/MultiPixelPackedSampleModel.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation
+/* Copyright (C) 2004, 2006, Free Software Foundation
This file is part of GNU Classpath.
@@ -56,12 +56,43 @@ public class MultiPixelPackedSampleModel extends SampleModel
private int numberOfBits;
private int numElems;
+ /**
+ * Creates a new <code>MultiPixelPackedSampleModel</code> with the specified
+ * data type, which should be one of:
+ * <ul>
+ * <li>{@link DataBuffer#TYPE_BYTE};</li>
+ * <li>{@link DataBuffer#TYPE_USHORT};</li>
+ * <li>{@link DataBuffer#TYPE_INT};</li>
+ * </ul>
+ *
+ * @param dataType the data type.
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ * @param numberOfBits the number of bits per pixel (must be a power of 2).
+ */
public MultiPixelPackedSampleModel(int dataType, int w, int h,
int numberOfBits)
{
this(dataType, w, h, numberOfBits, 0, 0);
}
+ /**
+ * Creates a new <code>MultiPixelPackedSampleModel</code> with the specified
+ * data type, which should be one of:
+ * <ul>
+ * <li>{@link DataBuffer#TYPE_BYTE};</li>
+ * <li>{@link DataBuffer#TYPE_USHORT};</li>
+ * <li>{@link DataBuffer#TYPE_INT};</li>
+ * </ul>
+ *
+ * @param dataType the data type.
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ * @param numberOfBits the number of bits per pixel (must be a power of 2).
+ * @param scanlineStride the number of data elements from a pixel on one
+ * row to the corresponding pixel in the next row.
+ * @param dataBitOffset the offset to the first data bit.
+ */
public MultiPixelPackedSampleModel(int dataType, int w, int h,
int numberOfBits, int scanlineStride,
int dataBitOffset)
@@ -101,7 +132,7 @@ public class MultiPixelPackedSampleModel extends SampleModel
// Compute scan line large enough for w pixels.
if (scanlineStride == 0)
- scanlineStride = ((dataBitOffset + w * numberOfBits) / elemBits);
+ scanlineStride = ((dataBitOffset + w * numberOfBits) - 1) / elemBits + 1;
this.scanlineStride = scanlineStride;
@@ -118,6 +149,16 @@ public class MultiPixelPackedSampleModel extends SampleModel
}
}
+ /**
+ * Creates a new <code>MultiPixelPackedSample</code> model with the same
+ * data type and bits per pixel as this model, but with the specified
+ * dimensions.
+ *
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ *
+ * @return The new sample model.
+ */
public SampleModel createCompatibleSampleModel(int w, int h)
{
/* FIXME: We can avoid recalculation of bit offsets and sample
@@ -126,78 +167,163 @@ public class MultiPixelPackedSampleModel extends SampleModel
return new MultiPixelPackedSampleModel(dataType, w, h, numberOfBits);
}
-
/**
* Creates a DataBuffer for holding pixel data in the format and
* layout described by this SampleModel. The returned buffer will
* consist of one single bank.
+ *
+ * @return A new data buffer.
*/
public DataBuffer createDataBuffer()
{
- int size;
-
- // FIXME: The comment refers to SinglePixelPackedSampleModel. See if the
- // same can be done for MultiPixelPackedSampleModel.
- // We can save (scanlineStride - width) pixels at the very end of
- // the buffer. The Sun reference implementation (J2SE 1.3.1 and
- // 1.4.1_01) seems to do this; tested with Mauve test code.
- size = scanlineStride * height;
-
+ int size = scanlineStride * height;
+ if (dataBitOffset > 0)
+ size += (dataBitOffset - 1) / elemBits + 1;
return Buffers.createBuffer(getDataType(), size);
}
-
+ /**
+ * Returns the number of data elements required to transfer a pixel in the
+ * get/setDataElements() methods.
+ *
+ * @return <code>1</code>.
+ */
public int getNumDataElements()
{
return 1;
}
+ /**
+ * Returns an array containing the size (in bits) of the samples in each
+ * band. The <code>MultiPixelPackedSampleModel</code> class supports only
+ * one band, so this method returns an array with length <code>1</code>.
+ *
+ * @return An array containing the size (in bits) of the samples in band zero.
+ *
+ * @see #getSampleSize(int)
+ */
public int[] getSampleSize()
{
- return sampleSize;
+ return (int[]) sampleSize.clone();
}
+ /**
+ * Returns the size of the samples in the specified band. Note that the
+ * <code>MultiPixelPackedSampleModel</code> supports only one band -- this
+ * method ignored the <code>band</code> argument, and always returns the size
+ * of band zero.
+ *
+ * @param band the band (this parameter is ignored).
+ *
+ * @return The size of the samples in band zero.
+ *
+ * @see #getSampleSize()
+ */
public int getSampleSize(int band)
{
return sampleSize[0];
}
+ /**
+ * Returns the index in the data buffer that stores the pixel at (x, y).
+ *
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ *
+ * @return The index in the data buffer that stores the pixel at (x, y).
+ *
+ * @see #getBitOffset(int)
+ */
public int getOffset(int x, int y)
{
- return scanlineStride * y + ((dataBitOffset + x*numberOfBits) / elemBits);
+ return scanlineStride * y + ((dataBitOffset + x * numberOfBits) / elemBits);
}
+ /**
+ * The bit offset (within an element in the data buffer) of the pixels with
+ * the specified x-coordinate.
+ *
+ * @param x the x-coordinate.
+ *
+ * @return The bit offset.
+ */
public int getBitOffset(int x)
{
- return (dataBitOffset + x*numberOfBits) % elemBits;
+ return (dataBitOffset + x * numberOfBits) % elemBits;
}
+ /**
+ * Returns the offset to the first data bit.
+ *
+ * @return The offset to the first data bit.
+ */
public int getDataBitOffset()
{
return dataBitOffset;
}
+ /**
+ * Returns the number of data elements from a pixel in one row to the
+ * corresponding pixel in the next row.
+ *
+ * @return The scanline stride.
+ */
public int getScanlineStride()
{
return scanlineStride;
}
+ /**
+ * Returns the number of bits per pixel.
+ *
+ * @return The number of bits per pixel.
+ */
public int getPixelBitStride()
{
return numberOfBits;
}
+
+ /**
+ * Returns the transfer type, which is one of the following (depending on
+ * the number of bits per sample for this model):
+ * <ul>
+ * <li>{@link DataBuffer#TYPE_BYTE};</li>
+ * <li>{@link DataBuffer#TYPE_USHORT};</li>
+ * <li>{@link DataBuffer#TYPE_INT};</li>
+ * </ul>
+ *
+ * @return The transfer type.
+ */
+ public int getTransferType()
+ {
+ if (numberOfBits <= DataBuffer.getDataTypeSize(DataBuffer.TYPE_BYTE))
+ return DataBuffer.TYPE_BYTE;
+ else if (numberOfBits <= DataBuffer.getDataTypeSize(DataBuffer.TYPE_USHORT))
+ return DataBuffer.TYPE_USHORT;
+ return DataBuffer.TYPE_INT;
+ }
-
+ /**
+ * Normally this method returns a sample model for accessing a subset of
+ * bands of image data, but since <code>MultiPixelPackedSampleModel</code>
+ * only supports a single band, this overridden implementation just returns
+ * a new instance of <code>MultiPixelPackedSampleModel</code>, with the same
+ * attributes as this instance.
+ *
+ * @param bands the bands to include in the subset (this is ignored, except
+ * that if it is non-<code>null</code> a check is made to ensure that the
+ * array length is equal to <code>1</code>).
+ *
+ * @throws RasterFormatException if <code>bands</code> is not
+ * <code>null</code> and <code>bands.length != 1</code>.
+ */
public SampleModel createSubsetSampleModel(int[] bands)
{
- int numBands = bands.length;
- if (numBands != 1)
+ if (bands != null && bands.length != 1)
throw new RasterFormatException("MultiPixelPackedSampleModel only"
- + " supports one band");
-
- return new MultiPixelPackedSampleModel(dataType, width, height,
- numberOfBits, scanlineStride,
- dataBitOffset);
+ + " supports one band");
+ return new MultiPixelPackedSampleModel(dataType, width, height,
+ numberOfBits, scanlineStride, dataBitOffset);
}
/**
@@ -207,68 +333,82 @@ public class MultiPixelPackedSampleModel extends SampleModel
* array obj, since there is only one band. If obj is null, a new array of
* getTransferType() is created.
*
- * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
- * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
- * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param x The x-coordinate of the pixel rectangle to store in
+ * <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in
+ * <code>obj</code>.
+ * @param obj The primitive array to store the pixels into or null to force
+ * creation.
* @param data The DataBuffer that is the source of the pixel data.
* @return The primitive array containing the pixel data.
- * @see java.awt.image.SampleModel#getDataElements(int, int, java.lang.Object, java.awt.image.DataBuffer)
+ * @see java.awt.image.SampleModel#getDataElements(int, int, Object,
+ * DataBuffer)
*/
- public Object getDataElements(int x, int y, Object obj,
- DataBuffer data)
+ public Object getDataElements(int x, int y, Object obj, DataBuffer data)
{
int pixel = getSample(x, y, 0, data);
switch (getTransferType())
- {
- case DataBuffer.TYPE_BYTE:
- if (obj == null) obj = new byte[1];
- ((byte[])obj)[0] = (byte)pixel;
- return obj;
- case DataBuffer.TYPE_USHORT:
- if (obj == null) obj = new short[1];
- ((short[])obj)[0] = (short)pixel;
- return obj;
- case DataBuffer.TYPE_INT:
- if (obj == null) obj = new int[1];
- ((int[])obj)[0] = pixel;
- return obj;
- default:
- // Seems like the only sensible thing to do.
- throw new ClassCastException();
- }
+ {
+ case DataBuffer.TYPE_BYTE:
+ if (obj == null)
+ obj = new byte[1];
+ ((byte[]) obj)[0] = (byte) pixel;
+ return obj;
+ case DataBuffer.TYPE_USHORT:
+ if (obj == null)
+ obj = new short[1];
+ ((short[]) obj)[0] = (short) pixel;
+ return obj;
+ case DataBuffer.TYPE_INT:
+ if (obj == null)
+ obj = new int[1];
+ ((int[]) obj)[0] = pixel;
+ return obj;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
}
+ /**
+ * Returns an array (of length 1) containing the sample for the pixel at
+ * (x, y) in the specified data buffer. If <code>iArray</code> is not
+ * <code>null</code>, it will be populated with the sample value and
+ * returned as the result of this function (this avoids allocating a new
+ * array instance).
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return An array containing the pixel sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
- if (iArray == null) iArray = new int[1];
+ if (iArray == null)
+ iArray = new int[1];
iArray[0] = getSample(x, y, 0, data);
-
return iArray;
}
- public int[] getPixels(int x, int y, int w, int h, int[] iArray,
- DataBuffer data)
- {
- int offset = getOffset(x, y);
- if (iArray == null) iArray = new int[w*h];
- int outOffset = 0;
- for (y=0; y<h; y++)
- {
- int lineOffset = offset;
- for (x=0; x<w;)
- {
- int samples = data.getElem(lineOffset++);
- for (int b=0; b<numElems && x<w; b++)
- {
- iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
- x++;
- }
- }
- offset += scanlineStride;
- }
- return iArray;
- }
-
+ /**
+ * Returns the sample value for the pixel at (x, y) in the specified data
+ * buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int getSample(int x, int y, int b, DataBuffer data)
{
int pos =
@@ -286,72 +426,82 @@ public class MultiPixelPackedSampleModel extends SampleModel
* @param y The y-coordinate of the data elements in <code>obj</code>.
* @param obj The primitive array containing the data elements to set.
* @param data The DataBuffer to store the data elements into.
- * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
*/
public void setDataElements(int x, int y, Object obj, DataBuffer data)
{
int transferType = getTransferType();
- if (getTransferType() != data.getDataType())
- {
- throw new IllegalArgumentException("transfer type ("+
- getTransferType()+"), "+
- "does not match data "+
- "buffer type (" +
- data.getDataType() +
- ").");
- }
-
- int offset = getOffset(x, y);
-
try
{
- switch (transferType)
- {
- case DataBuffer.TYPE_BYTE:
- {
- DataBufferByte out = (DataBufferByte) data;
- byte[] in = (byte[]) obj;
- out.getData()[offset] = in[0];
- return;
- }
- case DataBuffer.TYPE_USHORT:
- {
- DataBufferUShort out = (DataBufferUShort) data;
- short[] in = (short[]) obj;
- out.getData()[offset] = in[0];
- return;
- }
- case DataBuffer.TYPE_INT:
- {
- DataBufferInt out = (DataBufferInt) data;
- int[] in = (int[]) obj;
- out.getData()[offset] = in[0];
- return;
- }
- default:
- throw new ClassCastException("Unsupported data type");
- }
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ byte[] in = (byte[]) obj;
+ setSample(x, y, 0, in[0] & 0xFF, data);
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ short[] in = (short[]) obj;
+ setSample(x, y, 0, in[0] & 0xFFFF, data);
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ int[] in = (int[]) obj;
+ setSample(x, y, 0, in[0], data);
+ return;
+ }
+ default:
+ throw new ClassCastException("Unsupported data type");
+ }
}
catch (ArrayIndexOutOfBoundsException aioobe)
{
- String msg = "While writing data elements" +
- ", x="+x+", y="+y+
- ", width="+width+", height="+height+
- ", scanlineStride="+scanlineStride+
- ", offset="+offset+
- ", data.getSize()="+data.getSize()+
- ", data.getOffset()="+data.getOffset()+
- ": " +
- aioobe;
- throw new ArrayIndexOutOfBoundsException(msg);
+ String msg = "While writing data elements" +
+ ", x=" + x + ", y=" + y +
+ ", width=" + width + ", height=" + height +
+ ", scanlineStride=" + scanlineStride +
+ ", offset=" + getOffset(x, y) +
+ ", data.getSize()=" + data.getSize() +
+ ", data.getOffset()=" + data.getOffset() +
+ ": " + aioobe;
+ throw new ArrayIndexOutOfBoundsException(msg);
}
- }
+ }
+ /**
+ * Sets the sample value for the pixel at (x, y) in the specified data
+ * buffer to the specified value.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray the sample value (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ *
+ * @see #setSample(int, int, int, int, DataBuffer)
+ */
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
setSample(x, y, 0, iArray[0], data);
}
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the
+ * specified data buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public void setSample(int x, int y, int b, int s, DataBuffer data)
{
int bitpos =
@@ -367,6 +517,70 @@ public class MultiPixelPackedSampleModel extends SampleModel
}
/**
+ * Tests this sample model for equality with an arbitrary object. This
+ * method returns <code>true</code> if and only if:
+ * <ul>
+ * <li><code>obj</code> is not <code>null</code>;
+ * <li><code>obj</code> is an instance of
+ * <code>MultiPixelPackedSampleModel</code>;
+ * <li>both models have the same:
+ * <ul>
+ * <li><code>dataType</code>;
+ * <li><code>width</code>;
+ * <li><code>height</code>;
+ * <li><code>numberOfBits</code>;
+ * <li><code>scanlineStride</code>;
+ * <li><code>dataBitOffsets</code>.
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * @param obj the object (<code>null</code> permitted)
+ *
+ * @return <code>true</code> if this model is equal to <code>obj</code>, and
+ * <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (! (obj instanceof MultiPixelPackedSampleModel))
+ return false;
+ MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel) obj;
+ if (this.dataType != that.dataType)
+ return false;
+ if (this.width != that.width)
+ return false;
+ if (this.height != that.height)
+ return false;
+ if (this.numberOfBits != that.numberOfBits)
+ return false;
+ if (this.scanlineStride != that.scanlineStride)
+ return false;
+ if (this.dataBitOffset != that.dataBitOffset)
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns a hash code for this <code>MultiPixelPackedSampleModel</code>.
+ *
+ * @return A hash code.
+ */
+ public int hashCode()
+ {
+ // this hash code won't match Sun's, but that shouldn't matter...
+ int result = 193;
+ result = 37 * result + dataType;
+ result = 37 * result + width;
+ result = 37 * result + height;
+ result = 37 * result + numberOfBits;
+ result = 37 * result + scanlineStride;
+ result = 37 * result + dataBitOffset;
+ return result;
+ }
+
+ /**
* Creates a String with some information about this SampleModel.
* @return A String describing this SampleModel.
* @see java.lang.Object#toString()
diff --git a/libjava/classpath/java/awt/image/Raster.java b/libjava/classpath/java/awt/image/Raster.java
index 4af958a17c7..160f8be8b51 100644
--- a/libjava/classpath/java/awt/image/Raster.java
+++ b/libjava/classpath/java/awt/image/Raster.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2003, 2006, Free Software Foundation
This file is part of GNU Classpath.
@@ -41,39 +41,80 @@ import java.awt.Point;
import java.awt.Rectangle;
/**
+ * A rectangular collection of pixels composed from a {@link DataBuffer} which
+ * stores the pixel values, and a {@link SampleModel} which is used to retrieve
+ * the pixel values.
+ *
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
*/
public class Raster
{
+ /** The sample model used to access the pixel values. */
protected SampleModel sampleModel;
+
+ /** The data buffer used to store the pixel values. */
protected DataBuffer dataBuffer;
+
+ /** The x-coordinate of the top left corner of the raster. */
protected int minX;
+
+ /** The y-coordinate of the top left corner of the raster. */
protected int minY;
+
+ /** The width of the raster. */
protected int width;
+
+ /** The height of the raster. */
protected int height;
+
protected int sampleModelTranslateX;
+
protected int sampleModelTranslateY;
+
+ /** The number of bands. */
protected int numBands;
+
protected int numDataElements;
+
+ /** The raster's parent. */
protected Raster parent;
+ /**
+ * Creates a new raster.
+ *
+ * @param sampleModel the sample model.
+ * @param origin the origin.
+ */
protected Raster(SampleModel sampleModel, Point origin)
{
this(sampleModel, sampleModel.createDataBuffer(), origin);
}
+ /**
+ * Creates a new raster.
+ *
+ * @param sampleModel the sample model.
+ * @param dataBuffer the data buffer.
+ * @param origin the origin.
+ */
protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
- Point origin)
+ Point origin)
{
- this(sampleModel, dataBuffer,
- new Rectangle(origin.x, origin.y,
- sampleModel.getWidth(), sampleModel.getHeight()),
- origin, null);
+ this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y,
+ sampleModel.getWidth(), sampleModel.getHeight()), origin, null);
}
+ /**
+ * Creates a new raster.
+ *
+ * @param sampleModel the sample model.
+ * @param dataBuffer the data buffer.
+ * @param aRegion the raster's bounds.
+ * @param sampleModelTranslate the translation (<code>null</code> permitted).
+ * @param parent the raster's parent.
+ */
protected Raster(SampleModel sampleModel, DataBuffer dataBuffer,
- Rectangle aRegion,
- Point sampleModelTranslate, Raster parent)
+ Rectangle aRegion, Point sampleModelTranslate, Raster parent)
{
this.sampleModel = sampleModel;
this.dataBuffer = dataBuffer;
@@ -95,70 +136,127 @@ public class Raster
this.parent = parent;
}
+ /**
+ * Creates an interleaved raster using the specified data type.
+ *
+ * @param dataType the data type.
+ * @param w the width.
+ * @param h the height.
+ * @param bands the number of bands.
+ * @param location
+ *
+ * @return The new raster.
+ */
public static WritableRaster createInterleavedRaster(int dataType,
- int w, int h,
- int bands,
- Point location)
+ int w, int h, int bands, Point location)
{
int[] bandOffsets = new int[bands];
// TODO: Maybe not generate this every time.
- for (int b=0; b<bands; b++) bandOffsets[b] = b;
+ for (int b = 0; b < bands; b++)
+ bandOffsets[b] = b;
- int scanlineStride = bands*w;
+ int scanlineStride = bands * w;
return createInterleavedRaster(dataType, w, h, scanlineStride, bands,
- bandOffsets, location);
+ bandOffsets, location);
}
- public static WritableRaster createInterleavedRaster(int dataType,
- int w, int h,
- int scanlineStride,
- int pixelStride,
- int[] bandOffsets,
- Point location)
- {
- SampleModel sm = new ComponentSampleModel(dataType,
- w, h,
- pixelStride,
- scanlineStride,
- bandOffsets);
+ /**
+ * Creates an interleaved raster.
+ *
+ * @param dataType the data type.
+ * @param w the width.
+ * @param h the height.
+ * @param scanlineStride the number of data elements from a sample on one
+ * row to the corresponding sample on the next row.
+ * @param pixelStride the number of elements from a sample in one pixel to
+ * the corresponding sample in the next pixel.
+ * @param bandOffsets the band offsets.
+ * @param location
+ *
+ * @return The new raster.
+ */
+ public static WritableRaster createInterleavedRaster(int dataType,
+ int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets,
+ Point location)
+ {
+ SampleModel sm = new ComponentSampleModel(dataType, w, h, pixelStride,
+ scanlineStride, bandOffsets);
return createWritableRaster(sm, location);
}
- public static WritableRaster createBandedRaster(int dataType,
- int w, int h, int bands,
- Point location)
+ /**
+ * Creates a new banded raster.
+ *
+ * @param dataType the data type.
+ * @param w the width.
+ * @param h the height.
+ * @param bands the number of bands.
+ * @param location
+ *
+ * @return The new raster.
+ */
+ public static WritableRaster createBandedRaster(int dataType, int w, int h,
+ int bands, Point location)
{
SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
return createWritableRaster(sm, location);
}
- public static WritableRaster createBandedRaster(int dataType,
- int w, int h,
- int scanlineStride,
- int[] bankIndices,
- int[] bandOffsets,
- Point location)
+ /**
+ * Creates a new banded raster.
+ *
+ * @param dataType the data type.
+ * @param w the width.
+ * @param h the height.
+ * @param scanlineStride the number of data elements from a sample on one
+ * row to the corresponding sample on the next row.
+ * @param bankIndices the index for each bank.
+ * @param bandOffsets the offset for each band.
+ * @param location
+ *
+ * @return The new raster.
+ */
+ public static WritableRaster createBandedRaster(int dataType, int w, int h,
+ int scanlineStride, int[] bankIndices, int[] bandOffsets, Point location)
{
SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
- bankIndices, bandOffsets);
+ bankIndices, bandOffsets);
return createWritableRaster(sm, location);
}
- public static WritableRaster createPackedRaster(int dataType,
- int w, int h,
- int[] bandMasks,
- Point location)
+ /**
+ * Creates a new packed raster.
+ *
+ * @param dataType the data type.
+ * @param w the width.
+ * @param h the height.
+ * @param bandMasks the bit mask for each band.
+ * @param location
+ *
+ * @return The new raster.
+ */
+ public static WritableRaster createPackedRaster(int dataType, int w, int h,
+ int[] bandMasks, Point location)
{
- SampleModel sm = new SinglePixelPackedSampleModel(dataType,
- w, h,
- bandMasks);
+ SampleModel sm = new SinglePixelPackedSampleModel(dataType, w, h,
+ bandMasks);
return createWritableRaster(sm, location);
}
+ /**
+ * Creates a new raster.
+ *
+ * @param dataType the data type.
+ * @param w the width.
+ * @param h the height.
+ * @param bands the number of bands.
+ * @param bitsPerBand the number of bits per band.
+ * @param location
+ *
+ * @return The new raster.
+ */
public static WritableRaster createPackedRaster(int dataType,
- int w, int h,
- int bands, int bitsPerBand,
- Point location)
+ int w, int h, int bands, int bitsPerBand, Point location)
{
if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
throw new IllegalArgumentException();
@@ -166,135 +264,238 @@ public class Raster
SampleModel sm;
if (bands == 1)
- sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
+ sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
else
{
- int[] bandMasks = new int[bands];
- int mask = 0x1;
- for (int bits = bitsPerBand; --bits != 0;)
- mask = (mask << 1) | 0x1;
- for (int i = 0; i < bands; i++)
- {
- bandMasks[i] = mask;
- mask <<= bitsPerBand;
- }
-
- sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
+ int[] bandMasks = new int[bands];
+ int mask = 0x1;
+ for (int bits = bitsPerBand; --bits != 0;)
+ mask = (mask << 1) | 0x1;
+ for (int i = 0; i < bands; i++)
+ {
+ bandMasks[i] = mask;
+ mask <<= bitsPerBand;
+ }
+
+ sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
}
return createWritableRaster(sm, location);
}
- public static WritableRaster
- createInterleavedRaster(DataBuffer dataBuffer, int w, int h,
- int scanlineStride, int pixelStride,
- int[] bandOffsets, Point location)
+ /**
+ * Creates a new interleaved raster.
+ *
+ * @param dataBuffer the data buffer.
+ * @param w the width.
+ * @param h the height.
+ * @param scanlineStride the number of data elements from a sample on one
+ * row to the corresponding sample on the next row.
+ * @param pixelStride the number of elements from a sample in one pixel to
+ * the corresponding sample in the next pixel.
+ * @param bandOffsets the offset for each band.
+ * @param location
+ *
+ * @return The new raster.
+ */
+ public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
+ int w, int h, int scanlineStride, int pixelStride, int[] bandOffsets,
+ Point location)
{
SampleModel sm = new ComponentSampleModel(dataBuffer.getDataType(),
- w, h,
- scanlineStride,
- pixelStride,
- bandOffsets);
+ w, h, scanlineStride, pixelStride, bandOffsets);
return createWritableRaster(sm, dataBuffer, location);
}
- public static
- WritableRaster createBandedRaster(DataBuffer dataBuffer,
- int w, int h,
- int scanlineStride,
- int[] bankIndices,
- int[] bandOffsets,
- Point location)
+ /**
+ * Creates a new banded raster.
+ *
+ * @param dataBuffer the data buffer.
+ * @param w the width.
+ * @param h the height.
+ * @param scanlineStride the number of data elements from a sample on one
+ * row to the corresponding sample on the next row.
+ * @param bankIndices the index for each bank.
+ * @param bandOffsets the band offsets.
+ * @param location
+ *
+ * @return The new raster.
+ */
+ public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
+ int w, int h, int scanlineStride, int[] bankIndices, int[] bandOffsets,
+ Point location)
{
SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
- w, h, scanlineStride,
- bankIndices, bandOffsets);
+ w, h, scanlineStride, bankIndices, bandOffsets);
return createWritableRaster(sm, dataBuffer, location);
}
- public static WritableRaster
- createPackedRaster(DataBuffer dataBuffer,
- int w, int h,
- int scanlineStride,
- int[] bandMasks,
- Point location)
+ /**
+ * Creates a new packed raster.
+ *
+ * @param dataBuffer the data buffer.
+ * @param w the width.
+ * @param h the height.
+ * @param scanlineStride the number of data elements from a sample on one
+ * row to the corresponding sample on the next row.
+ * @param bandMasks the bit mask for each band.
+ * @param location
+ *
+ * @return The new raster.
+ */
+ public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+ int w, int h, int scanlineStride, int[] bandMasks, Point location)
{
- SampleModel sm =
- new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
- w, h,
- scanlineStride,
- bandMasks);
+ SampleModel sm = new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
+ w, h, scanlineStride, bandMasks);
return createWritableRaster(sm, dataBuffer, location);
}
- public static WritableRaster
- createPackedRaster(DataBuffer dataBuffer,
- int w, int h,
- int bitsPerPixel,
- Point location)
- {
- SampleModel sm =
- new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
- w, h,
- bitsPerPixel);
+ /**
+ * Creates a new packed raster.
+ *
+ * @param dataBuffer the data buffer.
+ * @param w the width.
+ * @param h the height.
+ * @param bitsPerPixel the number of bits per pixel.
+ * @param location
+ *
+ * @return The new raster.
+ */
+ public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
+ int w, int h, int bitsPerPixel, Point location)
+ {
+ SampleModel sm = new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
+ w, h, bitsPerPixel);
return createWritableRaster(sm, dataBuffer, location);
}
+ /**
+ * Creates a new raster.
+ *
+ * @param sm the sample model.
+ * @param db the data buffer.
+ * @param location
+ *
+ * @return The new raster.
+ */
public static Raster createRaster(SampleModel sm, DataBuffer db,
- Point location)
+ Point location)
{
return new Raster(sm, db, location);
}
+ /**
+ * Creates a new writable raster.
+ *
+ * @param sm the sample model.
+ * @param location
+ *
+ * @return The new writable raster.
+ */
public static WritableRaster createWritableRaster(SampleModel sm,
- Point location)
+ Point location)
{
return new WritableRaster(sm, location);
}
+ /**
+ * Creates a new writable raster.
+ *
+ * @param sm the sample model.
+ * @param db the data buffer.
+ * @param location
+ *
+ * @return The new writable raster.
+ */
public static WritableRaster createWritableRaster(SampleModel sm,
- DataBuffer db,
- Point location)
+ DataBuffer db, Point location)
{
return new WritableRaster(sm, db, location);
}
+ /**
+ * Returns the raster's parent.
+ *
+ * @return The raster's parent.
+ */
public Raster getParent()
{
return parent;
}
+ /**
+ * Returns the x-translation.
+ *
+ * @return The x-translation.
+ */
public final int getSampleModelTranslateX()
{
return sampleModelTranslateX;
}
+ /**
+ * Returns the y-translation.
+ *
+ * @return The y-translation.
+ */
public final int getSampleModelTranslateY()
{
return sampleModelTranslateY;
}
+ /**
+ * Creates a new writable raster that is compatible with this raster.
+ *
+ * @return A new writable raster.
+ */
public WritableRaster createCompatibleWritableRaster()
{
return new WritableRaster(getSampleModel(), new Point(minX, minY));
}
+ /**
+ * Creates a new writable raster that is compatible with this raster.
+ *
+ * @param w the width.
+ * @param h the height.
+ *
+ * @return A new writable raster.
+ */
public WritableRaster createCompatibleWritableRaster(int w, int h)
{
return createCompatibleWritableRaster(minX, minY, w, h);
}
+ /**
+ * Creates a new writable raster that is compatible with this raster, with
+ * the specified bounds.
+ *
+ * @param rect the raster bounds.
+ *
+ * @return A new writable raster.
+ */
public WritableRaster createCompatibleWritableRaster(Rectangle rect)
{
return createCompatibleWritableRaster(rect.x, rect.y,
- rect.width, rect.height);
+ rect.width, rect.height);
}
+ /**
+ * Creates a new writable raster that is compatible with this raster, with
+ * the specified bounds.
+ *
+ * @param x the x-coordinate of the top-left corner of the raster.
+ * @param y the y-coordinate of the top-left corner of the raster.
+ * @param w the raster width.
+ * @param h the raster height.
+ *
+ * @return A new writable raster.
+ */
public WritableRaster createCompatibleWritableRaster(int x, int y,
- int w, int h)
+ int w, int h)
{
SampleModel sm = getSampleModel().createCompatibleSampleModel(w, h);
- return new WritableRaster(sm, sm.createDataBuffer(),
- new Point(x, y));
+ return new WritableRaster(sm, sm.createDataBuffer(), new Point(x, y));
}
public Raster createTranslatedChild(int childMinX, int childMinY) {
@@ -302,15 +503,13 @@ public class Raster
int tcy = sampleModelTranslateY - minY + childMinY;
return new Raster(sampleModel, dataBuffer,
- new Rectangle(childMinX, childMinY,
- width, height),
- new Point(tcx, tcy),
- this);
+ new Rectangle(childMinX, childMinY, width, height),
+ new Point(tcx, tcy), this);
}
public Raster createChild(int parentX, int parentY, int width,
- int height, int childMinX, int childMinY,
- int[] bandList)
+ int height, int childMinX, int childMinY,
+ int[] bandList)
{
/* FIXME: Throw RasterFormatException if child bounds extends
beyond the bounds of this raster. */
@@ -343,38 +542,67 @@ public class Raster
*/
return new Raster(sm, dataBuffer,
- new Rectangle(childMinX, childMinY,
- width, height),
- new Point(sampleModelTranslateX+childMinX-parentX,
- sampleModelTranslateY+childMinY-parentY),
- this);
+ new Rectangle(childMinX, childMinY, width, height),
+ new Point(sampleModelTranslateX + childMinX - parentX,
+ sampleModelTranslateY + childMinY - parentY),
+ this);
}
+ /**
+ * Returns a new rectangle containing the bounds of this raster.
+ *
+ * @return A new rectangle containing the bounds of this raster.
+ */
public Rectangle getBounds()
{
return new Rectangle(minX, minY, width, height);
}
+ /**
+ * Returns the x-coordinate of the top left corner of the raster.
+ *
+ * @return The x-coordinate of the top left corner of the raster.
+ */
public final int getMinX()
{
return minX;
}
+ /**
+ * Returns the t-coordinate of the top left corner of the raster.
+ *
+ * @return The t-coordinate of the top left corner of the raster.
+ */
public final int getMinY()
{
return minY;
}
+ /**
+ * Returns the width of the raster.
+ *
+ * @return The width of the raster.
+ */
public final int getWidth()
{
return width;
}
+ /**
+ * Returns the height of the raster.
+ *
+ * @return The height of the raster.
+ */
public final int getHeight()
{
return height;
}
+ /**
+ * Returns the number of bands for this raster.
+ *
+ * @return The number of bands.
+ */
public final int getNumBands()
{
return numBands;
@@ -384,17 +612,34 @@ public class Raster
{
return numDataElements;
}
-
+
+ /**
+ * Returns the transfer type for the raster (this is determined by the
+ * raster's sample model).
+ *
+ * @return The transfer type.
+ */
public final int getTransferType()
{
return sampleModel.getTransferType();
}
+ /**
+ * Returns the data buffer that stores the pixel data for this raster.
+ *
+ * @return The data buffer.
+ */
public DataBuffer getDataBuffer()
{
return dataBuffer;
}
+ /**
+ * Returns the sample model that accesses the data buffer (to extract pixel
+ * data) for this raster.
+ *
+ * @return The sample model.
+ */
public SampleModel getSampleModel()
{
return sampleModel;
@@ -402,112 +647,275 @@ public class Raster
public Object getDataElements(int x, int y, Object outData)
{
- return sampleModel.getDataElements(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- outData, dataBuffer);
+ return sampleModel.getDataElements(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, outData, dataBuffer);
}
- public Object getDataElements(int x, int y, int w, int h,
- Object outData)
+ public Object getDataElements(int x, int y, int w, int h, Object outData)
{
- return sampleModel.getDataElements(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, outData, dataBuffer);
+ return sampleModel.getDataElements(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, w, h, outData, dataBuffer);
}
+ /**
+ * Returns an array containing the samples for the pixel at (x, y) in the
+ * raster. If <code>iArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of
+ * this function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The pixel sample values.
+ */
public int[] getPixel(int x, int y, int[] iArray)
{
- return sampleModel.getPixel(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- iArray, dataBuffer);
+ return sampleModel.getPixel(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, iArray, dataBuffer);
}
+ /**
+ * Returns an array containing the samples for the pixel at (x, y) in the
+ * raster. If <code>fArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of
+ * this function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param fArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The pixel sample values.
+ */
public float[] getPixel(int x, int y, float[] fArray)
{
- return sampleModel.getPixel(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- fArray, dataBuffer);
+ return sampleModel.getPixel(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, fArray, dataBuffer);
}
+ /**
+ * Returns an array containing the samples for the pixel at (x, y) in the
+ * raster. If <code>dArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of
+ * this function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param dArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The pixel sample values.
+ */
public double[] getPixel(int x, int y, double[] dArray)
{
- return sampleModel.getPixel(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- dArray, dataBuffer);
+ return sampleModel.getPixel(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, dArray, dataBuffer);
}
+ /**
+ * Returns an array containing the samples for the pixels in the region
+ * specified by (x, y, w, h) in the raster. The array is ordered by pixels
+ * (that is, all the samples for the first pixel are grouped together,
+ * followed by all the samples for the second pixel, and so on).
+ * If <code>iArray</code> is not <code>null</code>, it will be populated
+ * with the sample values and returned as the result of this function (this
+ * avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The pixel sample values.
+ */
public int[] getPixels(int x, int y, int w, int h, int[] iArray)
{
- return sampleModel.getPixels(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, iArray, dataBuffer);
+ return sampleModel.getPixels(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, w, h, iArray, dataBuffer);
}
- public float[] getPixels(int x, int y, int w, int h,
- float[] fArray)
+ /**
+ * Returns an array containing the samples for the pixels in the region
+ * specified by (x, y, w, h) in the raster. The array is ordered by pixels
+ * (that is, all the samples for the first pixel are grouped together,
+ * followed by all the samples for the second pixel, and so on).
+ * If <code>fArray</code> is not <code>null</code>, it will be populated
+ * with the sample values and returned as the result of this function (this
+ * avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param fArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The pixel sample values.
+ */
+ public float[] getPixels(int x, int y, int w, int h, float[] fArray)
{
- return sampleModel.getPixels(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, fArray, dataBuffer);
+ return sampleModel.getPixels(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, w, h, fArray, dataBuffer);
}
- public double[] getPixels(int x, int y, int w, int h,
- double[] dArray)
+ /**
+ * Returns an array containing the samples for the pixels in the region
+ * specified by (x, y, w, h) in the raster. The array is ordered by pixels
+ * (that is, all the samples for the first pixel are grouped together,
+ * followed by all the samples for the second pixel, and so on).
+ * If <code>dArray</code> is not <code>null</code>, it will be populated
+ * with the sample values and returned as the result of this function (this
+ * avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param dArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The pixel sample values.
+ */
+ public double[] getPixels(int x, int y, int w, int h, double[] dArray)
{
- return sampleModel.getPixels(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, dArray, dataBuffer);
+ return sampleModel.getPixels(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, w, h, dArray, dataBuffer);
}
+ /**
+ * Returns the sample value for the pixel at (x, y) in the raster.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ *
+ * @return The sample value.
+ */
public int getSample(int x, int y, int b)
{
- return sampleModel.getSample(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- b, dataBuffer);
+ return sampleModel.getSample(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, b, dataBuffer);
}
+ /**
+ * Returns the sample value for the pixel at (x, y) in the raster.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ *
+ * @return The sample value.
+ *
+ * @see #getSample(int, int, int)
+ */
public float getSampleFloat(int x, int y, int b)
{
- return sampleModel.getSampleFloat(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- b, dataBuffer);
+ return sampleModel.getSampleFloat(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, b, dataBuffer);
}
+ /**
+ * Returns the sample value for the pixel at (x, y) in the raster.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ *
+ * @return The sample value.
+ *
+ * @see #getSample(int, int, int)
+ */
public double getSampleDouble(int x, int y, int b)
{
- return sampleModel.getSampleDouble(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- b, dataBuffer);
+ return sampleModel.getSampleDouble(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, b, dataBuffer);
}
+ /**
+ * Returns an array containing the samples from one band for the pixels in
+ * the region specified by (x, y, w, h) in the raster. If
+ * <code>iArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The sample values.
+ */
public int[] getSamples(int x, int y, int w, int h, int b,
- int[] iArray)
+ int[] iArray)
{
- return sampleModel.getSamples(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, b, iArray, dataBuffer);
+ return sampleModel.getSamples(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, w, h, b, iArray, dataBuffer);
}
- public float[] getSamples(int x, int y, int w, int h, int b,
- float[] fArray)
- {
- return sampleModel.getSamples(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, b, fArray, dataBuffer);
+ /**
+ * Returns an array containing the samples from one band for the pixels in
+ * the region specified by (x, y, w, h) in the raster. If
+ * <code>fArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param fArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The sample values.
+ */
+ public float[] getSamples(int x, int y, int w, int h, int b, float[] fArray)
+ {
+ return sampleModel.getSamples(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, w, h, b, fArray, dataBuffer);
}
- public double[] getSamples(int x, int y, int w, int h, int b,
- double[] dArray)
+ /**
+ * Returns an array containing the samples from one band for the pixels in
+ * the region specified by (x, y, w, h) in the raster. If
+ * <code>dArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param dArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ *
+ * @return The sample values.
+ */
+ public double[] getSamples(int x, int y, int w, int h, int b,
+ double[] dArray)
{
- return sampleModel.getSamples(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, b, dArray, dataBuffer);
+ return sampleModel.getSamples(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, w, h, b, dArray, dataBuffer);
}
/**
- * Create a String representing the stat of this Raster.
+ * Create a String representing the state of this Raster.
+ *
* @return A String representing the stat of this Raster.
- * @see java.lang.Object#toString()
*/
public String toString()
{
@@ -524,23 +932,39 @@ public class Raster
return result.toString();
}
- // Map from datatype to bits
+ /**
+ * Returns the number of bits used to represent the specified data type.
+ * Valid types are:
+ * <ul>
+ * <li>{@link DataBuffer#TYPE_BYTE};</li>
+ * <li>{@link DataBuffer#TYPE_USHORT};</li>
+ * <li>{@link DataBuffer#TYPE_SHORT};</li>
+ * <li>{@link DataBuffer#TYPE_INT};</li>
+ * <li>{@link DataBuffer#TYPE_FLOAT};</li>
+ * <li>{@link DataBuffer#TYPE_DOUBLE};</li>
+ * </ul>
+ * This method returns 0 for invalid data types.
+ *
+ * @param dataType the data type.
+ *
+ * @return The number of bits used to represent the specified data type.
+ */
private static int getTypeBits(int dataType)
{
switch (dataType)
{
case DataBuffer.TYPE_BYTE:
- return 8;
+ return 8;
case DataBuffer.TYPE_USHORT:
case DataBuffer.TYPE_SHORT:
- return 16;
+ return 16;
case DataBuffer.TYPE_INT:
case DataBuffer.TYPE_FLOAT:
- return 32;
+ return 32;
case DataBuffer.TYPE_DOUBLE:
- return 64;
+ return 64;
default:
- return 0;
+ return 0;
}
}
}
diff --git a/libjava/classpath/java/awt/image/RasterOp.java b/libjava/classpath/java/awt/image/RasterOp.java
index e081ca3d2ad..656370e8bcc 100644
--- a/libjava/classpath/java/awt/image/RasterOp.java
+++ b/libjava/classpath/java/awt/image/RasterOp.java
@@ -1,5 +1,5 @@
/* RasterOp.java --
- Copyright (C) 2000, 2002, 2004, 2005 Free Software Foundation
+ Copyright (C) 2000, 2002, 2004, 2005, 2006, Free Software Foundation
This file is part of GNU Classpath.
@@ -42,16 +42,64 @@ import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
+/**
+ * An operation that is performed on one raster (the source) producing a new
+ * raster (the destination).
+ */
public interface RasterOp
{
+ /**
+ * Performs an operation on the source raster, returning the result in a
+ * writable raster. If <code>dest</code> is <code>null</code>, a new
+ * <code>WritableRaster</code> will be created by calling the
+ * {@link #createCompatibleDestRaster(Raster)} method. If <code>dest</code>
+ * is not <code>null</code>, the result is written to <code>dest</code> then
+ * returned (this avoids creating a new <code>WritableRaster</code> each
+ * time this method is called).
+ *
+ * @param src the source raster.
+ * @param dest the destination raster (<code>null</code> permitted).
+ *
+ * @return The filtered raster.
+ */
WritableRaster filter(Raster src, WritableRaster dest);
+ /**
+ * Returns the bounds of the destination raster on the basis of this
+ * <code>RasterOp</code> being applied to the specified source raster.
+ *
+ * @param src the source raster.
+ *
+ * @return The destination bounds.
+ */
Rectangle2D getBounds2D(Raster src);
+ /**
+ * Returns a raster that can be used by this <code>RasterOp</code> as the
+ * destination raster when operating on the specified source raster.
+ *
+ * @param src the source raster.
+ *
+ * @return A new writable raster that can be used as the destination raster.
+ */
WritableRaster createCompatibleDestRaster(Raster src);
+ /**
+ * Returns the point on the destination raster that corresponds to the given
+ * point on the source raster.
+ *
+ * @param srcPoint the source point.
+ * @param destPoint the destination point (<code>null</code> permitted).
+ *
+ * @return The destination point.
+ */
Point2D getPoint2D(Point2D srcPoint, Point2D destPoint);
+ /**
+ * Returns the rendering hints for this operation.
+ *
+ * @return The rendering hints.
+ */
RenderingHints getRenderingHints();
}
diff --git a/libjava/classpath/java/awt/image/SampleModel.java b/libjava/classpath/java/awt/image/SampleModel.java
index 6e3fd4069a3..cb352bb4d85 100644
--- a/libjava/classpath/java/awt/image/SampleModel.java
+++ b/libjava/classpath/java/awt/image/SampleModel.java
@@ -37,6 +37,9 @@ exception statement from your version. */
package java.awt.image;
/**
+ * A <code>SampleModel</code> is used to access pixel data from a
+ * {@link DataBuffer}. This is used by the {@link Raster} class.
+ *
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
*/
public abstract class SampleModel
@@ -100,16 +103,37 @@ public abstract class SampleModel
this.numBands = numBands;
}
+ /**
+ * Returns the width of the pixel data accessible via this
+ * <code>SampleModel</code>.
+ *
+ * @return The width.
+ *
+ * @see #getHeight()
+ */
public final int getWidth()
{
return width;
}
+ /**
+ * Returns the height of the pixel data accessible via this
+ * <code>SampleModel</code>.
+ *
+ * @return The height.
+ *
+ * @see #getWidth()
+ */
public final int getHeight()
{
return height;
}
+ /**
+ * Returns the number of bands for this <code>SampleModel</code>.
+ *
+ * @return The number of bands.
+ */
public final int getNumBands()
{
return numBands;
@@ -117,6 +141,12 @@ public abstract class SampleModel
public abstract int getNumDataElements();
+ /**
+ * Returns the type of the {@link DataBuffer} that this
+ * <code>SampleModel</code> accesses.
+ *
+ * @return The data buffer type.
+ */
public final int getDataType()
{
return dataType;
@@ -128,6 +158,22 @@ public abstract class SampleModel
return dataType;
}
+ /**
+ * Returns an array containing the samples for the pixel at (x, y) in the
+ * specified data buffer. If <code>iArray</code> is not <code>null</code>,
+ * it will be populated with the sample values and returned as the result of
+ * this function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The pixel sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
if (iArray == null)
@@ -234,6 +280,22 @@ public abstract class SampleModel
}
}
+ /**
+ * Returns an array containing the samples for the pixel at (x, y) in the
+ * specified data buffer. If <code>fArray</code> is not <code>null</code>,
+ * it will be populated with the sample values and returned as the result of
+ * this function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param fArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The pixel sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public float[] getPixel(int x, int y, float[] fArray, DataBuffer data)
{
if (fArray == null)
@@ -246,6 +308,22 @@ public abstract class SampleModel
return fArray;
}
+ /**
+ * Returns an array containing the samples for the pixel at (x, y) in the
+ * specified data buffer. If <code>dArray</code> is not <code>null</code>,
+ * it will be populated with the sample values and returned as the result of
+ * this function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param dArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The pixel sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public double[] getPixel(int x, int y, double[] dArray, DataBuffer data) {
if (dArray == null)
dArray = new double[numBands];
@@ -256,8 +334,27 @@ public abstract class SampleModel
return dArray;
}
- /* FIXME: Should it return a banded or pixel interleaved array of
- samples? (Assume interleaved.) */
+ /**
+ * Returns an array containing the samples for the pixels in the region
+ * specified by (x, y, w, h) in the specified data buffer. The array is
+ * ordered by pixels (that is, all the samples for the first pixel are
+ * grouped together, followed by all the samples for the second pixel, and so
+ * on). If <code>iArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The pixel sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
@@ -278,8 +375,27 @@ public abstract class SampleModel
return iArray;
}
- /* FIXME: Should it return a banded or pixel interleaved array of
- samples? (Assume interleaved.) */
+ /**
+ * Returns an array containing the samples for the pixels in the region
+ * specified by (x, y, w, h) in the specified data buffer. The array is
+ * ordered by pixels (that is, all the samples for the first pixel are
+ * grouped together, followed by all the samples for the second pixel, and so
+ * on). If <code>fArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param fArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The pixel sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public float[] getPixels(int x, int y, int w, int h, float[] fArray,
DataBuffer data)
{
@@ -299,8 +415,27 @@ public abstract class SampleModel
return fArray;
}
- /* FIXME: Should it return a banded or pixel interleaved array of
- samples? (Assume interleaved.) */
+ /**
+ * Returns an array containing the samples for the pixels in the region
+ * specified by (x, y, w, h) in the specified data buffer. The array is
+ * ordered by pixels (that is, all the samples for the first pixel are
+ * grouped together, followed by all the samples for the second pixel, and so
+ * on). If <code>dArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param dArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The pixel sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public double[] getPixels(int x, int y, int w, int h, double[] dArray,
DataBuffer data)
{
@@ -321,18 +456,85 @@ public abstract class SampleModel
return dArray;
}
+ /**
+ * Returns the sample value for the pixel at (x, y) in the specified data
+ * buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public abstract int getSample(int x, int y, int b, DataBuffer data);
+ /**
+ * Returns the sample value for the pixel at (x, y) in the specified data
+ * buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ *
+ * @see #getSample(int, int, int, DataBuffer)
+ */
public float getSampleFloat(int x, int y, int b, DataBuffer data)
{
return getSample(x, y, b, data);
}
+ /**
+ * Returns the sample value for the pixel at (x, y) in the specified data
+ * buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ *
+ * @see #getSample(int, int, int, DataBuffer)
+ */
public double getSampleDouble(int x, int y, int b, DataBuffer data)
{
return getSampleFloat(x, y, b, data);
}
+ /**
+ * Returns an array containing the samples from one band for the pixels in
+ * the region specified by (x, y, w, h) in the specified data buffer. If
+ * <code>iArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int[] getSamples(int x, int y, int w, int h, int b,
int[] iArray, DataBuffer data)
{
@@ -350,6 +552,27 @@ public abstract class SampleModel
return iArray;
}
+ /**
+ * Returns an array containing the samples from one band for the pixels in
+ * the region specified by (x, y, w, h) in the specified data buffer. If
+ * <code>fArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param fArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public float[] getSamples(int x, int y, int w, int h, int b,
float[] fArray, DataBuffer data)
{
@@ -367,6 +590,27 @@ public abstract class SampleModel
return fArray;
}
+ /**
+ * Returns an array containing the samples from one band for the pixels in
+ * the region specified by (x, y, w, h) in the specified data buffer. If
+ * <code>dArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param dArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public double[] getSamples(int x, int y, int w, int h, int b,
double[] dArray, DataBuffer data)
{
@@ -384,24 +628,77 @@ public abstract class SampleModel
return dArray;
}
+ /**
+ * Sets the samples for the pixel at (x, y) in the specified data buffer to
+ * the specified values.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
for (int b = 0; b < numBands; b++)
setSample(x, y, b, iArray[b], data);
}
+ /**
+ * Sets the samples for the pixel at (x, y) in the specified data buffer to
+ * the specified values.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param fArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>fArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixel(int x, int y, float[] fArray, DataBuffer data)
{
for (int b = 0; b < numBands; b++)
setSample(x, y, b, fArray[b], data);
}
+ /**
+ * Sets the samples for the pixel at (x, y) in the specified data buffer to
+ * the specified values.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param dArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>dArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixel(int x, int y, double[] dArray, DataBuffer data)
{
for (int b = 0; b < numBands; b++)
setSample(x, y, b, dArray[b], data);
}
+ /**
+ * Sets the sample values for the pixels in the region specified by
+ * (x, y, w, h) in the specified data buffer. The array is
+ * ordered by pixels (that is, all the samples for the first pixel are
+ * grouped together, followed by all the samples for the second pixel, and so
+ * on).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param iArray the pixel sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
@@ -418,6 +715,23 @@ public abstract class SampleModel
}
}
+ /**
+ * Sets the sample values for the pixels in the region specified by
+ * (x, y, w, h) in the specified data buffer. The array is
+ * ordered by pixels (that is, all the samples for the first pixel are
+ * grouped together, followed by all the samples for the second pixel, and so
+ * on).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param fArray the pixel sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>fArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixels(int x, int y, int w, int h, float[] fArray,
DataBuffer data)
{
@@ -434,6 +748,23 @@ public abstract class SampleModel
}
}
+ /**
+ * Sets the sample values for the pixels in the region specified by
+ * (x, y, w, h) in the specified data buffer. The array is
+ * ordered by pixels (that is, all the samples for the first pixel are
+ * grouped together, followed by all the samples for the second pixel, and so
+ * on).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param dArray the pixel sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>dArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixels(int x, int y, int w, int h, double[] dArray,
DataBuffer data)
{
@@ -450,21 +781,76 @@ public abstract class SampleModel
}
}
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the
+ * specified data buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public abstract void setSample(int x, int y, int b, int s,
DataBuffer data);
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the
+ * specified data buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public void setSample(int x, int y, int b, float s,
DataBuffer data)
{
setSample(x, y, b, (int) s, data);
}
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the
+ * specified data buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public void setSample(int x, int y, int b, double s,
DataBuffer data)
{
setSample(x, y, b, (float) s, data);
}
+ /**
+ * Sets the sample values for one band for the pixels in the region
+ * specified by (x, y, w, h) in the specified data buffer.
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param iArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setSamples(int x, int y, int w, int h, int b,
int[] iArray, DataBuffer data)
{
@@ -475,6 +861,22 @@ public abstract class SampleModel
setSample(xx, yy, b, iArray[inOffset++], data);
}
+ /**
+ * Sets the sample values for one band for the pixels in the region
+ * specified by (x, y, w, h) in the specified data buffer.
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param fArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setSamples(int x, int y, int w, int h, int b,
float[] fArray, DataBuffer data)
{
@@ -486,6 +888,22 @@ public abstract class SampleModel
}
+ /**
+ * Sets the sample values for one band for the pixels in the region
+ * specified by (x, y, w, h) in the specified data buffer.
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param dArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setSamples(int x, int y, int w, int h, int b,
double[] dArray, DataBuffer data) {
int size = w * h;
@@ -495,6 +913,15 @@ public abstract class SampleModel
setSample(xx, yy, b, dArray[inOffset++], data);
}
+ /**
+ * Creates a new <code>SampleModel</code> that is compatible with this
+ * model and has the specified width and height.
+ *
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ *
+ * @return The new sample model.
+ */
public abstract SampleModel createCompatibleSampleModel(int w, int h);
/**
@@ -510,9 +937,31 @@ public abstract class SampleModel
*/
public abstract SampleModel createSubsetSampleModel(int[] bands);
+ /**
+ * Creates a new {@link DataBuffer} of the correct type and size for this
+ * <code>SampleModel</code>.
+ *
+ * @return The data buffer.
+ */
public abstract DataBuffer createDataBuffer();
+ /**
+ * Returns an array containing the size (in bits) for each band accessed by
+ * the <code>SampleModel</code>.
+ *
+ * @return An array.
+ *
+ * @see #getSampleSize(int)
+ */
public abstract int[] getSampleSize();
+ /**
+ * Returns the size (in bits) of the samples for the specified band.
+ *
+ * @param band the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ *
+ * @return The sample size (in bits).
+ */
public abstract int getSampleSize(int band);
}
diff --git a/libjava/classpath/java/awt/image/ShortLookupTable.java b/libjava/classpath/java/awt/image/ShortLookupTable.java
index 5915a7939a3..858818cf26d 100644
--- a/libjava/classpath/java/awt/image/ShortLookupTable.java
+++ b/libjava/classpath/java/awt/image/ShortLookupTable.java
@@ -1,5 +1,5 @@
/* ShortLookupTable.java -- Java class for a pixel translation table.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -67,7 +67,13 @@ public class ShortLookupTable extends LookupTable
throws IllegalArgumentException
{
super(offset, data.length);
- this.data = data;
+
+ // tests show that Sun's implementation creates a new array to store the
+ // references from the incoming 'data' array - not sure why, but we'll
+ // match that behaviour just in case it matters...
+ this.data = new short[data.length][];
+ for (int i = 0; i < data.length; i++)
+ this.data[i] = data[i];
}
/**
@@ -77,17 +83,25 @@ public class ShortLookupTable extends LookupTable
* table. The same table is applied to all pixel components.
*
* @param offset Offset to be subtracted.
- * @param data Lookup table for all components.
+ * @param data Lookup table for all components (<code>null</code> not
+ * permitted).
* @exception IllegalArgumentException if offset &lt; 0.
*/
public ShortLookupTable(int offset, short[] data)
throws IllegalArgumentException
{
super(offset, 1);
+ if (data == null)
+ throw new NullPointerException("Null 'data' argument.");
this.data = new short[][] {data};
}
- /** Return the lookup tables. */
+ /**
+ * Return the lookup tables. This is a reference to the actual table, so
+ * modifying the contents of the returned array will modify the lookup table.
+ *
+ * @return The lookup table.
+ */
public final short[][] getTable()
{
return data;
@@ -117,11 +131,11 @@ public class ShortLookupTable extends LookupTable
dst = new int[src.length];
if (data.length == 1)
- for (int i=0; i < src.length; i++)
- dst[i] = data[0][src[i] - offset];
+ for (int i = 0; i < src.length; i++)
+ dst[i] = data[0][src[i] - offset];
else
- for (int i=0; i < src.length; i++)
- dst[i] = data[i][src[i] - offset];
+ for (int i = 0; i < src.length; i++)
+ dst[i] = data[i][src[i] - offset];
return dst;
}
@@ -142,6 +156,7 @@ public class ShortLookupTable extends LookupTable
* @param src Component values of a pixel.
* @param dst Destination array for values, or null.
* @return Translated values for the pixel.
+ *
*/
public short[] lookupPixel(short[] src, short[] dst)
throws ArrayIndexOutOfBoundsException
@@ -150,11 +165,11 @@ public class ShortLookupTable extends LookupTable
dst = new short[src.length];
if (data.length == 1)
- for (int i=0; i < src.length; i++)
- dst[i] = data[0][((int)src[i]) - offset];
+ for (int i = 0; i < src.length; i++)
+ dst[i] = data[0][((int) src[i]) - offset];
else
- for (int i=0; i < src.length; i++)
- dst[i] = data[i][((int)src[i]) - offset];
+ for (int i = 0; i < src.length; i++)
+ dst[i] = data[i][((int) src[i]) - offset];
return dst;
diff --git a/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java b/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java
index 6ccce753bd3..a37fc0bba3f 100644
--- a/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java
+++ b/libjava/classpath/java/awt/image/SinglePixelPackedSampleModel.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2003, 2004, 2006, Free Software Foundation
This file is part of GNU Classpath.
@@ -36,10 +36,16 @@ exception statement from your version. */
package java.awt.image;
+import java.util.Arrays;
+
import gnu.java.awt.BitMaskExtent;
import gnu.java.awt.Buffers;
/**
+ * A <code>SampleModel</code> used when all samples are stored in a single
+ * data element in the {@link DataBuffer}, and each data element contains
+ * samples for one pixel only.
+ *
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
*/
public class SinglePixelPackedSampleModel extends SampleModel
@@ -49,12 +55,32 @@ public class SinglePixelPackedSampleModel extends SampleModel
private int[] bitOffsets;
private int[] sampleSize;
+ /**
+ * Creates a new <code>SinglePixelPackedSampleModel</code>.
+ *
+ * @param dataType the data buffer type.
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ * @param bitMasks an array containing the bit mask used to extract the
+ * sample value for each band.
+ */
public SinglePixelPackedSampleModel(int dataType, int w, int h,
int[] bitMasks)
{
this(dataType, w, h, w, bitMasks);
}
+ /**
+ * Creates a new <code>SinglePixelPackedSampleModel</code>.
+ *
+ * @param dataType the data buffer type.
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ * @param scanlineStride the number of data elements between a pixel on one
+ * row and the corresponding pixel on the next row.
+ * @param bitMasks an array containing the bit mask used to extract the
+ * sample value for each band.
+ */
public SinglePixelPackedSampleModel(int dataType, int w, int h,
int scanlineStride, int[] bitMasks)
{
@@ -67,7 +93,8 @@ public class SinglePixelPackedSampleModel extends SampleModel
case DataBuffer.TYPE_INT:
break;
default:
- throw new IllegalArgumentException("SinglePixelPackedSampleModel unsupported dataType");
+ throw new IllegalArgumentException(
+ "SinglePixelPackedSampleModel unsupported dataType");
}
this.scanlineStride = scanlineStride;
@@ -77,19 +104,35 @@ public class SinglePixelPackedSampleModel extends SampleModel
sampleSize = new int[numBands];
BitMaskExtent extent = new BitMaskExtent();
- for (int b=0; b<numBands; b++)
+ for (int b = 0; b < numBands; b++)
{
- extent.setMask(bitMasks[b]);
- sampleSize[b] = extent.bitWidth;
- bitOffsets[b] = extent.leastSignificantBit;
+ // the mask is an unsigned integer
+ long mask = bitMasks[b] & 0xFFFFFFFFL;
+ extent.setMask(mask);
+ sampleSize[b] = extent.bitWidth;
+ bitOffsets[b] = extent.leastSignificantBit;
}
}
+ /**
+ * Returns the number of data elements.
+ *
+ * @return <code>1</code>.
+ */
public int getNumDataElements()
{
return 1;
}
+ /**
+ * Creates a new <code>SampleModel</code> that is compatible with this
+ * model and has the specified width and height.
+ *
+ * @param w the width (in pixels).
+ * @param h the height (in pixels).
+ *
+ * @return The new sample model.
+ */
public SampleModel createCompatibleSampleModel(int w, int h)
{
/* FIXME: We can avoid recalculation of bit offsets and sample
@@ -103,6 +146,8 @@ public class SinglePixelPackedSampleModel extends SampleModel
* Creates a DataBuffer for holding pixel data in the format and
* layout described by this SampleModel. The returned buffer will
* consist of one single bank.
+ *
+ * @return The data buffer.
*/
public DataBuffer createDataBuffer()
{
@@ -116,17 +161,40 @@ public class SinglePixelPackedSampleModel extends SampleModel
return Buffers.createBuffer(getDataType(), size);
}
-
+ /**
+ * Returns an array containing the size (in bits) for each band accessed by
+ * the <code>SampleModel</code>.
+ *
+ * @return An array.
+ *
+ * @see #getSampleSize(int)
+ */
public int[] getSampleSize()
{
- return sampleSize;
+ return (int[]) sampleSize.clone();
}
+ /**
+ * Returns the size (in bits) of the samples for the specified band.
+ *
+ * @param band the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ *
+ * @return The sample size (in bits).
+ */
public int getSampleSize(int band)
{
return sampleSize[band];
}
+ /**
+ * Returns the index in the data buffer that stores the pixel at (x, y).
+ *
+ * @param x the x-coordinate.
+ * @param y the y-coordinate.
+ *
+ * @return The index in the data buffer that stores the pixel at (x, y).
+ */
public int getOffset(int x, int y)
{
return scanlineStride*y + x;
@@ -142,20 +210,40 @@ public class SinglePixelPackedSampleModel extends SampleModel
return bitMasks;
}
+ /**
+ * Returns the number of data elements from a pixel in one row to the
+ * corresponding pixel in the next row.
+ *
+ * @return The scanline stride.
+ */
public int getScanlineStride()
{
return scanlineStride;
}
+ /**
+ * Creates a new <code>SinglePixelPackedSampleModel</code> that accesses
+ * the specified subset of bands.
+ *
+ * @param bands an array containing band indices (<code>null</code> not
+ * permitted).
+ *
+ * @return A new sample model.
+ *
+ * @throws NullPointerException if <code>bands</code> is <code>null</code>.
+ * @throws RasterFormatException if <code>bands.length</code> is greater
+ * than the number of bands in this model.
+ */
public SampleModel createSubsetSampleModel(int[] bands)
{
- // FIXME: Is this the right way to interpret bands?
+ if (bands.length > numBands)
+ throw new RasterFormatException("Too many bands.");
int numBands = bands.length;
int[] bitMasks = new int[numBands];
- for (int b=0; b<numBands; b++)
+ for (int b = 0; b < numBands; b++)
bitMasks[b] = this.bitMasks[bands[b]];
return new SinglePixelPackedSampleModel(dataType, width, height,
@@ -174,16 +262,20 @@ public class SinglePixelPackedSampleModel extends SampleModel
}
/**
- * This is a more efficient implementation of the default implementation in the super
- * class.
- * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
- * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * This is a more efficient implementation of the default implementation in
+ * the super class.
+ * @param x The x-coordinate of the pixel rectangle to store in
+ * <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in
+ * <code>obj</code>.
* @param w The width of the pixel rectangle to store in <code>obj</code>.
* @param h The height of the pixel rectangle to store in <code>obj</code>.
- * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param obj The primitive array to store the pixels into or null to force
+ * creation.
* @param data The DataBuffer that is the source of the pixel data.
* @return The primitive array containing the pixel data.
- * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ * @see java.awt.image.SampleModel#getDataElements(int, int, int, int,
+ * java.lang.Object, java.awt.image.DataBuffer)
*/
public Object getDataElements(int x, int y, int w, int h, Object obj,
DataBuffer data)
@@ -209,10 +301,11 @@ public class SinglePixelPackedSampleModel extends SampleModel
// Seems like the only sensible thing to do.
throw new ClassCastException();
}
- if(x==0 && scanlineStride == w)
+ if(x == 0 && scanlineStride == w)
{
// The full width need to be copied therefore we can copy in one shot.
- System.arraycopy(pixelData, scanlineStride*y + data.getOffset(), obj, 0, size);
+ System.arraycopy(pixelData, scanlineStride*y + data.getOffset(), obj,
+ 0, size);
}
else
{
@@ -229,32 +322,68 @@ public class SinglePixelPackedSampleModel extends SampleModel
return obj;
}
-
+ /**
+ * Returns an array containing the samples for the pixel at (x, y) in the
+ * specified data buffer. If <code>iArray</code> is not <code>null</code>,
+ * it will be populated with the sample values and returned as the result of
+ * this function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The pixel sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
{
int offset = scanlineStride*y + x;
if (iArray == null) iArray = new int[numBands];
int samples = data.getElem(offset);
- for (int b=0; b<numBands; b++)
+ for (int b = 0; b < numBands; b++)
iArray[b] = (samples & bitMasks[b]) >>> bitOffsets[b];
return iArray;
}
+ /**
+ * Returns an array containing the samples for the pixels in the region
+ * specified by (x, y, w, h) in the specified data buffer. The array is
+ * ordered by pixels (that is, all the samples for the first pixel are
+ * grouped together, followed by all the samples for the second pixel, and so
+ * on). If <code>iArray</code> is not <code>null</code>, it will be
+ * populated with the sample values and returned as the result of this
+ * function (this avoids allocating a new array instance).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param iArray an array to populate with the sample values and return as
+ * the result (if <code>null</code>, a new array will be allocated).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The pixel sample values.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int[] getPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
{
int offset = scanlineStride*y + x;
if (iArray == null) iArray = new int[numBands*w*h];
int outOffset = 0;
- for (y=0; y<h; y++)
+ for (y = 0; y < h; y++)
{
int lineOffset = offset;
- for (x=0; x<w; x++)
+ for (x = 0; x < w; x++)
{
int samples = data.getElem(lineOffset++);
- for (int b=0; b<numBands; b++)
+ for (int b = 0; b < numBands; b++)
iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
}
offset += scanlineStride;
@@ -262,6 +391,20 @@ public class SinglePixelPackedSampleModel extends SampleModel
return iArray;
}
+ /**
+ * Returns the sample value for the pixel at (x, y) in the specified data
+ * buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @return The sample value.
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public int getSample(int x, int y, int b, DataBuffer data)
{
int offset = scanlineStride*y + x;
@@ -270,16 +413,18 @@ public class SinglePixelPackedSampleModel extends SampleModel
}
/**
- * This method implements a more efficient way to set data elements than the default
- * implementation of the super class. It sets the data elements line by line instead
- * of pixel by pixel.
+ * This method implements a more efficient way to set data elements than the
+ * default implementation of the super class. It sets the data elements line
+ * by line instead of pixel by pixel.
+ *
* @param x The x-coordinate of the data elements in <code>obj</code>.
* @param y The y-coordinate of the data elements in <code>obj</code>.
* @param w The width of the data elements in <code>obj</code>.
* @param h The height of the data elements in <code>obj</code>.
* @param obj The primitive array containing the data elements to set.
* @param data The DataBuffer to store the data elements into.
- * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ * @see java.awt.image.SampleModel#setDataElements(int, int, int, int,
+ * java.lang.Object, java.awt.image.DataBuffer)
*/
public void setDataElements(int x, int y, int w, int h,
Object obj, DataBuffer data)
@@ -373,12 +518,24 @@ public class SinglePixelPackedSampleModel extends SampleModel
}
}
+ /**
+ * Sets the samples for the pixel at (x, y) in the specified data buffer to
+ * the specified values.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray the sample values (<code>null</code> not permitted).
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if either <code>iArray</code> or
+ * <code>data</code> is <code>null</code>.
+ */
public void setPixel(int x, int y, int[] iArray, DataBuffer data)
{
int offset = scanlineStride*y + x;
int samples = 0;
- for (int b=0; b<numBands; b++)
+ for (int b = 0; b < numBands; b++)
samples |= (iArray[b] << bitOffsets[b]) & bitMasks[b];
data.setElem(offset, samples);
@@ -394,7 +551,8 @@ public class SinglePixelPackedSampleModel extends SampleModel
* @param h The height of the pixel rectangle in <code>obj</code>.
* @param iArray The primitive array containing the pixels to set.
* @param data The DataBuffer to store the pixels into.
- * @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[], java.awt.image.DataBuffer)
+ * @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[],
+ * java.awt.image.DataBuffer)
*/
public void setPixels(int x, int y, int w, int h, int[] iArray,
DataBuffer data)
@@ -407,7 +565,7 @@ public class SinglePixelPackedSampleModel extends SampleModel
for (int xx=x; xx<(x+w); xx++)
{
int samples = 0;
- for (int b=0; b<numBands; b++)
+ for (int b = 0; b < numBands; b++)
samples |= (iArray[inOffset+b] << bitOffsets[b]) & bitMasks[b];
data.setElem(0, offset, samples);
inOffset += numBands;
@@ -416,7 +574,19 @@ public class SinglePixelPackedSampleModel extends SampleModel
}
}
-
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the
+ * specified data buffer.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ * @param data the data buffer (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>data</code> is <code>null</code>.
+ */
public void setSample(int x, int y, int b, int s, DataBuffer data)
{
int offset = scanlineStride*y + x;
@@ -428,6 +598,76 @@ public class SinglePixelPackedSampleModel extends SampleModel
}
/**
+ * Tests this sample model for equality with an arbitrary object. This
+ * method returns <code>true</code> if and only if:
+ * <ul>
+ * <li><code>obj</code> is not <code>null</code>;
+ * <li><code>obj</code> is an instance of
+ * <code>SinglePixelPackedSampleModel</code>;
+ * <li>both models have the same:
+ * <ul>
+ * <li><code>dataType</code>;
+ * <li><code>width</code>;
+ * <li><code>height</code>;
+ * <li><code>numBands</code>;
+ * <li><code>scanlineStride</code>;
+ * <li><code>bitMasks</code>;
+ * <li><code>bitOffsets</code>.
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * @param obj the object (<code>null</code> permitted)
+ *
+ * @return <code>true</code> if this model is equal to <code>obj</code>, and
+ * <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (! (obj instanceof SinglePixelPackedSampleModel))
+ return false;
+ SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel) obj;
+ if (this.dataType != that.dataType)
+ return false;
+ if (this.width != that.width)
+ return false;
+ if (this.height != that.height)
+ return false;
+ if (this.numBands != that.numBands)
+ return false;
+ if (this.scanlineStride != that.scanlineStride)
+ return false;
+ if (!Arrays.equals(this.bitMasks, that.bitMasks))
+ return false;
+ if (!Arrays.equals(this.bitOffsets, that.bitOffsets))
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns a hash code for this <code>SinglePixelPackedSampleModel</code>.
+ *
+ * @return A hash code.
+ */
+ public int hashCode()
+ {
+ // this hash code won't match Sun's, but that shouldn't matter...
+ int result = 193;
+ result = 37 * result + dataType;
+ result = 37 * result + width;
+ result = 37 * result + height;
+ result = 37 * result + numBands;
+ result = 37 * result + scanlineStride;
+ for (int i = 0; i < bitMasks.length; i++)
+ result = 37 * result + bitMasks[i];
+ for (int i = 0; i < bitOffsets.length; i++)
+ result = 37 * result + bitOffsets[i];
+ return result;
+ }
+
+ /**
* Creates a String with some information about this SampleModel.
* @return A String describing this SampleModel.
* @see java.lang.Object#toString()
@@ -438,9 +678,10 @@ public class SinglePixelPackedSampleModel extends SampleModel
result.append(getClass().getName());
result.append("[");
result.append("scanlineStride=").append(scanlineStride);
- for(int i=0; i < bitMasks.length; i+=1)
+ for(int i = 0; i < bitMasks.length; i+=1)
{
- result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+ result.append(", mask[").append(i).append("]=0x").append(
+ Integer.toHexString(bitMasks[i]));
}
result.append("]");
diff --git a/libjava/classpath/java/awt/image/WritableRaster.java b/libjava/classpath/java/awt/image/WritableRaster.java
index 2e5462fd92e..473c6fe41f9 100644
--- a/libjava/classpath/java/awt/image/WritableRaster.java
+++ b/libjava/classpath/java/awt/image/WritableRaster.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2003, 2006, Free Software Foundation
This file is part of GNU Classpath.
@@ -41,61 +41,98 @@ import java.awt.Point;
import java.awt.Rectangle;
/**
+ * A raster with methods to support updating pixel values.
+ *
* @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
*/
public class WritableRaster extends Raster
{
+ /**
+ * Creates a new <code>WritableRaster</code>.
+ *
+ * @param sampleModel the sample model.
+ * @param origin the origin.
+ */
protected WritableRaster(SampleModel sampleModel, Point origin)
{
this(sampleModel, sampleModel.createDataBuffer(), origin);
}
- protected WritableRaster(SampleModel sampleModel,
- DataBuffer dataBuffer, Point origin)
+ /**
+ * Creates a new <code>WritableRaster</code> instance.
+ *
+ * @param sampleModel the sample model.
+ * @param dataBuffer the data buffer.
+ * @param origin the origin.
+ */
+ protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer,
+ Point origin)
{
this(sampleModel, dataBuffer,
- new Rectangle(origin != null ? origin.x : 0,
+ new Rectangle(origin != null ? origin.x : 0,
origin != null ? origin.y : 0,
- sampleModel.getWidth(), sampleModel.getHeight()),
- origin,
- null);
+ sampleModel.getWidth(), sampleModel.getHeight()),
+ origin, null);
}
+ /**
+ * Creates a new <code>WritableRaster</code> instance.
+ *
+ * @param sampleModel the sample model.
+ * @param dataBuffer the data buffer.
+ * @param aRegion the raster's bounds.
+ * @param sampleModelTranslate the translation.
+ * @param parent the parent.
+ */
protected WritableRaster(SampleModel sampleModel,
- DataBuffer dataBuffer,
- Rectangle aRegion,
- Point sampleModelTranslate,
- WritableRaster parent)
+ DataBuffer dataBuffer,
+ Rectangle aRegion,
+ Point sampleModelTranslate,
+ WritableRaster parent)
{
- super(sampleModel, dataBuffer, aRegion, sampleModelTranslate,
- parent);
+ super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
}
+ /**
+ * Returns the raster's parent, cast as a {@link WritableRaster}.
+ *
+ * @return The raster's parent.
+ */
public WritableRaster getWritableParent()
{
return (WritableRaster) getParent();
}
+ /**
+ * @param childMinX
+ * @param childMinY
+ * @return
+ */
public WritableRaster createWritableTranslatedChild(int childMinX,
- int childMinY)
+ int childMinY)
{
// This mirrors the code from the super class
int tcx = sampleModelTranslateX - minX + childMinX;
int tcy = sampleModelTranslateY - minY + childMinY;
return new WritableRaster(sampleModel, dataBuffer,
- new Rectangle(childMinX, childMinY,
- width, height),
- new Point(tcx, tcy),
- this);
+ new Rectangle(childMinX, childMinY, width, height),
+ new Point(tcx, tcy), this);
}
- public WritableRaster createWritableChild(int parentX,
- int parentY,
- int w, int h,
- int childMinX,
- int childMinY,
- int[] bandList)
+ /**
+ *
+ * @param parentX
+ * @param parentY
+ * @param w
+ * @param h
+ * @param childMinX
+ * @param childMinY
+ * @param bandList
+ * @return
+ */
+ public WritableRaster createWritableChild(int parentX, int parentY,
+ int w, int h, int childMinX, int childMinY, int[] bandList)
{
// This mirrors the code from the super class
@@ -106,51 +143,52 @@ public class WritableRaster extends Raster
sampleModel :
sampleModel.createSubsetSampleModel(bandList);
- return new
- WritableRaster(sm, dataBuffer,
- new Rectangle(childMinX, childMinY,
- w, h),
- new Point(sampleModelTranslateX+childMinX-parentX,
- sampleModelTranslateY+childMinY-parentY),
- this);
+ return new WritableRaster(sm, dataBuffer,
+ new Rectangle(childMinX, childMinY, w, h),
+ new Point(sampleModelTranslateX + childMinX - parentX,
+ sampleModelTranslateY + childMinY - parentY),
+ this);
}
public void setDataElements(int x, int y, Object inData)
{
- sampleModel.setDataElements(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- inData, dataBuffer);
+ sampleModel.setDataElements(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, inData, dataBuffer);
}
public void setDataElements(int x, int y, Raster inRaster)
{
- Object dataElements = getDataElements(0, 0,
- inRaster.getWidth(),
- inRaster.getHeight(),
- null);
+ Object dataElements = getDataElements(0, 0, inRaster.getWidth(),
+ inRaster.getHeight(), null);
setDataElements(x, y, dataElements);
}
- public void setDataElements(int x, int y, int w, int h,
- Object inData)
+ public void setDataElements(int x, int y, int w, int h, Object inData)
{
- sampleModel.setDataElements(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, inData, dataBuffer);
+ sampleModel.setDataElements(x - sampleModelTranslateX,
+ y - sampleModelTranslateY, w, h, inData, dataBuffer);
}
+ /**
+ *
+ * @param srcRaster
+ */
public void setRect(Raster srcRaster)
{
setRect(0, 0, srcRaster);
}
+ /**
+ *
+ * @param dx
+ * @param dy
+ * @param srcRaster
+ */
public void setRect(int dx, int dy, Raster srcRaster)
{
- Rectangle targetUnclipped = new Rectangle(srcRaster.getMinX()+dx,
- srcRaster.getMinY()+dy,
- srcRaster.getWidth(),
- srcRaster.getHeight());
-
+ Rectangle targetUnclipped = new Rectangle(srcRaster.getMinX() + dx,
+ srcRaster.getMinY() + dy, srcRaster.getWidth(), srcRaster.getHeight());
+
Rectangle target = getBounds().intersection(targetUnclipped);
if (target.isEmpty()) return;
@@ -169,97 +207,225 @@ public class WritableRaster extends Raster
But this is probably not the place to consider such
optimizations.*/
- int[] pixels = srcRaster.getPixels(sx, sy,
- target.width, target.height,
- (int[]) null);
+ int[] pixels = srcRaster.getPixels(sx, sy, target.width, target.height,
+ (int[]) null);
setPixels(target.x, target.y, target.width, target.height, pixels);
}
+ /**
+ * Sets the samples for the pixel at (x, y) in the raster to the specified
+ * values.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param iArray the sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>iArray</code> is <code>null</code>.
+ */
public void setPixel(int x, int y, int[] iArray)
{
- sampleModel.setPixel(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- iArray, dataBuffer);
+ sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ iArray, dataBuffer);
}
+ /**
+ * Sets the samples for the pixel at (x, y) in the raster to the specified
+ * values.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param fArray the sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>fArray</code> is <code>null</code>.
+ */
public void setPixel(int x, int y, float[] fArray)
{
- sampleModel.setPixel(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- fArray, dataBuffer);
+ sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ fArray, dataBuffer);
}
+ /**
+ * Sets the samples for the pixel at (x, y) in the raster to the specified
+ * values.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param dArray the sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>dArray</code> is <code>null</code>.
+ */
public void setPixel(int x, int y, double[] dArray)
{
- sampleModel.setPixel(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- dArray, dataBuffer);
+ sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ dArray, dataBuffer);
}
+ /**
+ * Sets the sample values for the pixels in the region specified by
+ * (x, y, w, h) in the raster. The array is ordered by pixels (that is, all
+ * the samples for the first pixel are grouped together, followed by all the
+ * samples for the second pixel, and so on).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param iArray the pixel sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>iArray</code> is <code>null</code>.
+ */
public void setPixels(int x, int y, int w, int h, int[] iArray)
{
- sampleModel.setPixels(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, iArray, dataBuffer);
+ sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ w, h, iArray, dataBuffer);
}
+ /**
+ * Sets the sample values for the pixels in the region specified by
+ * (x, y, w, h) in the raster. The array is ordered by pixels (that is, all
+ * the samples for the first pixel are grouped together, followed by all the
+ * samples for the second pixel, and so on).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param fArray the pixel sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>fArray</code> is <code>null</code>.
+ */
public void setPixels(int x, int y, int w, int h, float[] fArray)
{
- sampleModel.setPixels(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, fArray, dataBuffer);
+ sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ w, h, fArray, dataBuffer);
}
+ /**
+ * Sets the sample values for the pixels in the region specified by
+ * (x, y, w, h) in the raster. The array is ordered by pixels (that is, all
+ * the samples for the first pixel are grouped together, followed by all the
+ * samples for the second pixel, and so on).
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param dArray the pixel sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>dArray</code> is <code>null</code>.
+ */
public void setPixels(int x, int y, int w, int h, double[] dArray)
{
- sampleModel.setPixels(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, dArray, dataBuffer);
+ sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ w, h, dArray, dataBuffer);
}
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the raster.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ */
public void setSample(int x, int y, int b, int s)
{
- sampleModel.setSample(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- b, s, dataBuffer);
+ sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ b, s, dataBuffer);
}
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the raster.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ */
public void setSample(int x, int y, int b, float s)
{
- sampleModel.setSample(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- b, s, dataBuffer);
+ sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ b, s, dataBuffer);
}
+ /**
+ * Sets the sample value for a band for the pixel at (x, y) in the raster.
+ *
+ * @param x the x-coordinate of the pixel.
+ * @param y the y-coordinate of the pixel.
+ * @param b the band (in the range <code>0</code> to
+ * <code>getNumBands() - 1</code>).
+ * @param s the sample value.
+ */
public void setSample(int x, int y, int b, double s)
{
- sampleModel.setSample(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- b, s, dataBuffer);
+ sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ b, s, dataBuffer);
}
+ /**
+ * Sets the sample values for one band for the pixels in the region
+ * specified by (x, y, w, h) in the raster.
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param iArray the sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>iArray</code> is <code>null</code>.
+ */
public void setSamples(int x, int y, int w, int h, int b,
- int[] iArray)
+ int[] iArray)
{
- sampleModel.setSamples(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, b, iArray, dataBuffer);
+ sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ w, h, b, iArray, dataBuffer);
}
+ /**
+ * Sets the sample values for one band for the pixels in the region
+ * specified by (x, y, w, h) in the raster.
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param fArray the sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>fArray</code> is <code>null</code>.
+ */
public void setSamples(int x, int y, int w, int h, int b,
- float[] fArray)
+ float[] fArray)
{
- sampleModel.setSamples(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, b, fArray, dataBuffer);
+ sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ w, h, b, fArray, dataBuffer);
}
+ /**
+ * Sets the sample values for one band for the pixels in the region
+ * specified by (x, y, w, h) in the raster.
+ *
+ * @param x the x-coordinate of the top-left pixel.
+ * @param y the y-coordinate of the top-left pixel.
+ * @param w the width of the region of pixels.
+ * @param h the height of the region of pixels.
+ * @param b the band (in the range <code>0</code> to
+ * </code>getNumBands() - 1</code>).
+ * @param dArray the sample values (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>dArray</code> is <code>null</code>.
+ */
public void setSamples(int x, int y, int w, int h, int b,
- double[] dArray)
+ double[] dArray)
{
- sampleModel.setSamples(x-sampleModelTranslateX,
- y-sampleModelTranslateY,
- w, h, b, dArray, dataBuffer);
+ sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY,
+ w, h, b, dArray, dataBuffer);
}
}
diff --git a/libjava/classpath/java/awt/peer/ComponentPeer.java b/libjava/classpath/java/awt/peer/ComponentPeer.java
index 97b96f49cdb..bc6e3a457f3 100644
--- a/libjava/classpath/java/awt/peer/ComponentPeer.java
+++ b/libjava/classpath/java/awt/peer/ComponentPeer.java
@@ -153,6 +153,12 @@ public interface ComponentPeer
* {@link Component#getMinimumSize()}.
*
* @return the minimum size for the component
+ *
+ * @specnote Presumably this method got added to replace minimumSize().
+ * However, testing shows that this is never called in the RI
+ * (tested with JDK5), but instead minimumSize() is called
+ * directly. It is advisable to implement this method to delegate
+ * to minimumSize() and put the real implementation in there.
*/
Dimension getMinimumSize();
@@ -161,6 +167,12 @@ public interface ComponentPeer
* {@link Component#getPreferredSize()}.
*
* @return the preferred size for the component
+ *
+ * @specnote Presumably this method got added to replace preferredSize().
+ * However, testing shows that this is never called in the RI
+ * (tested with JDK5), but instead preferredSize() is called
+ * directly. It is advisable to implement this method to delegate
+ * to preferredSize() and put the real implementation in there.
*/
Dimension getPreferredSize();
@@ -262,12 +274,21 @@ public interface ComponentPeer
* Requests that this component receives the focus. This is called from
* {@link Component#requestFocus()}.
*
- * @param source TODO
- * @param bool1 TODO
- * @param bool2 TODO
- * @param x TODO
- */
- boolean requestFocus(Component source, boolean bool1, boolean bool2, long x);
+ * This method is only called for heavyweight component's peers. Lightweight
+ * components ask their nearest heavyweight component to request focus.
+ * It's up to the heavyweight peer to decide if any of it's lightweight
+ * descendants are allowed to receive keyboard input focus or not. If the
+ * focus request is finally approved, then the peer must post a FOCUS_GAINED
+ * event for the requested component.
+ *
+ * @param request the component for which the focus is requested
+ * @param temporary indicates if the focus change is temporary (true) or
+ * permanent (false)
+ * @param allowWindowFocus indicates if it's allowed to change window focus
+ * @param time the timestamp
+ */
+ boolean requestFocus(Component request, boolean temporary,
+ boolean allowWindowFocus, long time);
/**
* Notifies the peer that the bounds of this component have changed. This
diff --git a/libjava/classpath/java/awt/peer/MouseInfoPeer.java b/libjava/classpath/java/awt/peer/MouseInfoPeer.java
new file mode 100644
index 00000000000..e9923a653aa
--- /dev/null
+++ b/libjava/classpath/java/awt/peer/MouseInfoPeer.java
@@ -0,0 +1,61 @@
+/* MouseInfoPeer.java -- peer interface for MouseInfo
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.peer;
+
+import java.awt.Point;
+import java.awt.Window;
+
+/**
+ * MouseInfoPeer is the peer interface java.awt.MouseInfo.
+ *
+ * @author Sven de Marothy
+ * @since 1.5
+ */
+public interface MouseInfoPeer
+{
+ /**
+ * Get the mouse pointer coordinates and store them in p (obviously non-null)
+ * returns the index of the current screen device of the mouse.
+ */
+ public int fillPointWithCoords(Point p);
+
+ /**
+ * Returns whether a given Window is under the mouse.
+ */
+ public boolean isWindowUnderMouse(Window w);
+}
diff --git a/libjava/classpath/java/awt/peer/WindowPeer.java b/libjava/classpath/java/awt/peer/WindowPeer.java
index 6c014de0b99..00d1035791a 100644
--- a/libjava/classpath/java/awt/peer/WindowPeer.java
+++ b/libjava/classpath/java/awt/peer/WindowPeer.java
@@ -1,5 +1,5 @@
/* WindowPeer.java -- Interface for window peers
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,7 +44,8 @@ public interface WindowPeer extends ContainerPeer
void toFront();
/**
- * FIXME: unknown.
+ * Update the always-on-top status of the Window.
+ *
* @since 1.5
*/
void updateAlwaysOnTop();