001: package net.xoetrope.xui.style;
002:
003: import java.io.BufferedReader;
004: import java.util.Enumeration;
005: import java.util.Hashtable;
006:
007: import java.awt.Color;
008: import java.awt.Font;
009:
010: import net.xoetrope.debug.DebugLogger;
011: import net.xoetrope.xml.XmlElement;
012: import net.xoetrope.xml.XmlSource;
013: import net.xoetrope.xui.XProjectManager;
014: import net.xoetrope.xui.XResourceManager;
015: import net.xoetrope.xui.build.BuildProperties;
016:
017: /**
018: * Class for managing XStyles. XStyles are created
019: * externally and added to the hashtable. Also handles the retrieval of styles.
020: * <p>Copyright (c) Xoetrope Ltd., 1998-2004<br>
021: * $Revision: 1.14 $
022: */
023: public class XStyleManager {
024: protected Hashtable styles;
025: protected Hashtable mergedStyles;
026: protected Hashtable fontCache;
027: protected static XStyle baseStyle = new XStyle();
028:
029: /**
030: * Construct a new style manager with an initial size.
031: */
032: public XStyleManager(int styleCount) {
033: styles = new Hashtable(styleCount);
034: mergedStyles = new Hashtable(styleCount);
035: fontCache = new Hashtable(10);
036:
037: try {
038: String styleFile = XProjectManager.getCurrentProject()
039: .getStartupParam("StyleFile");
040: if (styleFile == null)
041: styleFile = "styles.xml";
042: load(styleFile);
043: } catch (Exception ex) {
044: DebugLogger.logWarning("No style file loaded!");
045: }
046: }
047:
048: /**
049: * Add a new XStyle to the hashtable with a unique name
050: */
051: public void addStyle(String name, XStyle newStyle) {
052: styles.remove(name);
053: styles.put(name, newStyle);
054: }
055:
056: /**
057: * Retrieve a named XStyle from the hashtable. loop thru the "/" character
058: * and merge each one found with a new XStyle.
059: * @param name The name of the style.
060: * @param create booean to indicate whether the style should be created.
061: */
062: public XStyle getStyle(String name, boolean create) {
063: String styleName;
064: String qualifiedName = null;
065: qualifiedName = name;
066:
067: if (qualifiedName == null)
068: return null;
069:
070: XStyle tempXStyle = (XStyle) mergedStyles.get(qualifiedName);
071: if (tempXStyle != null)
072: return tempXStyle;
073:
074: int startPos = 0;
075: if (create) {
076: tempXStyle = (XStyle) baseStyle.clone();
077: int pos;
078: do {
079: pos = qualifiedName.indexOf("/", startPos);
080:
081: if (pos != -1)
082: styleName = qualifiedName.substring(0, pos);
083: else
084: styleName = qualifiedName;
085:
086: tempXStyle.mergeStyle((XStyle) styles.get(styleName));
087: startPos = pos + 1;
088: } while (pos != -1);
089:
090: mergedStyles.put(qualifiedName, tempXStyle);
091: }
092:
093: return tempXStyle;
094: }
095:
096: /**
097: * Retrieve a named XStyle from the hashtable. loop thru the "/" character
098: * and merge each one found with a new XStyle.
099: * @param name The name of the style.
100: */
101: public XStyle getStyle(String name) {
102: return getStyle(name, true);
103: }
104:
105: /**
106: * Get the font for a given style. Use the bold and italic attributes and do a
107: * bitwise or using the Font values to set the style.
108: * @param style the nsame of the style
109: */
110: public Font getFont(String style) {
111: return getFont(getStyle(style));
112: }
113:
114: /**
115: * Get the font for a given style. Use the bold and italic attributes and do a
116: * bitwise or using the Font values to set the style.
117: * @param style the style
118: */
119: public Font getFont(XStyle style) {
120: Font f = null; //(Font)fontCache.get( style.getFontHashcode());
121: if (f != null)
122: return f;
123: int bold = style.getStyleAsInt(XStyle.FONT_WEIGHT);
124: int italic = style.getStyleAsInt(XStyle.FONT_ITALIC);
125: int fontStyle = 0;
126:
127: if (bold == 1)
128: fontStyle = Font.BOLD;
129: if (italic == 1)
130: fontStyle = fontStyle | Font.ITALIC;
131:
132: if (style.getStyleAsString(XStyle.FONT_FACE) == null)
133: return null;
134:
135: f = new Font(style.getStyleAsString(XStyle.FONT_FACE),
136: fontStyle, style.getStyleAsInt(XStyle.FONT_SIZE));
137: int fontHashCode = f.hashCode();
138: style.setFontHashcode(fontHashCode);
139: fontCache.put(new Integer(fontHashCode), f);
140: return f;
141: }
142:
143: /**
144: * Create the singleton instance
145: * @deprecated since 1.03
146: */
147: public static XStyleManager getInstance() {
148: return XProjectManager.getStyleManager();
149: }
150:
151: /**
152: * Load the styles from the specified file
153: * @param file the file name of the file to load
154: */
155: public void load(String file) {
156: BufferedReader r = null;
157: try {
158: r = XResourceManager.getBufferedReader(file, null);
159: XmlElement element = XmlSource.read(r);
160: loadXStyle(element, null);
161: baseStyle = getStyle("base");
162: } catch (Exception ex) {
163: if (BuildProperties.DEBUG)
164: DebugLogger.trace("Error loading styles file: " + file);
165: ex.printStackTrace();
166: }
167: }
168:
169: /**
170: * Load a style from the XML element and save it to the specified path in the
171: * style hierarchy
172: * @param element the source element
173: * @param path the save path
174: */
175: public void loadXStyle(XmlElement element, String path) {
176: Enumeration e = element.getChildren().elements();
177: XStyle xstyle = new XStyle();
178: while (e.hasMoreElements()) {
179: XmlElement eleStyle = (XmlElement) e.nextElement();
180: if (eleStyle.getName().compareTo("style") == 0) {
181: String temp = element.getAttribute("name");
182: if ((path != null) && (path.length() > 0))
183: temp = path + "/" + element.getAttribute("name");
184: loadXStyle(eleStyle, temp);
185: } else
186: xstyle.setStyle(getStyleIndex(eleStyle.getName()),
187: eleStyle.getAttribute("value"));
188: }
189:
190: String styleName = element.getAttribute("name");
191: if ((path != null) && (path.length() > 0))
192: styleName = path + "/" + styleName;
193: if ((styleName != null) && (styleName.length() > 0))
194: addStyle(styleName, xstyle);
195: }
196:
197: /**
198: * Gets a integer constant corresponding to a style name
199: * @param name the style name e.g. "font_face"
200: * @return the style constant e.g. XStyle.FONT_FACE
201: */
202: protected int getStyleIndex(String name) {
203: name = name.toLowerCase();
204: if (name.compareTo("font_face") == 0)
205: return XStyle.FONT_FACE;
206: else if (name.compareTo("font_size") == 0)
207: return XStyle.FONT_SIZE;
208: else if (name.compareTo("font_weight") == 0)
209: return XStyle.FONT_WEIGHT;
210: else if (name.compareTo("font_italic") == 0)
211: return XStyle.FONT_ITALIC;
212: else if (name.compareTo("color_back") == 0)
213: return XStyle.COLOR_BACK;
214: else if (name.compareTo("color_fore") == 0)
215: return XStyle.COLOR_FORE;
216: else
217: return -1;
218: }
219:
220: /**
221: * Get the table of styles
222: * @return the stytle table
223: */
224: public Hashtable getStyles() {
225: return styles;
226: }
227:
228: /**
229: * Get the parent of the named style
230: * @param name the style name
231: * @return the parent style
232: */
233: public XStyle getStyleParent(String name) {
234: if (name.indexOf("/") > 0)
235: return getStyle("base/"
236: + name.substring(0, name.lastIndexOf("/")));
237: else
238: return null;
239: }
240: }
|