KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jgoodies > looks > windows > WindowsBorders


1 /*
2  * Copyright (c) 2001-2005 JGoodies Karsten Lentzsch. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * o Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * o Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * o Neither the name of JGoodies Karsten Lentzsch nor the names of
15  * its contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package com.jgoodies.looks.windows;
32
33 import java.awt.Color JavaDoc;
34 import java.awt.Component JavaDoc;
35 import java.awt.Graphics JavaDoc;
36 import java.awt.Insets JavaDoc;
37
38 import javax.swing.AbstractButton JavaDoc;
39 import javax.swing.ButtonModel JavaDoc;
40 import javax.swing.JButton JavaDoc;
41 import javax.swing.JToggleButton JavaDoc;
42 import javax.swing.UIDefaults JavaDoc;
43 import javax.swing.UIManager JavaDoc;
44 import javax.swing.border.AbstractBorder JavaDoc;
45 import javax.swing.border.Border JavaDoc;
46 import javax.swing.border.EmptyBorder JavaDoc;
47 import javax.swing.plaf.BorderUIResource JavaDoc;
48 import javax.swing.plaf.UIResource JavaDoc;
49 import javax.swing.plaf.basic.BasicBorders JavaDoc;
50 import javax.swing.plaf.basic.BasicGraphicsUtils JavaDoc;
51
52 /**
53  * Consists of static inner classes that define different
54  * <code>Borders</code> used in the JGoodies Windows look&amp;feel.
55  *
56  * @author Karsten Lentzsch
57  * @version $Revision: 1.3 $
58  */

