Imported GNU Classpath 0.92

2006-08-14  Mark Wielaard  <mark@klomp.org>

       Imported GNU Classpath 0.92
       * HACKING: Add more importing hints. Update automake version
       requirement.

       * configure.ac (gconf-peer): New enable AC argument.
       Add --disable-gconf-peer and --enable-default-preferences-peer
       to classpath configure when gconf is disabled.
       * scripts/makemake.tcl: Set gnu/java/util/prefs/gconf and
       gnu/java/awt/dnd/peer/gtk to bc. Classify
       gnu/java/security/Configuration.java as generated source file.

       * gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java,
       gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java,
       gnu/java/lang/management/VMClassLoadingMXBeanImpl.java,
       gnu/java/lang/management/VMRuntimeMXBeanImpl.java,
       gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java,
       gnu/java/lang/management/VMThreadMXBeanImpl.java,
       gnu/java/lang/management/VMMemoryMXBeanImpl.java,
       gnu/java/lang/management/VMCompilationMXBeanImpl.java: New VM stub
       classes.
       * java/lang/management/VMManagementFactory.java: Likewise.
       * java/net/VMURLConnection.java: Likewise.
       * gnu/java/nio/VMChannel.java: Likewise.

       * java/lang/Thread.java (getState): Add stub implementation.
       * java/lang/Class.java (isEnum): Likewise.
       * java/lang/Class.h (isEnum): Likewise.

       * gnu/awt/xlib/XToolkit.java (getClasspathTextLayoutPeer): Removed.

       * javax/naming/spi/NamingManager.java: New override for StackWalker
       functionality.

       * configure, sources.am, Makefile.in, gcj/Makefile.in,
       include/Makefile.in, testsuite/Makefile.in: Regenerated.

