40 |
|
|
41 |
import java.awt.Color; |
import java.awt.Color; |
42 |
import java.awt.Component; |
import java.awt.Component; |
43 |
|
import java.awt.Graphics; |
44 |
import java.awt.Insets; |
import java.awt.Insets; |
|
|
|
45 |
import java.io.Serializable; |
import java.io.Serializable; |
|
|
|
46 |
import javax.swing.AbstractButton; |
import javax.swing.AbstractButton; |
47 |
|
import javax.swing.ButtonModel; |
48 |
|
import javax.swing.JButton; |
49 |
import javax.swing.JPopupMenu; |
import javax.swing.JPopupMenu; |
50 |
import javax.swing.JToolBar; |
import javax.swing.JToolBar; |
51 |
|
import javax.swing.UIDefaults; |
52 |
|
import javax.swing.UIManager; |
53 |
import javax.swing.border.AbstractBorder; |
import javax.swing.border.AbstractBorder; |
54 |
|
import javax.swing.border.Border; |
55 |
import javax.swing.plaf.UIResource; |
import javax.swing.plaf.UIResource; |
56 |
|
import javax.swing.plaf.BorderUIResource; |
57 |
|
|
58 |
|
|
59 |
/** |
/** |
60 |
* STUBBED (except MarginBorder) |
* Provides various borders for the Basic look and feel. |
61 |
|
* |
62 |
|
* @author Sascha Brawer (brawer@dandelis.ch) |
63 |
*/ |
*/ |
64 |
public class BasicBorders |
public class BasicBorders |
65 |
{ |
{ |
66 |
|
/** |
67 |
|
* A MarginBorder that gets shared by multiple components. |
68 |
|
* Created on demand by the private helper function {@link |
69 |
|
* #getMarginBorder()}. |
70 |
|
*/ |
71 |
|
private static MarginBorder sharedMarginBorder; |
72 |
|
|
73 |
|
|
74 |
|
/** |
75 |
|
* Returns a border that is suitable for a button. |
76 |
|
* |
77 |
|
* <p>The colors of the border are retrieved from the |
78 |
|
* <code>UIDefaults</code> of the currently active look and feel |
79 |
|
* using the keys <code>“Button.shadow”</code>, |
80 |
|
* <code>“Button.darkShadow”</code>, |
81 |
|
* <code>“Button.light”</code>, and |
82 |
|
* <code>“Button.highlight”</code>. |
83 |
|
* |
84 |
|
* <p><img src="BasicBorders.ButtonBorder-1.png" width="300" |
85 |
|
* height="170" alt="[A screen shot of the returned border]" /> |
86 |
|
* |
87 |
|
* @return a {@link |
88 |
|
* javax.swing.plaf.BorderUIResource#CompoundBorderUIResource} |
89 |
|
* whose outer border is a {@link #ButtonBorder} and whose |
90 |
|
* inner border is a {@link #MarginBorder}. |
91 |
|
*/ |
92 |
|
public static Border getButtonBorder() |
93 |
|
{ |
94 |
|
UIDefaults defaults; |
95 |
|
Border outer; |
96 |
|
|
97 |
|
defaults = UIManager.getLookAndFeelDefaults(); |
98 |
|
|
99 |
|
/* The keys for UIDefaults have been determined by writing a |
100 |
|
* test program that dumps the UIDefaults to stdout; that program |
101 |
|
* was run on a JDK 1.4.1_01 for GNU/Linux. Note that in the API, |
102 |
|
* the key "light" is usually called "highlight", and "highlight" |
103 |
|
* is usually called "lightHighlight". |
104 |
|
*/ |
105 |
|
outer = new ButtonBorder(defaults.getColor("Button.shadow"), |
106 |
|
defaults.getColor("Button.darkShadow"), |
107 |
|
defaults.getColor("Button.light"), |
108 |
|
defaults.getColor("Button.highlight")); |
109 |
|
|
110 |
|
/* While the inner border is shared between multiple buttons, |
111 |
|
* we do not share the outer border because ButtonBorders store |
112 |
|
* their border colors. We cannot guarantee that the colors |
113 |
|
* (which come from UIDefaults) are unchanged between invocations |
114 |
|
* of getButtonBorder. We could store the last colors, and share |
115 |
|
* the button border if the colors are the same as in the last |
116 |
|
* invocation, but it probably is not worth the effort. |
117 |
|
*/ |
118 |
|
return new BorderUIResource.CompoundBorderUIResource( |
119 |
|
outer, |
120 |
|
/* inner */ getMarginBorder()); |
121 |
|
} |
122 |
|
|
123 |
|
|
124 |
|
/** |
125 |
|
* Returns a shared MarginBorder. |
126 |
|
*/ |
127 |
|
static Border getMarginBorder() // intentionally not public |
128 |
|
{ |
129 |
|
/* Swing is not designed to be thread-safe, so there is no |
130 |
|
* need to synchronize the access to the global variable. |
131 |
|
*/ |
132 |
|
if (sharedMarginBorder == null) |
133 |
|
sharedMarginBorder = new MarginBorder(); |
134 |
|
|
135 |
|
return sharedMarginBorder; |
136 |
|
} |
137 |
|
|
138 |
|
|
139 |
|
/** |
140 |
|
* A border whose appearance depends on the state of |
141 |
|
* the enclosed button. |
142 |
|
* |
143 |
|
* <p><img src="BasicBorders.ButtonBorder-1.png" width="300" |
144 |
|
* height="170" alt="[A screen shot of this border]" /> |
145 |
|
* |
146 |
|
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel |
147 |
|
* |
148 |
|
* @author Sascha Brawer (brawer@dandelis.ch) |
149 |
|
*/ |
150 |
public static class ButtonBorder |
public static class ButtonBorder |
151 |
|
extends AbstractBorder |
152 |
|
implements Serializable, UIResource |
153 |
{ |
{ |
154 |
} // class ButtonBorder |
/** |
155 |
|
* Determined using the <code>serialver</code> tool |
156 |
|
* of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. |
157 |
|
*/ |
158 |
|
static final long serialVersionUID = -157053874580739687L; |
159 |
|
|
160 |
|
|
161 |
|
/** |
162 |
|
* The color for drawing the shaded parts of the border. |
163 |
|
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel |
164 |
|
*/ |
165 |
|
protected Color shadow; |
166 |
|
|
167 |
|
|
168 |
|
/** |
169 |
|
* The color for drawing the dark shaded parts of the border. |
170 |
|
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel |
171 |
|
*/ |
172 |
|
protected Color darkShadow; |
173 |
|
|
174 |
|
|
175 |
|
/** |
176 |
|
* The color for drawing the highlighted parts of the border. |
177 |
|
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel |
178 |
|
*/ |
179 |
|
protected Color highlight; |
180 |
|
|
181 |
|
|
182 |
|
/** |
183 |
|
* The color for drawing the bright highlighted parts of the border. |
184 |
|
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel |
185 |
|
*/ |
186 |
|
protected Color lightHighlight; |
187 |
|
|
188 |
|
|
189 |
|
/** |
190 |
|
* Constructs a new border for drawing a button in the Basic |
191 |
|
* look and feel. |
192 |
|
* |
193 |
|
* @param shadow the shadow color. |
194 |
|
* @param darkShadow a darker variant of the shadow color. |
195 |
|
* @param highlight the highlight color. |
196 |
|
* @param lightHighlight a brighter variant of the highlight color. |
197 |
|
*/ |
198 |
|
public ButtonBorder(Color shadow, Color darkShadow, |
199 |
|
Color highlight, Color lightHighlight) |
200 |
|
{ |
201 |
|
/* These colors usually come from the UIDefaults of the current |
202 |
|
* look and feel. Use fallback values if the colors are not |
203 |
|
* supplied. The API specification is silent about what |
204 |
|
* behavior is expected for null colors, so users should not |
205 |
|
* rely on this fallback (which is why it is not documented in |
206 |
|
* the above Javadoc). |
207 |
|
*/ |
208 |
|
this.shadow = (shadow != null) ? shadow : Color.gray; |
209 |
|
this.darkShadow = (darkShadow != null) ? darkShadow : Color.black; |
210 |
|
this.highlight = (highlight != null) ? highlight : Color.lightGray; |
211 |
|
this.lightHighlight = (lightHighlight != null) |
212 |
|
? lightHighlight |
213 |
|
: Color.white; |
214 |
|
} |
215 |
|
|
216 |
|
|
217 |
|
/** |
218 |
|
* Paints the ButtonBorder around a given component. |
219 |
|
* |
220 |
|
* @param c the component whose border is to be painted. |
221 |
|
* @param g the graphics for painting. |
222 |
|
* @param x the horizontal position for painting the border. |
223 |
|
* @param y the vertical position for painting the border. |
224 |
|
* @param width the width of the available area for painting the border. |
225 |
|
* @param height the height of the available area for painting the border. |
226 |
|
* |
227 |
|
* @see javax.swing.plaf.basic.BasicGraphicsUtils#drawBezel |
228 |
|
*/ |
229 |
|
public void paintBorder(Component c, Graphics g, |
230 |
|
int x, int y, int width, int height) |
231 |
|
{ |
232 |
|
ButtonModel bmodel = null; |
233 |
|
|
234 |
|
if (c instanceof AbstractButton) |
235 |
|
bmodel = ((AbstractButton) c).getModel(); |
236 |
|
|
237 |
|
BasicGraphicsUtils.drawBezel( |
238 |
|
g, x, y, width, height, |
239 |
|
/* pressed */ (bmodel != null) |
240 |
|
&& /* mouse button pressed */ bmodel.isPressed() |
241 |
|
&& /* mouse inside */ bmodel.isArmed(), |
242 |
|
/* default */ (c instanceof JButton) |
243 |
|
&& ((JButton) c).isDefaultButton(), |
244 |
|
shadow, darkShadow, highlight, lightHighlight); |
245 |
|
} |
246 |
|
|
247 |
|
|
248 |
|
/** |
249 |
|
* Measures the width of this border. |
250 |
|
* |
251 |
|
* <p>Although the thickness of the actually painted border |
252 |
|
* depends on the state of the enclosed component, this |
253 |
|
* measurement always returns the same amount of pixels. Indeed, |
254 |
|
* it would be rather confusing if a button was appearing to |
255 |
|
* change its size depending on whether it is pressed or not. |
256 |
|
* |
257 |
|
* @param c the component whose border is to be measured. |
258 |
|
* |
259 |
|
* @return an Insets object whose <code>left</code>, |
260 |
|
* <code>right</code>, <code>top</code> and |
261 |
|
* <code>bottom</code> fields indicate the width of the |
262 |
|
* border at the respective edge. |
263 |
|
* |
264 |
|
* @see #getBorderInsets(java.awt.Component, java.awt.Insets) |
265 |
|
*/ |
266 |
|
public Insets getBorderInsets(Component c) |
267 |
|
{ |
268 |
|
/* There is no obvious reason for overriding this method, but we |
269 |
|
* try to have exactly the same API as the Sun reference |
270 |
|
* implementation. |
271 |
|
*/ |
272 |
|
return getBorderInsets(c, null); |
273 |
|
} |
274 |
|
|
275 |
|
|
276 |
|
/** |
277 |
|
* Measures the width of this border, storing the results into a |
278 |
|
* pre-existing Insets object. |
279 |
|
* |
280 |
|
* <p>Although the thickness of the actually painted border |
281 |
|
* depends on the state of the enclosed component, this |
282 |
|
* measurement always returns the same amount of pixels. Indeed, |
283 |
|
* it would be rather confusing if a button was appearing to |
284 |
|
* change its size depending on whether it is pressed or not. |
285 |
|
* |
286 |
|
* @param insets an Insets object for holding the result values. |
287 |
|
* After invoking this method, the <code>left</code>, |
288 |
|
* <code>right</code>, <code>top</code> and |
289 |
|
* <code>bottom</code> fields indicate the width of the |
290 |
|
* border at the respective edge. |
291 |
|
* |
292 |
|
* @return the same object that was passed for <code>insets</code>. |
293 |
|
* |
294 |
|
* @see #getBorderInsets() |
295 |
|
*/ |
296 |
|
public Insets getBorderInsets(Component c, Insets insets) |
297 |
|
{ |
298 |
|
/* The exact amount has been determined using a test program |
299 |
|
* that was run on the Sun reference implementation. With |
300 |
|
* Apple/Sun JDK 1.3.1 on MacOS X 10.1.5, the result is |
301 |
|
* [3, 3, 3, 3]. With Sun JDK 1.4.1_01 on Linux/x86, the |
302 |
|
* result is [2, 3, 3, 3]. We use the values from the 1.4.1_01 |
303 |
|
* release. |
304 |
|
*/ |
305 |
|
if (insets == null) |
306 |
|
return new Insets(2, 3, 3, 3); |
307 |
|
|
308 |
|
insets.top = 2; |
309 |
|
insets.bottom = insets.left = insets.right = 3; |
310 |
|
return insets; |
311 |
|
} |
312 |
|
} |
313 |
|
|
314 |
|
|
315 |
public static class FieldBorder |
public static class FieldBorder |
316 |
{ |
{ |
317 |
public FieldBorder(Color shadow, Color darkShadow, |
public FieldBorder(Color shadow, Color darkShadow, |