You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
390 lines
10 KiB
390 lines
10 KiB
/*
|
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
package javax.swing.text;
|
|
|
|
import java.util.Hashtable;
|
|
import java.util.Enumeration;
|
|
import java.util.Collections;
|
|
import java.io.IOException;
|
|
import java.io.ObjectInputStream;
|
|
import java.io.Serializable;
|
|
import java.util.AbstractMap;
|
|
import java.util.LinkedHashMap;
|
|
|
|
/**
|
|
* A straightforward implementation of MutableAttributeSet using a
|
|
* hash table.
|
|
* <p>
|
|
* <strong>Warning:</strong>
|
|
* Serialized objects of this class will not be compatible with
|
|
* future Swing releases. The current serialization support is
|
|
* appropriate for short term storage or RMI between applications running
|
|
* the same version of Swing. As of 1.4, support for long term storage
|
|
* of all JavaBeans™
|
|
* has been added to the <code>java.beans</code> package.
|
|
* Please see {@link java.beans.XMLEncoder}.
|
|
*
|
|
* @author Tim Prinzing
|
|
*/
|
|
public class SimpleAttributeSet implements MutableAttributeSet, Serializable, Cloneable
|
|
{
|
|
private static final long serialVersionUID = -6631553454711782652L;
|
|
|
|
/**
|
|
* An empty attribute set.
|
|
*/
|
|
public static final AttributeSet EMPTY = new EmptyAttributeSet();
|
|
|
|
private transient LinkedHashMap<Object, Object> table = new LinkedHashMap<>(3);
|
|
|
|
/**
|
|
* Creates a new attribute set.
|
|
*/
|
|
public SimpleAttributeSet() {
|
|
}
|
|
|
|
/**
|
|
* Creates a new attribute set based on a supplied set of attributes.
|
|
*
|
|
* @param source the set of attributes
|
|
*/
|
|
public SimpleAttributeSet(AttributeSet source) {
|
|
addAttributes(source);
|
|
}
|
|
|
|
/**
|
|
* Checks whether the set of attributes is empty.
|
|
*
|
|
* @return true if the set is empty else false
|
|
*/
|
|
public boolean isEmpty()
|
|
{
|
|
return table.isEmpty();
|
|
}
|
|
|
|
/**
|
|
* Gets a count of the number of attributes.
|
|
*
|
|
* @return the count
|
|
*/
|
|
public int getAttributeCount() {
|
|
return table.size();
|
|
}
|
|
|
|
/**
|
|
* Tells whether a given attribute is defined.
|
|
*
|
|
* @param attrName the attribute name
|
|
* @return true if the attribute is defined
|
|
*/
|
|
public boolean isDefined(Object attrName) {
|
|
return table.containsKey(attrName);
|
|
}
|
|
|
|
/**
|
|
* Compares two attribute sets.
|
|
*
|
|
* @param attr the second attribute set
|
|
* @return true if the sets are equal, false otherwise
|
|
*/
|
|
public boolean isEqual(AttributeSet attr) {
|
|
return ((getAttributeCount() == attr.getAttributeCount()) &&
|
|
containsAttributes(attr));
|
|
}
|
|
|
|
/**
|
|
* Makes a copy of the attributes.
|
|
*
|
|
* @return the copy
|
|
*/
|
|
public AttributeSet copyAttributes() {
|
|
return (AttributeSet) clone();
|
|
}
|
|
|
|
/**
|
|
* Gets the names of the attributes in the set.
|
|
*
|
|
* @return the names as an <code>Enumeration</code>
|
|
*/
|
|
public Enumeration<?> getAttributeNames() {
|
|
return Collections.enumeration(table.keySet());
|
|
}
|
|
|
|
/**
|
|
* Gets the value of an attribute.
|
|
*
|
|
* @param name the attribute name
|
|
* @return the value
|
|
*/
|
|
public Object getAttribute(Object name) {
|
|
Object value = table.get(name);
|
|
if (value == null) {
|
|
AttributeSet parent = getResolveParent();
|
|
if (parent != null) {
|
|
value = parent.getAttribute(name);
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Checks whether the attribute list contains a
|
|
* specified attribute name/value pair.
|
|
*
|
|
* @param name the name
|
|
* @param value the value
|
|
* @return true if the name/value pair is in the list
|
|
*/
|
|
public boolean containsAttribute(Object name, Object value) {
|
|
return value.equals(getAttribute(name));
|
|
}
|
|
|
|
/**
|
|
* Checks whether the attribute list contains all the
|
|
* specified name/value pairs.
|
|
*
|
|
* @param attributes the attribute list
|
|
* @return true if the list contains all the name/value pairs
|
|
*/
|
|
public boolean containsAttributes(AttributeSet attributes) {
|
|
boolean result = true;
|
|
|
|
Enumeration names = attributes.getAttributeNames();
|
|
while (result && names.hasMoreElements()) {
|
|
Object name = names.nextElement();
|
|
result = attributes.getAttribute(name).equals(getAttribute(name));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Adds an attribute to the list.
|
|
*
|
|
* @param name the attribute name
|
|
* @param value the attribute value
|
|
*/
|
|
public void addAttribute(Object name, Object value) {
|
|
table.put(name, value);
|
|
}
|
|
|
|
/**
|
|
* Adds a set of attributes to the list.
|
|
*
|
|
* @param attributes the set of attributes to add
|
|
*/
|
|
public void addAttributes(AttributeSet attributes) {
|
|
Enumeration names = attributes.getAttributeNames();
|
|
while (names.hasMoreElements()) {
|
|
Object name = names.nextElement();
|
|
addAttribute(name, attributes.getAttribute(name));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes an attribute from the list.
|
|
*
|
|
* @param name the attribute name
|
|
*/
|
|
public void removeAttribute(Object name) {
|
|
table.remove(name);
|
|
}
|
|
|
|
/**
|
|
* Removes a set of attributes from the list.
|
|
*
|
|
* @param names the set of names to remove
|
|
*/
|
|
public void removeAttributes(Enumeration<?> names) {
|
|
while (names.hasMoreElements())
|
|
removeAttribute(names.nextElement());
|
|
}
|
|
|
|
/**
|
|
* Removes a set of attributes from the list.
|
|
*
|
|
* @param attributes the set of attributes to remove
|
|
*/
|
|
public void removeAttributes(AttributeSet attributes) {
|
|
if (attributes == this) {
|
|
table.clear();
|
|
}
|
|
else {
|
|
Enumeration names = attributes.getAttributeNames();
|
|
while (names.hasMoreElements()) {
|
|
Object name = names.nextElement();
|
|
Object value = attributes.getAttribute(name);
|
|
if (value.equals(getAttribute(name)))
|
|
removeAttribute(name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the resolving parent. This is the set
|
|
* of attributes to resolve through if an attribute
|
|
* isn't defined locally. This is null if there
|
|
* are no other sets of attributes to resolve
|
|
* through.
|
|
*
|
|
* @return the parent
|
|
*/
|
|
public AttributeSet getResolveParent() {
|
|
return (AttributeSet) table.get(StyleConstants.ResolveAttribute);
|
|
}
|
|
|
|
/**
|
|
* Sets the resolving parent.
|
|
*
|
|
* @param parent the parent
|
|
*/
|
|
public void setResolveParent(AttributeSet parent) {
|
|
addAttribute(StyleConstants.ResolveAttribute, parent);
|
|
}
|
|
|
|
// --- Object methods ---------------------------------
|
|
|
|
/**
|
|
* Clones a set of attributes.
|
|
*
|
|
* @return the new set of attributes
|
|
*/
|
|
public Object clone() {
|
|
SimpleAttributeSet attr;
|
|
try {
|
|
attr = (SimpleAttributeSet) super.clone();
|
|
attr.table = (LinkedHashMap) table.clone();
|
|
} catch (CloneNotSupportedException cnse) {
|
|
attr = null;
|
|
}
|
|
return attr;
|
|
}
|
|
|
|
/**
|
|
* Returns a hashcode for this set of attributes.
|
|
* @return a hashcode value for this set of attributes.
|
|
*/
|
|
public int hashCode() {
|
|
return table.hashCode();
|
|
}
|
|
|
|
/**
|
|
* Compares this object to the specified object.
|
|
* The result is <code>true</code> if the object is an equivalent
|
|
* set of attributes.
|
|
* @param obj the object to compare this attribute set with
|
|
* @return <code>true</code> if the objects are equal;
|
|
* <code>false</code> otherwise
|
|
*/
|
|
public boolean equals(Object obj) {
|
|
if (this == obj) {
|
|
return true;
|
|
}
|
|
if (obj instanceof AttributeSet) {
|
|
AttributeSet attrs = (AttributeSet) obj;
|
|
return isEqual(attrs);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Converts the attribute set to a String.
|
|
*
|
|
* @return the string
|
|
*/
|
|
public String toString() {
|
|
String s = "";
|
|
Enumeration names = getAttributeNames();
|
|
while (names.hasMoreElements()) {
|
|
Object key = names.nextElement();
|
|
Object value = getAttribute(key);
|
|
if (value instanceof AttributeSet) {
|
|
// don't go recursive
|
|
s = s + key + "=**AttributeSet** ";
|
|
} else {
|
|
s = s + key + "=" + value + " ";
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
private void writeObject(java.io.ObjectOutputStream s) throws IOException {
|
|
s.defaultWriteObject();
|
|
StyleContext.writeAttributeSet(s, this);
|
|
}
|
|
|
|
private void readObject(ObjectInputStream s)
|
|
throws ClassNotFoundException, IOException {
|
|
s.defaultReadObject();
|
|
table = new LinkedHashMap<>(3);
|
|
StyleContext.readAttributeSet(s, this);
|
|
}
|
|
|
|
/**
|
|
* An AttributeSet that is always empty.
|
|
*/
|
|
static class EmptyAttributeSet implements AttributeSet, Serializable {
|
|
static final long serialVersionUID = -8714803568785904228L;
|
|
|
|
public int getAttributeCount() {
|
|
return 0;
|
|
}
|
|
public boolean isDefined(Object attrName) {
|
|
return false;
|
|
}
|
|
public boolean isEqual(AttributeSet attr) {
|
|
return (attr.getAttributeCount() == 0);
|
|
}
|
|
public AttributeSet copyAttributes() {
|
|
return this;
|
|
}
|
|
public Object getAttribute(Object key) {
|
|
return null;
|
|
}
|
|
public Enumeration getAttributeNames() {
|
|
return Collections.emptyEnumeration();
|
|
}
|
|
public boolean containsAttribute(Object name, Object value) {
|
|
return false;
|
|
}
|
|
public boolean containsAttributes(AttributeSet attributes) {
|
|
return (attributes.getAttributeCount() == 0);
|
|
}
|
|
public AttributeSet getResolveParent() {
|
|
return null;
|
|
}
|
|
public boolean equals(Object obj) {
|
|
if (this == obj) {
|
|
return true;
|
|
}
|
|
return ((obj instanceof AttributeSet) &&
|
|
(((AttributeSet)obj).getAttributeCount() == 0));
|
|
}
|
|
public int hashCode() {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|