001/* 002 * $Id$ 003 * 004 * Copyright 2009 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 */ 022package org.jdesktop.swingx.plaf.synth; 023 024import java.awt.Graphics; 025import java.awt.Rectangle; 026import java.beans.PropertyChangeEvent; 027 028import javax.swing.JComponent; 029import javax.swing.LookAndFeel; 030import javax.swing.UIManager; 031import javax.swing.plaf.synth.ColorType; 032import javax.swing.plaf.synth.Region; 033import javax.swing.plaf.synth.SynthConstants; 034import javax.swing.plaf.synth.SynthContext; 035import javax.swing.plaf.synth.SynthLookAndFeel; 036import javax.swing.plaf.synth.SynthPainter; 037import javax.swing.plaf.synth.SynthStyle; 038 039/** 040 * Utility class as stand-in for package private synth utility methods. 041 * 042 * @author Jeanette Winzenburg 043 */ 044public class SynthUtils { 045 046//----------------------- context-related 047 048 /** 049 * Used to avoid null painter checks everywhere. 050 */ 051 private static SynthPainter NULL_PAINTER = new SynthPainter() {}; 052 053 /** 054 * Returns a SynthContext with the specified values. 055 * 056 * @param component JComponent 057 * @param region Identifies the portion of the JComponent 058 * @param style Style associated with the component 059 * @param state State of the component as defined in SynthConstants. 060 * @return a SynthContext with the specified values. 061 * 062 * @throws NullPointerException if component, region of style is null. 063 * 064 */ 065 public static SynthContext getContext(JComponent c, Region region, SynthStyle style, int state) { 066 return new SynthContext(c, region, style, state); 067 } 068 069 /** 070 * @param context 071 * @param style 072 * @return 073 */ 074 public static SynthContext getContext(SynthContext context, SynthStyle style) { 075 if (context.getStyle().equals(style)) return context; 076 return getContext(context.getComponent(), context.getRegion(), style, context.getComponentState()); 077 } 078 /** 079 * Returns a context with the given component state and all other fields same as input context. 080 * 081 * @param context the context, must not be null 082 * @param state the component state. 083 * @return a context with the given component state and other fields as inpu context. 084 */ 085 public static SynthContext getContext(SynthContext context, int state) { 086 if (context.getComponentState() == state) return context; 087 return getContext(context.getComponent(), context.getRegion(), context.getStyle(), state); 088 } 089 090 /** 091 * Returns a SynthPainter from the context's style. Fall-back to default if 092 * none available. 093 * 094 * @param context SynthContext containing the style, must not be null. 095 * @return a SynthPainter from the context's style, or a default if null. 096 */ 097 public static SynthPainter getPainter(SynthContext context) { 098 SynthPainter painter = context.getStyle().getPainter(context); 099 return painter != null ? painter : NULL_PAINTER; 100 } 101 102//------------------- style-related 103 104 /** 105 * Returns true if the Style should be updated in response to the 106 * specified PropertyChangeEvent. This forwards to 107 * <code>shouldUpdateStyleOnAncestorChanged</code> as necessary. 108 */ 109 public static boolean shouldUpdateStyle(PropertyChangeEvent event) { 110 String eName = event.getPropertyName(); 111 if ("name" == eName) { 112 // Always update on a name change 113 return true; 114 } 115 else if ("componentOrientation" == eName) { 116 // Always update on a component orientation change 117 return true; 118 } 119 else if ("ancestor" == eName && event.getNewValue() != null) { 120 // Only update on an ancestor change when getting a valid 121 // parent and the LookAndFeel wants this. 122 LookAndFeel laf = UIManager.getLookAndFeel(); 123 return (laf instanceof SynthLookAndFeel && 124 ((SynthLookAndFeel)laf). 125 shouldUpdateStyleOnAncestorChanged()); 126 } 127 // Note: The following two nimbus based overrides should be refactored 128 // to be in the Nimbus LAF. Due to constraints in an update release, 129 // we couldn't actually provide the public API necessary to allow 130 // NimbusLookAndFeel (a subclass of SynthLookAndFeel) to provide its 131 // own rules for shouldUpdateStyle. 132 else if ("Nimbus.Overrides" == eName) { 133 // Always update when the Nimbus.Overrides client property has 134 // been changed 135 return true; 136 } 137 else if ("Nimbus.Overrides.InheritDefaults" == eName) { 138 // Always update when the Nimbus.Overrides.InheritDefaults 139 // client property has changed 140 return true; 141 } 142 else if ("JComponent.sizeVariant" == eName) { 143 // Always update when the JComponent.sizeVariant 144 // client property has changed 145 return true; 146 } 147 return false; 148 } 149 150//--------------- component related 151 152 public static int getComponentState(JComponent c) { 153 if (c.isEnabled()) { 154 if (c.isFocusOwner()) { 155 return SynthConstants.ENABLED | SynthConstants.FOCUSED; 156 } 157 return SynthConstants.ENABLED; 158 } 159 return SynthConstants.DISABLED; 160 } 161 162 // ---------------- divers ... 163 164 /** 165 * A convenience method that handles painting of the background. All SynthUI 166 * implementations should override update and invoke this method. 167 * 168 * @param context must not be null 169 * @param g must not be null 170 */ 171 public static void update(SynthContext context, Graphics g) { 172 update(context, g, null); 173 } 174 175 /** 176 * A convenience method that handles painting of the background. All SynthUI 177 * implementations should override update and invoke this method. 178 * 179 * @param context must not be null 180 * @param g must not be null 181 * @param the bounds to fill, may be null to indicate the complete size 182 */ 183 public static void update(SynthContext context, Graphics g, Rectangle bounds) { 184 JComponent c = context.getComponent(); 185 SynthStyle style = context.getStyle(); 186 int x, y, width, height; 187 188 if (bounds == null) { 189 x = 0; 190 y = 0; 191 width = c.getWidth(); 192 height = c.getHeight(); 193 } else { 194 x = bounds.x; 195 y = bounds.y; 196 width = bounds.width; 197 height = bounds.height; 198 } 199 200 // Fill in the background, if necessary. 201 boolean subregion = context.getRegion().isSubregion(); 202 if ((subregion && style.isOpaque(context)) 203 || (!subregion && c.isOpaque())) { 204 g.setColor(style.getColor(context, ColorType.BACKGROUND)); 205 g.fillRect(x, y, width, height); 206 } 207 } 208 209} 210