59 final class WindowsBorders {
60     
61     // Accessing and Creating Borders ***************************************************
62

63     private static Border JavaDoc menuBorder;
64     private static Border JavaDoc menuItemBorder;
65     private static Border JavaDoc popupMenuBorder;
66     private static Border JavaDoc separatorBorder;
67     private static Border JavaDoc etchedBorder;
68     private static Border JavaDoc menuBarHeaderBorder;
69     private static Border JavaDoc toolBarHeaderBorder;
70     private static Border JavaDoc rolloverButtonBorder;
71
72
73     /**
74      * Returns a <code>Border</code> for a <code>JButton</code>.
75      */

76     public static Border JavaDoc getButtonBorder() {
77         UIDefaults JavaDoc table = UIManager.getLookAndFeelDefaults();
78         Border JavaDoc outerBorder = new ButtonBorder(table.getColor("Button.shadow"),
79                 table.getColor("Button.darkShadow"), table
80                         .getColor("Button.light"), table
81                         .getColor("Button.highlight"), table
82                         .getColor("controlText"));
83
84         Border JavaDoc buttonBorder = new BorderUIResource.CompoundBorderUIResource JavaDoc(
85                 outerBorder, new BasicBorders.MarginBorder JavaDoc());
86         return buttonBorder;
87     }
88
89
90     /**
91      * Returns a border instance for a <code>JMenu</code>.
92      */

93     static Border JavaDoc getMenuBorder() {
94         if (menuBorder == null) {
95             menuBorder = new BorderUIResource.CompoundBorderUIResource JavaDoc(
96                             new MenuBorder(),
97                             new BasicBorders.MarginBorder JavaDoc());
98         }
99         return menuBorder;
100     }
101
102     /**
103      * Returns a border instance for a <code>JMenuItem</code>.
104      */

105     static Border JavaDoc getMenuItemBorder() {
106         if (menuItemBorder == null) {
107             menuItemBorder = new BorderUIResource JavaDoc(new BasicBorders.MarginBorder JavaDoc());
108         }
109         return menuItemBorder;
110     }
111
112     /**
113      * Returns a separator border instance for <code>JMenuBar</code> or <code>JToolBar</code>.
114      */

115     static Border JavaDoc getSeparatorBorder() {
116         if (separatorBorder == null) {
117             separatorBorder = new BorderUIResource.CompoundBorderUIResource JavaDoc(
118                                     new SeparatorBorder(),
119                                     new BasicBorders.MarginBorder JavaDoc());
120         }
121         return separatorBorder;
122     }
123
124     /**
125      * Returns an etched border instance for <code>JMenuBar</code> or <code>JToolBar</code>.
126      */

127     static Border JavaDoc getEtchedBorder() {
128         if (etchedBorder == null) {
129             etchedBorder = new BorderUIResource.CompoundBorderUIResource JavaDoc(
130                                     new EtchedBorder(),
131                                     new BasicBorders.MarginBorder JavaDoc());
132         }
133         return etchedBorder;
134     }
135
136     /**
137      * Returns a special border for a <code>JMenuBar</code> that
138      * is used in a header just above a <code>JToolBar</code>.
139      */

140     static Border JavaDoc getMenuBarHeaderBorder() {
141         if (menuBarHeaderBorder == null) {
142             menuBarHeaderBorder = new BorderUIResource.CompoundBorderUIResource JavaDoc(
143                                         new MenuBarHeaderBorder(),
144                                         new BasicBorders.MarginBorder JavaDoc());
145         }
146         return menuBarHeaderBorder;
147     }
148
149     /**
150      * Returns a border instance for a <code>JPopupMenu</code>.
151      *
152      * @return the lazily created popup menu border
153      */

154     static Border JavaDoc getPopupMenuBorder() {
155         if (popupMenuBorder == null) {
156             popupMenuBorder = new PopupMenuBorder();
157         }
158         return popupMenuBorder;
159     }
160
161     /**
162      * Returns a special border for a <code>JToolBar</code> that
163      * is used in a header just below a <code>JMenuBar</code>.
164      */

165     static Border JavaDoc getToolBarHeaderBorder() {
166         if (toolBarHeaderBorder == null) {
167             toolBarHeaderBorder = new BorderUIResource.CompoundBorderUIResource JavaDoc(
168                                         new ToolBarHeaderBorder(),
169                                         new BasicBorders.MarginBorder JavaDoc());
170         }
171         return toolBarHeaderBorder;
172     }
173
174     /**
175      * Returns a border for a rollover <code>AbstractButton</code>.
176      */

177     static Border JavaDoc getRolloverButtonBorder() {
178         if (rolloverButtonBorder == null) {
179             rolloverButtonBorder = new BorderUIResource.CompoundBorderUIResource JavaDoc(
180                                         new RolloverButtonBorder(),
181                                         new RolloverMarginBorder());
182         }
183         return rolloverButtonBorder;
184     }
185
186
187     // Helper Classes *******************************************************************
188

189
190     // Copied from BasicBorders, has correct black color for the outer default rectangle.
191
private static class ButtonBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
192     
193         private static final Insets JavaDoc EMPTY_INSETS = new Insets JavaDoc(0, 0, 0, 0);
194         
195         private final Color JavaDoc shadow;
196         private final Color JavaDoc darkShadow;
197         private final Color JavaDoc highlight;
198         private final Color JavaDoc lightHighlight;
199         private final Color JavaDoc defaultColor;
200
201         public ButtonBorder(Color JavaDoc shadow, Color JavaDoc darkShadow,
202                              Color JavaDoc highlight, Color JavaDoc lightHighlight, Color JavaDoc defaultColor) {
203             this.shadow = shadow;
204             this.darkShadow = darkShadow;
205             this.highlight = highlight;
206             this.lightHighlight = lightHighlight;
207             this.defaultColor = defaultColor;
208         }
209
210         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int width, int height) {
211             boolean isPressed = false;
212             boolean isDefault = false;
213       
214             if (c instanceof AbstractButton JavaDoc) {
215                 AbstractButton JavaDoc b = (AbstractButton JavaDoc)c;
216                 ButtonModel JavaDoc model = b.getModel();
217     
218                 isPressed = model.isPressed() && model.isArmed();
219                 if (c instanceof JButton JavaDoc) {
220                     isDefault = ((JButton JavaDoc)c).isDefaultButton();
221                 }
222             }
223             drawBezel(g, x, y, width, height, isPressed, isDefault, shadow,
224                       darkShadow, highlight, lightHighlight, defaultColor);
225         }
226
227         public Insets JavaDoc getBorderInsets(Component JavaDoc c) {
228             return getBorderInsets(c, EMPTY_INSETS);
229         }
230
231         public Insets JavaDoc getBorderInsets(Component JavaDoc c, Insets JavaDoc insets) {
232             // leave room for default visual
233
insets.top = 2;
234             insets.left = insets.bottom = insets.right = 3;
235             return insets;
236         }
237
238     }
239
240     /**
241      * An abstract superclass for borders.
242      */

243     private static abstract class AbstractButtonBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
244
245         private static final Insets JavaDoc INSETS = new Insets JavaDoc(2, 2, 2, 2);
246
247         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
248             AbstractButton JavaDoc button = (AbstractButton JavaDoc) c;
249             ButtonModel JavaDoc model = button.getModel();
250
251             //
252
//System.out.println("Pressed=" + model.isPressed() + "; armed=" + model.isArmed());
253
//if (!model.isArmed()) return;
254

255             if (model.isPressed())
256                 WindowsUtils.drawPressed3DBorder(g, x, y, w, h);
257             else
258                 WindowsUtils.drawFlush3DBorder(g, x, y, w, h);
259         }
260
261         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
262     }
263     
264
265     /**
266      * A border used for <code>Buttons</code> that have the rollover property enabled.
267      */

