1 |
/* ComponentUI.java |
/* ComponentUI.java |
2 |
Copyright (C) 2002 Free Software Foundation, Inc. |
Copyright (C) 2003 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
38 |
|
|
39 |
package javax.swing.plaf; |
package javax.swing.plaf; |
40 |
|
|
41 |
import java.awt.*; |
import java.awt.Dimension; |
42 |
import javax.swing.border.*; |
import java.awt.Graphics; |
43 |
import javax.swing.*; |
import javax.accessibility.Accessible; |
44 |
|
import javax.swing.JComponent; |
45 |
import javax.accessibility.*; |
|
46 |
|
|
47 |
|
/** |
48 |
|
* The abstract base class for all delegates that provide the |
49 |
|
* pluggable look and feel for Swing components. User applications |
50 |
|
* should not need to access this class; it is internal to Swing |
51 |
|
* and the look-and-feel implementations. |
52 |
|
* |
53 |
|
* <p><img src="ComponentUI-1.png" width="700" height="550" |
54 |
|
* alt="[UML diagram illustrating the architecture for pluggable |
55 |
|
* look and feels]" /> |
56 |
|
* |
57 |
|
* <p>Components such as {@link javax.swing.JSlider} do not directly |
58 |
|
* implement operations related to the look and feel of the user |
59 |
|
* interface, such as painting or layout. Instead, they use a delegate |
60 |
|
* object for all such tasks. In the case of <code>JSlider</code>, the |
61 |
|
* user interface would be provided by some concrete subclass of |
62 |
|
* {@link javax.swing.plaf.SliderUI}. |
63 |
|
* |
64 |
|
* <p>Soon after its creation, a <code>ComponentUI</code> will be sent |
65 |
|
* an {@link #installUI} message. The <code>ComponentUI</code> will |
66 |
|
* react by setting properties such as the border or the background |
67 |
|
* color of the <code>JComponent</code> for which it provides its |
68 |
|
* services. Soon before the end of its lifecycle, the |
69 |
|
* <code>ComponentUI</code> will receive an {@link #uninstallUI} |
70 |
|
* message, at which time the <code>ComponentUI</code> is expected to |
71 |
|
* undo any changes. |
72 |
|
* |
73 |
|
* <p>Note that the <code>ui</code> of a <code>JComponent</code> |
74 |
|
* changes whenever the user switches between look and feels. For |
75 |
|
* example, the <code>ui</code> property of a <code>JSlider</code> |
76 |
|
* could change from an instance of <code>MetalSliderUI</code> to an |
77 |
|
* instance of <code>FooSliderUI</code>. This switch can happen at any |
78 |
|
* time, but it will always be performed from inside the Swing thread. |
79 |
|
* |
80 |
|
* @author Sascha Brawer (brawer@dandelis.ch) |
81 |
|
*/ |
82 |
public abstract class ComponentUI |
public abstract class ComponentUI |
|
implements UIResource // ?? |
|
83 |
{ |
{ |
84 |
boolean contains(JComponent c, int x, int y) |
/** |
85 |
{ |
* Constructs a new UI delegate. |
86 |
return c.inside(x,y); |
*/ |
87 |
} |
public ComponentUI() |
88 |
|
{ |
89 |
// this SHOULD thow an error: |
} |
|
public static ComponentUI createUI(JComponent c) |
|
|
{ |
|
|
Exception e = new Exception("createUI from ComponentUI should never be called"); |
|
|
e.printStackTrace(); |
|
|
System.exit(1); |
|
|
return null; |
|
|
} |
|
|
|
|
|
public Accessible getAccessibleChild(JComponent c, int i) |
|
|
{ |
|
|
//Return the nth Accessible child of the object. |
|
|
return null; |
|
|
} |
|
90 |
|
|
|
public int getAccessibleChildrenCount(JComponent c) |
|
|
{ |
|
|
//Returns the number of accessible children in the object. |
|
|
return 0; |
|
|
} |
|
91 |
|
|
92 |
public Dimension getMaximumSize(JComponent c) |
/** |
93 |
{ |
* Sets up the specified component so it conforms the the design |
94 |
return getPreferredSize(c); |
* guidelines of the implemented look and feel. When the look and |
95 |
} |
* feel changes, a <code>ComponentUI</code> delegate is created. |
96 |
|
* The delegate object then receives an <code>installUI</code> |
97 |
public Dimension getMinimumSize(JComponent c) |
* message. |
98 |
{ |
* |
99 |
return getPreferredSize(c); |
* <p>This method should perform the following tasks: |
100 |
} |
* |
101 |
|
* <ul><li>Set visual properties such as borders, fonts, colors, or |
102 |
public Dimension getPreferredSize(JComponent c) |
* icons. However, no change should be performed for those |
103 |
{ |
* properties whose values have been directly set by the client |
104 |
return null; |
* application. To allow the distinction, LookAndFeels are expected |
105 |
} |
* to use values that implement the {@link UIResource} marker |
106 |
|
* interface, such as {@link BorderUIResource} or {@link |
107 |
public void installUI(JComponent c) |
* ColorUIResource}.</li> |
108 |
{ |
* |
109 |
String id = c.getUIClassID() + ".border"; |
* <li>If necessary, install a {@link java.awt.LayoutManager}.</li> |
110 |
|
* |
111 |
Border s = UIManager.getBorder( id ); |
* <li>Embed custom sub-components. For instance, the UI delegate |
112 |
|
* for a {@link javax.swing.JSplitPane} might install a special |
113 |
if (s != null) |
* component for the divider.</li> |
114 |
{ |
* |
115 |
c.setBorder( s ); |
* <li>Register event listeners.</li> |
116 |
//System.out.println("OK-INSTALL: " + this + ", ID=" + id + ",B="+s); |
* |
117 |
} |
* <li>Set up properties related to keyborad navigation, such as |
118 |
else |
* mnemonics or focus traversal policies.</li></ul> |
119 |
{ |
* |
120 |
///System.out.println("FAIL-INSTALL: " + this + ", " + id); |
* @param c the component for which this delegate will provide |
121 |
} |
* services. |
122 |
} |
* |
123 |
|
* @see #uninstallUI |
124 |
public void paint(Graphics g, JComponent c) |
* @see javax.swing.JComponent#setUI |
125 |
|
* @see javax.swing.JComponent#updateUI |
126 |
|
*/ |
127 |
|
public void installUI(JComponent c) |
128 |
|
{ |
129 |
|
// The default implementation does not change any properties. |
130 |
|
} |
131 |
|
|
132 |
|
|
133 |
|
/** |
134 |
|
* Puts the specified component into the state it had before |
135 |
|
* {@link #installUI} was called. |
136 |
|
* |
137 |
|
* @param c the component for which this delegate has provided |
138 |
|
* services. |
139 |
|
* |
140 |
|
* @see #installUI |
141 |
|
* @see javax.swing.JComponent#setUI |
142 |
|
* @see javax.swing.JComponent#updateUI |
143 |
|
*/ |
144 |
|
public void uninstallUI(JComponent c) |
145 |
|
{ |
146 |
|
// The default implementation does not change any properties. |
147 |
|
} |
148 |
|
|
149 |
|
|
150 |
|
/** |
151 |
|
* Paints the component according to the design guidelines |
152 |
|
* of the look and feel. Most subclasses will want to override |
153 |
|
* this method. |
154 |
|
* |
155 |
|
* @param g the graphics for painting. |
156 |
|
* |
157 |
|
* @param c the component for which this delegate performs |
158 |
|
* services. |
159 |
|
*/ |
160 |
|
public void paint(Graphics g, JComponent c) |
161 |
|
{ |
162 |
|
} |
163 |
|
|
164 |
|
|
165 |
|
/** |
166 |
|
* Fills the specified component with its background color |
167 |
|
* (unless the <code>opaque</code> property is <code>false</code>) |
168 |
|
* before calling {@link #paint}. |
169 |
|
* |
170 |
|
* <p>It is unlikely that a subclass needs to override this method. |
171 |
|
* The actual rendering should be performed by the {@link #paint} |
172 |
|
* method. |
173 |
|
* |
174 |
|
* @param g the graphics for painting. |
175 |
|
* |
176 |
|
* @param c the component for which this delegate performs |
177 |
|
* services. |
178 |
|
* |
179 |
|
* @see #paint |
180 |
|
* @see javax.swing.JComponent#paintComponent |
181 |
|
*/ |
182 |
|
public void update(Graphics g, JComponent c) |
183 |
|
{ |
184 |
|
if (c.isOpaque()) |
185 |
{ |
{ |
186 |
// System.out.println("UI-COMPONENT-> unimplemented paint: " + c + ", UI="+this); |
g.setColor(c.getBackground()); |
187 |
} |
g.fillRect(0, 0, c.getWidth(), c.getHeight()); |
|
|
|
|
public void uninstallUI(JComponent c) |
|
|
{ |
|
188 |
} |
} |
189 |
|
paint(g, c); |
190 |
|
} |
191 |
|
|
192 |
|
|
193 |
|
/** |
194 |
|
* Determines the preferred size of a component. The default |
195 |
|
* implementation returns <code>null</code>, which means that |
196 |
|
* <code>c</code>’s layout manager should be asked to |
197 |
|
* calculate the preferred size. |
198 |
|
* |
199 |
|
* @param c the component for which this delegate performs services. |
200 |
|
* |
201 |
|
* @return the preferred size, or <code>null</code> to indicate that |
202 |
|
* <code>c</code>’s layout manager should be asked |
203 |
|
* for the preferred size. |
204 |
|
*/ |
205 |
|
public Dimension getPreferredSize(JComponent c) |
206 |
|
{ |
207 |
|
return null; |
208 |
|
} |
209 |
|
|
210 |
|
|
211 |
|
/** |
212 |
|
* Determines the minimum size of a component. The default |
213 |
|
* implementation calls {@link #getPreferredSize}, but subclasses |
214 |
|
* might want to override this. |
215 |
|
* |
216 |
|
* @param c the component for which this delegate performs services. |
217 |
|
* |
218 |
|
* @return the minimum size, or <code>null</code> to indicate that |
219 |
|
* <code>c</code>’s layout manager should be asked |
220 |
|
* to calculate the minimum size. |
221 |
|
*/ |
222 |
|
public Dimension getMinimumSize(JComponent c) |
223 |
|
{ |
224 |
|
return getPreferredSize(c); |
225 |
|
} |
226 |
|
|
227 |
|
|
228 |
|
/** |
229 |
|
* Determines the maximum size of a component. The default |
230 |
|
* implementation calls {@link #getPreferredSize}, but subclasses |
231 |
|
* might want to override this. |
232 |
|
* |
233 |
|
* @param c the component for which this delegate performs services. |
234 |
|
* |
235 |
|
* @return the maximum size, or <code>null</code> to indicate that |
236 |
|
* <code>c</code>’s layout manager should be asked |
237 |
|
* to calculate the maximum size. |
238 |
|
*/ |
239 |
|
public Dimension getMaximumSize(JComponent c) |
240 |
|
{ |
241 |
|
return getPreferredSize(c); |
242 |
|
} |
243 |
|
|
244 |
|
|
245 |
|
/** |
246 |
|
* Determines whether a click into the component at a specified |
247 |
|
* location is considered as having hit the component. The default |
248 |
|
* implementation checks whether the point falls into the |
249 |
|
* component’s bounding rectangle. Some subclasses might want |
250 |
|
* to override this, for example in the case of a rounded button. |
251 |
|
* |
252 |
|
* @param c the component for which this delegate performs services. |
253 |
|
* |
254 |
|
* @param x the x coordinate of the point, relative to the local |
255 |
|
* coordinate system of the component. Zero would be be |
256 |
|
* component’s left edge, irrespective of the location |
257 |
|
* inside its parent. |
258 |
|
* |
259 |
|
* @param y the y coordinate of the point, relative to the local |
260 |
|
* coordinate system of the component. Zero would be be |
261 |
|
* component’s top edge, irrespective of the location |
262 |
|
* inside its parent. |
263 |
|
*/ |
264 |
|
public boolean contains(JComponent c, int x, int y) |
265 |
|
{ |
266 |
|
/* JComponent.contains calls the ui delegate for hit |
267 |
|
* testing. Therefore, endless mutual recursion would result if we |
268 |
|
* called c.contains(x, y) here. |
269 |
|
* |
270 |
|
* The previous Classpath implementation called the deprecated |
271 |
|
* method java.awt.Component.inside. In the Sun implementation, it |
272 |
|
* can be observed that inside, other than contains, does not call |
273 |
|
* the ui delegate. But that inside() behaves different to |
274 |
|
* contains() clearly is in violation of the method contract, and |
275 |
|
* it is not something that a good implementation should rely upon |
276 |
|
* -- even if Classpath ends up being forced to replicate this |
277 |
|
* apparent bug of the Sun implementation. |
278 |
|
*/ |
279 |
|
return (x >= 0) && (x < c.getWidth()) |
280 |
|
&& (y >= 0) && (y < c.getHeight()); |
281 |
|
} |
282 |
|
|
283 |
|
|
284 |
|
/** |
285 |
|
* Creates a delegate object for the specified component. Users |
286 |
|
* should use the <code>createUI</code> method of a suitable |
287 |
|
* subclass. The implementation of <code>ComponentUI</code> |
288 |
|
* always throws an error. |
289 |
|
* |
290 |
|
* @param c the component for which a UI delegate is requested. |
291 |
|
*/ |
292 |
|
public static ComponentUI createUI(JComponent c) |
293 |
|
{ |
294 |
|
throw new Error( |
295 |
|
"javax.swing.plaf.ComponentUI does not implement createUI; call " |
296 |
|
+ "createUI on a subclass."); |
297 |
|
} |
298 |
|
|
299 |
|
|
300 |
public void update(Graphics g, JComponent c) { |
/** |
301 |
if (c.isOpaque()) { |
* Counts the number of accessible children in the component. The |
302 |
g.setColor(c.getBackground()); |
* default implementation delegates the inquiry to the {@link |
303 |
g.fillRect(0, 0, c.getWidth(),c.getHeight()); |
* javax.accessibility.AccessibleContext} of <code>c</code>. |
304 |
} |
* |
305 |
paint(g, c); |
* @param c the component whose accessible children |
306 |
} |
* are to be counted. |
307 |
|
*/ |
308 |
|
public int getAccessibleChildrenCount(JComponent c) |
309 |
|
{ |
310 |
|
return c.getAccessibleContext().getAccessibleChildrenCount(); |
311 |
|
} |
312 |
|
|
313 |
|
|
314 |
|
/** |
315 |
|
* Returns the specified accessible child of the component. The |
316 |
|
* default implementation delegates the inquiry to the {@link |
317 |
|
* javax.accessibility.AccessibleContext} of <code>c</code>. |
318 |
|
* |
319 |
|
* @param i the index of the accessible child, starting at zero. |
320 |
|
* |
321 |
|
* @param c the component whose <code>i</code>-th accessible child |
322 |
|
* is requested. |
323 |
|
*/ |
324 |
|
public Accessible getAccessibleChild(JComponent c, int i) |
325 |
|
{ |
326 |
|
return c.getAccessibleContext().getAccessibleChild(i); |
327 |
|
} |
328 |
} |
} |
|
|
|