Imported GNU Classpath 0.90

Imported GNU Classpath 0.90
       * scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore.
       * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant.
       * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5.
       * java/lang/Math.java: New override file.
       * java/lang/Character.java: Merged from Classpath.
       (start, end): Now 'int's.
       (canonicalName): New field.
       (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants.
       (UnicodeBlock): Added argument.
       (of): New overload.
       (forName): New method.
       Updated unicode blocks.
       (sets): Updated.
       * sources.am: Regenerated.
       * Makefile.in: Likewise.

From-SVN: r111942
This commit is contained in:
Mark Wielaard 2006-03-10 21:46:48 +00:00
parent 27079765d0
commit 8aa540d2f7
1367 changed files with 188789 additions and 22762 deletions

View file

@ -40,14 +40,18 @@ package javax.swing;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.image.VolatileImage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
/**
@ -62,6 +66,7 @@ import java.util.WeakHashMap;
* href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">this
* document</a> for more details.</p>
*
* @author Roman Kennke (kennke@aicas.com)
* @author Graydon Hoare (graydon@redhat.com)
*/
public class RepaintManager
@ -69,8 +74,13 @@ public class RepaintManager
/**
* The current repaint managers, indexed by their ThreadGroups.
*/
static WeakHashMap currentRepaintManagers;
private static WeakHashMap currentRepaintManagers;
/**
* A rectangle object to be reused in damaged regions calculation.
*/
private static Rectangle rectCache = new Rectangle();
/**
* <p>A helper class which is placed into the system event queue at
* various times in order to facilitate repainting and layout. There is
@ -84,7 +94,7 @@ public class RepaintManager
* swing paint thread, which revalidates all invalid components and
* repaints any damage in the swing scene.</p>
*/
protected class RepaintWorker
private class RepaintWorker
implements Runnable
{
@ -107,12 +117,18 @@ public class RepaintManager
public void run()
{
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
RepaintManager rm =
(RepaintManager) currentRepaintManagers.get(threadGroup);
setLive(false);
rm.validateInvalidComponents();
rm.paintDirtyRegions();
try
{
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
RepaintManager rm =
(RepaintManager) currentRepaintManagers.get(threadGroup);
rm.validateInvalidComponents();
rm.paintDirtyRegions();
}
finally
{
setLive(false);
}
}
}
@ -135,41 +151,23 @@ public class RepaintManager
* @param o1 the first component
* @param o2 the second component
*
* @return a negative integer, if <code>o1</code> is higher in the
* hierarchy than <code>o2</code>, zero, if both are at the same
* level and a positive integer, if <code>o1</code> is deeper in
* the hierarchy than <code>o2</code>
* @return a negative integer, if <code>o1</code> is bigger in than
* <code>o2</code>, zero, if both are at the same size and a
* positive integer, if <code>o1</code> is smaller than
* <code>o2</code>
*/
public int compare(Object o1, Object o2)
{
if (o1 instanceof JComponent && o2 instanceof JComponent)
{
JComponent c1 = (JComponent) o1;
Rectangle d1 = (Rectangle) dirtyComponents.get(c1);
JComponent c2 = (JComponent) o2;
return getDepth(c1) - getDepth(c2);
Rectangle d2 = (Rectangle) dirtyComponents.get(c2);
return d2.width * d2.height - d1.width * d1.height;
}
else
throw new ClassCastException("This comparator can only be used with "
+ "JComponents");
}
/**
* Computes the depth for a given JComponent.
*
* @param c the component to compute the depth for
*
* @return the depth of the component
*/
private int getDepth(JComponent c)
{
Component comp = c;
int depth = 0;
while (comp != null)
{
comp = comp.getParent();
depth++;
}
return depth;
throw new ClassCastException("This comparator can only be used with "
+ "JComponents");
}
}
@ -179,6 +177,9 @@ public class RepaintManager
* to exactly one rectangle. When more regions are marked as dirty on a
* component, they are union'ed with the existing rectangle.
*
* This is package private to avoid a synthetic accessor method in inner
* class.
*
* @see #addDirtyRegion
* @see #getDirtyRegion
* @see #isCompletelyDirty
@ -187,18 +188,10 @@ public class RepaintManager
*/
HashMap dirtyComponents;
HashMap workDirtyComponents;
/**
* Stores the order in which the components get repainted.
*/
ArrayList repaintOrder;
ArrayList workRepaintOrder;
/**
* The comparator used for ordered inserting into the repaintOrder list.
*/
Comparator comparator;
private transient Comparator comparator;
/**
* A single, shared instance of the helper class. Any methods which mark
@ -209,7 +202,7 @@ public class RepaintManager
* @see #addDirtyRegion
* @see #addInvalidComponent
*/
RepaintWorker repaintWorker;
private RepaintWorker repaintWorker;
/**
* The set of components which need revalidation, in the "layout" sense.
@ -221,8 +214,7 @@ public class RepaintManager
* @see #removeInvalidComponent
* @see #validateInvalidComponents
*/
ArrayList invalidComponents;
ArrayList workInvalidComponents;
private ArrayList invalidComponents;
/**
* Whether or not double buffering is enabled on this repaint
@ -232,17 +224,27 @@ public class RepaintManager
* @see #isDoubleBufferingEnabled
* @see #setDoubleBufferingEnabled
*/
boolean doubleBufferingEnabled;
private boolean doubleBufferingEnabled;
/**
* The current offscreen buffer. This is reused for all requests for
* offscreen drawing buffers. It grows as necessary, up to {@link
* #doubleBufferMaximumSize}, but there is only one shared instance.
*
* @see #getOffscreenBuffer
* @see #doubleBufferMaximumSize
/**
* The offscreen buffers. This map holds one offscreen buffer per
* Window/Applet and releases them as soon as the Window/Applet gets garbage
* collected.
*/
Image doubleBuffer;
private WeakHashMap offscreenBuffers;
/**
* Indicates if the RepaintManager is currently repainting an area.
*/
private boolean repaintUnderway;
/**
* This holds buffer commit requests when the RepaintManager is working.
* This maps Component objects (the top level components) to Rectangle
* objects (the area of the corresponding buffer that must be blitted on
* the component).
*/
private HashMap commitRequests;
/**
* The maximum width and height to allocate as a double buffer. Requests
@ -252,7 +254,7 @@ public class RepaintManager
* @see #getDoubleBufferMaximumSize
* @see #setDoubleBufferMaximumSize
*/
Dimension doubleBufferMaximumSize;
private Dimension doubleBufferMaximumSize;
/**
@ -261,14 +263,13 @@ public class RepaintManager
public RepaintManager()
{
dirtyComponents = new HashMap();
workDirtyComponents = new HashMap();
repaintOrder = new ArrayList();
workRepaintOrder = new ArrayList();
invalidComponents = new ArrayList();
workInvalidComponents = new ArrayList();
repaintWorker = new RepaintWorker();
doubleBufferMaximumSize = new Dimension(2000,2000);
doubleBufferingEnabled = true;
offscreenBuffers = new WeakHashMap();
repaintUnderway = false;
commitRequests = new HashMap();
}
/**
@ -346,9 +347,9 @@ public class RepaintManager
*
* @see #removeInvalidComponent
*/
public synchronized void addInvalidComponent(JComponent component)
public void addInvalidComponent(JComponent component)
{
Component ancestor = component.getParent();
Component ancestor = component;
while (ancestor != null
&& (! (ancestor instanceof JComponent)
@ -363,8 +364,11 @@ public class RepaintManager
if (invalidComponents.contains(component))
return;
invalidComponents.add(component);
synchronized (invalidComponents)
{
invalidComponents.add(component);
}
if (! repaintWorker.isLive())
{
repaintWorker.setLive(true);
@ -379,9 +383,12 @@ public class RepaintManager
*
* @see #addInvalidComponent
*/
public synchronized void removeInvalidComponent(JComponent component)
public void removeInvalidComponent(JComponent component)
{
invalidComponents.remove(component);
synchronized (invalidComponents)
{
invalidComponents.remove(component);
}
}
/**
@ -402,38 +409,37 @@ public class RepaintManager
* @see #markCompletelyClean
* @see #markCompletelyDirty
*/
public synchronized void addDirtyRegion(JComponent component, int x, int y,
int w, int h)
public void addDirtyRegion(JComponent component, int x, int y,
int w, int h)
{
if (w == 0 || h == 0 || !component.isShowing())
if (w <= 0 || h <= 0 || !component.isShowing())
return;
Rectangle r = new Rectangle(x, y, w, h);
if (dirtyComponents.containsKey(component))
r = r.union((Rectangle)dirtyComponents.get(component));
else
insertInRepaintOrder(component);
dirtyComponents.put(component, r);
if (! repaintWorker.isLive())
{
repaintWorker.setLive(true);
SwingUtilities.invokeLater(repaintWorker);
}
}
/**
* Inserts a component into the repaintOrder list in an ordered fashion,
* using a binary search.
*
* @param c the component to be inserted
*/
private void insertInRepaintOrder(JComponent c)
{
if (comparator == null)
comparator = new ComponentComparator();
int insertIndex = Collections.binarySearch(repaintOrder, c, comparator);
if (insertIndex < 0)
insertIndex = -(insertIndex + 1);
repaintOrder.add(insertIndex, c);
component.computeVisibleRect(rectCache);
SwingUtilities.computeIntersection(x, y, w, h, rectCache);
if (! rectCache.isEmpty())
{
if (dirtyComponents.containsKey(component))
{
SwingUtilities.computeUnion(rectCache.x, rectCache.y,
rectCache.width, rectCache.height,
(Rectangle) dirtyComponents.get(component));
}
else
{
synchronized (dirtyComponents)
{
dirtyComponents.put(component, rectCache.getBounds());
}
}
if (! repaintWorker.isLive())
{
repaintWorker.setLive(true);
SwingUtilities.invokeLater(repaintWorker);
}
}
}
/**
@ -489,7 +495,7 @@ public class RepaintManager
*/
public void markCompletelyClean(JComponent component)
{
synchronized (this)
synchronized (dirtyComponents)
{
dirtyComponents.remove(component);
}
@ -523,63 +529,58 @@ public class RepaintManager
*/
public void validateInvalidComponents()
{
// In order to keep the blocking of application threads minimal, we switch
// the invalidComponents field with the workInvalidComponents field and
// work with the workInvalidComponents field.
synchronized(this)
{
ArrayList swap = invalidComponents;
invalidComponents = workInvalidComponents;
workInvalidComponents = swap;
}
for (Iterator i = workInvalidComponents.iterator(); i.hasNext(); )
// We don't use an iterator here because that would fail when there are
// components invalidated during the validation of others, which happens
// quite frequently. Instead we synchronize the access a little more.
while (invalidComponents.size() > 0)
{
Component comp = (Component) i.next();
// Find validate root.
while ((!(comp instanceof JComponent)
|| !((JComponent) comp).isValidateRoot())
&& comp.getParent() != null)
comp = comp.getParent();
// Validate the validate root.
Component comp;
synchronized (invalidComponents)
{
comp = (Component) invalidComponents.remove(0);
}
// Validate the validate component.
if (! (comp.isVisible() && comp.isShowing()))
continue;
comp.validate();
}
workInvalidComponents.clear();
}
/**
* Repaint all regions of all components which have been marked dirty in
* the {@link #dirtyComponents} table.
*/
public synchronized void paintDirtyRegions()
public void paintDirtyRegions()
{
// In order to keep the blocking of application threads minimal, we switch
// the dirtyComponents field with the workdirtyComponents field and the
// repaintOrder field with the workRepaintOrder field and work with the
// work* fields.
synchronized(this)
{
ArrayList swap = workRepaintOrder;
workRepaintOrder = repaintOrder;
repaintOrder = swap;
HashMap swap2 = workDirtyComponents;
workDirtyComponents = dirtyComponents;
dirtyComponents = swap2;
}
for (Iterator i = workRepaintOrder.iterator(); i.hasNext();)
// Short cicuit if there is nothing to paint.
if (dirtyComponents.size() == 0)
return;
synchronized (dirtyComponents)
{
JComponent comp = (JComponent) i.next();
// If a component is marked completely clean in the meantime, then skip
// it.
Rectangle damaged = (Rectangle) workDirtyComponents.get(comp);
if (damaged == null || damaged.isEmpty())
continue;
comp.paintImmediately(damaged);
// We sort the components by their size here. This way we have a good
// chance that painting the bigger components also paints the smaller
// components and we don't need to paint them twice.
ArrayList repaintOrder = new ArrayList(dirtyComponents.size());
repaintOrder.addAll(dirtyComponents.keySet());
if (comparator == null)
comparator = new ComponentComparator();
Collections.sort(repaintOrder, comparator);
repaintUnderway = true;
for (Iterator i = repaintOrder.iterator(); i.hasNext();)
{
JComponent comp = (JComponent) i.next();
// If a component is marked completely clean in the meantime, then skip
// it.
Rectangle damaged = (Rectangle) dirtyComponents.get(comp);
if (damaged == null || damaged.isEmpty())
continue;
comp.paintImmediately(damaged);
dirtyComponents.remove(comp);
}
repaintUnderway = false;
commitRemainingBuffers();
}
workRepaintOrder.clear();
workDirtyComponents.clear();
}
/**
@ -592,21 +593,114 @@ public class RepaintManager
* @param proposedHeight The proposed height of the offscreen buffer
*
* @return A shared offscreen buffer for painting
*
* @see #doubleBuffer
*/
public Image getOffscreenBuffer(Component component, int proposedWidth,
int proposedHeight)
{
if (doubleBuffer == null
|| (((doubleBuffer.getWidth(null) < proposedWidth)
|| (doubleBuffer.getHeight(null) < proposedHeight))
&& (proposedWidth < doubleBufferMaximumSize.width)
&& (proposedHeight < doubleBufferMaximumSize.height)))
Component root = SwingUtilities.getRoot(component);
Image buffer = (Image) offscreenBuffers.get(root);
if (buffer == null
|| buffer.getWidth(null) < proposedWidth
|| buffer.getHeight(null) < proposedHeight)
{
doubleBuffer = component.createImage(proposedWidth, proposedHeight);
int width = Math.max(proposedWidth, root.getWidth());
width = Math.min(doubleBufferMaximumSize.width, width);
int height = Math.max(proposedHeight, root.getHeight());
height = Math.min(doubleBufferMaximumSize.height, height);
buffer = component.createImage(width, height);
offscreenBuffers.put(root, buffer);
}
return buffer;
}
/**
* Blits the back buffer of the specified root component to the screen. If
* the RepaintManager is currently working on a paint request, the commit
* requests are queued up and committed at once when the paint request is
* done (by {@link #commitRemainingBuffers}). This is package private because
* it must get called by JComponent.
*
* @param root the component, either a Window or an Applet instance
* @param area the area to paint on screen
*/
void commitBuffer(Component root, Rectangle area)
{
// We synchronize on dirtyComponents here because that is what
// paintDirtyRegions also synchronizes on while painting.
synchronized (dirtyComponents)
{
// If the RepaintManager is not currently painting, then directly
// blit the requested buffer on the screen.
if (! repaintUnderway)
{
Graphics g = root.getGraphics();
Image buffer = (Image) offscreenBuffers.get(root);
Rectangle clip = g.getClipBounds();
if (clip != null)
area = SwingUtilities.computeIntersection(clip.x, clip.y,
clip.width, clip.height,
area);
int dx1 = area.x;
int dy1 = area.y;
int dx2 = area.x + area.width;
int dy2 = area.y + area.height;
// Make sure we have a sane clip at this point.
g.clipRect(area.x, area.y, area.width, area.height);
// Make sure the coordinates are inside the buffer, everything else
// might lead to problems.
// TODO: This code should not really be necessary, however, in fact
// we have two issues here:
// 1. We shouldn't get repaint requests in areas outside the buffer
// region in the first place. This still happens for example
// when a component is inside a JViewport, and the component has
// a size that would reach beyond the window size.
// 2. Graphics.drawImage() should not behave strange when trying
// to draw regions outside the image.
int bufferWidth = buffer.getWidth(root);
int bufferHeight = buffer.getHeight(root);
dx1 = Math.min(bufferWidth, dx1);
dy1 = Math.min(bufferHeight, dy1);
dx2 = Math.min(bufferWidth, dx2);
dy2 = Math.min(bufferHeight, dy2);
g.drawImage(buffer, dx1, dy1, dx2, dy2,
dx1, dy1, dx2, dy2, root);
g.dispose();
}
// Otherwise queue this request up, until all the RepaintManager work
// is done.
else
{
if (commitRequests.containsKey(root))
SwingUtilities.computeUnion(area.x, area.y, area.width,
area.height,
(Rectangle) commitRequests.get(root));
else
commitRequests.put(root, area);
}
}
}
/**
* Commits the queued up back buffers to screen all at once.
*/
private void commitRemainingBuffers()
{
// We synchronize on dirtyComponents here because that is what
// paintDirtyRegions also synchronizes on while painting.
synchronized (dirtyComponents)
{
Set entrySet = commitRequests.entrySet();
Iterator i = entrySet.iterator();
while (i.hasNext())
{
Map.Entry entry = (Map.Entry) i.next();
Component root = (Component) entry.getKey();
Rectangle area = (Rectangle) entry.getValue();
commitBuffer(root, area);
i.remove();
}
}
return doubleBuffer;
}
/**