RichEdit control classes

X-SVN-Rev: 1181
This commit is contained in:
Alan Liu 2000-04-20 17:33:31 +00:00
parent 5f7a92e6c0
commit 5cfa36a1fe
4 changed files with 1748 additions and 0 deletions

View File

@ -0,0 +1,529 @@
/*
* @(#)$RCSfile: AttributeMap.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:33:31 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
// Requires Java2
package com.ibm.textlayout.attributes;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.io.Externalizable;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.IOException;
/**
* AttributeMap is an immutable Map. Additionally, there are
* several methods for common operations (union,
* remove, intersect); these methods return new AttributeMap
* instances.
* <p>
* Although any non-null Object can be a key or value in an
* AttributeMap, typically the keys are fields of TextAttribute.
* @see TextAttribute
*/
public final class AttributeMap implements java.util.Map,
com.ibm.textlayout.attributes.Map,
Externalizable {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
private static final int CURRENT_VERSION = 1;
private static final long serialVersionUID = 9510803;
private static final String errString = "StyleSets are immutable.";
// This is passed to the Hashtable constructor as the
// load factor argument. It is chosen to avoid resizing
// the Hashtable whenever possible. I think that 1
// does this.
private static final int LOAD_FACTOR = 1;
private Hashtable styleTable;
private transient AttributeSet cachedKeySet = null;
private transient Collection cachedValueCollection = null;
private transient Set cachedEntrySet = null;
/**
* An empty AttributeMap.
*/
public static final AttributeMap EMPTY_ATTRIBUTE_MAP = new AttributeMap();
// ==============
// Constructors
// ==============
/**
* Create a new, empty AttributeMap. EMPTY_STYLE_SET can be used
* in place of an AttributeMap produced by this constructor.
*/
public AttributeMap() {
styleTable = new Hashtable(1, LOAD_FACTOR);
}
/**
* Create an AttributeMap with the same key-value
* entries as the given Map.
* @param map a Map whose key-value entries will
* become the entries for this AttributeMap. <code>map</code>
* is not modified, and must not contain null keys or values.
*/
public AttributeMap(java.util.Map map) {
styleTable = new Hashtable(map.size(), LOAD_FACTOR);
styleTable.putAll(map);
}
/**
* Create an AttributeMap with the same key-value
* entries as the given Hashtable.
* @param table a Hashtable whose key-value entries will
* become the entries for this AttributeMap. <code>table</code>
* is not modified.
*/
public AttributeMap(Hashtable hashtable) {
this((java.util.Map) hashtable);
}
/**
* Create an AttributeMap with a single entry of
* <code>{attribute, value}</code>.
* @param attribute the key in this AttributeMap's single entry
* @param value the value in this AttributeMap's single entry
*/
public AttributeMap(Object key, Object value) {
styleTable = new Hashtable(1, LOAD_FACTOR);
// hashtable checks value for null
styleTable.put(key, value);
}
// For internal use only.
private AttributeMap(Hashtable table, boolean clone) {
if (clone) {
styleTable = (Hashtable) table.clone();
}
else {
this.styleTable = table;
}
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(CURRENT_VERSION);
out.writeInt(styleTable.size());
Enumeration e = styleTable.keys();
while (e.hasMoreElements()) {
Object key = e.nextElement();
out.writeObject(AttributeKey.mapAttributeToKey(key));
out.writeObject(styleTable.get(key));
}
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
if (in.readInt() != CURRENT_VERSION) {
throw new IOException("Invalid version of StyleBuffer");
}
int count = in.readInt();
for (int i=0; i < count; i += 1) {
Object key = AttributeKey.mapKeyToAttribute(in.readObject());
Object value = in.readObject();
styleTable.put(key, value);
}
}
// ==============
// Map interface
// ==============
// queries
/**
* Return the number of entries in the AttributeMap.
* @return the number of entries in the AttributeMap
*/
public int size() {
return styleTable.size();
}
/**
* Return true if the number of entries in the AttributeMap
* is 0.
* @return true if the number of entries in the AttributeMap
* is 0
*/
public boolean isEmpty() {
return styleTable.isEmpty();
}
/**
* Return true if the given key is in this AttributeMap.
* @param key the key to test
* @return true if <code>key</code> is in this AttributeMap
*/
public boolean containsKey(Object key) {
return styleTable.containsKey(key);
}
/**
* Return true if the given value is in this AttributeMap.
* @param key the value to test
* @return true if <code>value</code> is in this AttributeMap
*/
public boolean containsValue(Object value) {
return styleTable.containsValue(value);
}
/**
* Return the value associated with the given key. If the
* key is not in this AttributeMap null is returned.
* @param key the key to look up
* @return the value associated with <code>key</code>, or
* null if <code>key</code> is not in this AttributeMap
*/
public Object get(Object key) {
return styleTable.get(key);
}
// modifiers - all throw exceptions
/**
* Throws UnsupportedOperationException.
* @see #addAttribute
* @throws UnsupportedOperationException
*/
public Object put(Object key, Object value) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #removeAttributes
* @throws UnsupportedOperationException
*/
public Object remove(Object key) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #addAttributes
* @throws UnsupportedOperationException
*/
public void putAll(java.util.Map t) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #EMPTY_ATTRIBUTE_MAP
* @throws UnsupportedOperationException
*/
public void clear() {
throw new UnsupportedOperationException(errString);
}
// views
/**
* Return an AttributeSet containing every key in this AttributeMap.
* @return an AttributeSet containing every key in this AttributeMap
*/
public Set keySet() {
return getKeySet();
}
/**
* Return an AttributeSet containing every key in this AttributeMap.
* @return an AttributeSet containing every key in this AttributeMap
*/
public AttributeSet getKeySet() {
AttributeSet result = cachedKeySet;
if (result == null) {
result = AttributeSet.createKeySet(styleTable);
cachedKeySet = result;
}
return result;
}
/**
* Return a Collection containing every value in this AttributeMap.
* @return a Collection containing every value in this AttributeMap
*/
public Collection values() {
Collection result = cachedValueCollection;
if (result == null) {
result = Collections.unmodifiableCollection(styleTable.values());
cachedValueCollection = result;
}
return result;
}
/**
* Return a Set containing all entries in this AttributeMap.
*/
public Set entrySet() {
Set result = cachedEntrySet;
if (result == null) {
result = Collections.unmodifiableSet(styleTable.entrySet());
cachedEntrySet = result;
}
return result;
}
public boolean equals(Object rhs) {
if (rhs == this) {
return true;
}
if (rhs == null) {
return false;
}
AttributeMap rhsStyleSet = null;
try {
rhsStyleSet = (AttributeMap) rhs;
}
catch(ClassCastException e) {
return false;
}
return styleTable.equals(rhsStyleSet.styleTable);
}
public int hashCode() {
return styleTable.hashCode();
}
public String toString() {
return styleTable.toString();
}
// ==============
// Operations
// ==============
/**
* Return a AttributeMap which contains entries in this AttributeMap,
* along with an entry for <attribute, value>. If attribute
* is already present in this AttributeMap its value becomes value.
*/
public AttributeMap addAttribute(Object key, Object value) {
// try to optimize for case where <key, value> is already there?
Hashtable newTable = new Hashtable(styleTable.size() + 1, LOAD_FACTOR);
newTable.putAll(styleTable);
newTable.put(key, value);
return new AttributeMap(newTable, false);
}
/**
* Return a AttributeMap which contains entries in this AttributeMap
* and in rhs. If an attribute appears in both StyleSets the
* value from rhs is used.
*/
public AttributeMap addAttributes(AttributeMap rhs) {
int thisSize = size();
if (thisSize == 0) {
return rhs;
}
int otherSize = rhs.size();
if (otherSize == 0) {
return this;
}
Hashtable newTable = new Hashtable(thisSize + otherSize, LOAD_FACTOR);
newTable.putAll(styleTable);
newTable.putAll(rhs);
return new AttributeMap(newTable, false);
}
/**
* Return a AttributeMap which contains entries in this AttributeMap
* and in rhs. If an attribute appears in both StyleSets the
* value from rhs is used.
* The Map's keys and values must be non-null.
*/
public AttributeMap addAttributes(java.util.Map rhs) {
if (rhs instanceof AttributeMap) {
return addAttributes((AttributeMap)rhs);
}
Hashtable newTable = new Hashtable(size() + rhs.size(), LOAD_FACTOR);
newTable.putAll(styleTable);
newTable.putAll(rhs);
return new AttributeMap(newTable, false);
}
/**
* Return a AttributeMap with the entries in this AttributeMap, but
* without attribute as a key.
*/
public AttributeMap removeAttribute(Object attribute) {
if (!containsKey(attribute)) {
return this;
}
Hashtable newTable = new Hashtable(styleTable.size(), LOAD_FACTOR);
newTable.putAll(styleTable);
newTable.remove(attribute);
return new AttributeMap(newTable, false);
}
/**
* Return a AttributeMap with the entries of this AttributeMap whose
* attributes are <b>not</b> in the Set.
*/
public AttributeMap removeAttributes(AttributeSet attributes) {
Set set = attributes;
return removeAttributes(set);
}
/**
* Return a AttributeMap with the entries of this AttributeMap whose
* attributes are <b>not</b> in the Set.
*/
public AttributeMap removeAttributes(Set attributes) {
// Create newTable on demand; if null at
// end of iteration then return this set.
// Should we intersect styleTable.keySet with
// attributes instead?
Hashtable newTable = null;
Iterator attrIter = attributes.iterator();
while (attrIter.hasNext()) {
Object current = attrIter.next();
if (current != null && styleTable.containsKey(current)) {
if (newTable == null) {
newTable = new Hashtable(styleTable.size(), LOAD_FACTOR);
newTable.putAll(styleTable);
}
newTable.remove(current);
}
}
if (newTable != null) {
return new AttributeMap(newTable, false);
}
else {
return this;
}
}
/**
* Return a AttributeMap with the keys of this AttributeMap which
* are also in the Set. The set must not contain null.
*/
public AttributeMap intersectWith(AttributeSet attributes) {
Set set = attributes;
return intersectWith(set);
}
/**
* Return a AttributeMap with the keys of this AttributeMap which
* are also in the Set. The set must not contain null.
*/
public AttributeMap intersectWith(Set attributes) {
// For now, forget about optimizing for the case when
// the return value is equivalent to this set.
int attrSize = attributes.size();
int styleTableSize = styleTable.size();
int size = Math.min(attrSize, styleTableSize);
Hashtable newTable = new Hashtable(size, LOAD_FACTOR);
if (attrSize < styleTableSize) {
Iterator attrIter = attributes.iterator();
while (attrIter.hasNext()) {
Object current = attrIter.next();
if (current != null) {
Object value = styleTable.get(current);
if (value != null) {
newTable.put(current, value);
}
}
}
}
else {
Iterator attrIter = keySet().iterator();
while (attrIter.hasNext()) {
Object current = attrIter.next();
if (attributes.contains(current)) {
newTable.put(current, styleTable.get(current));
}
}
}
return new AttributeMap(newTable, false);
}
/**
* Put all entries in this AttributeMap into the given Map.
* @param rhs the Map into which entries are placed
*/
public void putAllInto(java.util.Map rhs) {
rhs.putAll(this);
}
}

