001: /*
002: * Copyright (c) 2004 JETA Software, Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without modification,
005: * are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JETA Software nor the names of its contributors may
015: * be used to endorse or promote products derived from this software without
016: * specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
021: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
022: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
023: * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
024: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
025: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026: * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jeta.forms.store.properties;
031:
032: import java.awt.Color;
033: import java.io.IOException;
034:
035: import com.jeta.forms.colormgr.ColorManager;
036: import com.jeta.forms.gui.beans.JETABean;
037: import com.jeta.forms.store.JETAObjectInput;
038: import com.jeta.forms.store.JETAObjectOutput;
039: import com.jeta.open.registry.JETARegistry;
040:
041: /**
042: * A <code>ColorProperty</code> object defines a 'dynamic' color value for
043: * some components in this architecture. A dynamic color is one that depends on
044: * the current look and feel. For example, the background for a JButton has a
045: * different color for the Windows Look and Feel than it does for the Metal Look
046: * and Feel. This is important for effects such as gradients that need to fade
047: * out to the current background (which can change if the look and feel
048: * changes). The designer allows the user to select a color based on its
049: * resource name. This class uses the resource name to get the actual color from
050: * the ColorManager.
051: *
052: * @see com.jeta.forms.colormgr.ColorManager#getColor(String,java.awt.Color)
053: * @author Jeff Tassin
054: */
055: public class ColorProperty extends JETAProperty {
056: static final long serialVersionUID = -4907629297184715948L;
057:
058: /**
059: * The version of this class
060: */
061: public static final int VERSION = 2;
062:
063: /**
064: * Color key name for a constant color
065: */
066: public static final String CONSTANT_COLOR = "constant";
067:
068: /**
069: * This is for those components/borders that define their colors based on
070: * parent components or any associated components (in the case of borders).
071: */
072: public static final String DEFAULT_COLOR = "default";
073:
074: /**
075: * The color to use if for a constant color
076: */
077: private Color m_constant_color = Color.black;
078:
079: /**
080: * The resource name for the color
081: */
082: private String m_color_key = CONSTANT_COLOR;
083:
084: /**
085: * The brightness determines if the given color should be made brighter or
086: * darker depending on the selected color. +1 Color.brighter -1
087: * Color.darker.
088: */
089: private int m_brightness = 0;
090:
091: private float m_brightness_factor = 0.7f;
092:
093: /**
094: * The default brightness factor
095: */
096: public static final float DEFAULT_FACTOR = 0.7f;
097: public static final int DEFAULT_BRIGHTNESS = 0;
098:
099: /**
100: * The property name
101: */
102: public static final String PROPERTY_ID = "dyncolor";
103:
104: /**
105: * Creates a <code>ColorProperty</code> instance that specifies a
106: * constant, black color.
107: */
108: public ColorProperty() {
109: super (PROPERTY_ID);
110: }
111:
112: /**
113: * Creates a constant <code>ColorProperty</code> instance with the
114: * specified color
115: *
116: * @param c
117: * the color to set.
118: */
119: public ColorProperty(Color c) {
120: super (PROPERTY_ID);
121:
122: m_constant_color = c;
123: m_color_key = CONSTANT_COLOR;
124: }
125:
126: /**
127: * Creates a dynamic <code>ColorProperty</code> instance with the
128: * specified color resource name as defined by the UIManager.
129: *
130: * @param colorKey
131: * the name of the color resource.
132: * @see javax.swing.UIManager#getColor(String)
133: */
134: public ColorProperty(String colorKey) {
135: super (PROPERTY_ID);
136: m_color_key = colorKey;
137: assert (!CONSTANT_COLOR.equals(colorKey));
138: }
139:
140: /**
141: * Creates a brigher color based on the given factor. Based on the logic in
142: * the java.awt.Color class
143: *
144: * @param c
145: * the color to brighten
146: * @param factor
147: * the brightness factor
148: * @see java.awt.Color#brighter
149: */
150: private Color brighter(Color c, float factor) {
151: if (factor < 0.01)
152: factor = 0.01f;
153: else if (factor > 1.0)
154: factor = 1.0f;
155:
156: int red = c.getRed();
157: int green = c.getGreen();
158: int blue = c.getBlue();
159:
160: int i = (int) (1.0 / (1.0 - factor));
161: if (red == 0 && green == 0 && blue == 0) {
162: return new Color(i, i, i);
163: }
164:
165: if (red > 0 && red < i)
166: red = i;
167:
168: if (green > 0 && green < i)
169: green = i;
170:
171: if (blue > 0 && blue < i)
172: blue = i;
173:
174: return new Color(Math.min((int) (red / factor), 255), Math.min(
175: (int) (green / factor), 255), Math.min(
176: (int) (blue / factor), 255));
177: }
178:
179: /**
180: * Creates a darker color given a color and a factor.
181: *
182: * @param c
183: * the color to darken
184: * @param factor
185: * the brightness factor
186: * @see java.awt.Color#darker
187: */
188: public Color darker(Color c, float factor) {
189: return new Color(Math.max((int) (c.getRed() * factor), 0), Math
190: .max((int) (c.getGreen() * factor), 0), Math.max(
191: (int) (c.getBlue() * factor), 0));
192: }
193:
194: /**
195: * Object equals implementation.
196: */
197: public boolean equals(Object object) {
198: if (object instanceof ColorProperty) {
199: ColorProperty cp = (ColorProperty) object;
200: return (super .equals(object)
201: && isEqual(m_constant_color, cp.m_constant_color)
202: && isEqual(m_color_key, cp.m_color_key)
203: && m_brightness == cp.m_brightness && m_brightness_factor == cp.m_brightness_factor);
204: } else {
205: return false;
206: }
207: }
208:
209: /**
210: * Returns the color specified by this property. If the this property
211: * represents a constant color, then the constant color is returned.
212: * Otherwise, the color is retrieved from the color manager. Currently, the
213: * color manager merely forwards the call to the UIManager.
214: *
215: * @return the color specified by this property.
216: */
217: public Color getColor() {
218: Color result = Color.white;
219: if (isConstant()) {
220: result = m_constant_color;
221: } else {
222: ColorManager cmgr = (ColorManager) JETARegistry
223: .lookup(ColorManager.COMPONENT_ID);
224: if (cmgr != null)
225: result = cmgr.getColor(m_color_key, null);
226: }
227: if (result == null)
228: result = Color.white;
229:
230: result = modifyBrightness(result);
231: return result;
232: }
233:
234: /**
235: * Returns the brightness value for this color
236: *
237: * @return the brightness value for this color
238: */
239: public int getBrightness() {
240: return m_brightness;
241: }
242:
243: /**
244: * Returns the brightness factor for this color
245: *
246: * @return the brightness factor for this color
247: */
248: public float getBrightnessFactor() {
249: return m_brightness_factor;
250: }
251:
252: /**
253: * @return the resource name for the color. This is the name passed to the
254: * ColorManager.
255: */
256: public String getColorKey() {
257: return m_color_key;
258: }
259:
260: public Color getConstantColor() {
261: return m_constant_color;
262: }
263:
264: /**
265: * Modifies the color based on the given brightess values
266: */
267: private Color modifyBrightness(Color result) {
268: for (int count = 0; count < Math.abs(m_brightness); count++) {
269: if (m_brightness > 0) {
270: result = brighter(result, m_brightness_factor);
271: } else if (m_brightness < 0) {
272: result = darker(result, m_brightness_factor);
273: }
274: }
275: return result;
276: }
277:
278: public void setBrightness(int ival) {
279: m_brightness = ival;
280: }
281:
282: public void setBrightnessFactor(float fval) {
283: m_brightness_factor = fval;
284: }
285:
286: public void setColorKey(String color_key) {
287: m_color_key = color_key;
288: }
289:
290: /**
291: * @return true if the property represents a constant color
292: */
293: public boolean isConstant() {
294: return "constant".equalsIgnoreCase(m_color_key);
295: }
296:
297: public void setConstantColor(Color c) {
298: m_constant_color = c;
299: m_color_key = CONSTANT_COLOR;
300: }
301:
302: /**
303: * Sets this property to that of another property.
304: */
305: public void setValue(Object prop) {
306: if (prop instanceof ColorProperty) {
307: ColorProperty cprop = (ColorProperty) prop;
308: m_color_key = cprop.m_color_key;
309: m_constant_color = cprop.m_constant_color;
310: m_brightness = cprop.m_brightness;
311: m_brightness_factor = cprop.m_brightness_factor;
312: } else if (prop != null) {
313: assert (false);
314: }
315: }
316:
317: /**
318: * Updates the bean
319: */
320: public void updateBean(JETABean jbean) {
321: // no op
322: }
323:
324: /**
325: * JETAPersistable Implementation
326: */
327: public void read(JETAObjectInput in) throws ClassNotFoundException,
328: IOException {
329: super .read(in.getSuperClassInput());
330: int version = in.readVersion();
331: m_color_key = (String) in.readObject("colorkey");
332: Object color = in.readObject("constantcolor");
333: if (color instanceof Color)
334: m_constant_color = (Color) color;
335: else if (color instanceof ColorHolder)
336: m_constant_color = ((ColorHolder) color).getColor();
337:
338: if (version > 1) {
339: m_brightness = in.readInt("brightness", DEFAULT_BRIGHTNESS);
340: m_brightness_factor = in.readFloat("brightnessfactor",
341: DEFAULT_FACTOR);
342: }
343: }
344:
345: /**
346: * JETAPersistable Implementation
347: */
348: public void write(JETAObjectOutput out) throws IOException {
349: super .write(out.getSuperClassOutput(JETAProperty.class));
350: out.writeVersion(VERSION);
351: out.writeObject("colorkey", m_color_key);
352: if (isConstant()) {
353: out.writeObject("constantcolor", new ColorHolder(
354: m_constant_color));
355: } else {
356: out.writeObject("constantcolor", null);
357: }
358: out.writeInt("brightness", m_brightness, DEFAULT_BRIGHTNESS);
359: out.writeFloat("brightnessfactor", m_brightness_factor,
360: DEFAULT_FACTOR);
361: }
362:
363: }
|