1 /*
   2  * Copyright (c) 1997, 2011, 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;
  26 
  27 import java.awt.BasicStroke;
  28 import java.awt.Color;
  29 import java.awt.Font;
  30 import java.awt.Paint;
  31 import javax.swing.border.*;
  32 
  33 /**
  34  * Factory class for vending standard <code>Border</code> objects.  Wherever
  35  * possible, this factory will hand out references to shared
  36  * <code>Border</code> instances.
  37  * For further information and examples see
  38  * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/border.html">How
  39  to Use Borders</a>,
  40  * a section in <em>The Java Tutorial</em>.
  41  *
  42  * @author David Kloba
  43  */
  44 public class BorderFactory
  45 {
  46 
  47     /** Don't let anyone instantiate this class */
  48     private BorderFactory() {
  49     }
  50 
  51 
  52 //// LineBorder ///////////////////////////////////////////////////////////////
  53     /**
  54      * Creates a line border withe the specified color.
  55      *
  56      * @param color  a <code>Color</code> to use for the line
  57      * @return the <code>Border</code> object
  58      */
  59     public static Border createLineBorder(Color color) {
  60         return new LineBorder(color, 1);
  61     }
  62 
  63     /**
  64      * Creates a line border with the specified color
  65      * and width. The width applies to all four sides of the
  66      * border. To specify widths individually for the top,
  67      * bottom, left, and right, use
  68      * {@link #createMatteBorder(int,int,int,int,Color)}.
  69      *
  70      * @param color  a <code>Color</code> to use for the line
  71      * @param thickness  an integer specifying the width in pixels
  72      * @return the <code>Border</code> object
  73      */
  74     public static Border createLineBorder(Color color, int thickness)  {
  75         return new LineBorder(color, thickness);
  76     }
  77 
  78     /**
  79      * Creates a line border with the specified color, thickness, and corner shape.
  80      *
  81      * @param color      the color of the border
  82      * @param thickness  the thickness of the border
  83      * @param rounded    whether or not border corners should be round
  84      * @return the {@code Border} object
  85      *
  86      * @see LineBorder#LineBorder(Color, int, boolean)
  87      * @since 1.7
  88      */
  89     public static Border createLineBorder(Color color, int thickness, boolean rounded) {
  90         return new LineBorder(color, thickness, rounded);
  91     }
  92 
  93 //// BevelBorder /////////////////////////////////////////////////////////////
  94 ///////////////////////////////////////////////////////////////////////////////
  95     static final Border sharedRaisedBevel = new BevelBorder(BevelBorder.RAISED);
  96     static final Border sharedLoweredBevel = new BevelBorder(BevelBorder.LOWERED);
  97 
  98     /**
  99      * Creates a border with a raised beveled edge, using
 100      * brighter shades of the component's current background color
 101      * for highlighting, and darker shading for shadows.
 102      * (In a raised border, highlights are on top and shadows
 103      *  are underneath.)
 104      *
 105      * @return the <code>Border</code> object
 106      */
 107     public static Border createRaisedBevelBorder() {
 108         return createSharedBevel(BevelBorder.RAISED);
 109     }
 110 
 111     /**
 112      * Creates a border with a lowered beveled edge, using
 113      * brighter shades of the component's current background color
 114      * for highlighting, and darker shading for shadows.
 115      * (In a lowered border, shadows are on top and highlights
 116      *  are underneath.)
 117      *
 118      * @return the <code>Border</code> object
 119      */
 120     public static Border createLoweredBevelBorder() {
 121         return createSharedBevel(BevelBorder.LOWERED);
 122     }
 123 
 124     /**
 125      * Creates a beveled border of the specified type, using
 126      * brighter shades of the component's current background color
 127      * for highlighting, and darker shading for shadows.
 128      * (In a lowered border, shadows are on top and highlights
 129      *  are underneath.)
 130      *
 131      * @param type  an integer specifying either
 132      *                  <code>BevelBorder.LOWERED</code> or
 133      *                  <code>BevelBorder.RAISED</code>
 134      * @return the <code>Border</code> object
 135      */
 136     public static Border createBevelBorder(int type) {
 137         return createSharedBevel(type);
 138     }
 139 
 140     /**
 141      * Creates a beveled border of the specified type, using
 142      * the specified highlighting and shadowing. The outer
 143      * edge of the highlighted area uses a brighter shade of
 144      * the highlight color. The inner edge of the shadow area
 145      * uses a brighter shade of the shadow color.
 146      *
 147      * @param type  an integer specifying either
 148      *                  <code>BevelBorder.LOWERED</code> or
 149      *                  <code>BevelBorder.RAISED</code>
 150      * @param highlight  a <code>Color</code> object for highlights
 151      * @param shadow     a <code>Color</code> object for shadows
 152      * @return the <code>Border</code> object
 153      */
 154     public static Border createBevelBorder(int type, Color highlight, Color shadow) {
 155         return new BevelBorder(type, highlight, shadow);
 156     }
 157 
 158     /**
 159      * Creates a beveled border of the specified type, using
 160      * the specified colors for the inner and outer highlight
 161      * and shadow areas.
 162      *
 163      * @param type  an integer specifying either
 164      *          <code>BevelBorder.LOWERED</code> or
 165      *          <code>BevelBorder.RAISED</code>
 166      * @param highlightOuter  a <code>Color</code> object for the
 167      *                  outer edge of the highlight area
 168      * @param highlightInner  a <code>Color</code> object for the
 169      *                  inner edge of the highlight area
 170      * @param shadowOuter     a <code>Color</code> object for the
 171      *                  outer edge of the shadow area
 172      * @param shadowInner     a <code>Color</code> object for the
 173      *                  inner edge of the shadow area
 174      * @return the <code>Border</code> object
 175      */
 176     public static Border createBevelBorder(int type,
 177                         Color highlightOuter, Color highlightInner,
 178                         Color shadowOuter, Color shadowInner) {
 179         return new BevelBorder(type, highlightOuter, highlightInner,
 180                                         shadowOuter, shadowInner);
 181     }
 182 
 183     static Border createSharedBevel(int type)   {
 184         if(type == BevelBorder.RAISED) {
 185             return sharedRaisedBevel;
 186         } else if(type == BevelBorder.LOWERED) {
 187             return sharedLoweredBevel;
 188         }
 189         return null;
 190     }
 191 
 192 //// SoftBevelBorder ///////////////////////////////////////////////////////////
 193 ////////////////////////////////////////////////////////////////////////////////
 194 
 195     private static Border sharedSoftRaisedBevel;
 196     private static Border sharedSoftLoweredBevel;
 197 
 198     /**
 199      * Creates a beveled border with a raised edge and softened corners,
 200      * using brighter shades of the component's current background color
 201      * for highlighting, and darker shading for shadows.
 202      * In a raised border, highlights are on top and shadows are underneath.
 203      *
 204      * @return the {@code Border} object
 205      *
 206      * @since 1.7
 207      */
 208     public static Border createRaisedSoftBevelBorder() {
 209         if (sharedSoftRaisedBevel == null) {
 210             sharedSoftRaisedBevel = new SoftBevelBorder(BevelBorder.RAISED);
 211         }
 212         return sharedSoftRaisedBevel;
 213     }
 214 
 215     /**
 216      * Creates a beveled border with a lowered edge and softened corners,
 217      * using brighter shades of the component's current background color
 218      * for highlighting, and darker shading for shadows.
 219      * In a lowered border, shadows are on top and highlights are underneath.
 220      *
 221      * @return the {@code Border} object
 222      *
 223      * @since 1.7
 224      */
 225     public static Border createLoweredSoftBevelBorder() {
 226         if (sharedSoftLoweredBevel == null) {
 227             sharedSoftLoweredBevel = new SoftBevelBorder(BevelBorder.LOWERED);
 228         }
 229         return sharedSoftLoweredBevel;
 230     }
 231 
 232     /**
 233      * Creates a beveled border of the specified type with softened corners,
 234      * using brighter shades of the component's current background color
 235      * for highlighting, and darker shading for shadows.
 236      * The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
 237      *
 238      * @param type  a type of a bevel
 239      * @return the {@code Border} object or {@code null}
 240      *         if the specified type is not valid
 241      *
 242      * @see BevelBorder#BevelBorder(int)
 243      * @since 1.7
 244      */
 245     public static Border createSoftBevelBorder(int type) {
 246         if (type == BevelBorder.RAISED) {
 247             return createRaisedSoftBevelBorder();
 248         }
 249         if (type == BevelBorder.LOWERED) {
 250             return createLoweredSoftBevelBorder();
 251         }
 252         return null;
 253     }
 254 
 255     /**
 256      * Creates a beveled border of the specified type with softened corners,
 257      * using the specified highlighting and shadowing.
 258      * The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
 259      * The outer edge of the highlight area uses
 260      * a brighter shade of the {@code highlight} color.
 261      * The inner edge of the shadow area uses
 262      * a brighter shade of the {@code shadow} color.
 263      *
 264      * @param type       a type of a bevel
 265      * @param highlight  a basic color of the highlight area
 266      * @param shadow     a basic color of the shadow area
 267      * @return the {@code Border} object
 268      *
 269      * @see BevelBorder#BevelBorder(int, Color, Color)
 270      * @since 1.7
 271      */
 272     public static Border createSoftBevelBorder(int type, Color highlight, Color shadow) {
 273         return new SoftBevelBorder(type, highlight, shadow);
 274     }
 275 
 276     /**
 277      * Creates a beveled border of the specified type with softened corners,
 278      * using the specified colors for the inner and outer edges
 279      * of the highlight and the shadow areas.
 280      * The type is either {@link BevelBorder#RAISED} or {@link BevelBorder#LOWERED}.
 281      * Note: The shadow inner and outer colors are switched
 282      * for a lowered bevel border.
 283      *
 284      * @param type            a type of a bevel
 285      * @param highlightOuter  a color of the outer edge of the highlight area
 286      * @param highlightInner  a color of the inner edge of the highlight area
 287      * @param shadowOuter     a color of the outer edge of the shadow area
 288      * @param shadowInner     a color of the inner edge of the shadow area
 289      * @return the {@code Border} object
 290      *
 291      * @see BevelBorder#BevelBorder(int, Color, Color, Color, Color)
 292      * @since 1.7
 293      */
 294     public static Border createSoftBevelBorder(int type, Color highlightOuter, Color highlightInner, Color shadowOuter, Color shadowInner) {
 295         return new SoftBevelBorder(type, highlightOuter, highlightInner, shadowOuter, shadowInner);
 296     }
 297 
 298 //// EtchedBorder ///////////////////////////////////////////////////////////
 299 
 300     static final Border sharedEtchedBorder = new EtchedBorder();
 301     private static Border sharedRaisedEtchedBorder;
 302 
 303     /**
 304      * Creates a border with an "etched" look using
 305      * the component's current background color for
 306      * highlighting and shading.
 307      *
 308      * @return the <code>Border</code> object
 309      */
 310     public static Border createEtchedBorder()    {
 311         return sharedEtchedBorder;
 312     }
 313 
 314     /**
 315      * Creates a border with an "etched" look using
 316      * the specified highlighting and shading colors.
 317      *
 318      * @param highlight  a <code>Color</code> object for the border highlights
 319      * @param shadow     a <code>Color</code> object for the border shadows
 320      * @return the <code>Border</code> object
 321      */
 322     public static Border createEtchedBorder(Color highlight, Color shadow)    {
 323         return new EtchedBorder(highlight, shadow);
 324     }
 325 
 326     /**
 327      * Creates a border with an "etched" look using
 328      * the component's current background color for
 329      * highlighting and shading.
 330      *
 331      * @param type      one of <code>EtchedBorder.RAISED</code>, or
 332      *                  <code>EtchedBorder.LOWERED</code>
 333      * @return the <code>Border</code> object
 334      * @exception IllegalArgumentException if type is not either
 335      *                  <code>EtchedBorder.RAISED</code> or
 336      *                  <code>EtchedBorder.LOWERED</code>
 337      * @since 1.3
 338      */
 339     public static Border createEtchedBorder(int type)    {
 340         switch (type) {
 341         case EtchedBorder.RAISED:
 342             if (sharedRaisedEtchedBorder == null) {
 343                 sharedRaisedEtchedBorder = new EtchedBorder
 344                                            (EtchedBorder.RAISED);
 345             }
 346             return sharedRaisedEtchedBorder;
 347         case EtchedBorder.LOWERED:
 348             return sharedEtchedBorder;
 349         default:
 350             throw new IllegalArgumentException("type must be one of EtchedBorder.RAISED or EtchedBorder.LOWERED");
 351         }
 352     }
 353 
 354     /**
 355      * Creates a border with an "etched" look using
 356      * the specified highlighting and shading colors.
 357      *
 358      * @param type      one of <code>EtchedBorder.RAISED</code>, or
 359      *                  <code>EtchedBorder.LOWERED</code>
 360      * @param highlight  a <code>Color</code> object for the border highlights
 361      * @param shadow     a <code>Color</code> object for the border shadows
 362      * @return the <code>Border</code> object
 363      * @since 1.3
 364      */
 365     public static Border createEtchedBorder(int type, Color highlight,
 366                                             Color shadow)    {
 367         return new EtchedBorder(type, highlight, shadow);
 368     }
 369 
 370 //// TitledBorder ////////////////////////////////////////////////////////////
 371     /**
 372      * Creates a new titled border with the specified title,
 373      * the default border type (determined by the current look and feel),
 374      * the default text position (determined by the current look and feel),
 375      * the default justification (leading), and the default
 376      * font and text color (determined by the current look and feel).
 377      *
 378      * @param title      a <code>String</code> containing the text of the title
 379      * @return the <code>TitledBorder</code> object
 380      */
 381     public static TitledBorder createTitledBorder(String title)     {
 382         return new TitledBorder(title);
 383     }
 384 
 385     /**
 386      * Creates a new titled border with an empty title,
 387      * the specified border object,
 388      * the default text position (determined by the current look and feel),
 389      * the default justification (leading), and the default
 390      * font and text color (determined by the current look and feel).
 391      *
 392      * @param border     the <code>Border</code> object to add the title to; if
 393      *                   <code>null</code> the <code>Border</code> is determined
 394      *                   by the current look and feel.
 395      * @return the <code>TitledBorder</code> object
 396      */
 397     public static TitledBorder createTitledBorder(Border border)       {
 398         return new TitledBorder(border);
 399     }
 400 
 401     /**
 402      * Adds a title to an existing border,
 403      * with default positioning (determined by the current look and feel),
 404      * default justification (leading) and the default
 405      * font and text color (determined by the current look and feel).
 406      *
 407      * @param border     the <code>Border</code> object to add the title to
 408      * @param title      a <code>String</code> containing the text of the title
 409      * @return the <code>TitledBorder</code> object
 410      */
 411     public static TitledBorder createTitledBorder(Border border,
 412                                                    String title) {
 413         return new TitledBorder(border, title);
 414     }
 415 
 416     /**
 417      * Adds a title to an existing border, with the specified
 418      * positioning and using the default
 419      * font and text color (determined by the current look and feel).
 420      *
 421      * @param border      the <code>Border</code> object to add the title to
 422      * @param title       a <code>String</code> containing the text of the title
 423      * @param titleJustification  an integer specifying the justification
 424      *        of the title -- one of the following:
 425      *<ul>
 426      *<li><code>TitledBorder.LEFT</code>
 427      *<li><code>TitledBorder.CENTER</code>
 428      *<li><code>TitledBorder.RIGHT</code>
 429      *<li><code>TitledBorder.LEADING</code>
 430      *<li><code>TitledBorder.TRAILING</code>
 431      *<li><code>TitledBorder.DEFAULT_JUSTIFICATION</code> (leading)
 432      *</ul>
 433      * @param titlePosition       an integer specifying the vertical position of
 434      *        the text in relation to the border -- one of the following:
 435      *<ul>
 436      *<li><code> TitledBorder.ABOVE_TOP</code>
 437      *<li><code>TitledBorder.TOP</code> (sitting on the top line)
 438      *<li><code>TitledBorder.BELOW_TOP</code>
 439      *<li><code>TitledBorder.ABOVE_BOTTOM</code>
 440      *<li><code>TitledBorder.BOTTOM</code> (sitting on the bottom line)
 441      *<li><code>TitledBorder.BELOW_BOTTOM</code>
 442      *<li><code>TitledBorder.DEFAULT_POSITION</code> (the title position
 443      *  is determined by the current look and feel)
 444      *</ul>
 445      * @return the <code>TitledBorder</code> object
 446      */
 447     public static TitledBorder createTitledBorder(Border border,
 448                         String title,
 449                         int titleJustification,
 450                         int titlePosition)      {
 451         return new TitledBorder(border, title, titleJustification,
 452                         titlePosition);
 453     }
 454 
 455     /**
 456      * Adds a title to an existing border, with the specified
 457      * positioning and font, and using the default text color
 458      * (determined by the current look and feel).
 459      *
 460      * @param border      the <code>Border</code> object to add the title to
 461      * @param title       a <code>String</code> containing the text of the title
 462      * @param titleJustification  an integer specifying the justification
 463      *        of the title -- one of the following:
 464      *<ul>
 465      *<li><code>TitledBorder.LEFT</code>
 466      *<li><code>TitledBorder.CENTER</code>
 467      *<li><code>TitledBorder.RIGHT</code>
 468      *<li><code>TitledBorder.LEADING</code>
 469      *<li><code>TitledBorder.TRAILING</code>
 470      *<li><code>TitledBorder.DEFAULT_JUSTIFICATION</code> (leading)
 471      *</ul>
 472      * @param titlePosition       an integer specifying the vertical position of
 473      *        the text in relation to the border -- one of the following:
 474      *<ul>
 475      *<li><code> TitledBorder.ABOVE_TOP</code>
 476      *<li><code>TitledBorder.TOP</code> (sitting on the top line)
 477      *<li><code>TitledBorder.BELOW_TOP</code>
 478      *<li><code>TitledBorder.ABOVE_BOTTOM</code>
 479      *<li><code>TitledBorder.BOTTOM</code> (sitting on the bottom line)
 480      *<li><code>TitledBorder.BELOW_BOTTOM</code>
 481      *<li><code>TitledBorder.DEFAULT_POSITION</code> (the title position
 482      *  is determined by the current look and feel)
 483      *</ul>
 484      * @param titleFont           a Font object specifying the title font
 485      * @return the TitledBorder object
 486      */
 487     public static TitledBorder createTitledBorder(Border border,
 488                         String title,
 489                         int titleJustification,
 490                         int titlePosition,
 491                         Font titleFont) {
 492         return new TitledBorder(border, title, titleJustification,
 493                         titlePosition, titleFont);
 494     }
 495 
 496     /**
 497      * Adds a title to an existing border, with the specified
 498      * positioning, font and color.
 499      *
 500      * @param border      the <code>Border</code> object to add the title to
 501      * @param title       a <code>String</code> containing the text of the title
 502      * @param titleJustification  an integer specifying the justification
 503      *        of the title -- one of the following:
 504      *<ul>
 505      *<li><code>TitledBorder.LEFT</code>
 506      *<li><code>TitledBorder.CENTER</code>
 507      *<li><code>TitledBorder.RIGHT</code>
 508      *<li><code>TitledBorder.LEADING</code>
 509      *<li><code>TitledBorder.TRAILING</code>
 510      *<li><code>TitledBorder.DEFAULT_JUSTIFICATION</code> (leading)
 511      *</ul>
 512      * @param titlePosition       an integer specifying the vertical position of
 513      *        the text in relation to the border -- one of the following:
 514      *<ul>
 515      *<li><code> TitledBorder.ABOVE_TOP</code>
 516      *<li><code>TitledBorder.TOP</code> (sitting on the top line)
 517      *<li><code>TitledBorder.BELOW_TOP</code>
 518      *<li><code>TitledBorder.ABOVE_BOTTOM</code>
 519      *<li><code>TitledBorder.BOTTOM</code> (sitting on the bottom line)
 520      *<li><code>TitledBorder.BELOW_BOTTOM</code>
 521      *<li><code>TitledBorder.DEFAULT_POSITION</code> (the title position
 522      *  is determined by the current look and feel)
 523      *</ul>
 524      * @param titleFont   a <code>Font</code> object specifying the title font
 525      * @param titleColor  a <code>Color</code> object specifying the title color
 526      * @return the <code>TitledBorder</code> object
 527      */
 528     public static TitledBorder createTitledBorder(Border border,
 529                         String title,
 530                         int titleJustification,
 531                         int titlePosition,
 532                         Font titleFont,
 533                         Color titleColor)       {
 534         return new TitledBorder(border, title, titleJustification,
 535                         titlePosition, titleFont, titleColor);
 536     }
 537 //// EmptyBorder ///////////////////////////////////////////////////////////
 538     final static Border emptyBorder = new EmptyBorder(0, 0, 0, 0);
 539 
 540     /**
 541      * Creates an empty border that takes up no space. (The width
 542      * of the top, bottom, left, and right sides are all zero.)
 543      *
 544      * @return the <code>Border</code> object
 545      */
 546     public static Border createEmptyBorder() {
 547         return emptyBorder;
 548     }
 549 
 550     /**
 551      * Creates an empty border that takes up space but which does
 552      * no drawing, specifying the width of the top, left, bottom, and
 553      * right sides.
 554      *
 555      * @param top     an integer specifying the width of the top,
 556      *                  in pixels
 557      * @param left    an integer specifying the width of the left side,
 558      *                  in pixels
 559      * @param bottom  an integer specifying the width of the bottom,
 560      *                  in pixels
 561      * @param right   an integer specifying the width of the right side,
 562      *                  in pixels
 563      * @return the <code>Border</code> object
 564      */
 565     public static Border createEmptyBorder(int top, int left,
 566                                                 int bottom, int right) {
 567         return new EmptyBorder(top, left, bottom, right);
 568     }
 569 
 570 //// CompoundBorder ////////////////////////////////////////////////////////
 571     /**
 572      * Creates a compound border with a <code>null</code> inside edge and a
 573      * <code>null</code> outside edge.
 574      *
 575      * @return the <code>CompoundBorder</code> object
 576      */
 577     public static CompoundBorder createCompoundBorder() {
 578         return new CompoundBorder();
 579     }
 580 
 581     /**
 582      * Creates a compound border specifying the border objects to use
 583      * for the outside and inside edges.
 584      *
 585      * @param outsideBorder  a <code>Border</code> object for the outer
 586      *                          edge of the compound border
 587      * @param insideBorder   a <code>Border</code> object for the inner
 588      *                          edge of the compound border
 589      * @return the <code>CompoundBorder</code> object
 590      */
 591     public static CompoundBorder createCompoundBorder(Border outsideBorder,
 592                                                 Border insideBorder) {
 593         return new CompoundBorder(outsideBorder, insideBorder);
 594     }
 595 
 596 //// MatteBorder ////////////////////////////////////////////////////////
 597     /**
 598      * Creates a matte-look border using a solid color. (The difference between
 599      * this border and a line border is that you can specify the individual
 600      * border dimensions.)
 601      *
 602      * @param top     an integer specifying the width of the top,
 603      *                          in pixels
 604      * @param left    an integer specifying the width of the left side,
 605      *                          in pixels
 606      * @param bottom  an integer specifying the width of the right side,
 607      *                          in pixels
 608      * @param right   an integer specifying the width of the bottom,
 609      *                          in pixels
 610      * @param color   a <code>Color</code> to use for the border
 611      * @return the <code>MatteBorder</code> object
 612      */
 613     public static MatteBorder createMatteBorder(int top, int left, int bottom, int right,
 614                                                 Color color) {
 615         return new MatteBorder(top, left, bottom, right, color);
 616     }
 617 
 618     /**
 619      * Creates a matte-look border that consists of multiple tiles of a
 620      * specified icon. Multiple copies of the icon are placed side-by-side
 621      * to fill up the border area.
 622      * <p>
 623      * Note:<br>
 624      * If the icon doesn't load, the border area is painted gray.
 625      *
 626      * @param top     an integer specifying the width of the top,
 627      *                          in pixels
 628      * @param left    an integer specifying the width of the left side,
 629      *                          in pixels
 630      * @param bottom  an integer specifying the width of the right side,
 631      *                          in pixels
 632      * @param right   an integer specifying the width of the bottom,
 633      *                          in pixels
 634      * @param tileIcon  the <code>Icon</code> object used for the border tiles
 635      * @return the <code>MatteBorder</code> object
 636      */
 637     public static MatteBorder createMatteBorder(int top, int left, int bottom, int right,
 638                                                 Icon tileIcon) {
 639         return new MatteBorder(top, left, bottom, right, tileIcon);
 640     }
 641 
 642 //// StrokeBorder //////////////////////////////////////////////////////////////
 643 ////////////////////////////////////////////////////////////////////////////////
 644 
 645     /**
 646      * Creates a border of the specified {@code stroke}.
 647      * The component's foreground color will be used to render the border.
 648      *
 649      * @param stroke  the {@link BasicStroke} object used to stroke a shape
 650      * @return the {@code Border} object
 651      *
 652      * @throws NullPointerException if the specified {@code stroke} is {@code null}
 653      *
 654      * @since 1.7
 655      */
 656     public static Border createStrokeBorder(BasicStroke stroke) {
 657         return new StrokeBorder(stroke);
 658     }
 659 
 660     /**
 661      * Creates a border of the specified {@code stroke} and {@code paint}.
 662      * If the specified {@code paint} is {@code null},
 663      * the component's foreground color will be used to render the border.
 664      *
 665      * @param stroke  the {@link BasicStroke} object used to stroke a shape
 666      * @param paint   the {@link Paint} object used to generate a color
 667      * @return the {@code Border} object
 668      *
 669      * @throws NullPointerException if the specified {@code stroke} is {@code null}
 670      *
 671      * @since 1.7
 672      */
 673     public static Border createStrokeBorder(BasicStroke stroke, Paint paint) {
 674         return new StrokeBorder(stroke, paint);
 675     }
 676 
 677 //// DashedBorder //////////////////////////////////////////////////////////////
 678 ////////////////////////////////////////////////////////////////////////////////
 679 
 680     private static Border sharedDashedBorder;
 681 
 682     /**
 683      * Creates a dashed border of the specified {@code paint}.
 684      * If the specified {@code paint} is {@code null},
 685      * the component's foreground color will be used to render the border.
 686      * The width of a dash line is equal to {@code 1}.
 687      * The relative length of a dash line and
 688      * the relative spacing between dash lines are equal to {@code 1}.
 689      * A dash line is not rounded.
 690      *
 691      * @param paint  the {@link Paint} object used to generate a color
 692      * @return the {@code Border} object
 693      *
 694      * @since 1.7
 695      */
 696     public static Border createDashedBorder(Paint paint) {
 697         return createDashedBorder(paint, 1.0f, 1.0f, 1.0f, false);
 698     }
 699 
 700     /**
 701      * Creates a dashed border of the specified {@code paint},
 702      * relative {@code length}, and relative {@code spacing}.
 703      * If the specified {@code paint} is {@code null},
 704      * the component's foreground color will be used to render the border.
 705      * The width of a dash line is equal to {@code 1}.
 706      * A dash line is not rounded.
 707      *
 708      * @param paint    the {@link Paint} object used to generate a color
 709      * @param length   the relative length of a dash line
 710      * @param spacing  the relative spacing between dash lines
 711      * @return the {@code Border} object
 712      *
 713      * @throws IllegalArgumentException if the specified {@code length} is less than {@code 1}, or
 714      *                                  if the specified {@code spacing} is less than {@code 0}
 715      * @since 1.7
 716      */
 717     public static Border createDashedBorder(Paint paint, float length, float spacing) {
 718         return createDashedBorder(paint, 1.0f, length, spacing, false);
 719     }
 720 
 721     /**
 722      * Creates a dashed border of the specified {@code paint}, {@code thickness},
 723      * line shape, relative {@code length}, and relative {@code spacing}.
 724      * If the specified {@code paint} is {@code null},
 725      * the component's foreground color will be used to render the border.
 726      *
 727      * @param paint      the {@link Paint} object used to generate a color
 728      * @param thickness  the width of a dash line
 729      * @param length     the relative length of a dash line
 730      * @param spacing    the relative spacing between dash lines
 731      * @param rounded    whether or not line ends should be round
 732      * @return the {@code Border} object
 733      *
 734      * @throws IllegalArgumentException if the specified {@code thickness} is less than {@code 1}, or
 735      *                                  if the specified {@code length} is less than {@code 1}, or
 736      *                                  if the specified {@code spacing} is less than {@code 0}
 737      * @since 1.7
 738      */
 739     public static Border createDashedBorder(Paint paint, float thickness, float length, float spacing, boolean rounded) {
 740         boolean shared = !rounded && (paint == null) && (thickness == 1.0f) && (length == 1.0f) && (spacing == 1.0f);
 741         if (shared && (sharedDashedBorder != null)) {
 742             return sharedDashedBorder;
 743         }
 744         if (thickness < 1.0f) {
 745             throw new IllegalArgumentException("thickness is less than 1");
 746         }
 747         if (length < 1.0f) {
 748             throw new IllegalArgumentException("length is less than 1");
 749         }
 750         if (spacing < 0.0f) {
 751             throw new IllegalArgumentException("spacing is less than 0");
 752         }
 753         int cap = rounded ? BasicStroke.CAP_ROUND : BasicStroke.CAP_SQUARE;
 754         int join = rounded ? BasicStroke.JOIN_ROUND : BasicStroke.JOIN_MITER;
 755         float[] array = { thickness * (length - 1.0f), thickness * (spacing + 1.0f) };
 756         Border border = createStrokeBorder(new BasicStroke(thickness, cap, join, thickness * 2.0f, array, 0.0f), paint);
 757         if (shared) {
 758             sharedDashedBorder = border;
 759         }
 760         return border;
 761     }
 762 }