268     private static class RolloverButtonBorder extends AbstractButtonBorder {
269         
270         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
271             AbstractButton JavaDoc b = (AbstractButton JavaDoc) c;
272             ButtonModel JavaDoc model = b.getModel();
273
274             if (!model.isEnabled())
275                 return;
276
277             if (!(c instanceof JToggleButton JavaDoc)) {
278                 if (model.isRollover()) // && !( model.isPressed() && !model.isArmed()))
279
super.paintBorder(c, g, x, y, w, h);
280                 return;
281             }
282
283             if (model.isSelected())
284                 WindowsUtils.drawPressed3DBorder(g, x, y, w, h);
285             else if (model.isRollover()) {
286                 super.paintBorder(c, g, x, y, w, h);
287                 /*
288                 if (model.isPressed() && model.isArmed()) {
289                 ExtMetalUtils.drawPressed3DBorder(g, x, y, w, h);
290                 } else {
291                 ExtMetalUtils.drawFlush3DBorder(g, x, y, w, h);
292                 }*/

293             }
294         }
295     }
296
297
298     /**
299      * A border which is like a Margin border but it will only honor the margin
300      * if the margin has been explicitly set by the developer.
301      */

302     private static class RolloverMarginBorder extends EmptyBorder JavaDoc {
303
304         private RolloverMarginBorder() {
305             super(1, 1, 1, 1);
306         }
307
308
309         public Insets JavaDoc getBorderInsets(Component JavaDoc c) {
310             return getBorderInsets(c, new Insets JavaDoc(0, 0, 0, 0));
311         }
312
313
314         public Insets JavaDoc getBorderInsets(Component JavaDoc c, Insets JavaDoc insets) {
315             Insets JavaDoc margin = null;
316
317             if (c instanceof AbstractButton JavaDoc) {
318                 margin = ((AbstractButton JavaDoc) c).getMargin();
319             }
320             if (margin == null || margin instanceof UIResource JavaDoc) {
321                 // default margin so replace
322
insets.left = left;
323                 insets.top = top;
324                 insets.right = right;
325                 insets.bottom = bottom;
326             } else {
327                 // Margin which has been explicitly set by the user.
328
insets.left = margin.left;
329                 insets.top = margin.top;
330                 insets.right = margin.right;
331                 insets.bottom = margin.bottom;
332             }
333             return insets;
334         }
335     }
336
337     /**
338      * A border that looks like a separator line; used for menu bars and tool bars.
339      */

340     private static class SeparatorBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
341
342         private static final Insets JavaDoc INSETS = new Insets JavaDoc(0, 3, 2, 1);
343
344         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
345             g.translate(x, y);
346             g.setColor( UIManager.getColor("Separator.foreground"));
347             g.drawLine( 0, h - 2, w - 1, h - 2 );
348
349             g.setColor( UIManager.getColor("Separator.background"));
350             g.drawLine( 0, h - 1, w - 1, h - 1 );
351             g.translate(-x, -y);
352         }
353         
354         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
355     }
356
357
358     /**
359      * A thin raised border.
360      */

361     static class ThinRaisedBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
362
363         private static final Insets JavaDoc INSETS = new Insets JavaDoc(1, 1, 1, 1);
364
365         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
366             WindowsUtils.drawFlush3DBorder(g, x, y, w, h);
367         }
368         
369         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
370     }
371     
372     
373     /**
374      * A thin lowered border.
375      */

376     static class ThinLoweredBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
377
378         private static final Insets JavaDoc INSETS = new Insets JavaDoc(1, 1, 1, 1);
379
380         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
381             WindowsUtils.drawPressed3DBorder(g, x, y, w, h);
382         }
383         
384         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
385     }
386     
387     
388     /**
389      * A border used for menu bars and tool bars in <code>HeaderStyle.SINGLE</code>.
390      * The bar is wrapped by an inner thin raised border,
391      * which in turn is wrapped by an outer thin lowered border.
392      */

393     private static class EtchedBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
394
395         private static final Insets JavaDoc INSETS = new Insets JavaDoc(2, 2, 2, 2);
396
397         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
398             WindowsUtils.drawPressed3DBorder(g, x, y, w, h);
399             WindowsUtils.drawFlush3DBorder (g, x + 1, y + 1, w - 2, h - 2);
400         }
401
402         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
403     }
404     
405     
406     /**
407      * A border used for menu bars in <code>HeaderStyle.BOTH</code>.
408      * The menu bar and tool bar are wrapped by a thin raised border,
409      * both together are wrapped by a thin lowered border.
410      */

