/*
* @(#)Region.java 1.2 02/08/21
*
* Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved.
*/
package com.sun.media.ui;
import java.awt.Rectangle;
import java.util.Vector;
import java.util.Enumeration;
import java.lang.Cloneable;
import java.io.Serializable;
class Region implements Cloneable, Serializable {
/**
* List of rectangles that make up the region.
*/
protected Vector rects;
/**
* Create a new region with no rectangles.
*/
public Region() {
rects = new Vector();
}
/**
* Create a region with one rectangle in it.
*/
public Region(Rectangle r) {
rects = new Vector();
addRectangle(r);
}
/**
* Create a region with two rectangles. Useful for moving-sprites
* which need to invalidate old and new positions.
*/
public Region(Rectangle r1, Rectangle r2) {
rects = new Vector();
addRectangle(r1);
addRectangle(r2);
}
/**
* Returns true if the region contains no rectangles.
*/
public boolean isEmpty() {
return rects.isEmpty();
}
public int getNumRectangles() {
return rects.size();
}
/**
* Returns an Enumeration of the list of rectangles.
*/
public java.util.Enumeration rectangles() {
return rects.elements();
}
/**
* Returns a clone of the region.
*/
public Object clone() {
Region r = new Region();
r.rects = (Vector)rects.clone();
return r;
}
public Rectangle getBounds() {
Rectangle r = new Rectangle();
for (int i = 0; i < rects.size(); i++) {
r = r.union((Rectangle)rects.elementAt(i));
}
return r;
}
/**
* Adds a rectangle to the region. This method checks for intersecting
* rectangles and merges them into one.
*/
public void addRectangle(Rectangle r) {
Rectangle current;
int position = 0;
while (position < rects.size())
{
current = (Rectangle)rects.elementAt(position);
// First check to see if the current rectangle
// already includes the new one
if ((r.x > current.x) && (r.y > current.y) &&
(right(r) <= right(current)) &&
(bottom(r) <= bottom(current)))
return;
if (r.intersects(current))
{
r = r.union(current);
rects.removeElementAt(position);
} else {
position++;
}
}
// Add it to the end of the list
rects.addElement(r);
}
/**
* Checks if the rectangle <b>r</b> intersects any of the rectangles
* in the region.
*/
public boolean intersects(Rectangle r) {
Rectangle rect;
int position = 0;
while (position < rects.size()) {
rect = (Rectangle)rects.elementAt(position);
if (rect.intersects(r)) {
return true;
}
position++;
}
return false;
}
/**
* Intersects all the rectangles in the region with rectangle <b>r</b>
* and throws away any that dont intersect.
*/
public void intersect(Rectangle r) {
Rectangle rect;
int position = 0;
while (position < rects.size()) {
rect = (Rectangle)rects.elementAt(position);
rect = rect.intersection(r);
if (rect.isEmpty()) {
rects.removeElementAt(position);
} else {
rects.setElementAt(rect, position);
position++;
}
}
}
/**
* Adds a region <b>r</b> to the current region.
*/
public void addRegion(Region r) {
for (Enumeration e = r.rectangles(); e.hasMoreElements(); )
{
addRectangle((Rectangle)e.nextElement());
}
}
/**
* Translates all rectangles in the region by (dx,dy).
*/
public void translate(int dx, int dy) {
Rectangle r;
for (int p = 0; p < rects.size(); p++) {
r = (Rectangle)rects.elementAt(p);
r.translate(dx, dy);
}
}
/**
* Converts the list of rectangles to a displayable string.
*/
public String toString() {
String s = getClass().getName() + " = [\n";
for (Enumeration e = rectangles(); e.hasMoreElements(); )
{
s += "(" + (Rectangle)e.nextElement() + ")\n";
}
return s + "]";
}
/**
* Returns the x-coordinate of the right edge of a rectangle.
*/
public static int right(Rectangle r) {
return r.x + r.width - 1;
}
/**
* Returns the y-coordinate of the bottom edge of a rectangle.
*/
public static int bottom(Rectangle r) {
return r.y + r.height - 1;
}
}
|