View File

@ -0,0 +1,345 @@
/*
* @(#)$RCSfile: AttributeSet.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:33:31 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
// Requires Java2
package com.ibm.textlayout.attributes;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
import java.util.Collection;
/**
* An AttributeSet is an immutable collection of unique Objects.
* It has several operations
* which return new AttributeSet instances.
*/
public final class AttributeSet implements Set {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
/**
* An AttributeSet with no members.
*/
public static final AttributeSet EMPTY_SET = new AttributeSet();
private Hashtable elements;
private static final String errString = "AttributeSet is immutable.";
private AttributeSet(Hashtable elements) {
this.elements = elements;
}
/**
* Package only. For AttributeMap use.
*/
static AttributeSet createKeySet(Hashtable hashtable) {
Hashtable newElements = new Hashtable();
Enumeration e = hashtable.keys();
while (e.hasMoreElements()) {
Object next = e.nextElement();
newElements.put(next, next);
}
return new AttributeSet(newElements);
}
/**
* Create a new, empty AttributeSet. The set is semantically
* equivalent to EMPTY_SET.
*/
public AttributeSet() {
elements = new Hashtable();
}
/**
* Create a new AttributeSet with the single element elem.
*/
public AttributeSet(Object elem) {
elements = new Hashtable(1, 1);
elements.put(elem, elem);
}
/**
* Create a new AttributeSet containing the items in the array elems.
*/
public AttributeSet(Object[] elems) {
elements = new Hashtable(elems.length, 1);
for (int i=0; i < elems.length; i++) {
Object next = elems[i];
elements.put(next, next);
}
}
/**
* Return true if the number of elements in this set is 0.
* @return true if the number of elements in this set is 0
*/
public boolean isEmpty() {
return elements.isEmpty();
}
/**
* Return the number of elements in this set.
* @return the number of elements in this set
*/
public int size() {
return elements.size();
}
public boolean equals(Object rhs) {
try {
return equals((AttributeSet) rhs);
}
catch(ClassCastException e) {
return false;
}
}
public boolean equals(AttributeSet rhs) {
if (rhs == null) {
return false;
}
return elements.equals(rhs.elements);
}
/**
* Return true if this set contains the given Object
* @return true if this set contains <code>o</code>
*/
public boolean contains(Object o) {
Object value = elements.get(o);
return value != null;
}
/**
* Return true if this set contains all elements in the given
* Collection
* @param coll the collection to compare with
* @return true if this set contains all elements in the given
* Collection
*/
public boolean containsAll(Collection coll) {
return elements.keySet().containsAll(coll);
}
/**
* Return an Enumeration of the elements in this set.
* @return an Enumeration of the elements in this set
*/
public Enumeration elements() {
return elements.keys();
}
/**
* Return an Iterator with the elements in this set.
* @return an Iterator with the elements in this set.
* The Iterator cannot be used to modify this AttributeSet.
*/
public Iterator iterator() {
return new EnumerationIterator(elements.keys());
}
/**
* Fill in the given array with the elements in this set.
* @param storage an array to fill with this set's elements.
* The array cannot be null.
* @return the <tt>storage</tt> array.
*/
public Object[] toArray(Object[] storage) {
Enumeration keys = elements.keys();
int n=0;
while (keys.hasMoreElements()) {
storage[n++] = keys.nextElement();
}
return storage;
}
/**
* Return an array with the elements in this set.
* @return an array with the elements in this set
*/
public Object[] toArray() {
return toArray(new Object[size()]);
}
/**
* Throws UnsupportedOperationException.
* @see #addElement
* @throws UnsupportedOperationException
*/
public boolean add(Object o){
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @throws UnsupportedOperationException
*/
public boolean remove(Object o) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #unionWith
* @throws UnsupportedOperationException
*/
public boolean addAll(Collection coll) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #subtract
* @throws UnsupportedOperationException
*/
public boolean removeAll(Collection coll) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #intersectWith
* @throws UnsupportedOperationException
*/
public boolean retainAll(Collection coll) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #EMPTY_SET
* @throws UnsupportedOperationException
*/
public void clear() {
throw new UnsupportedOperationException(errString);
}
/**
* Return an AttributeSet containing the elements of this set
* and the given element
* @param element the element to add
* @return an AttributeSet like this one, with <code>element</code>
* added
*/
public AttributeSet addElement(Object element) {
Hashtable newElements = (Hashtable) elements.clone();
newElements.put(element, element);
return new AttributeSet(newElements);
}
/**
* Return an AttributeSet which is the union of
* this set with the given set.
* @param s the set to union with
* @return an AttributeSet of the elements in this set or
* in <code>s</code>
*/
public AttributeSet unionWith(AttributeSet s) {
Hashtable newElements = (Hashtable) elements.clone();
Iterator iter = s.iterator();
while (iter.hasNext()) {
Object next = iter.next();
newElements.put(next, next);
}
return new AttributeSet(newElements);
}
/**
* Return an AttributeSet which is the intersection of
* this set with the given set.
* @param s the set to intersect with
* @return an AttributeSet of the elements in this set which
* are in <code>s</code>
*/
public AttributeSet intersectWith(AttributeSet s) {
Hashtable newElements = new Hashtable();
Iterator iter = s.iterator();
while (iter.hasNext()) {
Object next = iter.next();
if (elements.get(next) != null) {
newElements.put(next, next);
}
}
return new AttributeSet(newElements);
}
/**
* Return an AttributeSet with the elements in this set which
* are not in the given set.
* @param s the set of elements to exclude
* @return an AttributeSet of the elements in this set which
* are not in <code>s</code>
*/
public AttributeSet subtract(AttributeSet s) {
Hashtable newElements = (Hashtable) elements.clone();
Iterator iter = s.iterator();
while (iter.hasNext()) {
newElements.remove(iter.next());
}
return new AttributeSet(newElements);
}
private static final class EnumerationIterator implements Iterator {
private Enumeration e;
EnumerationIterator(Enumeration e) {
this.e = e;
}
public boolean hasNext() {
return e.hasMoreElements();
}
public Object next() {
return e.nextElement();
}
public void remove() {
throw new UnsupportedOperationException(errString);
}
}
}

View File

@ -0,0 +1,529 @@
/*
* @(#)$RCSfile: AttributeMap.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:33:31 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
// Requires Java2
package com.ibm.textlayout.attributes;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.io.Externalizable;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.IOException;
/**
* AttributeMap is an immutable Map. Additionally, there are
* several methods for common operations (union,
* remove, intersect); these methods return new AttributeMap
* instances.
* <p>
* Although any non-null Object can be a key or value in an
* AttributeMap, typically the keys are fields of TextAttribute.
* @see TextAttribute
*/
public final class AttributeMap implements java.util.Map,
com.ibm.textlayout.attributes.Map,
Externalizable {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
private static final int CURRENT_VERSION = 1;
private static final long serialVersionUID = 9510803;
private static final String errString = "StyleSets are immutable.";
// This is passed to the Hashtable constructor as the
// load factor argument. It is chosen to avoid resizing
// the Hashtable whenever possible. I think that 1
// does this.
private static final int LOAD_FACTOR = 1;
private Hashtable styleTable;
private transient AttributeSet cachedKeySet = null;
private transient Collection cachedValueCollection = null;
private transient Set cachedEntrySet = null;
/**
* An empty AttributeMap.
*/
public static final AttributeMap EMPTY_ATTRIBUTE_MAP = new AttributeMap();
// ==============
// Constructors
// ==============
/**
* Create a new, empty AttributeMap. EMPTY_STYLE_SET can be used
* in place of an AttributeMap produced by this constructor.
*/
public AttributeMap() {
styleTable = new Hashtable(1, LOAD_FACTOR);
}
/**
* Create an AttributeMap with the same key-value
* entries as the given Map.
* @param map a Map whose key-value entries will
* become the entries for this AttributeMap. <code>map</code>
* is not modified, and must not contain null keys or values.
*/
public AttributeMap(java.util.Map map) {
styleTable = new Hashtable(map.size(), LOAD_FACTOR);
styleTable.putAll(map);
}
/**
* Create an AttributeMap with the same key-value
* entries as the given Hashtable.
* @param table a Hashtable whose key-value entries will
* become the entries for this AttributeMap. <code>table</code>
* is not modified.
*/
public AttributeMap(Hashtable hashtable) {
this((java.util.Map) hashtable);
}
/**
* Create an AttributeMap with a single entry of
* <code>{attribute, value}</code>.
* @param attribute the key in this AttributeMap's single entry
* @param value the value in this AttributeMap's single entry
*/
public AttributeMap(Object key, Object value) {
styleTable = new Hashtable(1, LOAD_FACTOR);
// hashtable checks value for null
styleTable.put(key, value);
}
// For internal use only.
private AttributeMap(Hashtable table, boolean clone) {
if (clone) {
styleTable = (Hashtable) table.clone();
}
else {
this.styleTable = table;
}
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(CURRENT_VERSION);
out.writeInt(styleTable.size());
Enumeration e = styleTable.keys();
while (e.hasMoreElements()) {
Object key = e.nextElement();
out.writeObject(AttributeKey.mapAttributeToKey(key));
out.writeObject(styleTable.get(key));
}
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
if (in.readInt() != CURRENT_VERSION) {
throw new IOException("Invalid version of StyleBuffer");
}
int count = in.readInt();
for (int i=0; i < count; i += 1) {
Object key = AttributeKey.mapKeyToAttribute(in.readObject());
Object value = in.readObject();
styleTable.put(key, value);
}
}
// ==============
// Map interface
// ==============
// queries
/**
* Return the number of entries in the AttributeMap.
* @return the number of entries in the AttributeMap
*/
public int size() {
return styleTable.size();
}
/**
* Return true if the number of entries in the AttributeMap
* is 0.
* @return true if the number of entries in the AttributeMap
* is 0
*/
public boolean isEmpty() {
return styleTable.isEmpty();
}
/**
* Return true if the given key is in this AttributeMap.
* @param key the key to test
* @return true if <code>key</code> is in this AttributeMap
*/
public boolean containsKey(Object key) {
return styleTable.containsKey(key);
}
/**
* Return true if the given value is in this AttributeMap.
* @param key the value to test
* @return true if <code>value</code> is in this AttributeMap
*/
public boolean containsValue(Object value) {
return styleTable.containsValue(value);
}
/**
* Return the value associated with the given key. If the
* key is not in this AttributeMap null is returned.
* @param key the key to look up
* @return the value associated with <code>key</code>, or
* null if <code>key</code> is not in this AttributeMap
*/
public Object get(Object key) {
return styleTable.get(key);
}
// modifiers - all throw exceptions
/**
* Throws UnsupportedOperationException.
* @see #addAttribute
* @throws UnsupportedOperationException
*/
public Object put(Object key, Object value) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #removeAttributes
* @throws UnsupportedOperationException
*/
public Object remove(Object key) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #addAttributes
* @throws UnsupportedOperationException
*/
public void putAll(java.util.Map t) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #EMPTY_ATTRIBUTE_MAP
* @throws UnsupportedOperationException
*/
public void clear() {
throw new UnsupportedOperationException(errString);
}
// views
/**
* Return an AttributeSet containing every key in this AttributeMap.
* @return an AttributeSet containing every key in this AttributeMap
*/
public Set keySet() {
return getKeySet();
}
/**
* Return an AttributeSet containing every key in this AttributeMap.
* @return an AttributeSet containing every key in this AttributeMap
*/
public AttributeSet getKeySet() {
AttributeSet result = cachedKeySet;
if (result == null) {
result = AttributeSet.createKeySet(styleTable);
cachedKeySet = result;
}
return result;
}
/**
* Return a Collection containing every value in this AttributeMap.
* @return a Collection containing every value in this AttributeMap
*/
public Collection values() {
Collection result = cachedValueCollection;
if (result == null) {
result = Collections.unmodifiableCollection(styleTable.values());
cachedValueCollection = result;
}
return result;
}
/**
* Return a Set containing all entries in this AttributeMap.
*/
public Set entrySet() {
Set result = cachedEntrySet;
if (result == null) {
result = Collections.unmodifiableSet(styleTable.entrySet());
cachedEntrySet = result;
}
return result;
}
public boolean equals(Object rhs) {
if (rhs == this) {
return true;
}
if (rhs == null) {
return false;
}
AttributeMap rhsStyleSet = null;
try {
rhsStyleSet = (AttributeMap) rhs;
}
catch(ClassCastException e) {
return false;
}
return styleTable.equals(rhsStyleSet.styleTable);
}
public int hashCode() {
return styleTable.hashCode();
}
public String toString() {
return styleTable.toString();
}
// ==============
// Operations
// ==============
/**
* Return a AttributeMap which contains entries in this AttributeMap,
* along with an entry for <attribute, value>. If attribute
* is already present in this AttributeMap its value becomes value.
*/
public AttributeMap addAttribute(Object key, Object value) {
// try to optimize for case where <key, value> is already there?
Hashtable newTable = new Hashtable(styleTable.size() + 1, LOAD_FACTOR);
newTable.putAll(styleTable);
newTable.put(key, value);
return new AttributeMap(newTable, false);
}
/**
* Return a AttributeMap which contains entries in this AttributeMap
* and in rhs. If an attribute appears in both StyleSets the
* value from rhs is used.
*/
public AttributeMap addAttributes(AttributeMap rhs) {
int thisSize = size();
if (thisSize == 0) {
return rhs;
}
int otherSize = rhs.size();
if (otherSize == 0) {
return this;
}
Hashtable newTable = new Hashtable(thisSize + otherSize, LOAD_FACTOR);
newTable.putAll(styleTable);
newTable.putAll(rhs);
return new AttributeMap(newTable, false);
}
/**
* Return a AttributeMap which contains entries in this AttributeMap
* and in rhs. If an attribute appears in both StyleSets the
* value from rhs is used.
* The Map's keys and values must be non-null.
*/
public AttributeMap addAttributes(java.util.Map rhs) {
if (rhs instanceof AttributeMap) {
return addAttributes((AttributeMap)rhs);
}
Hashtable newTable = new Hashtable(size() + rhs.size(), LOAD_FACTOR);
newTable.putAll(styleTable);
newTable.putAll(rhs);
return new AttributeMap(newTable, false);
}
/**
* Return a AttributeMap with the entries in this AttributeMap, but
* without attribute as a key.
*/
public AttributeMap removeAttribute(Object attribute) {
if (!containsKey(attribute)) {
return this;
}
Hashtable newTable = new Hashtable(styleTable.size(), LOAD_FACTOR);
newTable.putAll(styleTable);
newTable.remove(attribute);
return new AttributeMap(newTable, false);
}
/**
* Return a AttributeMap with the entries of this AttributeMap whose
* attributes are <b>not</b> in the Set.
*/
public AttributeMap removeAttributes(AttributeSet attributes) {
Set set = attributes;
return removeAttributes(set);
}
/**
* Return a AttributeMap with the entries of this AttributeMap whose
* attributes are <b>not</b> in the Set.
*/
public AttributeMap removeAttributes(Set attributes) {
// Create newTable on demand; if null at
// end of iteration then return this set.
// Should we intersect styleTable.keySet with
// attributes instead?
Hashtable newTable = null;
Iterator attrIter = attributes.iterator();
while (attrIter.hasNext()) {
Object current = attrIter.next();
if (current != null && styleTable.containsKey(current)) {
if (newTable == null) {
newTable = new Hashtable(styleTable.size(), LOAD_FACTOR);
newTable.putAll(styleTable);
}
newTable.remove(current);
}
}
if (newTable != null) {
return new AttributeMap(newTable, false);
}
else {
return this;
}
}
/**
* Return a AttributeMap with the keys of this AttributeMap which
* are also in the Set. The set must not contain null.
*/
public AttributeMap intersectWith(AttributeSet attributes) {
Set set = attributes;
return intersectWith(set);
}
/**
* Return a AttributeMap with the keys of this AttributeMap which
* are also in the Set. The set must not contain null.
*/
public AttributeMap intersectWith(Set attributes) {
// For now, forget about optimizing for the case when
// the return value is equivalent to this set.
int attrSize = attributes.size();
int styleTableSize = styleTable.size();
int size = Math.min(attrSize, styleTableSize);
Hashtable newTable = new Hashtable(size, LOAD_FACTOR);
if (attrSize < styleTableSize) {
Iterator attrIter = attributes.iterator();
while (attrIter.hasNext()) {
Object current = attrIter.next();
if (current != null) {
Object value = styleTable.get(current);
if (value != null) {
newTable.put(current, value);
}
}
}
}
else {
Iterator attrIter = keySet().iterator();
while (attrIter.hasNext()) {
Object current = attrIter.next();
if (attributes.contains(current)) {
newTable.put(current, styleTable.get(current));
}
}
}
return new AttributeMap(newTable, false);
}
/**
* Put all entries in this AttributeMap into the given Map.
* @param rhs the Map into which entries are placed
*/
public void putAllInto(java.util.Map rhs) {
rhs.putAll(this);
}
}

View File

@ -0,0 +1,345 @@
/*
* @(#)$RCSfile: AttributeSet.java,v $ $Revision: 1.1 $ $Date: 2000/04/20 17:33:31 $
*
* (C) Copyright IBM Corp. 1998-1999. All Rights Reserved.
*
* The program is provided "as is" without any warranty express or
* implied, including the warranty of non-infringement and the implied
* warranties of merchantibility and fitness for a particular purpose.
* IBM will not be liable for any damages suffered by you as a result
* of using the Program. In no event will IBM be liable for any
* special, indirect or consequential damages or lost profits even if
* IBM has been advised of the possibility of their occurrence. IBM
* will not be liable for any third party claims against you.
*/
// Requires Java2
package com.ibm.textlayout.attributes;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
import java.util.Collection;
/**
* An AttributeSet is an immutable collection of unique Objects.
* It has several operations
* which return new AttributeSet instances.
*/
public final class AttributeSet implements Set {
static final String COPYRIGHT =
"(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
/**
* An AttributeSet with no members.
*/
public static final AttributeSet EMPTY_SET = new AttributeSet();
private Hashtable elements;
private static final String errString = "AttributeSet is immutable.";
private AttributeSet(Hashtable elements) {
this.elements = elements;
}
/**
* Package only. For AttributeMap use.
*/
static AttributeSet createKeySet(Hashtable hashtable) {
Hashtable newElements = new Hashtable();
Enumeration e = hashtable.keys();
while (e.hasMoreElements()) {
Object next = e.nextElement();
newElements.put(next, next);
}
return new AttributeSet(newElements);
}
/**
* Create a new, empty AttributeSet. The set is semantically
* equivalent to EMPTY_SET.
*/
public AttributeSet() {
elements = new Hashtable();
}
/**
* Create a new AttributeSet with the single element elem.
*/
public AttributeSet(Object elem) {
elements = new Hashtable(1, 1);
elements.put(elem, elem);
}
/**
* Create a new AttributeSet containing the items in the array elems.
*/
public AttributeSet(Object[] elems) {
elements = new Hashtable(elems.length, 1);
for (int i=0; i < elems.length; i++) {
Object next = elems[i];
elements.put(next, next);
}
}
/**
* Return true if the number of elements in this set is 0.
* @return true if the number of elements in this set is 0
*/
public boolean isEmpty() {
return elements.isEmpty();
}
/**
* Return the number of elements in this set.
* @return the number of elements in this set
*/
public int size() {
return elements.size();
}
public boolean equals(Object rhs) {
try {
return equals((AttributeSet) rhs);
}
catch(ClassCastException e) {
return false;
}
}
public boolean equals(AttributeSet rhs) {
if (rhs == null) {
return false;
}
return elements.equals(rhs.elements);
}
/**
* Return true if this set contains the given Object
* @return true if this set contains <code>o</code>
*/
public boolean contains(Object o) {
Object value = elements.get(o);
return value != null;
}
/**
* Return true if this set contains all elements in the given
* Collection
* @param coll the collection to compare with
* @return true if this set contains all elements in the given
* Collection
*/
public boolean containsAll(Collection coll) {
return elements.keySet().containsAll(coll);
}
/**
* Return an Enumeration of the elements in this set.
* @return an Enumeration of the elements in this set
*/
public Enumeration elements() {
return elements.keys();
}
/**
* Return an Iterator with the elements in this set.
* @return an Iterator with the elements in this set.
* The Iterator cannot be used to modify this AttributeSet.
*/
public Iterator iterator() {
return new EnumerationIterator(elements.keys());
}
/**
* Fill in the given array with the elements in this set.
* @param storage an array to fill with this set's elements.
* The array cannot be null.
* @return the <tt>storage</tt> array.
*/
public Object[] toArray(Object[] storage) {
Enumeration keys = elements.keys();
int n=0;
while (keys.hasMoreElements()) {
storage[n++] = keys.nextElement();
}
return storage;
}
/**
* Return an array with the elements in this set.
* @return an array with the elements in this set
*/
public Object[] toArray() {
return toArray(new Object[size()]);
}
/**
* Throws UnsupportedOperationException.
* @see #addElement
* @throws UnsupportedOperationException
*/
public boolean add(Object o){
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @throws UnsupportedOperationException
*/
public boolean remove(Object o) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #unionWith
* @throws UnsupportedOperationException
*/
public boolean addAll(Collection coll) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #subtract
* @throws UnsupportedOperationException
*/
public boolean removeAll(Collection coll) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #intersectWith
* @throws UnsupportedOperationException
*/
public boolean retainAll(Collection coll) {
throw new UnsupportedOperationException(errString);
}
/**
* Throws UnsupportedOperationException.
* @see #EMPTY_SET
* @throws UnsupportedOperationException
*/
public void clear() {
throw new UnsupportedOperationException(errString);
}
/**
* Return an AttributeSet containing the elements of this set
* and the given element
* @param element the element to add
* @return an AttributeSet like this one, with <code>element</code>
* added
*/
public AttributeSet addElement(Object element) {
Hashtable newElements = (Hashtable) elements.clone();
newElements.put(element, element);
return new AttributeSet(newElements);
}
/**
* Return an AttributeSet which is the union of
* this set with the given set.
* @param s the set to union with
* @return an AttributeSet of the elements in this set or
* in <code>s</code>
*/
public AttributeSet unionWith(AttributeSet s) {
Hashtable newElements = (Hashtable) elements.clone();
Iterator iter = s.iterator();
while (iter.hasNext()) {
Object next = iter.next();
newElements.put(next, next);
}
return new AttributeSet(newElements);
}
/**
* Return an AttributeSet which is the intersection of
* this set with the given set.
* @param s the set to intersect with
* @return an AttributeSet of the elements in this set which
* are in <code>s</code>
*/
public AttributeSet intersectWith(AttributeSet s) {
Hashtable newElements = new Hashtable();
Iterator iter = s.iterator();
while (iter.hasNext()) {
Object next = iter.next();
if (elements.get(next) != null) {
newElements.put(next, next);
}
}
return new AttributeSet(newElements);
}
/**
* Return an AttributeSet with the elements in this set which
* are not in the given set.
* @param s the set of elements to exclude
* @return an AttributeSet of the elements in this set which
* are not in <code>s</code>
*/
public AttributeSet subtract(AttributeSet s) {
Hashtable newElements = (Hashtable) elements.clone();
Iterator iter = s.iterator();
while (iter.hasNext()) {
newElements.remove(iter.next());
}
return new AttributeSet(newElements);
}
private static final class EnumerationIterator implements Iterator {
private Enumeration e;
EnumerationIterator(Enumeration e) {
this.e = e;
}
public boolean hasNext() {
return e.hasMoreElements();
}
public Object next() {
return e.nextElement();
}
public void remove() {
throw new UnsupportedOperationException(errString);
}
}
}