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 }