View Javadoc
1   /*
2    * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  package javax.swing.plaf.synth;
26  
27  import javax.swing.*;
28  import java.util.*;
29  
30  /**
31   * An immutable transient object containing contextual information about
32   * a <code>Region</code>. A <code>SynthContext</code> should only be
33   * considered valid for the duration
34   * of the method it is passed to. In other words you should not cache
35   * a <code>SynthContext</code> that is passed to you and expect it to
36   * remain valid.
37   *
38   * @since 1.5
39   * @author Scott Violet
40   */
41  public class SynthContext {
42      private static final Map<Class, List<SynthContext>> contextMap;
43  
44      private JComponent component;
45      private Region region;
46      private SynthStyle style;
47      private int state;
48  
49  
50      static {
51          contextMap = new HashMap<Class, List<SynthContext>>();
52      }
53  
54  
55      static SynthContext getContext(Class type, JComponent component,
56                                     Region region, SynthStyle style,
57                                     int state) {
58          SynthContext context = null;
59  
60          synchronized(contextMap) {
61              List<SynthContext> instances = contextMap.get(type);
62  
63              if (instances != null) {
64                  int size = instances.size();
65  
66                  if (size > 0) {
67                      context = instances.remove(size - 1);
68                  }
69              }
70          }
71          if (context == null) {
72              try {
73                  context = (SynthContext)type.newInstance();
74              } catch (IllegalAccessException iae) {
75              } catch (InstantiationException ie) {
76              }
77          }
78          context.reset(component, region, style, state);
79          return context;
80      }
81  
82      static void releaseContext(SynthContext context) {
83          synchronized(contextMap) {
84              List<SynthContext> instances = contextMap.get(context.getClass());
85  
86              if (instances == null) {
87                  instances = new ArrayList<SynthContext>(5);
88                  contextMap.put(context.getClass(), instances);
89              }
90              instances.add(context);
91          }
92      }
93  
94  
95      SynthContext() {
96      }
97  
98      /**
99       * Creates a SynthContext with the specified values. This is meant
100      * for subclasses and custom UI implementors. You very rarely need to
101      * construct a SynthContext, though some methods will take one.
102      *
103      * @param component JComponent
104      * @param region Identifies the portion of the JComponent
105      * @param style Style associated with the component
106      * @param state State of the component as defined in SynthConstants.
107      * @throws NullPointerException if component, region of style is null.
108      */
109     public SynthContext(JComponent component, Region region, SynthStyle style,
110                         int state) {
111         if (component == null || region == null || style == null) {
112             throw new NullPointerException(
113                 "You must supply a non-null component, region and style");
114         }
115         reset(component, region, style, state);
116     }
117 
118 
119     /**
120      * Returns the hosting component containing the region.
121      *
122      * @return Hosting Component
123      */
124     public JComponent getComponent() {
125         return component;
126     }
127 
128     /**
129      * Returns the Region identifying this state.
130      *
131      * @return Region of the hosting component
132      */
133     public Region getRegion() {
134         return region;
135     }
136 
137     /**
138      * A convenience method for <code>getRegion().isSubregion()</code>.
139      */
140     boolean isSubregion() {
141         return getRegion().isSubregion();
142     }
143 
144     void setStyle(SynthStyle style) {
145         this.style = style;
146     }
147 
148     /**
149      * Returns the style associated with this Region.
150      *
151      * @return SynthStyle associated with the region.
152      */
153     public SynthStyle getStyle() {
154         return style;
155     }
156 
157     void setComponentState(int state) {
158         this.state = state;
159     }
160 
161     /**
162      * Returns the state of the widget, which is a bitmask of the
163      * values defined in <code>SynthConstants</code>. A region will at least
164      * be in one of
165      * <code>ENABLED</code>, <code>MOUSE_OVER</code>, <code>PRESSED</code>
166      * or <code>DISABLED</code>.
167      *
168      * @see SynthConstants
169      * @return State of Component
170      */
171     public int getComponentState() {
172         return state;
173     }
174 
175     /**
176      * Resets the state of the Context.
177      */
178     void reset(JComponent component, Region region, SynthStyle style,
179                int state) {
180         this.component = component;
181         this.region = region;
182         this.style = style;
183         this.state = state;
184     }
185 
186     void dispose() {
187         this.component = null;
188         this.style = null;
189         releaseContext(this);
190     }
191 
192     /**
193      * Convenience method to get the Painter from the current SynthStyle.
194      * This will NEVER return null.
195      */
196     SynthPainter getPainter() {
197         SynthPainter painter = getStyle().getPainter(this);
198 
199         if (painter != null) {
200             return painter;
201         }
202         return SynthPainter.NULL_PAINTER;
203     }
204 }