411     private static class MenuBarHeaderBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
412
413         private static final Insets JavaDoc INSETS = new Insets JavaDoc(2, 2, 1, 2);
414
415         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
416             WindowsUtils.drawPressed3DBorder(g, x, y, w, h + 1);
417             WindowsUtils.drawFlush3DBorder (g, x + 1, y + 1, w - 2, h - 1);
418         }
419
420         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
421     }
422     
423     
424     private static class PopupMenuBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
425         private static final Insets JavaDoc INSETS = new Insets JavaDoc(3, 3, 3, 3);
426
427         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
428             g.translate(x, y);
429             g.setColor(UIManager.getColor("controlShadow"));
430             g.drawRect(0, 0, w-1, h-1);
431             g.setColor(UIManager.getColor("MenuItem.background"));
432             g.drawRect(1, 1, w-3, h-3);
433             g.drawRect(2, 2, w-5, h-5);
434             g.translate(-x, -y);
435         }
436
437         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
438     }
439     
440
441     /**
442      * A border used for tool bars in <code>HeaderStyle.BOTH</code>.
443      * The menu bar and tool bar are wrapped by a thin raised border,
444      * both together are wrapped by a thin lowered border.
445      */

446     private static class ToolBarHeaderBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
447
448         private static final Insets JavaDoc INSETS = new Insets JavaDoc(1, 2, 2, 2);
449
450         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
451             WindowsUtils.drawPressed3DBorder(g, x, y - 1, w, h + 1);
452             WindowsUtils.drawFlush3DBorder (g, x + 1, y, w - 2, h - 1);
453         }
454
455         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
456     }
457     
458     
459     /**
460      * A border used for menus.
461      */

462     private static class MenuBorder extends AbstractBorder JavaDoc implements UIResource JavaDoc {
463         
464         private static final Insets JavaDoc INSETS = new Insets JavaDoc(1, 1, 1, 1);
465
466         public void paintBorder(Component JavaDoc c, Graphics JavaDoc g, int x, int y, int w, int h) {
467             AbstractButton JavaDoc b = (AbstractButton JavaDoc) c;
468             ButtonModel JavaDoc model = b.getModel();
469
470             //System.out.println("rollover=" + model.isRollover());
471
//if ((3 < 4) || model.isRollover()) { // && !(model.isPressed() && !model.isArmed())) {
472
if (model.isSelected())
473                 WindowsUtils.drawPressed3DBorder(g, x, y, w, h);
474             else if (model.isRollover())
475                 WindowsUtils.drawFlush3DBorder(g, x, y, w, h);
476             //}
477
}
478         
479         public Insets JavaDoc getBorderInsets(Component JavaDoc c) { return INSETS; }
480
481     }
482
483
484     // Helper Code **********************************************************************
485

486     // Copied from BasicGraphicsUtils, has an additional color for the default rectangle.
487
private static void drawBezel(Graphics JavaDoc g, int x, int y, int w, int h,
488                                  boolean isPressed, boolean isDefault,
489                                  Color JavaDoc shadow, Color JavaDoc darkShadow,
490                                  Color JavaDoc highlight, Color JavaDoc lightHighlight, Color JavaDoc defaultColor)
491     {
492         Color JavaDoc oldColor = g.getColor(); // Make no net change to g
493
g.translate(x, y);
494         
495         if (isPressed && isDefault) {
496             g.setColor(darkShadow);
497             g.drawRect(0, 0, w - 1, h - 1);
498             g.setColor(shadow);
499             g.drawRect(1, 1, w - 3, h - 3);
500         } else if (isPressed) {
501             BasicGraphicsUtils.drawLoweredBezel(g, x, y, w, h,
502                              shadow, darkShadow, highlight, lightHighlight);
503         } else if (isDefault) {
504             g.setColor(defaultColor);
505             g.drawRect(0, 0, w-1, h-1);
506
507             g.setColor(lightHighlight);
508             g.drawLine(1, 1, 1, h-3);
509             g.drawLine(2, 1, w-3, 1);
510
511             g.setColor(highlight);
512             g.drawLine(2, 2, 2, h-4);
513             g.drawLine(3, 2, w-4, 2);
514
515             g.setColor(shadow);
516             g.drawLine(2, h-3, w-3, h-3);
517             g.drawLine(w-3, 2, w-3, h-4);
518
519             g.setColor(darkShadow);
520             g.drawLine(1, h-2, w-2, h-2);
521             g.drawLine(w-2, h-2, w-2, 1);
522         } else {
523             g.setColor(lightHighlight);
524             g.drawLine(0, 0, 0, h-1);
525             g.drawLine(1, 0, w-2, 0);
526
527             g.setColor(highlight);
528             g.drawLine(1, 1, 1, h-3);
529             g.drawLine(2, 1, w-3, 1);
530
531             g.setColor(shadow);
532             g.drawLine(1, h-2, w-2, h-2);
533             g.drawLine(w-2, 1, w-2, h-3);
534
535             g.setColor(darkShadow);
536             g.drawLine(0, h-1, w-1, h-1);
537             g.drawLine(w-1, h-1, w-1, 0);
538         }
539         g.translate(-x, -y);
540         g.setColor(oldColor);
541     }
542
543 }
Popular Tags