From-SVN: r116139
This commit is contained in:
Mark Wielaard
2006-08-14 23:12:35 +00:00
parent abab460491
commit ac1ed908de
1294 changed files with 99479 additions and 35933 deletions
+5
View File
@@ -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;
+68 -55
View File
@@ -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;
}
}
+20
View File
@@ -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++;
}
}
@@ -350,6 +350,7 @@ public class CardLayout implements LayoutManager2, Serializable
}
}
((Component) target).setVisible (true);
parent.validate();
}
}
@@ -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
+20
View File
@@ -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
File diff suppressed because it is too large Load Diff
+245 -91
View File
@@ -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;
@@ -87,16 +88,18 @@ public class Container extends Component
Dimension maxSize;
/**
* Keeps track if the Container was cleared during a paint/update.
*/
private boolean backCleared;
/**
* @since 1.4
*/
boolean focusCycleRoot;
/**
* Indicates if this container provides a focus traversal policy.
*
* @since 1.5
*/
private boolean focusTraversalPolicyProvider;
int containerSerializedDataVersion;
/* Anything else is non-serializable, and should be declared "transient". */
@@ -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();
}
}
/**
@@ -1548,6 +1609,42 @@ public class Container extends Component
this.focusCycleRoot = focusCycleRoot;
}
/**
* 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.
*
@@ -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 ())
@@ -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;
+14 -1
View File
@@ -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.
@@ -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 ();
@@ -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)
{
@@ -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
+4 -6
View File
@@ -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;
}
+38 -1
View File
@@ -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
@@ -575,6 +584,34 @@ public class Font implements Serializable
return tk().createFont(fontFormat, is);
}
/**
* 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
+5 -7
View File
@@ -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).
@@ -48,68 +48,93 @@ 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. */
/**
* 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.
* Position to where a page starts. Equals NORTH for horizontal orientations.
*/
public static final int FIRST_LINE_END = 24;
public static final int PAGE_START = 19;
/**
* Position to where the first text line would start. Equals to NORTHWEST for
* horizontal left-to-right orientations.
* Position to where a page ends. Equals SOUTH for horizontal orientations.
*/
public static final int FIRST_LINE_START = 23;
/**
* 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;
/**
* Position to where the last text line would start. Equals to SOUTHWEST for
* horizontal left-to-right orientations.
*/
public static final int LAST_LINE_START = 25;
/**
* Position to where a text line would end. Equals to EAST for
* left-to-right orientations.
*/
public static final int LINE_END = 22;
public static final int PAGE_END = 20;
/**
* Position to where a text line would start. Equals to WEST for
@@ -118,14 +143,34 @@ public class GridBagConstraints implements Cloneable, Serializable
public static final int LINE_START = 21;
/**
* Position to where a page ends. Equals SOUTH for horizontal orientations.
* Position to where a text line would end. Equals to EAST for
* left-to-right orientations.
*/
public static final int PAGE_END = 20;
public static final int LINE_END = 22;
/**
* Position to where a page starts. Equals NORTH for horizontal orientations.
* Position to where the first text line would start. Equals to NORTHWEST for
* horizontal left-to-right orientations.
*/
public static final int PAGE_START = 19;
public static final int FIRST_LINE_START = 23;
/**
* Position to where the first text line would end. Equals to NORTHEAST for
* horizontal left-to-right orientations.
*/
public static final int FIRST_LINE_END = 24;
/**
* Position to where the last text line would start. Equals to SOUTHWEST for
* horizontal left-to-right orientations.
*/
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,
+63 -53
View File
@@ -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);
}
}
+3 -9
View File
@@ -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
+ "]");
+36 -2
View File
@@ -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
{
@@ -101,6 +101,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.
*/
@@ -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
+3 -4
View File
@@ -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 + ']';
}
/**
@@ -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);
}
}
+226 -250
View File
@@ -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;
/*************************************************************************/
/*
* Instance Variables
*/
/**
* @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;
/**
* @serial The text displayed in the label
*/
private String text;
/*************************************************************************/
/*
* Constructors
*/
/**
* 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 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 ();
}
/*************************************************************************/
/*
* Instance Variables
*/
/**
* 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);
}
/*************************************************************************/
/**
* 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);
}
/*************************************************************************/
/**
* 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();
}
}
/*************************************************************************/
/**
* 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());
}
/**
* This class provides accessibility support for the label.
*/
protected class AccessibleAWTLabel
extends AccessibleAWTComponent
{
/**
* For compatability with Sun's JDK 1.4.2 rev. 5
* Alignment constant aligning the text to the left of its window.
*/
private static final long serialVersionUID = -3568967560160480438L;
public static final int LEFT = 0;
/**
* Constructor for the accessible label.
* Alignment constant aligning the text in the center of its window.
*/
public AccessibleAWTLabel()
{
}
public static final int CENTER = 1;
/**
* Returns the accessible name for the label. This is
* the text used in the label.
* 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;
/**
* @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;
/**
* @serial The text displayed in the label
*/
private String text;
/**
* Initializes a new instance of <code>Label</code> with no text.
*
* @return a <code>String</code> containing the accessible
* name for this label.
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
public String getAccessibleName()
public Label()
{
return getText();
this("", LEFT);
}
/**
* Returns the accessible role for the label.
* Initializes a new instance of <code>Label</code> with the specified
* text that is aligned to the left.
*
* @return an instance of <code>AccessibleRole</code>, describing
* the role of the label.
* @param text The text of the label.
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
public AccessibleRole getAccessibleRole()
public Label(String text)
{
return AccessibleRole.LABEL;
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();
}
/**
* 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);
}
/**
* 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;
}
/**
* 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();
}
}
/**
* 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());
}
/**
* 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()
{
}
/**
* 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()
{
return getText();
}
/**
* 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;
}
}
/**
* 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;
}
/**
* Generate a unique name for this button.
*
* @return A unique name for this button.
*/
String generateName()
{
return "label" + getUniqueLong();
}
/**
* The number used to generate the name returned by getName.
*/
private static transient long nextLabelNumber;
private static synchronized long getUniqueLong()
{
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
@@ -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;
+29 -9
View File
@@ -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
+20
View File
@@ -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
+21 -1
View File
@@ -60,9 +60,14 @@ 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
*/
@@ -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.
@@ -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.
+23 -2
View File
@@ -63,9 +63,15 @@ public class MenuItem extends MenuComponent
/*
* Static Variables
*/
// Serialization Constant
private static final long serialVersionUID = -21757335363267194L;
/**
* 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;
/*************************************************************************/
@@ -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
+95
View File
@@ -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();
}
}
+7 -6
View File
@@ -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);
}
/**
@@ -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;
}
}
+22 -2
View File
@@ -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
+27 -5
View File
@@ -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
+7 -5
View File
@@ -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
}
+45 -19
View File
@@ -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 (rows < 0)
this.rows = 0;
else
this.rows = rows;
if (columns < 0)
this.columns = 0;
else
this.columns = columns;
if (scrollbarVisibility != SCROLLBARS_BOTH
&& scrollbarVisibility != SCROLLBARS_VERTICAL_ONLY
&& scrollbarVisibility != SCROLLBARS_HORIZONTAL_ONLY
&& scrollbarVisibility != SCROLLBARS_NONE)
throw new IllegalArgumentException ("Bad scrollbar visibility value");
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);
}
}
/**
+307 -373
View File
@@ -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
*/
private static final long serialVersionUID = -2214773872412987419L;
// Constant for serialization
private static final long serialVersionUID = -2214773872412987419L;
/**
* @serial Indicates whether or not this component is editable.
* This is package-private to avoid an accessor method.
*/
boolean editable;
/*
* Instance Variables
*/
/**
* @serial The starting position of the selected text region.
* This is package-private to avoid an accessor method.
*/
int selectionStart;
/**
* @serial Indicates whether or not this component is editable.
* This is package-private to avoid an accessor method.
*/
boolean editable;
/**
* @serial The ending position of the selected text region.
* This is package-private to avoid an accessor method.
*/
int selectionEnd;
/**
* @serial The starting position of the selected text region.
* This is package-private to avoid an accessor method.
*/
int selectionStart;
/**
* @serial The text in the component
* This is package-private to avoid an accessor method.
*/
String text;
/**
* @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;
/**
* 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)
{
if (text == null)
this.text = "";
else
this.text = text;
this.editable = true;
}
TextComponent(String text)
{
this.text = text;
this.editable = true;
}
/*************************************************************************/
/**
* 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();
/*
* Instance Methods
*/
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;
/*************************************************************************/
TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
tcp.setText(text);
setCaretPosition(0);
}
/**
* 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 = "";
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));
}
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();
/**
* 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);
}
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();
/**
* 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());
}
return(selectionEnd);
}
/*************************************************************************/
/**
* 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);
}
/**
* 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();
/**
* 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;
return(selectionEnd);
}
if (selectionStart > getText().length())
selectionStart = text.length();
/*************************************************************************/
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.selectionStart = selectionStart;
this.selectionEnd = selectionEnd;
TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
tcp.select(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;
/**
* Selects all of the text in the component.
*/
public synchronized void selectAll()
{
select(0, getText().length());
}
if (selectionStart > getText().length())
selectionStart = text.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);
}
if (selectionEnd > text.length())
selectionEnd = text.length();
if (selectionStart > selectionEnd)
selectionStart = selectionEnd;
this.selectionStart = selectionStart;
this.selectionEnd = selectionEnd;
TextComponentPeer tcp = (TextComponentPeer)getPeer();
if (tcp != null)
tcp.select(selectionStart, selectionEnd);
}
/*************************************************************************/
/**
* 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);
}
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);
}
/**
* 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);
}
/**
* 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;
/**
* Notifies the component that it should destroy its native peer.
*/
public void removeNotify()
{
super.removeNotify();
}
TextComponentPeer tcp = (TextComponentPeer)getPeer();
if (tcp != null)
tcp.setEditable(editable);
}
/**
* 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);
/*************************************************************************/
enableEvents(AWTEvent.TEXT_EVENT_MASK);
}
/**
* Notifies the component that it should destroy its native peer.
*/
public void
removeNotify()
{
super.removeNotify();
}
/**
* 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 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);
}
/**
* 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 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);
}
enableEvents(AWTEvent.TEXT_EVENT_MASK);
}
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);
}
/*************************************************************************/
/**
* 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 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);
}
/*************************************************************************/
/**
* 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
+374 -440
View File
@@ -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)
*/
* 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.
*
* @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
*/
/**
* 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)
{
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;
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 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 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 ());
}
/*************************************************************************/
/**
* 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);
}
/*************************************************************************/
/**
* Returns the preferred size for this text field.
*
* @return The preferred size for this text field.
*/
public Dimension
getPreferredSize()
{
return getPreferredSize (getColumns ());
}
/*************************************************************************/
/**
* 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 ());
}
/*************************************************************************/
/**
* 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);
return peer.getPreferredSize (columns);
}
/*************************************************************************/
/**
* Notifies this object that it should create its native peer.
*/
public void
addNotify()
{
if (getPeer() != null)
return;
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);
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 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);
}
/*************************************************************************/
/**
* 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);
}
/*************************************************************************/
/**
/**
* The number used to generate the name returned by getName.
*/
private static transient long next_textfield_number;
private static final long serialVersionUID = -2966288784432217853L;
/**
* @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;
/**
* 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());
}
/**
* 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;
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);
}
/**
* 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)
{
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;
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 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 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 ());
}
/**
* 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);
}
/**
* Returns the preferred size for this text field.
*
* @return The preferred size for this text field.
*/
public Dimension getPreferredSize()
{
return getPreferredSize(getColumns ());
}
/**
* 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 ());
}
/**
* 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);
return peer.getPreferredSize (columns);
}
/**
* Notifies this object that it should create its native peer.
*/
public void addNotify()
{
if (getPeer() != null)
return;
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);
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 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);
}
/**
* 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
}
+21
View File
@@ -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;
@@ -331,6 +332,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>.
*
@@ -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;
}
+58 -70
View File
@@ -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();
}
/**
@@ -1235,6 +1174,55 @@ public class Window extends Container implements Accessible
return null;
}
/**
* 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.
*
@@ -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);
@@ -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;
}
@@ -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
@@ -131,6 +131,7 @@ public abstract class DragGestureRecognizer implements Serializable
throws NotImplementedException
{
events = new ArrayList();
// FIXME: Not implemented fully.
}
/**
+87 -37
View File
@@ -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
public DragGestureRecognizer createDragGestureRecognizer(Class recognizer,
Component c,
int actions,
DragGestureListener dgl)
{
NoDragGestureRecognizer(DragSource ds, Component c, int actions,
DragGestureListener dgl)
{
super(ds, c, actions, dgl);
}
protected void registerListeners() { }
protected void unregisterListeners() { }
return Toolkit.getDefaultToolkit().createDragGestureRecognizer(recognizer,
this, c,
actions, dgl);
}
public DragGestureRecognizer
createDragGestureRecognizer(Class recognizer, Component c, int actions,
DragGestureListener dgl)
public DragGestureRecognizer createDefaultDragGestureRecognizer(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;
}
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
@@ -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
+62 -8
View File
@@ -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
@@ -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;
}
@@ -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
@@ -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()
@@ -59,6 +59,7 @@ public class InvalidDnDOperationException extends IllegalStateException
*/
public InvalidDnDOperationException()
{
super();
}
/**
@@ -992,6 +992,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.
@@ -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 ());
}
@@ -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--;
if( guessOffset >= offsetLimit )
return offsetLimit;
text.setIndex( guessOffset );
// If we're on a breaking character, return directly
if( Character.isWhitespace( text.current() ) )
return 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;
}
+156 -84
View File
@@ -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;
@@ -72,6 +71,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.
*/
@@ -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
int ri = charIndices[ firstEndpoint ][0];
int gi = charIndices[ firstEndpoint ][1];
double advance = 0;
// go to first run
while( runIndices[i + 1][1] < firstEndpoint )
for( int i = 0; i < ri; i++ )
advance += runs[i].getLogicalBounds().getWidth();
for( int i = ri; i <= charIndices[ secondEndpoint - 1 ][0]; i++ )
{
advance += runs[i].getLogicalBounds().getWidth();
i++;
}
int dg;
if( i == charIndices[ secondEndpoint - 1 ][0] )
dg = charIndices[ secondEndpoint - 1][1];
else
dg = runs[i].getNumGlyphs() - 1;
int j = 0; // index into the run.
if( runIndices[i][1] - runIndices[i][0] > 1 )
{
while( runs[i].getGlyphCharIndex( j + 1 ) <
(firstEndpoint - runIndices[i][0] ) )j++;
}
gp.append(runs[i].getGlyphVisualBounds( j ), false);
boolean keepGoing = true;;
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
Rectangle2D r = null;
int ri = charIndices[ firstEndpoint ][0];
int gi = charIndices[ firstEndpoint ][1];
double advance = 0;
for( int i = 0; i < ri; i++ )
advance += runs[i].getLogicalBounds().getWidth();
// go to first run
if( i > 0 )
while( runIndices[i + 1][1] < firstEndpoint )
{
advance += runs[i].getLogicalBounds().getWidth();
i++;
}
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;;
do
{
while( j < runs[i].getNumGlyphs() &&
runs[i].getGlyphCharIndex( j ) + runIndices[i][0] <
secondEndpoint )
{
Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( j )).
getBounds2D();
Point2D p = runs[i].getGlyphPosition( j );
r2.setRect( advance + p.getX(), r2.getY(),
r2.getWidth(), r2.getHeight() );
r = r.createUnion( r2 );
j++;
}
if( j >= runs[i].getNumGlyphs() )
{
advance += runs[i].getLogicalBounds().getWidth();
i++;
j = 0;
}
int dg; // last index in this run to use.
if( i == charIndices[ secondEndpoint - 1 ][0] )
dg = charIndices[ secondEndpoint - 1][1];
else
keepGoing = false;
dg = runs[i].getNumGlyphs() - 1;
for(; gi <= dg; gi++ )
{
Rectangle2D r2 = (runs[i].getGlyphLogicalBounds( gi )).
getBounds2D();
if( r == null )
r = r2;
else
r = r.createUnion(r2);
}
gi = 0; // reset glyph index into run for next run.
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 ()
+125 -38
View File
@@ -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");
}
public float getAdvanceBetween (int start, int limit)
throws NotImplementedException
{
throw new Error ("not implemented");
}
public TextLayout getLayout (int start, int limit)
throws NotImplementedException
{
throw new Error ("not implemented");
}
public int getLineBreakIndex (int start, float maxAdvance)
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)
throws NotImplementedException
{
throw new Error ("not implemented");
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)
{
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)
{
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)
{
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 );
// Return first index that doesn't fit.
if( !makeSmaller )
guessOffset--;
if( guessOffset > numChars )
return numChars;
return guessOffset;
}
}
@@ -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];
@@ -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("]");
@@ -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);
@@ -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
}
@@ -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};
}
@@ -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();
}
@@ -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()
{
@@ -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));
}
@@ -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++)
{
}
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++)
{
}
// 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;
// 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);
}
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);
}
}
/* (non-Javadoc)
@@ -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;
+45 -17
View File
@@ -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)
{
@@ -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 =
@@ -366,6 +516,70 @@ public class MultiPixelPackedSampleModel extends SampleModel
data.setElem(offset, sample);
}
/**
* 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.
File diff suppressed because it is too large Load Diff
+49 -1
View File
@@ -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();
}
@@ -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);
}
@@ -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;
@@ -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;
@@ -427,6 +597,76 @@ public class SinglePixelPackedSampleModel extends SampleModel
data.setElem(offset, samples);
}
/**
* 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.
@@ -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("]");
@@ -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);
}
}
@@ -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
* 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 source, boolean bool1, boolean bool2, long x);
boolean requestFocus(Component request, boolean temporary,
boolean allowWindowFocus, long time);
/**
* Notifies the peer that the bounds of this component have changed. This
@@ -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);
}
@@ -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();
@@ -1,5 +1,6 @@
/* VetoableChangeSupport.java -- support to manage vetoable change listeners
Copyright (C) 1998, 1999, 2000, 2002, 2005 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2002, 2005, 2006,
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -120,14 +121,15 @@ public class VetoableChangeSupport implements Serializable
* vetoable change events will be sent to this listener. The listener add
* is not unique: that is, <em>n</em> adds with the same listener will
* result in <em>n</em> events being sent to that listener for every
* vetoable change. Adding a null listener may cause a NullPointerException
* down the road. This method will unwrap a VetoableChangeListenerProxy,
* vetoable change. This method will unwrap a VetoableChangeListenerProxy,
* registering the underlying delegate to the named property list.
*
* @param l the listener to add
* @param l the listener to add (<code>null</code> ignored).
*/
public synchronized void addVetoableChangeListener(VetoableChangeListener l)
{
if (l == null)
return;
if (l instanceof VetoableChangeListenerProxy)
{
VetoableChangeListenerProxy p = (VetoableChangeListenerProxy) l;
@@ -215,19 +217,19 @@ public class VetoableChangeSupport implements Serializable
* being sent to that listener when that property is changed. The effect is
* cumulative, too; if you are registered to listen to receive events on
* all vetoable changes, and then you register on a particular property,
* you will receive change events for that property twice. Adding a null
* listener may cause a NullPointerException down the road. This method
* you will receive change events for that property twice. This method
* will unwrap a VetoableChangeListenerProxy, registering the underlying
* delegate to the named property list if the names match, and discarding
* it otherwise.
*
* @param propertyName the name of the property to listen on
* @param l the listener to add
* @throws NullPointerException if propertyName is null
*/
public synchronized void addVetoableChangeListener(String propertyName,
VetoableChangeListener l)
{
if (propertyName == null || l == null)
return;
while (l instanceof VetoableChangeListenerProxy)
{
VetoableChangeListenerProxy p = (VetoableChangeListenerProxy) l;
@@ -1,5 +1,5 @@
/* BeanContextSupport.java --
Copyright (C) 2003, 2005 Free Software Foundation, Inc.
Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,6 +40,7 @@ package java.beans.beancontext;
import gnu.classpath.NotImplementedException;
import java.beans.Beans;
import java.beans.DesignMode;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -59,7 +60,12 @@ import java.util.Iterator;
import java.util.Locale;
/**
* This is a helper class for implementing a bean context. It is
* intended to be used either by subclassing or by calling methods
* of this implementation from another.
*
* @author Michael Koch
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.2
*/
public class BeanContextSupport extends BeanContextChildSupport
@@ -180,27 +186,102 @@ public class BeanContextSupport extends BeanContextChildSupport
initialize ();
}
public boolean add (Object targetChild)
/**
* <p>
* Add a child to the bean context. A child can be a simple
* <code>Object</code>, a <code>BeanContextChild</code>
* or another <code>BeanContext</code>.
* </p>
* <p>
* The children of a <code>BeanContext</code> form a set. As
* a result, this method returns <code>false</code> if the given
* object is already a child of this context.
* </p>
* <p>
* If the child is a <code>BeanContextChild</code>, or a proxy
* for such a child, the <code>setBeanContext()</code> method
* is invoked on the child. If this operation is vetoed by the
* child, via throwing a <code>PropertyVetoException</code>,
* then the current completion state of the <code>add()</code>
* operation is rolled back and a <code>IllegalStateException</code>
* is thrown. If the <code>BeanContextChild</code> is successfully
* added, then the context registers with its
* <code>PropertyChangeListener</code> and
* <code>VetoableChangeListener</code> for "beanContext" events.
* </p>
* <p>
* If the child implements <code>java.beans.Visibility</code>,
* then its ability to use a GUI is set based on that of
* this context.
* </p>
* <p>
* A <code>BeanContextMembershipEvent</code> is fired when the
* child is successfully added to the bean context.
* </p>
* <p>
* This method is synchronized over the global hierarchy lock.
* </p>
*
* @param targetChild the child to add.
* @return false if the child has already been added.
* @throws IllegalArgumentException if the child is null.
* @throws IllegalStateException if the child vetos the setting
* of its context.
*/
public boolean add(Object targetChild)
{
if (targetChild == null)
throw new IllegalArgumentException();
synchronized (globalHierarchyLock)
{
if (targetChild == null)
throw new IllegalArgumentException();
BCSChild child;
synchronized (children)
{
if (children.containsKey(targetChild)
|| ! validatePendingAdd(targetChild))
return false;
child = createBCSChild(targetChild, beanContextChildPeer);
children.put(targetChild, child);
BCSChild child;
synchronized (children)
{
if (children.containsKey(targetChild)
|| ! validatePendingAdd(targetChild))
return false;
child = createBCSChild(targetChild, beanContextChildPeer);
children.put(targetChild, child);
}
synchronized (targetChild)
{
BeanContextChild bcChild = null;
if (targetChild instanceof BeanContextChild)
bcChild = (BeanContextChild) targetChild;
if (targetChild instanceof BeanContextProxy)
bcChild = ((BeanContextProxy) targetChild).getBeanContextProxy();
if (bcChild != null)
try
{
bcChild.setBeanContext(this);
bcChild.addVetoableChangeListener("beanContext", this);
bcChild.addPropertyChangeListener("beanContext", this);
}
catch (PropertyVetoException e)
{
synchronized (children)
{
children.remove(targetChild);
}
throw new IllegalStateException("The child refused to " +
"associate itself with " +
"this context.", e);
}
if (targetChild instanceof Visibility)
{
Visibility visibleChild = (Visibility) targetChild;
if (okToUseGui)
visibleChild.okToUseGui();
else
visibleChild.dontUseGui();
}
childJustAddedHook(targetChild, child);
}
fireChildrenAdded(new BeanContextMembershipEvent(this,
new Object[]{ targetChild }));
return true;
}
synchronized (targetChild)
{
childJustAddedHook(targetChild, child);
}
fireChildrenAdded(new BeanContextMembershipEvent(this,
new Object[] { targetChild }));
return true;
}
public boolean addAll (Collection c)
@@ -219,10 +300,18 @@ public class BeanContextSupport extends BeanContextChildSupport
}
}
public boolean avoidingGui ()
/**
* Returns true if this bean needs a GUI
* but is being prevented from using one.
*
* @return true if <code>needsGui()</code>
* is true but the bean has been
* told not to use it.
*/
public boolean avoidingGui()
throws NotImplementedException
{
throw new Error ("Not implemented");
return needsGui() && (!okToUseGui);
}
protected Iterator bcsChildren ()
@@ -321,10 +410,13 @@ public class BeanContextSupport extends BeanContextChildSupport
throw new Error ("Not implemented");
}
public void dontUseGui ()
throws NotImplementedException
/**
* Informs this bean that is should not make
* use of the GUI.
*/
public void dontUseGui()
{
throw new Error ("Not implemented");
okToUseGui = false;
}
protected final void fireChildrenAdded (BeanContextMembershipEvent bcme)
@@ -426,10 +518,20 @@ public class BeanContextSupport extends BeanContextChildSupport
children = new HashMap();
}
/**
* This is a convenience method for instantiating a bean inside this
* context. It delegates to the appropriate method in
* <code>java.beans.Beans</code> using the context's classloader.
*
* @param beanName the name of the class of bean to instantiate.
* @throws IOException if an I/O error occurs in loading the class.
* @throws ClassNotFoundException if the class, <code>beanName</code>,
* can not be found.
*/
public Object instantiateChild (String beanName)
throws IOException, ClassNotFoundException, NotImplementedException
throws IOException, ClassNotFoundException
{
throw new Error ("Not implemented");
return Beans.instantiate(getClass().getClassLoader(), beanName, this);
}
public boolean isDesignTime ()
@@ -437,6 +539,11 @@ public class BeanContextSupport extends BeanContextChildSupport
return designTime;
}
/**
* Returns true if this bean context has no children.
*
* @return true if there are no children.
*/
public boolean isEmpty ()
{
synchronized (children)
@@ -459,22 +566,38 @@ public class BeanContextSupport extends BeanContextChildSupport
}
}
public boolean needsGui ()
throws NotImplementedException
/**
* Returns false as this bean does not a
* GUI for its operation.
*
* @return false
*/
public boolean needsGui()
{
throw new Error ("Not implemented");
return false;
}
/**
* Informs this bean that it is okay to make use of
* the GUI.
*/
public void okToUseGui ()
throws NotImplementedException
{
throw new Error ("Not implemented");
okToUseGui = true;
}
/**
* Subclasses may use this method to catch property changes
* arising from the children of this context. At present,
* we just listen for the beans being assigned to a different
* context and remove them from here if such an event occurs.
*
* @param pce the property change event.
*/
public void propertyChange (PropertyChangeEvent pce)
throws NotImplementedException
{
throw new Error ("Not implemented");
if (pce.getNewValue() != this)
remove(pce.getSource(), false);
}
public final void readChildren (ObjectInputStream ois)
@@ -483,18 +606,100 @@ public class BeanContextSupport extends BeanContextChildSupport
throw new Error ("Not implemented");
}
/**
* Remove the specified child from the context. This is
* the same as calling <code>remove(Object,boolean)</code>
* with a request for the <code>setBeanContext()</code> method
* of the child to be called (i.e. the second argument is true).
*
* @param targetChild the child to remove.
*/
public boolean remove (Object targetChild)
{
return remove(targetChild, true);
}
/**
* <p>
* Removes a child from the bean context. A child can be a simple
* <code>Object</code>, a <code>BeanContextChild</code>
* or another <code>BeanContext</code>. If the given child is not
* a child of this context, this method returns <code>false</code>.
* </p>
* <p>
* If the child is a <code>BeanContextChild</code>, or a proxy
* for such a child, the <code>setBeanContext()</code> method
* is invoked on the child (if specified). If this operation is vetoed
* by the child, via throwing a <code>PropertyVetoException</code>,
* then the current completion state of the <code>remove()</code>
* operation is rolled back and a <code>IllegalStateException</code>
* is thrown. If the <code>BeanContextChild</code> is successfully
* removed, then the context deregisters with its
* <code>PropertyChangeListener</code> and
* <code>VetoableChangeListener</code> for "beanContext" events.
* </p>
* <p>
* A <code>BeanContextMembershipEvent</code> is fired when the
* child is successfully removed from the bean context.
* </p>
* <p>
* This method is synchronized over the global hierarchy lock.
* </p>
*
* @param targetChild the child to add.
* @param callChildSetBC true if the <code>setBeanContext()</code>
* method of the child should be called.
* @return false if the child doesn't exist.
* @throws IllegalArgumentException if the child is null.
* @throws IllegalStateException if the child vetos the setting
* of its context.
*/
protected boolean remove (Object targetChild, boolean callChildSetBC)
throws NotImplementedException
{
if (targetChild == null)
throw new IllegalArgumentException();
throw new Error ("Not implemented");
synchronized (globalHierarchyLock)
{
if (targetChild == null)
throw new IllegalArgumentException();
BCSChild child;
synchronized (children)
{
if (!children.containsKey(targetChild)
|| !validatePendingRemove(targetChild))
return false;
child = (BCSChild) children.remove(targetChild);
}
synchronized (targetChild)
{
BeanContextChild bcChild = null;
if (targetChild instanceof BeanContextChild)
bcChild = (BeanContextChild) targetChild;
if (targetChild instanceof BeanContextProxy)
bcChild = ((BeanContextProxy) targetChild).getBeanContextProxy();
if (bcChild != null)
try
{
if (callChildSetBC)
bcChild.setBeanContext(null);
bcChild.removeVetoableChangeListener("beanContext", this);
bcChild.removePropertyChangeListener("beanContext", this);
}
catch (PropertyVetoException e)
{
synchronized (children)
{
children.put(targetChild, child);
}
throw new IllegalStateException("The child refused to " +
"disassociate itself with " +
"this context.", e);
}
childJustRemovedHook(targetChild, child);
}
fireChildrenRemoved(new BeanContextMembershipEvent(this,
new Object[]{ targetChild }));
return true;
}
}
public boolean removeAll (Collection c)
@@ -578,10 +783,16 @@ public class BeanContextSupport extends BeanContextChildSupport
return true;
}
/**
* Subclasses may use this method to veto changes arising
* from the children of this context.
*
* @param pce the vetoable property change event fired.
*/
public void vetoableChange (PropertyChangeEvent pce)
throws PropertyVetoException, NotImplementedException
throws PropertyVetoException
{
throw new Error ("Not implemented");
/* Purposefully left empty */
}
public final void writeChildren (ObjectOutputStream oos)
+39 -7
View File
@@ -1,5 +1,5 @@
/* File.java -- Class representing a file on disk
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -82,7 +82,7 @@ public class File implements Serializable, Comparable
/**
* This is the string that is used to separate the host name from the
* path name in paths than include the host name. It is the value of
* path name in paths that include the host name. It is the value of
* the <code>path.separator</code> system property.
*/
public static final String pathSeparator
@@ -484,9 +484,9 @@ public class File implements Serializable, Comparable
/**
* This method returns a canonical representation of the pathname of
* this file. The actual form of the canonical representation is
* different. On the GNU system, the canonical form differs from the
* absolute form in that all relative file references to "." and ".."
* are resolved and removed.
* system-dependent. On the GNU system, conversion to canonical
* form involves the removal of redundant separators, references to
* "." and "..", and symbolic links.
* <p>
* Note that this method, unlike the other methods which return path
* names, can throw an IOException. This is because native method
@@ -542,7 +542,8 @@ public class File implements Serializable, Comparable
/**
* This method returns a <code>String</code> the represents this file's
* parent. <code>null</code> is returned if the file has no parent. The
* parent is determined via a simple operation which removes the
* parent is determined via a simple operation which removes the name
* after the last file separator character, as determined by the platform.
*
* @return The parent directory of this file
*/
@@ -1199,7 +1200,38 @@ public class File implements Serializable, Comparable
*/
public static File[] listRoots()
{
return VMFile.listRoots();
File[] roots = VMFile.listRoots();
SecurityManager s = System.getSecurityManager();
if (s != null)
{
// Only return roots to which the security manager permits read access.
int count = roots.length;
for (int i = 0; i < roots.length; i++)
{
try
{
s.checkRead (roots[i].path);
}
catch (SecurityException sx)
{
roots[i] = null;
count--;
}
}
if (count != roots.length)
{
File[] newRoots = new File[count];
int k = 0;
for (int i = 0; i < roots.length; i++)
{
if (roots[i] != null)
newRoots[k++] = roots[i];
}
roots = newRoots;
}
}
return roots;
}
/**
@@ -274,12 +274,7 @@ public final class FilePermission extends Permission implements Serializable
break;
default:
if (f2.charAt(f2.length() - 1) == File.separatorChar)
{
if (! f1.equals(f2.substring(0, f2.length() - 1)))
return false;
}
else if (!f1.equals(f2))
if (!f1.equals(f2))
return false;
break;
}
@@ -424,7 +424,23 @@ public class ObjectInputStream extends InputStream
clearHandles();
throw new WriteAbortedException("Exception thrown during writing of stream", e);
}
case TC_ENUM:
{
/* TC_ENUM classDesc newHandle enumConstantName */
if (dump)
dumpElementln("ENUM=");
ObjectStreamClass osc = (ObjectStreamClass) readObject();
String constantName = (String) readObject();
if (dump)
dumpElementln("CONSTANT NAME = " + constantName);
Class clazz = osc.forClass();
Enum instance = Enum.valueOf(clazz, constantName);
assignNewHandle(instance);
ret_val = instance;
break;
}
default:
throw new IOException("Unknown marker on stream: " + marker);
}
@@ -253,7 +253,17 @@ public class ObjectOutputStream extends OutputStream
ObjectStreamClass osc = ObjectStreamClass.lookupForClassObject(clazz);
if (osc == null)
throw new NotSerializableException(clazz.getName());
if (osc.isEnum())
{
/* TC_ENUM classDesc newHandle enumConstantName */
realOutput.writeByte(TC_ENUM);
writeObject(osc);
assignNewHandle(obj);
writeObject(((Enum) obj).name());
break;
}
if ((replacementEnabled || obj instanceof Serializable)
&& ! replaceDone)
{
@@ -432,7 +442,10 @@ public class ObjectOutputStream extends OutputStream
{
realOutput.writeByte(TC_CLASSDESC);
realOutput.writeUTF(osc.getName());
realOutput.writeLong(osc.getSerialVersionUID());
if (osc.isEnum())
realOutput.writeLong(0L);
else
realOutput.writeLong(osc.getSerialVersionUID());
assignNewHandle(osc);
int flags = osc.getFlags();
@@ -219,6 +219,12 @@ public class ObjectStreamClass implements Serializable
return (flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0;
}
// Returns true iff the class that this ObjectStreamClass represents
// implements Externalizable.
boolean isEnum()
{
return (flags & ObjectStreamConstants.SC_ENUM) != 0;
}
// Returns the <code>ObjectStreamClass</code> that represents the
// class that is the superclass of the class this
@@ -587,6 +593,9 @@ outer:
if (writeObjectMethod != null)
flags |= ObjectStreamConstants.SC_WRITE_METHOD;
if (cl.isEnum() || cl == Enum.class)
flags |= ObjectStreamConstants.SC_ENUM;
}
@@ -596,7 +605,7 @@ outer:
{
SetAccessibleAction setAccessible = new SetAccessibleAction();
if (!isSerializable() || isExternalizable())
if (!isSerializable() || isExternalizable() || isEnum())
{
fields = NO_FIELDS;
return;
@@ -50,8 +50,6 @@ package java.io;
*/
public interface ObjectStreamConstants
{
// FIXME: Javadoc comment these values.
/**
* The serialization stream protocol version 1. This version was
* the default serialization protocol before JDK 1.2.
@@ -70,37 +68,159 @@ public interface ObjectStreamConstants
*/
int PROTOCOL_VERSION_2 = 2;
/**
* The magic number that is written as part of the stream header.
*/
short STREAM_MAGIC = (short)0xaced;
/**
* The stream version number that is written as part of the stream header.
* Note that this is different from the protocol version that specifies
* the data format for the stream.
*/
short STREAM_VERSION = 5;
/**
* Token value to designate a <code>null</code> reference in the stream.
*/
byte TC_NULL = (byte)112; //0x70
/**
* Token value to designate a reference to an already serialized object.
*/
byte TC_REFERENCE = (byte)113; //0x71
/**
* Token value to designate a class descriptor is next in the stream.
*/
byte TC_CLASSDESC = (byte)114; //0x72
/**
* Token value to designate a new object is next in the stream.
*/
byte TC_OBJECT = (byte)115; //0x73
/**
* Token value to designate a new string is next in the stream.
*/
byte TC_STRING = (byte)116; //0x74
/**
* Token value to designate a new array is next in the stream.
*/
byte TC_ARRAY = (byte)117; //0x75
/**
* Token reference to designate a reference to a class.
*/
byte TC_CLASS = (byte)118; //0x76
/**
* Token value to designate a block of primitive data is next in the stream.
* The next byte in the stream holds the size of the block (in bytes).
*/
byte TC_BLOCKDATA = (byte)119; //0x77
/**
* Token value to designate the end of a block of primitve data.
*/
byte TC_ENDBLOCKDATA = (byte)120; //0x78
/**
* Token value to designate a reset of the stream state.
*/
byte TC_RESET = (byte)121; //0x79
/**
* Token value to designate a long block of primitive data is next in the
* stream. The next long in the stream holds the size of the block
* (in bytes).
*/
byte TC_BLOCKDATALONG = (byte)122; //0x7A
/**
* Token value to designate an exception occured during serialization.
*/
byte TC_EXCEPTION = (byte)123; //0x7B
/**
* Token value to designate a long string is next in the stream.
*/
byte TC_LONGSTRING = (byte)124; //0x7C
/**
* Token value to designate a proxy class descriptor is next in the stream.
*/
byte TC_PROXYCLASSDESC = (byte)125; //0x7D
/**
* Token value to designate an enum constant is next in the stream.
*
* @since 1.5
*/
byte TC_ENUM = (byte)126; //0x7E
/**
* The first token value.
*/
byte TC_BASE = TC_NULL;
byte TC_MAX = TC_PROXYCLASSDESC;
/**
* The last token value.
*/
byte TC_MAX = TC_ENUM;
/**
* The first handle that will be assigned to an object, for later references.
*/
int baseWireHandle = 0x7e0000;
/**
* Flag used in <code>ObjectStreamClass</code> to designate that the class
* defines the <code>writeObject</code> method.
*/
byte SC_WRITE_METHOD = 0x01;
/**
* Flag used in <code>ObjectStreamClass</code> to designate that the class
* is serializeable.
*/
byte SC_SERIALIZABLE = 0x02;
/**
* Flag used in <code>ObjectStreamClass</code> to designate that the class
* is externalizable.
*/
byte SC_EXTERNALIZABLE = 0x04;
/**
* Flag used in <code>ObjectStreamClass</code> to designate that
* externalizable data is written in block data mode.
*
* @since 1.2
*/
byte SC_BLOCK_DATA = 0x08;
/**
* Flag used in <code>ObjectStreamClass</code> to designate that the class
* is an enum constant.
*
* @since 1.5
*/
byte SC_ENUM = 0x10;
/**
* Constant for use with a <code>SecurityManager</code> to check if
* substitution of objects is allowed.
*/
SerializablePermission SUBSTITUTION_PERMISSION
= new SerializablePermission("enableSubstitution");
/**
* Constant for use with a <code>SecurityManager</code> to check if
* overriding of the <code>writeObject</code> and <code>readObject</code>
* methods is allowed.
*/
SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION
= new SerializablePermission("enableSubclassImplementation");
}
+2 -2
View File
@@ -1,5 +1,5 @@
/* OutputStream.java -- Base class for byte output streams
Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2001, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -48,7 +48,7 @@ package java.io;
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey (tromey@cygnus.com)
*/
public abstract class OutputStream
public abstract class OutputStream implements Closeable, Flushable
{
/**
* This is the default no-argument constructor for this class. This method
+72 -4
View File
@@ -87,8 +87,76 @@ public class PrintStream extends FilterOutputStream
private boolean auto_flush;
/**
* This method intializes a new <code>PrintStream</code> object to write
* to the specified output sink.
* This method initializes a new <code>PrintStream</code> object to write
* to the specified output File. Doesn't autoflush.
*
* @param file The <code>File</code> to write to.
* @throws FileNotFoundException if an error occurs while opening the file.
*
* @since 1.5
*/
public PrintStream (File file)
throws FileNotFoundException
{
this (new FileOutputStream(file), false);
}
/**
* This method initializes a new <code>PrintStream</code> object to write
* to the specified output File. Doesn't autoflush.
*
* @param file The <code>File</code> to write to.
* @param encoding The name of the character encoding to use for this
* object.
* @throws FileNotFoundException If an error occurs while opening the file.
* @throws UnsupportedEncodingException If the charset specified by
* <code>encoding</code> is invalid.
*
* @since 1.5
*/
public PrintStream (File file, String encoding)
throws FileNotFoundException,UnsupportedEncodingException
{
this (new FileOutputStream(file), false, encoding);
}
/**
* This method initializes a new <code>PrintStream</code> object to write
* to the specified output File. Doesn't autoflush.
*
* @param fileName The name of the <code>File</code> to write to.
* @throws FileNotFoundException if an error occurs while opening the file,
*
* @since 1.5
*/
public PrintStream (String fileName)
throws FileNotFoundException
{
this (new FileOutputStream(new File(fileName)), false);
}
/**
* This method initializes a new <code>PrintStream</code> object to write
* to the specified output File. Doesn't autoflush.
*
* @param fileName The name of the <code>File</code> to write to.
* @param encoding The name of the character encoding to use for this
* object.
* @throws FileNotFoundException if an error occurs while opening the file.
* @throws UnsupportedEncodingException If the charset specified by
* <code>encoding</code> is invalid.
*
* @since 1.5
*/
public PrintStream (String fileName, String encoding)
throws FileNotFoundException,UnsupportedEncodingException
{
this (new FileOutputStream(new File(fileName)), false, encoding);
}
/**
* This method initializes a new <code>PrintStream</code> object to write
* to the specified output sink. Doesn't autoflush.
*
* @param out The <code>OutputStream</code> to write to.
*/
@@ -98,7 +166,7 @@ public class PrintStream extends FilterOutputStream
}
/**
* This method intializes a new <code>PrintStream</code> object to write
* This method initializes a new <code>PrintStream</code> object to write
* to the specified output sink. This constructor also allows "auto-flush"
* functionality to be specified where the stream will be flushed after
* every <code>print</code> or <code>println</code> call, when the
@@ -127,7 +195,7 @@ public class PrintStream extends FilterOutputStream
}
/**
* This method intializes a new <code>PrintStream</code> object to write
* This method initializes a new <code>PrintStream</code> object to write
* to the specified output sink. This constructor also allows "auto-flush"
* functionality to be specified where the stream will be flushed after
* every <code>print</code> or <code>println</code> call, when the
+2 -1
View File
@@ -38,7 +38,8 @@ exception statement from your version. */
package java.lang;
import java.util.Iterator;
// We only need Iterator, but we import * to support lib/mkcollections.pl
import java.util.*;
/**
* This interface is used to indicate that a given class can be
@@ -421,7 +421,7 @@ public class SecurityManager
public void checkAccess(Thread thread)
{
if (thread.getThreadGroup() != null
&& thread.getThreadGroup().getParent() == null)
&& thread.getThreadGroup().parent == null)
checkPermission(new RuntimePermission("modifyThread"));
}
@@ -454,7 +454,7 @@ public class SecurityManager
*/
public void checkAccess(ThreadGroup g)
{
if (g.getParent() == null)
if (g.parent == null)
checkPermission(new RuntimePermission("modifyThreadGroup"));
}
+497 -1
View File
@@ -1,5 +1,5 @@
/* java.lang.StrictMath -- common mathematical functions, strict Java
Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -632,6 +632,227 @@ public final strictfp class StrictMath
return y > 0 ? PI - (z - PI_L) : z - PI_L - PI;
}
/**
* Returns the hyperbolic cosine of <code>x</code>, which is defined as
* (exp(x) + exp(-x)) / 2.
*
* Special cases:
* <ul>
* <li>If the argument is NaN, the result is NaN</li>
* <li>If the argument is positive infinity, the result is positive
* infinity.</li>
* <li>If the argument is negative infinity, the result is positive
* infinity.</li>
* <li>If the argument is zero, the result is one.</li>
* </ul>
*
* @param x the argument to <em>cosh</em>
* @return the hyperbolic cosine of <code>x</code>
*
* @since 1.5
*/
public static double cosh(double x)
{
// Method :
// mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
// 1. Replace x by |x| (cosh(x) = cosh(-x)).
// 2.
// [ exp(x) - 1 ]^2
// 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
// 2*exp(x)
//
// exp(x) + 1/exp(x)
// ln2/2 <= x <= 22 : cosh(x) := ------------------
// 2
// 22 <= x <= lnovft : cosh(x) := exp(x)/2
// lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
// ln2ovft < x : cosh(x) := +inf (overflow)
double t, w;
long bits;
int hx;
int lx;
// handle special cases
if (x != x)
return Double.NaN;
if (x == Double.POSITIVE_INFINITY)
return Double.POSITIVE_INFINITY;
if (x == Double.NEGATIVE_INFINITY)
return Double.POSITIVE_INFINITY;
bits = Double.doubleToLongBits(x);
hx = getHighDWord(bits) & 0x7fffffff; // ignore sign
lx = getLowDWord(bits);
// |x| in [0, 0.5 * ln(2)], return 1 + expm1(|x|)^2 / (2 * exp(|x|))
if (hx < 0x3fd62e43)
{
t = expm1(abs(x));
w = 1.0 + t;
// for tiny arguments return 1.
if (hx < 0x3c800000)
return w;
return 1.0 + (t * t) / (w + w);
}
// |x| in [0.5 * ln(2), 22], return exp(|x|)/2 + 1 / (2 * exp(|x|))
if (hx < 0x40360000)
{
t = exp(abs(x));
return 0.5 * t + 0.5 / t;
}
// |x| in [22, log(Double.MAX_VALUE)], return 0.5 * exp(|x|)
if (hx < 0x40862e42)
return 0.5 * exp(abs(x));
// |x| in [log(Double.MAX_VALUE), overflowthreshold],
// return exp(x/2)/2 * exp(x/2)
// we need to force an unsigned <= compare, thus can not use lx.
if ((hx < 0x408633ce)
|| ((hx == 0x408633ce)
&& ((bits & 0x00000000ffffffffL) <= 0x8fb9f87dL)))
{
w = exp(0.5 * abs(x));
t = 0.5 * w;
return t * w;
}
// |x| > overflowthreshold
return Double.POSITIVE_INFINITY;
}
/**
* Returns the lower two words of a long. This is intended to be
* used like this:
* <code>getLowDWord(Double.doubleToLongBits(x))</code>.
*/
private static int getLowDWord(long x)
{
return (int) (x & 0x00000000ffffffffL);
}
/**
* Returns the higher two words of a long. This is intended to be
* used like this:
* <code>getHighDWord(Double.doubleToLongBits(x))</code>.
*/
private static int getHighDWord(long x)
{
return (int) ((x & 0xffffffff00000000L) >> 32);
}
/**
* Returns a double with the IEEE754 bit pattern given in the lower
* and higher two words <code>lowDWord</code> and <code>highDWord</code>.
*/
private static double buildDouble(int lowDWord, int highDWord)
{
return Double.longBitsToDouble((((long) highDWord & 0xffffffffL) << 32)
| ((long) lowDWord & 0xffffffffL));
}
/**
* Returns the cube root of <code>x</code>. The sign of the cube root
* is equal to the sign of <code>x</code>.
*
* Special cases:
* <ul>
* <li>If the argument is NaN, the result is NaN</li>
* <li>If the argument is positive infinity, the result is positive
* infinity.</li>
* <li>If the argument is negative infinity, the result is negative
* infinity.</li>
* <li>If the argument is zero, the result is zero with the same
* sign as the argument.</li>
* </ul>
*
* @param x the number to take the cube root of
* @return the cube root of <code>x</code>
* @see #sqrt(double)
*
* @since 1.5
*/
public static double cbrt(double x)
{
boolean negative = (x < 0);
double r;
double s;
double t;
double w;
long bits;
int l;
int h;
// handle the special cases
if (x != x)
return Double.NaN;
if (x == Double.POSITIVE_INFINITY)
return Double.POSITIVE_INFINITY;
if (x == Double.NEGATIVE_INFINITY)
return Double.NEGATIVE_INFINITY;
if (x == 0)
return x;
x = abs(x);
bits = Double.doubleToLongBits(x);
if (bits < 0x0010000000000000L) // subnormal number
{
t = TWO_54;
t *= x;
// __HI(t)=__HI(t)/3+B2;
bits = Double.doubleToLongBits(t);
h = getHighDWord(bits);
l = getLowDWord(bits);
h = h / 3 + CBRT_B2;
t = buildDouble(l, h);
}
else
{
// __HI(t)=__HI(x)/3+B1;
h = getHighDWord(bits);
l = 0;
h = h / 3 + CBRT_B1;
t = buildDouble(l, h);
}
// new cbrt to 23 bits
r = t * t / x;
s = CBRT_C + r * t;
t *= CBRT_G + CBRT_F / (s + CBRT_E + CBRT_D / s);
// chopped to 20 bits and make it larger than cbrt(x)
bits = Double.doubleToLongBits(t);
h = getHighDWord(bits);
// __LO(t)=0;
// __HI(t)+=0x00000001;
l = 0;
h += 1;
t = buildDouble(l, h);
// one step newton iteration to 53 bits with error less than 0.667 ulps
s = t * t; // t * t is exact
r = x / s;
w = t + t;
r = (r - t) / (w + r); // r - s is exact
t = t + t * r;
return negative ? -t : t;
}
/**
* Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the
* argument is NaN, the result is NaN; if the argument is positive infinity,
@@ -693,6 +914,254 @@ public final strictfp class StrictMath
return scale(y, k);
}
/**
* Returns <em>e</em><sup>x</sup> - 1.
* Special cases:
* <ul>
* <li>If the argument is NaN, the result is NaN.</li>
* <li>If the argument is positive infinity, the result is positive
* infinity</li>
* <li>If the argument is negative infinity, the result is -1.</li>
* <li>If the argument is zero, the result is zero.</li>
* </ul>
*
* @param x the argument to <em>e</em><sup>x</sup> - 1.
* @return <em>e</em> raised to the power <code>x</code> minus one.
* @see #exp(double)
*/
public static double expm1(double x)
{
// Method
// 1. Argument reduction:
// Given x, find r and integer k such that
//
// x = k * ln(2) + r, |r| <= 0.5 * ln(2)
//
// Here a correction term c will be computed to compensate
// the error in r when rounded to a floating-point number.
//
// 2. Approximating expm1(r) by a special rational function on
// the interval [0, 0.5 * ln(2)]:
// Since
// r*(exp(r)+1)/(exp(r)-1) = 2 + r^2/6 - r^4/360 + ...
// we define R1(r*r) by
// r*(exp(r)+1)/(exp(r)-1) = 2 + r^2/6 * R1(r*r)
// That is,
// R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
// = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
// = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
// We use a special Remes algorithm on [0, 0.347] to generate
// a polynomial of degree 5 in r*r to approximate R1. The
// maximum error of this polynomial approximation is bounded
// by 2**-61. In other words,
// R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
// where Q1 = -1.6666666666666567384E-2,
// Q2 = 3.9682539681370365873E-4,
// Q3 = -9.9206344733435987357E-6,
// Q4 = 2.5051361420808517002E-7,
// Q5 = -6.2843505682382617102E-9;
// (where z=r*r, and Q1 to Q5 are called EXPM1_Qx in the source)
// with error bounded by
// | 5 | -61
// | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
// | |
//
// expm1(r) = exp(r)-1 is then computed by the following
// specific way which minimize the accumulation rounding error:
// 2 3
// r r [ 3 - (R1 + R1*r/2) ]
// expm1(r) = r + --- + --- * [--------------------]
// 2 2 [ 6 - r*(3 - R1*r/2) ]
//
// To compensate the error in the argument reduction, we use
// expm1(r+c) = expm1(r) + c + expm1(r)*c
// ~ expm1(r) + c + r*c
// Thus c+r*c will be added in as the correction terms for
// expm1(r+c). Now rearrange the term to avoid optimization
// screw up:
// ( 2 2 )
// ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
// expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
// ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
// ( )
//
// = r - E
// 3. Scale back to obtain expm1(x):
// From step 1, we have
// expm1(x) = either 2^k*[expm1(r)+1] - 1
// = or 2^k*[expm1(r) + (1-2^-k)]
// 4. Implementation notes:
// (A). To save one multiplication, we scale the coefficient Qi
// to Qi*2^i, and replace z by (x^2)/2.
// (B). To achieve maximum accuracy, we compute expm1(x) by
// (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
// (ii) if k=0, return r-E
// (iii) if k=-1, return 0.5*(r-E)-0.5
// (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
// else return 1.0+2.0*(r-E);
// (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
// (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
// (vii) return 2^k(1-((E+2^-k)-r))
boolean negative = (x < 0);
double y, hi, lo, c, t, e, hxs, hfx, r1;
int k;
long bits;
int h_bits;
int l_bits;
c = 0.0;
y = abs(x);
bits = Double.doubleToLongBits(y);
h_bits = getHighDWord(bits);
l_bits = getLowDWord(bits);
// handle special cases and large arguments
if (h_bits >= 0x4043687a) // if |x| >= 56 * ln(2)
{
if (h_bits >= 0x40862e42) // if |x| >= EXP_LIMIT_H
{
if (h_bits >= 0x7ff00000)
{
if (((h_bits & 0x000fffff) | (l_bits & 0xffffffff)) != 0)
return Double.NaN; // exp(NaN) = NaN
else
return negative ? -1.0 : x; // exp({+-inf}) = {+inf, -1}
}
if (x > EXP_LIMIT_H)
return Double.POSITIVE_INFINITY; // overflow
}
if (negative) // x <= -56 * ln(2)
return -1.0;
}
// argument reduction
if (h_bits > 0x3fd62e42) // |x| > 0.5 * ln(2)
{
if (h_bits < 0x3ff0a2b2) // |x| < 1.5 * ln(2)
{
if (negative)
{
hi = x + LN2_H;
lo = -LN2_L;
k = -1;
}
else
{
hi = x - LN2_H;
lo = LN2_L;
k = 1;
}
}
else
{
k = (int) (INV_LN2 * x + (negative ? - 0.5 : 0.5));
t = k;
hi = x - t * LN2_H;
lo = t * LN2_L;
}
x = hi - lo;
c = (hi - x) - lo;
}
else if (h_bits < 0x3c900000) // |x| < 2^-54 return x
return x;
else
k = 0;
// x is now in primary range
hfx = 0.5 * x;
hxs = x * hfx;
r1 = 1.0 + hxs * (EXPM1_Q1
+ hxs * (EXPM1_Q2
+ hxs * (EXPM1_Q3
+ hxs * (EXPM1_Q4
+ hxs * EXPM1_Q5))));
t = 3.0 - r1 * hfx;
e = hxs * ((r1 - t) / (6.0 - x * t));
if (k == 0)
{
return x - (x * e - hxs); // c == 0
}
else
{
e = x * (e - c) - c;
e -= hxs;
if (k == -1)
return 0.5 * (x - e) - 0.5;
if (k == 1)
{
if (x < - 0.25)
return -2.0 * (e - (x + 0.5));
else
return 1.0 + 2.0 * (x - e);
}
if (k <= -2 || k > 56) // sufficient to return exp(x) - 1
{
y = 1.0 - (e - x);
bits = Double.doubleToLongBits(y);
h_bits = getHighDWord(bits);
l_bits = getLowDWord(bits);
h_bits += (k << 20); // add k to y's exponent
y = buildDouble(l_bits, h_bits);
return y - 1.0;
}
t = 1.0;
if (k < 20)
{
bits = Double.doubleToLongBits(t);
h_bits = 0x3ff00000 - (0x00200000 >> k);
l_bits = getLowDWord(bits);
t = buildDouble(l_bits, h_bits); // t = 1 - 2^(-k)
y = t - (e - x);
bits = Double.doubleToLongBits(y);
h_bits = getHighDWord(bits);
l_bits = getLowDWord(bits);
h_bits += (k << 20); // add k to y's exponent
y = buildDouble(l_bits, h_bits);
}
else
{
bits = Double.doubleToLongBits(t);
h_bits = (0x000003ff - k) << 20;
l_bits = getLowDWord(bits);
t = buildDouble(l_bits, h_bits); // t = 2^(-k)
y = x - (e + t);
y += 1.0;
bits = Double.doubleToLongBits(y);
h_bits = getHighDWord(bits);
l_bits = getLowDWord(bits);
h_bits += (k << 20); // add k to y's exponent
y = buildDouble(l_bits, h_bits);
}
}
return y;
}
/**
* Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the
* argument is NaN or negative, the result is NaN; if the argument is
@@ -1428,6 +1897,33 @@ public final strictfp class StrictMath
AT9 = -0.036531572744216916, // Long bits 0xbfa2b4442c6a6c2fL.
AT10 = 0.016285820115365782; // Long bits 0x3f90ad3ae322da11L.
/**
* Constants for computing {@link #cbrt(double)}.
*/
private static final int
CBRT_B1 = 715094163, // B1 = (682-0.03306235651)*2**20
CBRT_B2 = 696219795; // B2 = (664-0.03306235651)*2**20
/**
* Constants for computing {@link #cbrt(double)}.
*/
private static final double
CBRT_C = 5.42857142857142815906e-01, // Long bits 0x3fe15f15f15f15f1L
CBRT_D = -7.05306122448979611050e-01, // Long bits 0xbfe691de2532c834L
CBRT_E = 1.41428571428571436819e+00, // Long bits 0x3ff6a0ea0ea0ea0fL
CBRT_F = 1.60714285714285720630e+00, // Long bits 0x3ff9b6db6db6db6eL
CBRT_G = 3.57142857142857150787e-01; // Long bits 0x3fd6db6db6db6db7L
/**
* Constants for computing {@link #expm1(double)}
*/
private static final double
EXPM1_Q1 = -3.33333333333331316428e-02, // Long bits 0xbfa11111111110f4L
EXPM1_Q2 = 1.58730158725481460165e-03, // Long bits 0x3f5a01a019fe5585L
EXPM1_Q3 = -7.93650757867487942473e-05, // Long bits 0xbf14ce199eaadbb7L
EXPM1_Q4 = 4.00821782732936239552e-06, // Long bits 0x3ed0cfca86e65239L
EXPM1_Q5 = -2.01099218183624371326e-07; // Long bits 0xbe8afdb76e09c32dL
/**
* Helper function for reducing an angle to a multiple of pi/2 within
* [-pi/4, pi/4].
+1 -1
View File
@@ -1820,7 +1820,7 @@ public final class String implements Serializable, Comparable, CharSequence
*/
public synchronized int codePointCount(int start, int end)
{
if (start < 0 || end >= count || start > end)
if (start < 0 || end > count || start > end)
throw new StringIndexOutOfBoundsException();
start += offset;
+31
View File
@@ -222,6 +222,36 @@ public final class System
return VMSystem.currentTimeMillis();
}
/**
* <p>
* Returns the current value of a nanosecond-precise system timer.
* The value of the timer is an offset relative to some arbitrary fixed
* time, which may be in the future (making the value negative). This
* method is useful for timing events where nanosecond precision is
* required. This is achieved by calling this method before and after the
* event, and taking the difference betweent the two times:
* </p>
* <p>
* <code>long startTime = System.nanoTime();</code><br />
* <code>... <emph>event code</emph> ...</code><br />
* <code>long endTime = System.nanoTime();</code><br />
* <code>long duration = endTime - startTime;</code><br />
* </p>
* <p>
* Note that the value is only nanosecond-precise, and not accurate; there
* is no guarantee that the difference between two values is really a
* nanosecond. Also, the value is prone to overflow if the offset
* exceeds 2^63.
* </p>
*
* @return the time of a system timer in nanoseconds.
* @since 1.5
*/
public static long nanoTime()
{
return VMSystem.nanoTime();
}
/**
* Copy one array onto another from <code>src[srcStart]</code> ...
* <code>src[srcStart+len-1]</code> to <code>dest[destStart]</code> ...
@@ -319,6 +349,7 @@ public final class System
* <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
* <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd>
* <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd>
* <dt>gnu.javax.print.server</dt> <dd>Hostname of external CUPS server.</dd>
* </dl>
*
* @return the system properties, will never be null
+168 -16
View File
@@ -38,8 +38,16 @@ exception statement from your version. */
package java.lang;
import gnu.classpath.VMStackWalker;
import gnu.java.util.WeakIdentityHashMap;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.security.Permission;
import java.util.HashMap;
import java.util.Map;
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
@@ -131,15 +139,16 @@ public class Thread implements Runnable
/** The context classloader for this Thread. */
private ClassLoader contextClassLoader;
private boolean contextClassLoaderIsSystemClassLoader;
/** This thread's ID. */
private final long threadId;
/** The next thread number to use. */
private static int numAnonymousThreadsCreated;
/** The next thread ID to use. */
private static long nextThreadId;
/** Used to generate the next thread ID to use. */
private static long totalThreadsCreated;
/** The default exception handler. */
private static UncaughtExceptionHandler defaultHandler;
@@ -248,7 +257,7 @@ public class Thread implements Runnable
*/
public Thread(ThreadGroup group, Runnable target)
{
this(group, target, "Thread-" + ++numAnonymousThreadsCreated, 0);
this(group, target, createAnonymousThreadName(), 0);
}
/**
@@ -347,8 +356,8 @@ public class Thread implements Runnable
if (group == null)
group = current.group;
}
else if (sm != null)
sm.checkAccess(group);
if (sm != null)
sm.checkAccess(group);
this.group = group;
// Use toString hack to detect null.
@@ -358,12 +367,14 @@ public class Thread implements Runnable
synchronized (Thread.class)
{
this.threadId = nextThreadId++;
this.threadId = ++totalThreadsCreated;
}
priority = current.priority;
daemon = current.daemon;
contextClassLoader = current.contextClassLoader;
contextClassLoaderIsSystemClassLoader =
current.contextClassLoaderIsSystemClassLoader;
group.addThread(this);
InheritableThreadLocal.newChildThread(this);
@@ -373,6 +384,9 @@ public class Thread implements Runnable
* Used by the VM to create thread objects for threads started outside
* of Java. Note: caller is responsible for adding the thread to
* a group and InheritableThreadLocal.
* Note: This constructor should not call any methods that could result
* in a call to Thread.currentThread(), because that makes life harder
* for the VM.
*
* @param vmThread the native thread
* @param name the thread name or null to use the default naming scheme
@@ -384,16 +398,32 @@ public class Thread implements Runnable
this.vmThread = vmThread;
this.runnable = null;
if (name == null)
name = "Thread-" + ++numAnonymousThreadsCreated;
name = createAnonymousThreadName();
this.name = name;
this.priority = priority;
this.daemon = daemon;
this.contextClassLoader = ClassLoader.getSystemClassLoader();
// By default the context class loader is the system class loader,
// we set a flag to signal this because we don't want to call
// ClassLoader.getSystemClassLoader() at this point, because on
// VMs that lazily create the system class loader that might result
// in running user code (when a custom system class loader is specified)
// and that user code could call Thread.currentThread().
// ClassLoader.getSystemClassLoader() can also return null, if the system
// is currently in the process of constructing the system class loader
// (and, as above, the constructiong sequence calls Thread.currenThread()).
contextClassLoaderIsSystemClassLoader = true;
synchronized (Thread.class)
{
this.threadId = nextThreadId++;
this.threadId = ++totalThreadsCreated;
}
}
/**
* Generate a name for an anonymous thread.
*/
private static synchronized String createAnonymousThreadName()
{
return "Thread-" + ++numAnonymousThreadsCreated;
}
/**
@@ -746,12 +776,18 @@ public class Thread implements Runnable
*/
public synchronized ClassLoader getContextClassLoader()
{
// Bypass System.getSecurityManager, for bootstrap efficiency.
ClassLoader loader = contextClassLoaderIsSystemClassLoader ?
ClassLoader.getSystemClassLoader() : contextClassLoader;
// Check if we may get the classloader
SecurityManager sm = SecurityManager.current;
if (sm != null)
// XXX Don't check this if the caller's class loader is an ancestor.
sm.checkPermission(new RuntimePermission("getClassLoader"));
return contextClassLoader;
if (loader != null && sm != null)
{
// Get the calling classloader
ClassLoader cl = VMStackWalker.getCallingClassLoader();
if (cl != null && !cl.isAncestorOf(loader))
sm.checkPermission(new RuntimePermission("getClassLoader"));
}
return loader;
}
/**
@@ -772,6 +808,7 @@ public class Thread implements Runnable
if (sm != null)
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
this.contextClassLoader = classloader;
contextClassLoaderIsSystemClassLoader = false;
}
/**
@@ -1173,7 +1210,7 @@ public class Thread implements Runnable
* @author Andrew John Hughes <gnu_andrew@member.fsf.org>
* @since 1.5
* @see Thread#getUncaughtExceptionHandler()
* @see Thread#setUncaughtExceptionHander(java.lang.Thread.UncaughtExceptionHandler)
* @see Thread#setUncaughtExceptionHandler(UncaughtExceptionHandler)
* @see Thread#getDefaultUncaughtExceptionHandler()
* @see
* Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)
@@ -1191,4 +1228,119 @@ public class Thread implements Runnable
*/
void uncaughtException(Thread thr, Throwable exc);
}
/**
* Returns the current state of the thread. This
* is designed for monitoring thread behaviour, rather
* than for synchronization control.
*
* @return the current thread state.
*/
public String getState()
{
VMThread t = vmThread;
if (t != null)
return t.getState();
if (group == null)
return "TERMINATED";
return "NEW";
}
/**
* <p>
* Returns a map of threads to stack traces for each
* live thread. The keys of the map are {@link Thread}
* objects, which map to arrays of {@link StackTraceElement}s.
* The results obtained from Calling this method are
* equivalent to calling {@link getStackTrace()} on each
* thread in succession. Threads may be executing while
* this takes place, and the results represent a snapshot
* of the thread at the time its {@link getStackTrace()}
* method is called.
* </p>
* <p>
* The stack trace information contains the methods called
* by the thread, with the most recent method forming the
* first element in the array. The array will be empty
* if the virtual machine can not obtain information on the
* thread.
* </p>
* <p>
* To execute this method, the current security manager
* (if one exists) must allow both the
* <code>"getStackTrace"</code> and
* <code>"modifyThreadGroup"</code> {@link RuntimePermission}s.
* </p>
*
* @return a map of threads to arrays of {@link StackTraceElement}s.
* @throws SecurityException if a security manager exists, and
* prevents either or both the runtime
* permissions specified above.
* @since 1.5
* @see #getStackTrace()
*/
public static Map getAllStackTraces()
{
ThreadGroup group = currentThread().group;
while (group.getParent() != null)
group = group.getParent();
int arraySize = group.activeCount();
Thread[] threadList = new Thread[arraySize];
int filled = group.enumerate(threadList);
while (filled == arraySize)
{
arraySize *= 2;
threadList = new Thread[arraySize];
filled = group.enumerate(threadList);
}
Map traces = new HashMap();
for (int a = 0; a < filled; ++a)
traces.put(threadList[a],
threadList[a].getStackTrace());
return traces;
}
/**
* <p>
* Returns an array of {@link StackTraceElement}s
* representing the current stack trace of this thread.
* The first element of the array is the most recent
* method called, and represents the top of the stack.
* The elements continue in this order, with the last
* element representing the bottom of the stack.
* </p>
* <p>
* A zero element array is returned for threads which
* have not yet started (and thus have not yet executed
* any methods) or for those which have terminated.
* Where the virtual machine can not obtain a trace for
* the thread, an empty array is also returned. The
* virtual machine may also omit some methods from the
* trace in non-zero arrays.
* </p>
* <p>
* To execute this method, the current security manager
* (if one exists) must allow both the
* <code>"getStackTrace"</code> and
* <code>"modifyThreadGroup"</code> {@link RuntimePermission}s.
* </p>
*
* @return a stack trace for this thread.
* @throws SecurityException if a security manager exists, and
* prevents the use of the
* <code>"getStackTrace"</code>
* permission.
* @since 1.5
* @see #getAllStackTraces()
*/
public StackTraceElement[] getStackTrace()
{
SecurityManager sm = SecurityManager.current; // Be thread-safe.
if (sm != null)
sm.checkPermission(new RuntimePermission("getStackTrace"));
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo info = bean.getThreadInfo(threadId, Integer.MAX_VALUE);
return info.getStackTrace();
}
}
+40 -1
View File
@@ -66,7 +66,7 @@ public class ThreadGroup implements UncaughtExceptionHandler
static boolean had_uncaught_exception;
/** The parent thread group. */
private final ThreadGroup parent;
final ThreadGroup parent;
/** The group name, non-null. */
final String name;
@@ -749,4 +749,43 @@ public class ThreadGroup implements UncaughtExceptionHandler
parent.removeGroup(this);
}
}
/*
* Helper method for the VM. Find a Thread by its Id.
*
* @param id The Thread Id.
* @return Thread object or null if thread doesn't exist.
*/
static Thread getThreadFromId(long id)
{
return root.getThreadFromIdImpl(id);
}
private Thread getThreadFromIdImpl(long id)
{
synchronized (threads)
{
for (int i = 0; i < threads.size(); i++)
{
Thread t = (Thread) threads.get(i);
if (t.getId() == id)
return t;
}
}
Vector groups = this.groups;
if (groups != null)
{
synchronized (groups)
{
for (int i = 0; i < groups.size(); i++)
{
ThreadGroup g = (ThreadGroup) groups.get(i);
Thread t = g.getThreadFromIdImpl(id);
if (t != null)
return t;
}
}
}
return null;
}
} // class ThreadGroup
@@ -0,0 +1,106 @@
/* IncompleteAnnotationException.java - Thrown when annotation has changed
Copyright (C) 2004 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.lang.annotation;
/**
* Thrown when accessing an element within an annotation which
* was added since compilation or serialization took place, and
* does not have a default value.
*
* @author Tom Tromey (tromey@redhat.com)
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.5
*/
public class IncompleteAnnotationException extends RuntimeException
{
/**
* Constructs a new <code>IncompleteAnnotationException</code>
* which indicates that the element, <code>name</code>, was missing
* from the annotation, <code>type</code> at compile time and does
* not have a default value.
*
* @param type the type of annotation from which an element is missing.
* @param name the name of the missing element.
*/
public IncompleteAnnotationException(Class type, String name)
{
this.annotationType = type;
this.elementName = name;
}
/**
* Returns the class representing the type of annotation
* from which an element was missing.
*
* @return the type of annotation.
*/
public Class annotationType()
{
return annotationType;
}
/**
* Returns the name of the missing annotation element.
*
* @return the element name.
*/
public String elementName()
{
return elementName;
}
// Names are chosen from serialization spec.
/**
* The class representing the type of annotation from
* which an element was found to be missing.
*
* @serial the type of the annotation from which an
* element was missing.
*/
private Class annotationType;
/**
* The name of the missing element.
*
* @serial the name of the missing element.
*/
private String elementName;
}
@@ -0,0 +1,103 @@
/* ClassLoadingMXBean.java - Interface for a class loading bean
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.lang.management;
/**
* Provides access to information about the class loading
* behaviour of the current invocation of the virtual
* machine. An instance of this bean is obtained by calling
* {@link ManagementFactory#getClassLoadingMXBean()}.
*
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.5
*/
public interface ClassLoadingMXBean
{
/**
* Returns the number of classes currently loaded by
* the virtual machine.
*
* @return the number of loaded classes.
*/
int getLoadedClassCount();
/**
* Returns the total number of classes loaded by the
* virtual machine since it was started. This is the
* sum of the currently loaded classes and those that
* have been unloaded.
*
* @return the total number of classes that have been
* loaded by the virtual machine since it started.
*/
long getTotalLoadedClassCount();
/**
* Returns the number of classes that have been unloaded
* by the virtual machine since it was started.
*
* @return the number of unloaded classes.
*/
long getUnloadedClassCount();
/**
* Returns true if the virtual machine will emit additional
* information when classes are loaded and unloaded. The
* format of the output is left up to the virtual machine.
*
* @return true if verbose class loading output is on.
*/
boolean isVerbose();
/**
* Turns on or off the emission of additional information
* when classes are loaded and unloaded. The format of the
* output is left up to the virtual machine. This method
* may be called by multiple threads concurrently, but there
* is only one global setting of verbosity that is affected.
*
* @param verbose the new setting for verbose class loading
* output.
* @throws SecurityException if a security manager exists and
* denies ManagementPermission("control").
*/
void setVerbose(boolean verbose);
}
@@ -0,0 +1,85 @@
/* CompilationMXBean.java - Interface for a compilation bean
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.lang.management;
/**
* Provides access to information about the Just-In-Time
* (JIT) compiler provided by the virtual machine, if one
* exists. An instance of this bean is obtainable by
* calling {@link ManagementFactory#getCompilationMXBean()}
* if a JIT is available. Otherwise, the method returns
* <code>null</code>.
*
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.5
*/
public interface CompilationMXBean
{
/**
* Returns the name of the Just-In-Time (JIT) compiler.
*
* @return the name of the JIT compiler.
*/
String getName();
/**
* Returns true if the virtual machine's JIT compiler
* supports monitoring of the time spent compiling.
*
* @return true if the JIT compiler can be monitored
* for time spent compiling.
*/
boolean isCompilationTimeMonitoringSupported();
/**
* Returns the accumulated time, in milliseconds, that
* the JIT compiler has spent compiling Java bytecodes
* to native machine code. This value represents a single
* time measurement for the whole virtual machine, including
* all multiple threads of operation. The value is not
* intended as a performance measurement.
*
* @return the accumulated number of milliseconds the JIT
* compiler has spent compiling.
* @throws UnsupportedOperationException if time monitoring
* is not supported.
*/
long getTotalCompilationTime();
}
@@ -0,0 +1,79 @@
/* GarbageCollectorMXBean.java - Interface for a garbage collector bean
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.lang.management;
/**
* Provides access to information about the garbage collectors
* of the virtual machine. Garbage collectors are responsible
* for removing unreferenced objects from memory. A garbage
* collector is a type of memory manager, so this interface
* is combined with that of generic memory managers. An instance
* of this bean for each garbage collector is obtained by calling
* {@link ManagementFactory#getGarbageCollectorMXBeans()}.
*
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.5
*/
public interface GarbageCollectorMXBean
extends MemoryManagerMXBean
{
/**
* Returns the number of collections the garbage collector
* represented by this bean has made. -1 is returned if the
* collection count is undefined.
*
* @return the number of collections made, or -1 if this is
* undefined.
*/
long getCollectionCount();
/**
* Returns the accumulated number of milliseconds this garbage
* collector has spent freeing the memory used by unreferenced
* objects. -1 is returned if the collection time is undefined.
* Note that the accumulated time may not change, even when the
* collection count increases, if the time taken is sufficiently
* short; this depends on the resolution of the timer used.
*
* @return the accumulated number of milliseconds spent collecting,
* or -1 if this is undefined.
*/
long getCollectionTime();
}
@@ -0,0 +1,331 @@
/* ManagementFactory.java - Factory for obtaining system beans.
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.lang.management;
import gnu.classpath.SystemProperties;
import gnu.java.lang.management.ClassLoadingMXBeanImpl;
import gnu.java.lang.management.CompilationMXBeanImpl;
import gnu.java.lang.management.GarbageCollectorMXBeanImpl;
import gnu.java.lang.management.OperatingSystemMXBeanImpl;
import gnu.java.lang.management.MemoryMXBeanImpl;
import gnu.java.lang.management.MemoryManagerMXBeanImpl;
import gnu.java.lang.management.MemoryPoolMXBeanImpl;
import gnu.java.lang.management.RuntimeMXBeanImpl;
import gnu.java.lang.management.ThreadMXBeanImpl;
import java.util.ArrayList;
import java.util.List;
import javax.management.NotCompliantMBeanException;
/**
* <p>
* Provides access to the system's management beans via a series
* of static methods.
* </p>
* <p>
* An instance of a system management bean can be obtained by
* using one of the following methods:
* </p>
* <ol>
* <li>Calling the appropriate static method of this factory.
* </li>
* </ol>
*
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.5
*/
public class ManagementFactory
{
/**
* The operating system management bean.
*/
private static OperatingSystemMXBean osBean;
/**
* The runtime management bean.
*/
private static RuntimeMXBean runtimeBean;
/**
* The class loading management bean.
*/
private static ClassLoadingMXBean classLoadingBean;
/**
* The thread bean.
*/
private static ThreadMXBean threadBean;
/**
* The memory bean.
*/
private static MemoryMXBean memoryBean;
/**
* The compilation bean (may remain null).
*/
private static CompilationMXBean compilationBean;
/**
* Private constructor to prevent instance creation.
*/
private ManagementFactory() {}
/**
* Returns the operating system management bean for the
* operating system on which the virtual machine is running.
*
* @return an instance of {@link OperatingSystemMXBean} for
* the underlying operating system.
*/
public static OperatingSystemMXBean getOperatingSystemMXBean()
{
if (osBean == null)
try
{
osBean = new OperatingSystemMXBeanImpl();
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"operating system bean is not a " +
"compliant management bean.");
}
return osBean;
}
/**
* Returns the runtime management bean for the
* running virtual machine.
*
* @return an instance of {@link RuntimeMXBean} for
* this virtual machine.
*/
public static RuntimeMXBean getRuntimeMXBean()
{
if (runtimeBean == null)
try
{
runtimeBean = new RuntimeMXBeanImpl();
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"runtime bean is not a compliant " +
"management bean.");
}
return runtimeBean;
}
/**
* Returns the class loading management bean for the
* running virtual machine.
*
* @return an instance of {@link ClassLoadingMXBean} for
* this virtual machine.
*/
public static ClassLoadingMXBean getClassLoadingMXBean()
{
if (classLoadingBean == null)
try
{
classLoadingBean = new ClassLoadingMXBeanImpl();
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"class loading bean is not a " +
"compliant management bean.");
}
return classLoadingBean;
}
/**
* Returns the thread management bean for the running
* virtual machine.
*
* @return an instance of {@link ThreadMXBean} for
* this virtual machine.
*/
public static ThreadMXBean getThreadMXBean()
{
if (threadBean == null)
try
{
threadBean = new ThreadMXBeanImpl();
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"thread bean is not a compliant " +
"management bean.");
}
return threadBean;
}
/**
* Returns the memory management bean for the running
* virtual machine.
*
* @return an instance of {@link MemoryMXBean} for
* this virtual machine.
*/
public static MemoryMXBean getMemoryMXBean()
{
if (memoryBean == null)
try
{
memoryBean = new MemoryMXBeanImpl();
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"memory bean is not a compliant " +
"management bean.");
}
return memoryBean;
}
/**
* Returns the compilation bean for the running
* virtual machine, if supported. Otherwise,
* it returns <code>null</code>.
*
* @return an instance of {@link CompilationMXBean} for
* this virtual machine, or <code>null</code>
* if the virtual machine doesn't include
* a Just-In-Time (JIT) compiler.
*/
public static CompilationMXBean getCompilationMXBean()
{
if (compilationBean == null &&
SystemProperties.getProperty("gnu.java.compiler.name") != null)
try
{
compilationBean = new CompilationMXBeanImpl();
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"compilation bean is not a compliant " +
"management bean.");
}
return compilationBean;
}
/**
* Returns the memory pool beans for the running
* virtual machine. These may change during the course
* of execution.
*
* @return a list of memory pool beans, one for each pool.
*/
public static List getMemoryPoolMXBeans()
{
List poolBeans = new ArrayList();
String[] names = VMManagementFactory.getMemoryPoolNames();
for (int a = 0; a < names.length; ++a)
try
{
poolBeans.add(new MemoryPoolMXBeanImpl(names[a]));
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"memory pool bean, " + a + ", is " +
"not a compliant management bean.");
}
return poolBeans;
}
/**
* Returns the memory manager beans for the running
* virtual machine. These may change during the course
* of execution.
*
* @return a list of memory manager beans, one for each manager.
*/
public static List getMemoryManagerMXBeans()
{
List managerBeans = new ArrayList();
String[] names = VMManagementFactory.getMemoryManagerNames();
for (int a = 0; a < names.length; ++a)
try
{
managerBeans.add(new MemoryManagerMXBeanImpl(names[a]));
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"memory manager bean, " + a + ", is " +
"not a compliant management bean.");
}
managerBeans.addAll(getGarbageCollectorMXBeans());
return managerBeans;
}
/**
* Returns the garbage collector beans for the running
* virtual machine. These may change during the course
* of execution.
*
* @return a list of garbage collector beans, one for each pool.
*/
public static List getGarbageCollectorMXBeans()
{
List gcBeans = new ArrayList();
String[] names = VMManagementFactory.getGarbageCollectorNames();
for (int a = 0; a < names.length; ++a)
try
{
gcBeans.add(new GarbageCollectorMXBeanImpl(names[a]));
}
catch (NotCompliantMBeanException e)
{
throw new InternalError("The GNU implementation of the " +
"garbage collector bean, " + a +
", is not a compliant management " +
"bean.");
}
return gcBeans;
}
}
@@ -0,0 +1,132 @@
/* ManagementPermission.java - Permissions for system management.
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.lang.management;
import java.security.BasicPermission;
/**
* <p>
* Represents the permission to view or modify the data
* which forms part of the system management interfaces.
* Calls to methods of the system management beans,
* provided by the {@link ManagementFactory}, may perform
* checks against the current {@link java.lang.SecurityManager}
* (if any) before allowing the operation to proceed.
* Instances of this object are supplied to the
* {@link java.lang.SecurityManager} in order to perform
* these checks. It is not normal for instances of this
* class to be created outside the use of the
* {@link java.lang.SecurityManager}.
* </p>
* <p>
* This object can represent two types of management
* permission:
* </p>
* <ul>
* <li><strong>monitor</strong> &mdash; this allows access
* to information such as the arguments supplied to the
* virtual machine, the currently loaded classes and the
* stack traces of running threads. Malicious code may
* use this to obtain information about the system and
* exploit any vulnerabilities found.</li>
* <li><strong>control</strong> &mdash; this allows the
* information stored by the management beans to be altered.
* For example, additional debugging information (such
* as class loading traces) may be turned on or memory
* usage limits changed. Malicious code could use
* this to alter the behaviour of the system.</li>
* </ul>
*
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @since 1.5
*/
public final class ManagementPermission
extends BasicPermission
{
/**
* Compatible with JDK 1.5
*/
private static final long serialVersionUID = 1897496590799378737L;
/**
* Constructs a new <code>ManagementPermission</code>
* for one of the two permission targets, "monitor"
* and "control".
*
* @param name the name of the permission this instance
* should represent; either "monitor" or
* "control".
* @throws IllegalArgumentException if the name is not
* either "monitor"
* or "control".
*/
public ManagementPermission(String name)
{
super(name);
if (!(name.equals("monitor") || name.equals("control")))
throw new IllegalArgumentException("Invalid permission.");
}
/**
* Constructs a new <code>ManagementPermission</code>
* for one of the two permission targets, "monitor"
* and "control". Actions are not supported, so
* this value should be either <code>null</code>
* or the empty string.
*
* @param name the name of the permission this instance
* should represent; either "monitor" or
* "control".
* @param actions either <code>null</code> or the
* empty string.
* @throws IllegalArgumentException if the name is not
* either "monitor"
* or "control", or
* a value for actions
* is specified.
*/
public ManagementPermission(String name, String actions)
{
this(name);
if (!(actions == null || actions.equals("")))
throw new IllegalArgumentException("Invalid actions.");
}
}

Some files were not shown because too many files have changed in this diff Show More