src/share/classes/javax/swing/plaf/metal/MetalBorders.java

Print this page


   1 /*
   2  * Copyright (c) 1998, 2013, 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


  39 import java.awt.Graphics;
  40 import java.awt.Window;
  41 
  42 import sun.swing.StringUIClientPropertyKey;
  43 
  44 
  45 /**
  46  * Factory object that can vend Borders appropriate for the metal L & F.
  47  * @author Steve Wilson
  48  */
  49 
  50 public class MetalBorders {
  51 
  52     /**
  53      * Client property indicating the button shouldn't provide a rollover
  54      * indicator. Only used with the Ocean theme.
  55      */
  56     static Object NO_BUTTON_ROLLOVER =
  57         new StringUIClientPropertyKey("NoButtonRollover");
  58 
  59 
  60     public static class Flush3DBorder extends AbstractBorder implements UIResource{
  61         public void paintBorder(Component c, Graphics g, int x, int y,
  62                           int w, int h) {
  63             if (c.isEnabled()) {
  64                 MetalUtils.drawFlush3DBorder(g, x, y, w, h);
  65             } else {
  66                 MetalUtils.drawDisabledBorder(g, x, y, w, h);
  67             }
  68         }
  69 
  70         public Insets getBorderInsets(Component c, Insets newInsets) {
  71             newInsets.set(2, 2, 2, 2);
  72             return newInsets;
  73         }
  74     }
  75 

  76     public static class ButtonBorder extends AbstractBorder implements UIResource {
  77 
  78         protected static Insets borderInsets = new Insets( 3, 3, 3, 3 );
  79 
  80         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
  81             if (!(c instanceof AbstractButton)) {
  82                 return;
  83             }
  84             if (MetalLookAndFeel.usingOcean()) {
  85                 paintOceanBorder(c, g, x, y, w, h);
  86                 return;
  87             }
  88             AbstractButton button = (AbstractButton)c;
  89             ButtonModel model = button.getModel();
  90 
  91             if ( model.isEnabled() ) {
  92                 boolean isPressed = model.isPressed() && model.isArmed();
  93                 boolean isDefault = (button instanceof JButton && ((JButton)button).isDefaultButton());
  94 
  95                 if (isPressed && isDefault) {


 170                 else {
 171                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
 172                     g.drawRect(0, 0, w - 1, h - 1);
 173                 }
 174             }
 175             else {
 176                 g.setColor(MetalLookAndFeel.getInactiveControlTextColor());
 177                 g.drawRect(0, 0, w - 1, h - 1);
 178                 if ((c instanceof JButton) && ((JButton)c).isDefaultButton()) {
 179                     g.drawRect(1, 1, w - 3, h - 3);
 180                 }
 181             }
 182         }
 183 
 184         public Insets getBorderInsets(Component c, Insets newInsets) {
 185             newInsets.set(3, 3, 3, 3);
 186             return newInsets;
 187         }
 188     }
 189 

 190     public static class InternalFrameBorder extends AbstractBorder implements UIResource {
 191         private static final int corner = 14;
 192 
 193         public void paintBorder(Component c, Graphics g, int x, int y,
 194                           int w, int h) {
 195 
 196             Color background;
 197             Color highlight;
 198             Color shadow;
 199 
 200             if (c instanceof JInternalFrame && ((JInternalFrame)c).isSelected()) {
 201                 background = MetalLookAndFeel.getPrimaryControlDarkShadow();
 202                 highlight = MetalLookAndFeel.getPrimaryControlShadow();
 203                 shadow = MetalLookAndFeel.getPrimaryControlInfo();
 204             } else {
 205                 background = MetalLookAndFeel.getControlDarkShadow();
 206                 highlight = MetalLookAndFeel.getControlShadow();
 207                 shadow = MetalLookAndFeel.getControlInfo();
 208             }
 209 


 231                   g.setColor(shadow);
 232                   // Draw the Long shadow lines
 233                   g.drawLine( corner, 2, w-corner-1, 2);
 234                   g.drawLine( 2, corner, 2, h-corner-1);
 235                   g.drawLine( w-3, corner, w-3, h-corner-1);
 236                   g.drawLine( corner, h-3, w-corner-1, h-3);
 237               }
 238 
 239           }
 240 
 241           public Insets getBorderInsets(Component c, Insets newInsets) {
 242               newInsets.set(5, 5, 5, 5);
 243               return newInsets;
 244           }
 245     }
 246 
 247     /**
 248      * Border for a Frame.
 249      * @since 1.4
 250      */

 251     static class FrameBorder extends AbstractBorder implements UIResource {
 252         private static final int corner = 14;
 253 
 254         public void paintBorder(Component c, Graphics g, int x, int y,
 255             int w, int h) {
 256 
 257             Color background;
 258             Color highlight;
 259             Color shadow;
 260 
 261             Window window = SwingUtilities.getWindowAncestor(c);
 262             if (window != null && window.isActive()) {
 263                 background = MetalLookAndFeel.getPrimaryControlDarkShadow();
 264                 highlight = MetalLookAndFeel.getPrimaryControlShadow();
 265                 shadow = MetalLookAndFeel.getPrimaryControlInfo();
 266             } else {
 267                 background = MetalLookAndFeel.getControlDarkShadow();
 268                 highlight = MetalLookAndFeel.getControlShadow();
 269                 shadow = MetalLookAndFeel.getControlInfo();
 270             }


 293                 // Draw the Long shadow lines
 294                 g.drawLine( corner, 2, w-corner-1, 2);
 295                 g.drawLine( 2, corner, 2, h-corner-1);
 296                 g.drawLine( w-3, corner, w-3, h-corner-1);
 297                 g.drawLine( corner, h-3, w-corner-1, h-3);
 298             }
 299 
 300         }
 301 
 302         public Insets getBorderInsets(Component c, Insets newInsets)
 303         {
 304             newInsets.set(5, 5, 5, 5);
 305             return newInsets;
 306         }
 307     }
 308 
 309     /**
 310      * Border for a Frame.
 311      * @since 1.4
 312      */

 313     static class DialogBorder extends AbstractBorder implements UIResource
 314     {
 315         private static final int corner = 14;
 316 
 317         protected Color getActiveBackground()
 318         {
 319             return MetalLookAndFeel.getPrimaryControlDarkShadow();
 320         }
 321 
 322         protected Color getActiveHighlight()
 323         {
 324             return MetalLookAndFeel.getPrimaryControlShadow();
 325         }
 326 
 327         protected Color getActiveShadow()
 328         {
 329             return MetalLookAndFeel.getPrimaryControlInfo();
 330         }
 331 
 332         protected Color getInactiveBackground()


 386                 // Draw the Long shadow lines
 387                 g.drawLine( corner, 2, w-corner-1, 2);
 388                 g.drawLine( 2, corner, 2, h-corner-1);
 389                 g.drawLine( w-3, corner, w-3, h-corner-1);
 390                 g.drawLine( corner, h-3, w-corner-1, h-3);
 391             }
 392 
 393         }
 394 
 395         public Insets getBorderInsets(Component c, Insets newInsets)
 396         {
 397             newInsets.set(5, 5, 5, 5);
 398             return newInsets;
 399         }
 400     }
 401 
 402     /**
 403      * Border for an Error Dialog.
 404      * @since 1.4
 405      */

 406     static class ErrorDialogBorder extends DialogBorder implements UIResource
 407     {
 408         protected Color getActiveBackground() {
 409             return UIManager.getColor("OptionPane.errorDialog.border.background");
 410         }
 411     }
 412 
 413 
 414     /**
 415      * Border for a QuestionDialog.  Also used for a JFileChooser and a
 416      * JColorChooser..
 417      * @since 1.4
 418      */

 419     static class QuestionDialogBorder extends DialogBorder implements UIResource
 420     {
 421         protected Color getActiveBackground() {
 422             return UIManager.getColor("OptionPane.questionDialog.border.background");
 423         }
 424     }
 425 
 426 
 427     /**
 428      * Border for a Warning Dialog.
 429      * @since 1.4
 430      */

 431     static class WarningDialogBorder extends DialogBorder implements UIResource
 432     {
 433         protected Color getActiveBackground() {
 434             return UIManager.getColor("OptionPane.warningDialog.border.background");
 435         }
 436     }
 437 
 438 
 439     /**
 440      * Border for a Palette.
 441      * @since 1.3
 442      */

 443     public static class PaletteBorder extends AbstractBorder implements UIResource {
 444         int titleHeight = 0;
 445 
 446         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 447 
 448             g.translate(x,y);
 449             g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
 450             g.drawLine(0, 1, 0, h-2);
 451             g.drawLine(1, h-1, w-2, h-1);
 452             g.drawLine(w-1,  1, w-1, h-2);
 453             g.drawLine( 1, 0, w-2, 0);
 454             g.drawRect(1,1, w-3, h-3);
 455             g.translate(-x,-y);
 456 
 457         }
 458 
 459         public Insets getBorderInsets(Component c, Insets newInsets) {
 460             newInsets.set(1, 1, 1, 1);
 461             return newInsets;
 462         }
 463     }
 464 

 465     public static class OptionDialogBorder extends AbstractBorder implements UIResource {
 466         int titleHeight = 0;
 467 
 468         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 469 
 470             g.translate(x,y);
 471 
 472             int messageType = JOptionPane.PLAIN_MESSAGE;
 473             if (c instanceof JInternalFrame) {
 474                 Object obj = ((JInternalFrame) c).getClientProperty(
 475                               "JInternalFrame.messageType");
 476                 if (obj instanceof Integer) {
 477                     messageType = (Integer) obj;
 478                 }
 479             }
 480 
 481             Color borderColor;
 482 
 483             switch (messageType) {
 484             case(JOptionPane.ERROR_MESSAGE):


 506               g.drawLine( 1, 0, w-2, 0);
 507               g.drawLine( 0, 1, 0, h-2);
 508               g.drawLine( w-1, 1, w-1, h-2);
 509               g.drawLine( 1, h-1, w-2, h-1);
 510 
 511               // Draw the bulk of the border
 512               for (int i = 1; i < 3; i++) {
 513                   g.drawRect(i, i, w-(i*2)-1, h-(i*2)-1);
 514               }
 515 
 516             g.translate(-x,-y);
 517 
 518         }
 519 
 520         public Insets getBorderInsets(Component c, Insets newInsets) {
 521             newInsets.set(3, 3, 3, 3);
 522             return newInsets;
 523         }
 524     }
 525 
 526 
 527     public static class MenuBarBorder extends AbstractBorder implements UIResource {
 528         protected static Insets borderInsets = new Insets( 1, 0, 1, 0 );
 529 
 530         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 531             g.translate( x, y );
 532 
 533             if (MetalLookAndFeel.usingOcean()) {
 534                 // Only paint a border if we're not next to a horizontal
 535                 // toolbar
 536                 if ((c instanceof JMenuBar) && !MetalToolBarUI.doesMenuBarBorderToolBar((JMenuBar)c)) {
 537                     g.setColor(MetalLookAndFeel.getControl());
 538                     g.drawLine(0, h - 2, w, h - 2);
 539                     g.setColor(UIManager.getColor("MenuBar.borderColor"));
 540                     g.drawLine(0, h - 1, w, h - 1);
 541                 }
 542             }
 543             else {
 544                 g.setColor( MetalLookAndFeel.getControlShadow() );
 545                 g.drawLine( 0, h-1, w, h-1 );
 546             }
 547 
 548             g.translate( -x, -y );
 549 
 550         }
 551 
 552         public Insets getBorderInsets(Component c, Insets newInsets) {
 553             if (MetalLookAndFeel.usingOcean()) {
 554                 newInsets.set(0, 0, 2, 0);
 555             }
 556             else {
 557                 newInsets.set(1, 0, 1, 0);
 558             }
 559             return newInsets;
 560         }
 561     }
 562 

 563     public static class MenuItemBorder extends AbstractBorder implements UIResource {
 564         protected static Insets borderInsets = new Insets( 2, 2, 2, 2 );
 565 
 566         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 567             if (!(c instanceof JMenuItem)) {
 568                 return;
 569             }
 570             JMenuItem b = (JMenuItem) c;
 571             ButtonModel model = b.getModel();
 572 
 573             g.translate( x, y );
 574 
 575             if ( c.getParent() instanceof JMenuBar ) {
 576                 if ( model.isArmed() || model.isSelected() ) {
 577                     g.setColor( MetalLookAndFeel.getControlDarkShadow() );
 578                     g.drawLine( 0, 0, w - 2, 0 );
 579                     g.drawLine( 0, 0, 0, h - 1 );
 580                     g.drawLine( w - 2, 2, w - 2, h - 1 );
 581 
 582                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );


 590                     g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
 591                     g.drawLine( 0, 0, w - 1, 0 );
 592 
 593                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
 594                     g.drawLine( 0, h - 1, w - 1, h - 1 );
 595                 } else {
 596                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
 597                     g.drawLine( 0, 0, 0, h - 1 );
 598                 }
 599             }
 600 
 601             g.translate( -x, -y );
 602         }
 603 
 604         public Insets getBorderInsets(Component c, Insets newInsets) {
 605             newInsets.set(2, 2, 2, 2);
 606             return newInsets;
 607         }
 608     }
 609 

 610     public static class PopupMenuBorder extends AbstractBorder implements UIResource {
 611         protected static Insets borderInsets = new Insets( 3, 1, 2, 1 );
 612 
 613         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 614             g.translate( x, y );
 615 
 616             g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
 617             g.drawRect( 0, 0, w - 1, h - 1 );
 618 
 619             g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
 620             g.drawLine( 1, 1, w - 2, 1 );
 621             g.drawLine( 1, 2, 1, 2 );
 622             g.drawLine( 1, h - 2, 1, h - 2 );
 623 
 624             g.translate( -x, -y );
 625 
 626         }
 627 
 628         public Insets getBorderInsets(Component c, Insets newInsets) {
 629             newInsets.set(3, 1, 2, 1);
 630             return newInsets;
 631         }
 632     }
 633 
 634 
 635     public static class RolloverButtonBorder extends ButtonBorder {
 636 
 637         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 638             AbstractButton b = (AbstractButton) c;
 639             ButtonModel model = b.getModel();
 640 
 641             if ( model.isRollover() && !( model.isPressed() && !model.isArmed() ) ) {
 642                 super.paintBorder( c, g, x, y, w, h );
 643             }
 644         }
 645 
 646     }
 647 
 648     /**
 649      * A border which is like a Margin border but it will only honor the margin
 650      * if the margin has been explicitly set by the developer.
 651      *
 652      * Note: This is identical to the package private class
 653      * BasicBorders.RolloverMarginBorder and should probably be consolidated.
 654      */

 655     static class RolloverMarginBorder extends EmptyBorder {
 656 
 657         public RolloverMarginBorder() {
 658             super(3,3,3,3); // hardcoded margin for JLF requirements.
 659         }
 660 
 661         public Insets getBorderInsets(Component c, Insets insets) {
 662             Insets margin = null;
 663 
 664             if (c instanceof AbstractButton) {
 665                 margin = ((AbstractButton)c).getMargin();
 666             }
 667             if (margin == null || margin instanceof UIResource) {
 668                 // default margin so replace
 669                 insets.left = left;
 670                 insets.top = top;
 671                 insets.right = right;
 672                 insets.bottom = bottom;
 673             } else {
 674                 // Margin which has been explicitly set by the user.
 675                 insets.left = margin.left;
 676                 insets.top = margin.top;
 677                 insets.right = margin.right;
 678                 insets.bottom = margin.bottom;
 679             }
 680             return insets;
 681         }
 682     }
 683 

 684     public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants
 685     {
 686         protected MetalBumps bumps = new MetalBumps( 10, 10,
 687                                       MetalLookAndFeel.getControlHighlight(),
 688                                       MetalLookAndFeel.getControlDarkShadow(),
 689                                      UIManager.getColor("ToolBar.background"));
 690 
 691         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h )
 692         {
 693             if (!(c instanceof JToolBar)) {
 694                 return;
 695             }
 696             g.translate( x, y );
 697 
 698             if ( ((JToolBar) c).isFloatable() )
 699             {
 700                 if ( ((JToolBar) c).getOrientation() == HORIZONTAL )
 701                 {
 702                     int shift = MetalLookAndFeel.usingOcean() ? -1 : 0;
 703                     bumps.setBumpArea( 10, h - 4 );


 791                                                    new BasicBorders.MarginBorder());
 792         }
 793         return textBorder;
 794     }
 795 
 796     private static Border textFieldBorder;
 797 
 798     /**
 799      * Returns a border instance for a JTextField
 800      * @since 1.3
 801      */
 802     public static Border getTextFieldBorder() {
 803         if (textFieldBorder == null) {
 804             textFieldBorder = new BorderUIResource.CompoundBorderUIResource(
 805                                                    new MetalBorders.TextFieldBorder(),
 806                                                    new BasicBorders.MarginBorder());
 807         }
 808         return textFieldBorder;
 809     }
 810 

 811     public static class TextFieldBorder extends Flush3DBorder {
 812 
 813         public void paintBorder(Component c, Graphics g, int x, int y,
 814                                 int w, int h) {
 815 
 816           if (!(c instanceof JTextComponent)) {
 817                 // special case for non-text components (bug ID 4144840)
 818                 if (c.isEnabled()) {
 819                     MetalUtils.drawFlush3DBorder(g, x, y, w, h);
 820                 } else {
 821                     MetalUtils.drawDisabledBorder(g, x, y, w, h);
 822                 }
 823                 return;
 824             }
 825 
 826             if (c.isEnabled() && ((JTextComponent)c).isEditable()) {
 827                 MetalUtils.drawFlush3DBorder(g, x, y, w, h);
 828             } else {
 829                 MetalUtils.drawDisabledBorder(g, x, y, w, h);
 830             }
 831 
 832         }
 833     }
 834 

 835     public static class ScrollPaneBorder extends AbstractBorder implements UIResource {
 836         public void paintBorder(Component c, Graphics g, int x, int y,
 837                           int w, int h) {
 838 
 839             if (!(c instanceof JScrollPane)) {
 840                 return;
 841             }
 842             JScrollPane scroll = (JScrollPane)c;
 843             JComponent colHeader = scroll.getColumnHeader();
 844             int colHeaderHeight = 0;
 845             if (colHeader != null)
 846                colHeaderHeight = colHeader.getHeight();
 847 
 848             JComponent rowHeader = scroll.getRowHeader();
 849             int rowHeaderWidth = 0;
 850             if (rowHeader != null)
 851                rowHeaderWidth = rowHeader.getWidth();
 852 
 853 
 854             g.translate( x, y);


 875     }
 876 
 877     private static Border toggleButtonBorder;
 878 
 879     /**
 880      * Returns a border instance for a JToggleButton
 881      * @since 1.3
 882      */
 883     public static Border getToggleButtonBorder() {
 884         if (toggleButtonBorder == null) {
 885             toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
 886                                                    new MetalBorders.ToggleButtonBorder(),
 887                                                    new BasicBorders.MarginBorder());
 888         }
 889         return toggleButtonBorder;
 890     }
 891 
 892     /**
 893      * @since 1.3
 894      */

 895     public static class ToggleButtonBorder extends ButtonBorder {
 896         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
 897             AbstractButton button = (AbstractButton)c;
 898             ButtonModel model = button.getModel();
 899             if (MetalLookAndFeel.usingOcean()) {
 900                 if(model.isArmed() || !button.isEnabled()) {
 901                     super.paintBorder(c, g, x, y, w, h);
 902                 }
 903                 else {
 904                  g.setColor(MetalLookAndFeel.getControlDarkShadow());
 905                  g.drawRect(0, 0, w - 1, h - 1);
 906             }
 907             return;
 908         }
 909             if (! c.isEnabled() ) {
 910                 MetalUtils.drawDisabledBorder( g, x, y, w-1, h-1 );
 911             } else {
 912                 if ( model.isPressed() && model.isArmed() ) {
 913                    MetalUtils.drawPressed3DBorder( g, x, y, w, h );
 914                 } else if ( model.isSelected() ) {
 915                     MetalUtils.drawDark3DBorder( g, x, y, w, h );
 916                 } else {
 917                     MetalUtils.drawFlush3DBorder( g, x, y, w, h );
 918                 }
 919             }
 920         }
 921     }
 922 
 923     /**
 924      * Border for a Table Header
 925      * @since 1.3
 926      */

 927     public static class TableHeaderBorder extends javax.swing.border.AbstractBorder {
 928         protected Insets editorBorderInsets = new Insets( 2, 2, 2, 0 );
 929 
 930         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
 931             g.translate( x, y );
 932 
 933             g.setColor( MetalLookAndFeel.getControlDarkShadow() );
 934             g.drawLine( w-1, 0, w-1, h-1 );
 935             g.drawLine( 1, h-1, w-1, h-1 );
 936             g.setColor( MetalLookAndFeel.getControlHighlight() );
 937             g.drawLine( 0, 0, w-2, 0 );
 938             g.drawLine( 0, 0, 0, h-2 );
 939 
 940             g.translate( -x, -y );
 941         }
 942 
 943         public Insets getBorderInsets(Component c, Insets insets) {
 944             insets.set(2, 2, 2, 0);
 945             return insets;
 946         }


   1 /*
   2  * Copyright (c) 1998, 2014, 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


  39 import java.awt.Graphics;
  40 import java.awt.Window;
  41 
  42 import sun.swing.StringUIClientPropertyKey;
  43 
  44 
  45 /**
  46  * Factory object that can vend Borders appropriate for the metal L &amp; F.
  47  * @author Steve Wilson
  48  */
  49 
  50 public class MetalBorders {
  51 
  52     /**
  53      * Client property indicating the button shouldn't provide a rollover
  54      * indicator. Only used with the Ocean theme.
  55      */
  56     static Object NO_BUTTON_ROLLOVER =
  57         new StringUIClientPropertyKey("NoButtonRollover");
  58 
  59     @SuppressWarnings("serial") // Superclass is not serializable across versions
  60     public static class Flush3DBorder extends AbstractBorder implements UIResource{
  61         public void paintBorder(Component c, Graphics g, int x, int y,
  62                           int w, int h) {
  63             if (c.isEnabled()) {
  64                 MetalUtils.drawFlush3DBorder(g, x, y, w, h);
  65             } else {
  66                 MetalUtils.drawDisabledBorder(g, x, y, w, h);
  67             }
  68         }
  69 
  70         public Insets getBorderInsets(Component c, Insets newInsets) {
  71             newInsets.set(2, 2, 2, 2);
  72             return newInsets;
  73         }
  74     }
  75 
  76     @SuppressWarnings("serial") // Superclass is not serializable across versions
  77     public static class ButtonBorder extends AbstractBorder implements UIResource {
  78 
  79         protected static Insets borderInsets = new Insets( 3, 3, 3, 3 );
  80 
  81         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
  82             if (!(c instanceof AbstractButton)) {
  83                 return;
  84             }
  85             if (MetalLookAndFeel.usingOcean()) {
  86                 paintOceanBorder(c, g, x, y, w, h);
  87                 return;
  88             }
  89             AbstractButton button = (AbstractButton)c;
  90             ButtonModel model = button.getModel();
  91 
  92             if ( model.isEnabled() ) {
  93                 boolean isPressed = model.isPressed() && model.isArmed();
  94                 boolean isDefault = (button instanceof JButton && ((JButton)button).isDefaultButton());
  95 
  96                 if (isPressed && isDefault) {


 171                 else {
 172                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
 173                     g.drawRect(0, 0, w - 1, h - 1);
 174                 }
 175             }
 176             else {
 177                 g.setColor(MetalLookAndFeel.getInactiveControlTextColor());
 178                 g.drawRect(0, 0, w - 1, h - 1);
 179                 if ((c instanceof JButton) && ((JButton)c).isDefaultButton()) {
 180                     g.drawRect(1, 1, w - 3, h - 3);
 181                 }
 182             }
 183         }
 184 
 185         public Insets getBorderInsets(Component c, Insets newInsets) {
 186             newInsets.set(3, 3, 3, 3);
 187             return newInsets;
 188         }
 189     }
 190 
 191     @SuppressWarnings("serial") // Superclass is not serializable across versions
 192     public static class InternalFrameBorder extends AbstractBorder implements UIResource {
 193         private static final int corner = 14;
 194 
 195         public void paintBorder(Component c, Graphics g, int x, int y,
 196                           int w, int h) {
 197 
 198             Color background;
 199             Color highlight;
 200             Color shadow;
 201 
 202             if (c instanceof JInternalFrame && ((JInternalFrame)c).isSelected()) {
 203                 background = MetalLookAndFeel.getPrimaryControlDarkShadow();
 204                 highlight = MetalLookAndFeel.getPrimaryControlShadow();
 205                 shadow = MetalLookAndFeel.getPrimaryControlInfo();
 206             } else {
 207                 background = MetalLookAndFeel.getControlDarkShadow();
 208                 highlight = MetalLookAndFeel.getControlShadow();
 209                 shadow = MetalLookAndFeel.getControlInfo();
 210             }
 211 


 233                   g.setColor(shadow);
 234                   // Draw the Long shadow lines
 235                   g.drawLine( corner, 2, w-corner-1, 2);
 236                   g.drawLine( 2, corner, 2, h-corner-1);
 237                   g.drawLine( w-3, corner, w-3, h-corner-1);
 238                   g.drawLine( corner, h-3, w-corner-1, h-3);
 239               }
 240 
 241           }
 242 
 243           public Insets getBorderInsets(Component c, Insets newInsets) {
 244               newInsets.set(5, 5, 5, 5);
 245               return newInsets;
 246           }
 247     }
 248 
 249     /**
 250      * Border for a Frame.
 251      * @since 1.4
 252      */
 253     @SuppressWarnings("serial") // Superclass is not serializable across versions
 254     static class FrameBorder extends AbstractBorder implements UIResource {
 255         private static final int corner = 14;
 256 
 257         public void paintBorder(Component c, Graphics g, int x, int y,
 258             int w, int h) {
 259 
 260             Color background;
 261             Color highlight;
 262             Color shadow;
 263 
 264             Window window = SwingUtilities.getWindowAncestor(c);
 265             if (window != null && window.isActive()) {
 266                 background = MetalLookAndFeel.getPrimaryControlDarkShadow();
 267                 highlight = MetalLookAndFeel.getPrimaryControlShadow();
 268                 shadow = MetalLookAndFeel.getPrimaryControlInfo();
 269             } else {
 270                 background = MetalLookAndFeel.getControlDarkShadow();
 271                 highlight = MetalLookAndFeel.getControlShadow();
 272                 shadow = MetalLookAndFeel.getControlInfo();
 273             }


 296                 // Draw the Long shadow lines
 297                 g.drawLine( corner, 2, w-corner-1, 2);
 298                 g.drawLine( 2, corner, 2, h-corner-1);
 299                 g.drawLine( w-3, corner, w-3, h-corner-1);
 300                 g.drawLine( corner, h-3, w-corner-1, h-3);
 301             }
 302 
 303         }
 304 
 305         public Insets getBorderInsets(Component c, Insets newInsets)
 306         {
 307             newInsets.set(5, 5, 5, 5);
 308             return newInsets;
 309         }
 310     }
 311 
 312     /**
 313      * Border for a Frame.
 314      * @since 1.4
 315      */
 316     @SuppressWarnings("serial") // Superclass is not serializable across versions
 317     static class DialogBorder extends AbstractBorder implements UIResource
 318     {
 319         private static final int corner = 14;
 320 
 321         protected Color getActiveBackground()
 322         {
 323             return MetalLookAndFeel.getPrimaryControlDarkShadow();
 324         }
 325 
 326         protected Color getActiveHighlight()
 327         {
 328             return MetalLookAndFeel.getPrimaryControlShadow();
 329         }
 330 
 331         protected Color getActiveShadow()
 332         {
 333             return MetalLookAndFeel.getPrimaryControlInfo();
 334         }
 335 
 336         protected Color getInactiveBackground()


 390                 // Draw the Long shadow lines
 391                 g.drawLine( corner, 2, w-corner-1, 2);
 392                 g.drawLine( 2, corner, 2, h-corner-1);
 393                 g.drawLine( w-3, corner, w-3, h-corner-1);
 394                 g.drawLine( corner, h-3, w-corner-1, h-3);
 395             }
 396 
 397         }
 398 
 399         public Insets getBorderInsets(Component c, Insets newInsets)
 400         {
 401             newInsets.set(5, 5, 5, 5);
 402             return newInsets;
 403         }
 404     }
 405 
 406     /**
 407      * Border for an Error Dialog.
 408      * @since 1.4
 409      */
 410     @SuppressWarnings("serial") // Superclass is not serializable across versions
 411     static class ErrorDialogBorder extends DialogBorder implements UIResource
 412     {
 413         protected Color getActiveBackground() {
 414             return UIManager.getColor("OptionPane.errorDialog.border.background");
 415         }
 416     }
 417 
 418 
 419     /**
 420      * Border for a QuestionDialog.  Also used for a JFileChooser and a
 421      * JColorChooser..
 422      * @since 1.4
 423      */
 424     @SuppressWarnings("serial") // Superclass is not serializable across versions
 425     static class QuestionDialogBorder extends DialogBorder implements UIResource
 426     {
 427         protected Color getActiveBackground() {
 428             return UIManager.getColor("OptionPane.questionDialog.border.background");
 429         }
 430     }
 431 
 432 
 433     /**
 434      * Border for a Warning Dialog.
 435      * @since 1.4
 436      */
 437     @SuppressWarnings("serial") // Superclass is not serializable across versions
 438     static class WarningDialogBorder extends DialogBorder implements UIResource
 439     {
 440         protected Color getActiveBackground() {
 441             return UIManager.getColor("OptionPane.warningDialog.border.background");
 442         }
 443     }
 444 
 445 
 446     /**
 447      * Border for a Palette.
 448      * @since 1.3
 449      */
 450     @SuppressWarnings("serial") // Superclass is not serializable across versions
 451     public static class PaletteBorder extends AbstractBorder implements UIResource {
 452         int titleHeight = 0;
 453 
 454         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 455 
 456             g.translate(x,y);
 457             g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
 458             g.drawLine(0, 1, 0, h-2);
 459             g.drawLine(1, h-1, w-2, h-1);
 460             g.drawLine(w-1,  1, w-1, h-2);
 461             g.drawLine( 1, 0, w-2, 0);
 462             g.drawRect(1,1, w-3, h-3);
 463             g.translate(-x,-y);
 464 
 465         }
 466 
 467         public Insets getBorderInsets(Component c, Insets newInsets) {
 468             newInsets.set(1, 1, 1, 1);
 469             return newInsets;
 470         }
 471     }
 472 
 473     @SuppressWarnings("serial") // Superclass is not serializable across versions
 474     public static class OptionDialogBorder extends AbstractBorder implements UIResource {
 475         int titleHeight = 0;
 476 
 477         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 478 
 479             g.translate(x,y);
 480 
 481             int messageType = JOptionPane.PLAIN_MESSAGE;
 482             if (c instanceof JInternalFrame) {
 483                 Object obj = ((JInternalFrame) c).getClientProperty(
 484                               "JInternalFrame.messageType");
 485                 if (obj instanceof Integer) {
 486                     messageType = (Integer) obj;
 487                 }
 488             }
 489 
 490             Color borderColor;
 491 
 492             switch (messageType) {
 493             case(JOptionPane.ERROR_MESSAGE):


 515               g.drawLine( 1, 0, w-2, 0);
 516               g.drawLine( 0, 1, 0, h-2);
 517               g.drawLine( w-1, 1, w-1, h-2);
 518               g.drawLine( 1, h-1, w-2, h-1);
 519 
 520               // Draw the bulk of the border
 521               for (int i = 1; i < 3; i++) {
 522                   g.drawRect(i, i, w-(i*2)-1, h-(i*2)-1);
 523               }
 524 
 525             g.translate(-x,-y);
 526 
 527         }
 528 
 529         public Insets getBorderInsets(Component c, Insets newInsets) {
 530             newInsets.set(3, 3, 3, 3);
 531             return newInsets;
 532         }
 533     }
 534 
 535     @SuppressWarnings("serial") // Superclass is not serializable across versions
 536     public static class MenuBarBorder extends AbstractBorder implements UIResource {
 537         protected static Insets borderInsets = new Insets( 1, 0, 1, 0 );
 538 
 539         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 540             g.translate( x, y );
 541 
 542             if (MetalLookAndFeel.usingOcean()) {
 543                 // Only paint a border if we're not next to a horizontal
 544                 // toolbar
 545                 if ((c instanceof JMenuBar) && !MetalToolBarUI.doesMenuBarBorderToolBar((JMenuBar)c)) {
 546                     g.setColor(MetalLookAndFeel.getControl());
 547                     g.drawLine(0, h - 2, w, h - 2);
 548                     g.setColor(UIManager.getColor("MenuBar.borderColor"));
 549                     g.drawLine(0, h - 1, w, h - 1);
 550                 }
 551             }
 552             else {
 553                 g.setColor( MetalLookAndFeel.getControlShadow() );
 554                 g.drawLine( 0, h-1, w, h-1 );
 555             }
 556 
 557             g.translate( -x, -y );
 558 
 559         }
 560 
 561         public Insets getBorderInsets(Component c, Insets newInsets) {
 562             if (MetalLookAndFeel.usingOcean()) {
 563                 newInsets.set(0, 0, 2, 0);
 564             }
 565             else {
 566                 newInsets.set(1, 0, 1, 0);
 567             }
 568             return newInsets;
 569         }
 570     }
 571 
 572     @SuppressWarnings("serial") // Superclass is not serializable across versions
 573     public static class MenuItemBorder extends AbstractBorder implements UIResource {
 574         protected static Insets borderInsets = new Insets( 2, 2, 2, 2 );
 575 
 576         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 577             if (!(c instanceof JMenuItem)) {
 578                 return;
 579             }
 580             JMenuItem b = (JMenuItem) c;
 581             ButtonModel model = b.getModel();
 582 
 583             g.translate( x, y );
 584 
 585             if ( c.getParent() instanceof JMenuBar ) {
 586                 if ( model.isArmed() || model.isSelected() ) {
 587                     g.setColor( MetalLookAndFeel.getControlDarkShadow() );
 588                     g.drawLine( 0, 0, w - 2, 0 );
 589                     g.drawLine( 0, 0, 0, h - 1 );
 590                     g.drawLine( w - 2, 2, w - 2, h - 1 );
 591 
 592                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );


 600                     g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
 601                     g.drawLine( 0, 0, w - 1, 0 );
 602 
 603                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
 604                     g.drawLine( 0, h - 1, w - 1, h - 1 );
 605                 } else {
 606                     g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
 607                     g.drawLine( 0, 0, 0, h - 1 );
 608                 }
 609             }
 610 
 611             g.translate( -x, -y );
 612         }
 613 
 614         public Insets getBorderInsets(Component c, Insets newInsets) {
 615             newInsets.set(2, 2, 2, 2);
 616             return newInsets;
 617         }
 618     }
 619 
 620     @SuppressWarnings("serial") // Superclass is not serializable across versions
 621     public static class PopupMenuBorder extends AbstractBorder implements UIResource {
 622         protected static Insets borderInsets = new Insets( 3, 1, 2, 1 );
 623 
 624         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 625             g.translate( x, y );
 626 
 627             g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
 628             g.drawRect( 0, 0, w - 1, h - 1 );
 629 
 630             g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
 631             g.drawLine( 1, 1, w - 2, 1 );
 632             g.drawLine( 1, 2, 1, 2 );
 633             g.drawLine( 1, h - 2, 1, h - 2 );
 634 
 635             g.translate( -x, -y );
 636 
 637         }
 638 
 639         public Insets getBorderInsets(Component c, Insets newInsets) {
 640             newInsets.set(3, 1, 2, 1);
 641             return newInsets;
 642         }
 643     }
 644 
 645     @SuppressWarnings("serial") // Superclass is not serializable across versions
 646     public static class RolloverButtonBorder extends ButtonBorder {
 647 
 648         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
 649             AbstractButton b = (AbstractButton) c;
 650             ButtonModel model = b.getModel();
 651 
 652             if ( model.isRollover() && !( model.isPressed() && !model.isArmed() ) ) {
 653                 super.paintBorder( c, g, x, y, w, h );
 654             }
 655         }
 656 
 657     }
 658 
 659     /**
 660      * A border which is like a Margin border but it will only honor the margin
 661      * if the margin has been explicitly set by the developer.
 662      *
 663      * Note: This is identical to the package private class
 664      * BasicBorders.RolloverMarginBorder and should probably be consolidated.
 665      */
 666     @SuppressWarnings("serial") // Superclass is not serializable across versions
 667     static class RolloverMarginBorder extends EmptyBorder {
 668 
 669         public RolloverMarginBorder() {
 670             super(3,3,3,3); // hardcoded margin for JLF requirements.
 671         }
 672 
 673         public Insets getBorderInsets(Component c, Insets insets) {
 674             Insets margin = null;
 675 
 676             if (c instanceof AbstractButton) {
 677                 margin = ((AbstractButton)c).getMargin();
 678             }
 679             if (margin == null || margin instanceof UIResource) {
 680                 // default margin so replace
 681                 insets.left = left;
 682                 insets.top = top;
 683                 insets.right = right;
 684                 insets.bottom = bottom;
 685             } else {
 686                 // Margin which has been explicitly set by the user.
 687                 insets.left = margin.left;
 688                 insets.top = margin.top;
 689                 insets.right = margin.right;
 690                 insets.bottom = margin.bottom;
 691             }
 692             return insets;
 693         }
 694     }
 695 
 696     @SuppressWarnings("serial") // Superclass is not serializable across versions
 697     public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants
 698     {
 699         protected MetalBumps bumps = new MetalBumps( 10, 10,
 700                                       MetalLookAndFeel.getControlHighlight(),
 701                                       MetalLookAndFeel.getControlDarkShadow(),
 702                                      UIManager.getColor("ToolBar.background"));
 703 
 704         public void paintBorder( Component c, Graphics g, int x, int y, int w, int h )
 705         {
 706             if (!(c instanceof JToolBar)) {
 707                 return;
 708             }
 709             g.translate( x, y );
 710 
 711             if ( ((JToolBar) c).isFloatable() )
 712             {
 713                 if ( ((JToolBar) c).getOrientation() == HORIZONTAL )
 714                 {
 715                     int shift = MetalLookAndFeel.usingOcean() ? -1 : 0;
 716                     bumps.setBumpArea( 10, h - 4 );


 804                                                    new BasicBorders.MarginBorder());
 805         }
 806         return textBorder;
 807     }
 808 
 809     private static Border textFieldBorder;
 810 
 811     /**
 812      * Returns a border instance for a JTextField
 813      * @since 1.3
 814      */
 815     public static Border getTextFieldBorder() {
 816         if (textFieldBorder == null) {
 817             textFieldBorder = new BorderUIResource.CompoundBorderUIResource(
 818                                                    new MetalBorders.TextFieldBorder(),
 819                                                    new BasicBorders.MarginBorder());
 820         }
 821         return textFieldBorder;
 822     }
 823 
 824     @SuppressWarnings("serial") // Superclass is not serializable across versions
 825     public static class TextFieldBorder extends Flush3DBorder {
 826 
 827         public void paintBorder(Component c, Graphics g, int x, int y,
 828                                 int w, int h) {
 829 
 830           if (!(c instanceof JTextComponent)) {
 831                 // special case for non-text components (bug ID 4144840)
 832                 if (c.isEnabled()) {
 833                     MetalUtils.drawFlush3DBorder(g, x, y, w, h);
 834                 } else {
 835                     MetalUtils.drawDisabledBorder(g, x, y, w, h);
 836                 }
 837                 return;
 838             }
 839 
 840             if (c.isEnabled() && ((JTextComponent)c).isEditable()) {
 841                 MetalUtils.drawFlush3DBorder(g, x, y, w, h);
 842             } else {
 843                 MetalUtils.drawDisabledBorder(g, x, y, w, h);
 844             }
 845 
 846         }
 847     }
 848 
 849     @SuppressWarnings("serial") // Superclass is not serializable across versions
 850     public static class ScrollPaneBorder extends AbstractBorder implements UIResource {
 851         public void paintBorder(Component c, Graphics g, int x, int y,
 852                           int w, int h) {
 853 
 854             if (!(c instanceof JScrollPane)) {
 855                 return;
 856             }
 857             JScrollPane scroll = (JScrollPane)c;
 858             JComponent colHeader = scroll.getColumnHeader();
 859             int colHeaderHeight = 0;
 860             if (colHeader != null)
 861                colHeaderHeight = colHeader.getHeight();
 862 
 863             JComponent rowHeader = scroll.getRowHeader();
 864             int rowHeaderWidth = 0;
 865             if (rowHeader != null)
 866                rowHeaderWidth = rowHeader.getWidth();
 867 
 868 
 869             g.translate( x, y);


 890     }
 891 
 892     private static Border toggleButtonBorder;
 893 
 894     /**
 895      * Returns a border instance for a JToggleButton
 896      * @since 1.3
 897      */
 898     public static Border getToggleButtonBorder() {
 899         if (toggleButtonBorder == null) {
 900             toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
 901                                                    new MetalBorders.ToggleButtonBorder(),
 902                                                    new BasicBorders.MarginBorder());
 903         }
 904         return toggleButtonBorder;
 905     }
 906 
 907     /**
 908      * @since 1.3
 909      */
 910     @SuppressWarnings("serial") // Superclass is not serializable across versions
 911     public static class ToggleButtonBorder extends ButtonBorder {
 912         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
 913             AbstractButton button = (AbstractButton)c;
 914             ButtonModel model = button.getModel();
 915             if (MetalLookAndFeel.usingOcean()) {
 916                 if(model.isArmed() || !button.isEnabled()) {
 917                     super.paintBorder(c, g, x, y, w, h);
 918                 }
 919                 else {
 920                  g.setColor(MetalLookAndFeel.getControlDarkShadow());
 921                  g.drawRect(0, 0, w - 1, h - 1);
 922             }
 923             return;
 924         }
 925             if (! c.isEnabled() ) {
 926                 MetalUtils.drawDisabledBorder( g, x, y, w-1, h-1 );
 927             } else {
 928                 if ( model.isPressed() && model.isArmed() ) {
 929                    MetalUtils.drawPressed3DBorder( g, x, y, w, h );
 930                 } else if ( model.isSelected() ) {
 931                     MetalUtils.drawDark3DBorder( g, x, y, w, h );
 932                 } else {
 933                     MetalUtils.drawFlush3DBorder( g, x, y, w, h );
 934                 }
 935             }
 936         }
 937     }
 938 
 939     /**
 940      * Border for a Table Header
 941      * @since 1.3
 942      */
 943     @SuppressWarnings("serial") // Superclass is not serializable across versions
 944     public static class TableHeaderBorder extends javax.swing.border.AbstractBorder {
 945         protected Insets editorBorderInsets = new Insets( 2, 2, 2, 0 );
 946 
 947         public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
 948             g.translate( x, y );
 949 
 950             g.setColor( MetalLookAndFeel.getControlDarkShadow() );
 951             g.drawLine( w-1, 0, w-1, h-1 );
 952             g.drawLine( 1, h-1, w-1, h-1 );
 953             g.setColor( MetalLookAndFeel.getControlHighlight() );
 954             g.drawLine( 0, 0, w-2, 0 );
 955             g.drawLine( 0, 0, 0, h-2 );
 956 
 957             g.translate( -x, -y );
 958         }
 959 
 960         public Insets getBorderInsets(Component c, Insets insets) {
 961             insets.set(2, 2, 2, 0);
 962             return insets;
 963         }