001/* 002 * $Id: DefaultVisuals.java 3778 2010-09-07 10:10:49Z kleopatra $ 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 */ 021package org.jdesktop.swingx.renderer; 022 023import java.awt.Color; 024import java.io.Serializable; 025 026import 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 * <li> name 049 * </ul> 050 * 051 * Client code will rarely need to be aware of this class. It's the single 052 * place to change on introduction of new properties considered as belonging 053 * to the "default visuals" of rendering components. <p> 054 * 055 * PENDING: allow mutators for overruling the <code>CellContext</code>s 056 * defaults? Would prefer not to, as in the context of SwingX visual config on 057 * the renderer level is discouraged (the way to go are <code>Highlighter</code>s.<p> 058 * 059 * PENDING: not yet quite decided whether the toolTipText property belongs 060 * into the visual default config. Doing so gives client code the choice to 061 * set it either in a Highlighter or a custom ComponentProvider. 062 * 063 * @author Jeanette Winzenburg 064 * 065 * @see CellContext 066 */ 067public class DefaultVisuals<T extends JComponent> implements Serializable { 068 069 070 private Color unselectedForeground; 071 072 private Color unselectedBackground; 073 074 /** 075 * Sets the renderer's unselected-foreground color to the specified color. 076 * If <code>not null</code> this color will overrule the default color of 077 * the CellContext. 078 * 079 * @param c set the foreground color to this value 080 */ 081 public void setForeground(Color c) { 082 unselectedForeground = c; 083 } 084 085 /** 086 * Sets the renderer's unselected-background color to the specified color. 087 * If <code>not null</code> this color will overrule the default color of 088 * the CellContext. 089 * 090 * @param c set the background color to this value 091 */ 092 public void setBackground(Color c) { 093 unselectedBackground = c; 094 } 095 096 097 //---------------- subclass configuration 098 /** 099 * Configures all default visual state of the rendering component from the 100 * given cell context. 101 * 102 * @param renderingComponent the component to configure, must not be null 103 * @param context the cell context to configure from, must not be null 104 * @throws NullPointerException if either renderingComponent or cellContext 105 * is null 106 */ 107 public void configureVisuals(T renderingComponent, CellContext context) { 108 configureState(renderingComponent, context); 109 configureColors(renderingComponent, context); 110 configureBorder(renderingComponent, context); 111 configurePainter(renderingComponent, context); 112 } 113 114 /** 115 * Configures the default Painter if applicable. Here: set's to null. 116 * 117 * @param renderingComponent the component to configure, must not be null 118 * @param context the cell context to configure from, must not be null 119 */ 120 protected void configurePainter(T renderingComponent, CellContext context) { 121 if (renderingComponent instanceof PainterAware) { 122 ((PainterAware) renderingComponent).setPainter(null); 123 } 124 125 } 126 127 /** 128 * Configure "divers" visual state of the rendering component from the given 129 * cell context. 130 * <p> 131 * 132 * Here: synch <code>Font</code>, <code>ComponentOrientation</code> and 133 * <code>enabled</code> to context's component. Resets toolTipText to null. 134 * Calls configureSizes to reset xxSize if appropriate. Resets the component's 135 * name property. 136 * <p> 137 * 138 * PENDING: not fully defined - "divers" means everything that's not 139 * <code>Color</code>s 140 * nor <code>Border</code> nor <code>Painter</code>. 141 * 142 * @param renderingComponent the component to configure, must not be null 143 * @param context the cell context to configure from, must not be null 144 */ 145 protected void configureState(T renderingComponent, CellContext context) { 146 renderingComponent.setName(context.getCellRendererName()); 147 renderingComponent.setToolTipText(null); 148 configureSizes(renderingComponent, context); 149 // PENDING JW: as of Issue #1269 this was changed to query the 150 // CellContext for the font - should move out off the else? 151 // context takes care of null component 152 renderingComponent.setFont(context.getFont()); 153 if (context.getComponent() == null) { 154 // what to do? 155 // we guarantee to cleanup completely - what are the defaults? 156 // leave the decistion to the context? 157 } else { 158 renderingComponent.setEnabled(context.getComponent().isEnabled()); 159 renderingComponent.applyComponentOrientation(context.getComponent() 160 .getComponentOrientation()); 161 } 162 } 163 164 /** 165 * Configures min-, max, preferredSize properties of the renderingComponent. 166 * 167 * Here: set all to null. 168 * 169 * @param renderingComponent the component to configure, must not be null 170 * @param context the cell context to configure from, must not be null 171 */ 172 protected void configureSizes(T renderingComponent, CellContext context) { 173 renderingComponent.setPreferredSize(null); 174 renderingComponent.setMinimumSize(null); 175 renderingComponent.setMaximumSize(null); 176 } 177 178 /** 179 * Configures colors of rendering component from the given cell context. 180 * 181 * @param renderingComponent the component to configure, must not be null 182 * @param context the cell context to configure from, must not be null 183 */ 184 protected void configureColors(T renderingComponent, CellContext context) { 185 if (context.isSelected()) { 186 renderingComponent.setForeground(context.getSelectionForeground()); 187 renderingComponent.setBackground(context.getSelectionBackground()); 188 } else { 189 renderingComponent.setForeground(getForeground(context)); 190 renderingComponent.setBackground(getBackground(context)); 191 } 192 if (context.isFocused()) { 193 configureFocusColors(renderingComponent, context); 194 } 195 } 196 /** 197 * Configures focus-related colors form given cell context.<p> 198 * 199 * PENDING: move to context as well? - it's the only comp 200 * with focus specifics? Problem is the parameter type... 201 * 202 * @param renderingComponent the component to configure, must not be null 203 * @param context the cell context to configure from, must not be null 204 */ 205 protected void configureFocusColors(T renderingComponent, CellContext context) { 206 if (!context.isSelected() && context.isEditable()) { 207 Color col = context.getFocusForeground(); 208 if (col != null) { 209 renderingComponent.setForeground(col); 210 } 211 col = context.getFocusBackground(); 212 if (col != null) { 213 renderingComponent.setBackground(col); 214 } 215 } 216 } 217 218 219 /** 220 * Configures the rendering component's border from the given cell context.<p> 221 * 222 * @param renderingComponent the component to configure, must not be null 223 * @param context the cell context to configure from, must not be null 224 */ 225 protected void configureBorder(T renderingComponent, CellContext context) { 226 renderingComponent.setBorder(context.getBorder()); 227 } 228 229 /** 230 * Returns the unselected foreground to use for the rendering 231 * component. <p> 232 * 233 * Here: returns this renderer's unselected foreground is not null, 234 * returns the foreground from the given context. In other words: 235 * the renderer's foreground takes precedence if set. 236 * 237 * @param context the cell context. 238 * @return the unselected foreground. 239 */ 240 protected Color getForeground(CellContext context) { 241 if (unselectedForeground != null) 242 return unselectedForeground; 243 return context.getForeground(); 244 } 245 246 /** 247 * Returns the unselected background to use for the rendering 248 * component. <p> 249 * 250 * Here: returns this renderer's unselected background is not null, 251 * returns the background from the given context. In other words: 252 * the renderer's background takes precedence if set. 253 * 254 * @param context the cell context. 255 * @return the unselected background. 256 */ 257 protected Color getBackground(CellContext context) { 258 if (unselectedBackground != null) 259 return unselectedBackground; 260 return context.getBackground(); 261 } 262 263 264 265}