001 /*
002 * $Id: DefaultVisuals.java 3100 2008-10-14 22:33:10Z rah003 $
003 *
004 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021 package org.jdesktop.swingx.renderer;
022
023 import java.awt.Color;
024 import java.io.Serializable;
025
026 import javax.swing.JComponent;
027
028 /**
029 * Encapsulates the default visual configuration of renderering components,
030 * respecting the state of the passed-in <code>CellContext</code>. It's
031 * basically re-usable across all types of renderees (JTable, JList, JTree).
032 * <p>
033 *
034 * Guarantees to completely configure the default visual properties (listed
035 * below) of a given component. As a consequence, client code (f.i. in
036 * <code>Highlighter</code>s) can safely change them without long-lasting
037 * visual artefacts.
038 *
039 * <ul>
040 * <li> foreground and background, depending on selected and focused state
041 * <li> border
042 * <li> font
043 * <li> Painter (if applicable)
044 * <li> enabled
045 * <li> componentOrientation
046 * <li> toolTipText
047 * <li> minimum-, maximum-, preferredSize
048 * </ul>
049 *
050 * Client code will rarely need to be aware of this class. It's the single
051 * place to change on introduction of new properties considered as belonging
052 * to the "default visuals" of rendering components. <p>
053 *
054 * PENDING: allow mutators for overruling the <code>CellContext</code>s
055 * defaults? Would prefer not to, as in the context of SwingX visual config on
056 * the renderer level is discouraged (the way to go are <code>Highlighter</code>s.<p>
057 *
058 * PENDING: not yet quite decided whether the toolTipText property belongs
059 * into the visual default config. Doing so gives client code the choice to
060 * set it either in a Highlighter or a custom ComponentProvider.
061 *
062 * @author Jeanette Winzenburg
063 *
064 * @see CellContext
065 */
066 public class DefaultVisuals<T extends JComponent> implements Serializable {
067
068
069 private Color unselectedForeground;
070
071 private Color unselectedBackground;
072
073 /**
074 * Sets the renderer's unselected-foreground color to the specified color.
075 * If <code>not null</code> this color will overrule the default color of
076 * the CellContext.
077 *
078 * @param c set the foreground color to this value
079 */
080 public void setForeground(Color c) {
081 unselectedForeground = c;
082 }
083
084 /**
085 * Sets the renderer's unselected-background color to the specified color.
086 * If <code>not null</code> this color will overrule the default color of
087 * the CellContext.
088 *
089 * @param c set the background color to this value
090 */
091 public void setBackground(Color c) {
092 unselectedBackground = c;
093 }
094
095
096 //---------------- subclass configuration
097 /**
098 * Configures all default visual state of the rendering component from the
099 * given cell context.
100 *
101 * @param renderingComponent the component to configure, must not be null
102 * @param context the cell context to configure from, must not be null
103 * @throws NullPointerException if either renderingComponent or cellContext
104 * is null
105 */
106 public void configureVisuals(T renderingComponent, CellContext context) {
107 configureState(renderingComponent, context);
108 configureColors(renderingComponent, context);
109 configureBorder(renderingComponent, context);
110 configurePainter(renderingComponent, context);
111 }
112
113 /**
114 * Configures the default Painter if applicable. Here: set's to null.
115 *
116 * @param renderingComponent the component to configure, must not be null
117 * @param context the cell context to configure from, must not be null
118 */
119 protected void configurePainter(T renderingComponent, CellContext context) {
120 if (renderingComponent instanceof PainterAware) {
121 ((PainterAware) renderingComponent).setPainter(null);
122 }
123
124 }
125
126 /**
127 * Configure "divers" visual state of the rendering component from the given
128 * cell context.
129 * <p>
130 *
131 * Here: synch <code>Font</code>, <code>ComponentOrientation</code> and
132 * <code>enabled</code> to context's component. Resets toolTipText to null.
133 * Calls configureSizes to reset xxSize if appropriate.
134 * <p>
135 *
136 * PENDING: not fully defined - "divers" means everything that's not
137 * <code>Color</code>s
138 * nor <code>Border</code> nor <code>Painter</code>.
139 *
140 * @param renderingComponent the component to configure, must not be null
141 * @param context the cell context to configure from, must not be null
142 */
143 protected void configureState(T renderingComponent, CellContext context) {
144 renderingComponent.setToolTipText(null);
145 configureSizes(renderingComponent, context);
146 if (context.getComponent() == null) {
147 // what to do?
148 // we guarantee to cleanup completely - what are the defaults?
149 // leave the decistion to the context?
150 } else {
151 renderingComponent.setFont(context.getComponent().getFont());
152 renderingComponent.setEnabled(context.getComponent().isEnabled());
153 renderingComponent.applyComponentOrientation(context.getComponent()
154 .getComponentOrientation());
155 }
156 }
157
158 /**
159 * Configures min-, max, preferredSize properties of the renderingComponent.
160 *
161 * Here: set all to null.
162 *
163 * @param renderingComponent the component to configure, must not be null
164 * @param context the cell context to configure from, must not be null
165 */
166 protected void configureSizes(T renderingComponent, CellContext context) {
167 renderingComponent.setPreferredSize(null);
168 renderingComponent.setMinimumSize(null);
169 renderingComponent.setMaximumSize(null);
170 }
171
172 /**
173 * Configures colors of rendering component from the given cell context.
174 *
175 * @param renderingComponent the component to configure, must not be null
176 * @param context the cell context to configure from, must not be null
177 */
178 protected void configureColors(T renderingComponent, CellContext context) {
179 if (context.isSelected()) {
180 renderingComponent.setForeground(context.getSelectionForeground());
181 renderingComponent.setBackground(context.getSelectionBackground());
182 } else {
183 renderingComponent.setForeground(getForeground(context));
184 renderingComponent.setBackground(getBackground(context));
185 }
186 if (context.isFocused()) {
187 configureFocusColors(renderingComponent, context);
188 }
189 }
190 /**
191 * Configures focus-related colors form given cell context.<p>
192 *
193 * PENDING: move to context as well? - it's the only comp
194 * with focus specifics? Problem is the parameter type...
195 *
196 * @param renderingComponent the component to configure, must not be null
197 * @param context the cell context to configure from, must not be null
198 */
199 protected void configureFocusColors(T renderingComponent, CellContext context) {
200 if (!context.isSelected() && context.isEditable()) {
201 Color col = context.getFocusForeground();
202 if (col != null) {
203 renderingComponent.setForeground(col);
204 }
205 col = context.getFocusBackground();
206 if (col != null) {
207 renderingComponent.setBackground(col);
208 }
209 }
210 }
211
212
213 /**
214 * Configures the rendering component's border from the given cell context.<p>
215 *
216 * @param renderingComponent the component to configure, must not be null
217 * @param context the cell context to configure from, must not be null
218 */
219 protected void configureBorder(T renderingComponent, CellContext context) {
220 renderingComponent.setBorder(context.getBorder());
221 }
222
223 /**
224 * Returns the unselected foreground to use for the rendering
225 * component. <p>
226 *
227 * Here: returns this renderer's unselected foreground is not null,
228 * returns the foreground from the given context. In other words:
229 * the renderer's foreground takes precedence if set.
230 *
231 * @param context the cell context.
232 * @return the unselected foreground.
233 */
234 protected Color getForeground(CellContext context) {
235 if (unselectedForeground != null)
236 return unselectedForeground;
237 return context.getForeground();
238 }
239
240 /**
241 * Returns the unselected background to use for the rendering
242 * component. <p>
243 *
244 * Here: returns this renderer's unselected background is not null,
245 * returns the background from the given context. In other words:
246 * the renderer's background takes precedence if set.
247 *
248 * @param context the cell context.
249 * @return the unselected background.
250 */
251 protected Color getBackground(CellContext context) {
252 if (unselectedBackground != null)
253 return unselectedBackground;
254 return context.getBackground();
255 }
256
257
258
259 }