001: /*
002: * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, 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 JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without 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,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.binding.adapter;
032:
033: import java.awt.Color;
034: import java.beans.PropertyChangeEvent;
035: import java.beans.PropertyChangeListener;
036:
037: import javax.swing.colorchooser.DefaultColorSelectionModel;
038:
039: import com.jgoodies.binding.value.ValueModel;
040:
041: /**
042: * Converts ValueModels to the ColorSelectionModel interface. Useful to bind
043: * JColorChooser and similar classes to a ValueModel.<p>
044: *
045: * <strong>Constraints:</strong> The subject ValueModel must be of type Color
046: * and must allow read-access to its value. Also, it is strongly recommended
047: * (though not required) that the underlying ValueModel provides only non-null
048: * values. This is so because the ColorSelectionModel behavior is undefined
049: * for <code>null</code> values and it may have unpredictable results.<p>
050: *
051: * <strong>Examples:</strong><pre>
052: * // Recommended binding style using a factory
053: * ValueModel model = presentationModel.getModel(MyBean.PROPERTYNAME_COLOR);
054: * JColorChooser colorChooser = BasicComponentFactory.createColorChooser(model);
055: *
056: * // Binding using the Bindings class
057: * ValueModel model = presentationModel.getModel(MyBean.PROPERTYNAME_COLOR);
058: * JColorChooser colorChooser = new JColorChooser();
059: * Bindings.bind(colorChooser, model);
060: *
061: * // Hand-made binding
062: * ValueModel model = presentationModel.getModel(MyBean.PROPERTYNAME_COLOR);
063: * JColorChooser colorChooser = new JColorChooser(new ColorSelectionAdapter(model));
064: * </pre>
065: *
066: * @author Karsten Lentzsch
067: * @version $Revision: 1.7 $
068: *
069: * @see javax.swing.colorchooser.ColorSelectionModel
070: * @see javax.swing.JColorChooser
071: *
072: * @since 1.0.3
073: */
074: public final class ColorSelectionAdapter extends
075: DefaultColorSelectionModel {
076:
077: /**
078: * Refers to the underlying ValueModel that is used to read and write values.
079: */
080: private final ValueModel subject;
081:
082: /**
083: * An optional color that is returned as selected color
084: * if the underlying ValueModel returns <code>null</code>.
085: */
086: private final Color defaultColor;
087:
088: // Instance Creation *****************************************************
089:
090: /**
091: * Constructs a ColorSelectionAdapter on the given subject ValueModel.
092: *
093: * @param subject the subject that holds the value
094: * @throws NullPointerException if the subject is <code>null</code>.
095: */
096: public ColorSelectionAdapter(ValueModel subject) {
097: this (subject, null);
098: }
099:
100: /**
101: * Constructs a ColorSelectionAdapter on the given subject ValueModel.
102: *
103: * @param subject the subject that holds the value
104: * @param defaultColor an optional default color that is used as
105: * selected color if the subject returns <code>null</code>
106: * @throws NullPointerException if the subject is <code>null</code>.
107: */
108: public ColorSelectionAdapter(ValueModel subject, Color defaultColor) {
109: if (subject == null)
110: throw new NullPointerException(
111: "The subject must not be null.");
112:
113: this .subject = subject;
114: this .defaultColor = defaultColor;
115: subject.addValueChangeListener(new SubjectValueChangeHandler());
116: }
117:
118: // Overriding Superclass Behavior *****************************************
119:
120: /**
121: * Returns the selected Color which should be non-<code>null</code>.
122: * The return value is the subject value model's value, if non-null,
123: * otherwise the default color. Note that the latter may be null too.
124: *
125: * @return the selected Color
126: *
127: * @throws ClassCastException if the subject value is not a Color
128: *
129: * @see #setSelectedColor(Color)
130: */
131: @Override
132: public Color getSelectedColor() {
133: Color subjectColor = (Color) subject.getValue();
134: return subjectColor != null ? subjectColor : defaultColor;
135: }
136:
137: /**
138: * Sets the selected color to <code>color</code>.
139: * Note that setting the color to <code>null</code>
140: * is undefined and may have unpredictable results.
141: * This method fires a state changed event if it sets the
142: * current color to a new non-<code>null</code> color.
143: *
144: * @param color the new Color
145: *
146: * @see #getSelectedColor()
147: */
148: @Override
149: public void setSelectedColor(Color color) {
150: subject.setValue(color);
151: }
152:
153: // Event Handling *********************************************************
154:
155: /**
156: * Handles changes in the subject's value.
157: */
158: private final class SubjectValueChangeHandler implements
159: PropertyChangeListener {
160:
161: /**
162: * The subject value has changed. Notifies all registered listeners
163: * about a state change.
164: *
165: * @param evt the property change event fired by the subject
166: */
167: public void propertyChange(PropertyChangeEvent evt) {
168: fireStateChanged();
169: }
170:
171: }
172:
173: }
|