Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2010, 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   
   26   package javax.swing.plaf.basic;
   27   
   28   import javax.swing;
   29   import javax.swing.border;
   30   import javax.swing.plaf;
   31   import javax.swing.text.JTextComponent;
   32   
   33   import java.awt.Component;
   34   import java.awt.Insets;
   35   import java.awt.Dimension;
   36   import java.awt.Rectangle;
   37   import java.awt.Color;
   38   import java.awt.Graphics;
   39   
   40   /**
   41    * Factory object that can vend Borders appropriate for the basic L & F.
   42    * @author Georges Saab
   43    * @author Amy Fowler
   44    */
   45   
   46   public class BasicBorders {
   47   
   48       public static Border getButtonBorder() {
   49           UIDefaults table = UIManager.getLookAndFeelDefaults();
   50           Border buttonBorder = new BorderUIResource.CompoundBorderUIResource(
   51                              new BasicBorders.ButtonBorder(
   52                                              table.getColor("Button.shadow"),
   53                                              table.getColor("Button.darkShadow"),
   54                                              table.getColor("Button.light"),
   55                                              table.getColor("Button.highlight")),
   56                                        new MarginBorder());
   57           return buttonBorder;
   58       }
   59   
   60       public static Border getRadioButtonBorder() {
   61           UIDefaults table = UIManager.getLookAndFeelDefaults();
   62           Border radioButtonBorder = new BorderUIResource.CompoundBorderUIResource(
   63                              new BasicBorders.RadioButtonBorder(
   64                                              table.getColor("RadioButton.shadow"),
   65                                              table.getColor("RadioButton.darkShadow"),
   66                                              table.getColor("RadioButton.light"),
   67                                              table.getColor("RadioButton.highlight")),
   68                                        new MarginBorder());
   69           return radioButtonBorder;
   70       }
   71   
   72       public static Border getToggleButtonBorder() {
   73           UIDefaults table = UIManager.getLookAndFeelDefaults();
   74           Border toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
   75                                        new BasicBorders.ToggleButtonBorder(
   76                                              table.getColor("ToggleButton.shadow"),
   77                                              table.getColor("ToggleButton.darkShadow"),
   78                                              table.getColor("ToggleButton.light"),
   79                                              table.getColor("ToggleButton.highlight")),
   80                                        new MarginBorder());
   81           return toggleButtonBorder;
   82       }
   83   
   84       public static Border getMenuBarBorder() {
   85           UIDefaults table = UIManager.getLookAndFeelDefaults();
   86           Border menuBarBorder = new BasicBorders.MenuBarBorder(
   87                                           table.getColor("MenuBar.shadow"),
   88                                           table.getColor("MenuBar.highlight")
   89                                      );
   90           return menuBarBorder;
   91       }
   92   
   93       public static Border getSplitPaneBorder() {
   94           UIDefaults table = UIManager.getLookAndFeelDefaults();
   95           Border splitPaneBorder = new BasicBorders.SplitPaneBorder(
   96                                        table.getColor("SplitPane.highlight"),
   97                                        table.getColor("SplitPane.darkShadow"));
   98           return splitPaneBorder;
   99       }
  100   
  101       /**
  102        * Returns a border instance for a JSplitPane divider
  103        * @since 1.3
  104        */
  105       public static Border getSplitPaneDividerBorder() {
  106           UIDefaults table = UIManager.getLookAndFeelDefaults();
  107           Border splitPaneBorder = new BasicBorders.SplitPaneDividerBorder(
  108                                        table.getColor("SplitPane.highlight"),
  109                                        table.getColor("SplitPane.darkShadow"));
  110           return splitPaneBorder;
  111       }
  112   
  113       public static Border getTextFieldBorder() {
  114           UIDefaults table = UIManager.getLookAndFeelDefaults();
  115           Border textFieldBorder = new BasicBorders.FieldBorder(
  116                                              table.getColor("TextField.shadow"),
  117                                              table.getColor("TextField.darkShadow"),
  118                                              table.getColor("TextField.light"),
  119                                              table.getColor("TextField.highlight"));
  120           return textFieldBorder;
  121       }
  122   
  123       public static Border getProgressBarBorder() {
  124           UIDefaults table = UIManager.getLookAndFeelDefaults();
  125           Border progressBarBorder = new BorderUIResource.LineBorderUIResource(Color.green, 2);
  126           return progressBarBorder;
  127       }
  128   
  129       public static Border getInternalFrameBorder() {
  130           UIDefaults table = UIManager.getLookAndFeelDefaults();
  131           Border internalFrameBorder = new BorderUIResource.CompoundBorderUIResource(
  132                                   new BevelBorder(BevelBorder.RAISED,
  133                                           table.getColor("InternalFrame.borderLight"),
  134                                           table.getColor("InternalFrame.borderHighlight"),
  135                                           table.getColor("InternalFrame.borderDarkShadow"),
  136                                           table.getColor("InternalFrame.borderShadow")),
  137                                   BorderFactory.createLineBorder(
  138                                           table.getColor("InternalFrame.borderColor"), 1));
  139   
  140           return internalFrameBorder;
  141       }
  142   
  143       /**
  144        * Special thin border for rollover toolbar buttons.
  145        * @since 1.4
  146        */
  147       public static class RolloverButtonBorder extends ButtonBorder {
  148   
  149           public RolloverButtonBorder(Color shadow, Color darkShadow,
  150                                     Color highlight, Color lightHighlight) {
  151               super(shadow, darkShadow, highlight, lightHighlight);
  152           }
  153   
  154           public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
  155               AbstractButton b = (AbstractButton) c;
  156               ButtonModel model = b.getModel();
  157   
  158               Color shade = shadow;
  159               Component p = b.getParent();
  160               if (p != null && p.getBackground().equals(shadow)) {
  161                   shade = darkShadow;
  162               }
  163   
  164               if ((model.isRollover() && !(model.isPressed() && !model.isArmed())) ||
  165                   model.isSelected()) {
  166   
  167                   Color oldColor = g.getColor();
  168                   g.translate(x, y);
  169   
  170                   if (model.isPressed() && model.isArmed() || model.isSelected()) {
  171                       // Draw the pressd button
  172                       g.setColor(shade);
  173                       g.drawRect(0, 0, w-1, h-1);
  174                       g.setColor(lightHighlight);
  175                       g.drawLine(w-1, 0, w-1, h-1);
  176                       g.drawLine(0, h-1, w-1, h-1);
  177                   } else {
  178                       // Draw a rollover button
  179                       g.setColor(lightHighlight);
  180                       g.drawRect(0, 0, w-1, h-1);
  181                       g.setColor(shade);
  182                       g.drawLine(w-1, 0, w-1, h-1);
  183                       g.drawLine(0, h-1, w-1, h-1);
  184                   }
  185                   g.translate(-x, -y);
  186                   g.setColor(oldColor);
  187               }
  188           }
  189       }
  190   
  191   
  192       /**
  193        * A border which is like a Margin border but it will only honor the margin
  194        * if the margin has been explicitly set by the developer.
  195        *
  196        * Note: This is identical to the package private class
  197        * MetalBorders.RolloverMarginBorder and should probably be consolidated.
  198        */
  199       static class RolloverMarginBorder extends EmptyBorder {
  200   
  201           public RolloverMarginBorder() {
  202               super(3,3,3,3); // hardcoded margin for JLF requirements.
  203           }
  204   
  205           public Insets getBorderInsets(Component c, Insets insets) {
  206               Insets margin = null;
  207   
  208               if (c instanceof AbstractButton) {
  209                   margin = ((AbstractButton)c).getMargin();
  210               }
  211               if (margin == null || margin instanceof UIResource) {
  212                   // default margin so replace
  213                   insets.left = left;
  214                   insets.top = top;
  215                   insets.right = right;
  216                   insets.bottom = bottom;
  217               } else {
  218                   // Margin which has been explicitly set by the user.
  219                   insets.left = margin.left;
  220                   insets.top = margin.top;
  221                   insets.right = margin.right;
  222                   insets.bottom = margin.bottom;
  223               }
  224               return insets;
  225           }
  226       }
  227   
  228      public static class ButtonBorder extends AbstractBorder implements UIResource {
  229           protected Color shadow;
  230           protected Color darkShadow;
  231           protected Color highlight;
  232           protected Color lightHighlight;
  233   
  234           public ButtonBorder(Color shadow, Color darkShadow,
  235                               Color highlight, Color lightHighlight) {
  236               this.shadow = shadow;
  237               this.darkShadow = darkShadow;
  238               this.highlight = highlight;
  239               this.lightHighlight = lightHighlight;
  240           }
  241   
  242           public void paintBorder(Component c, Graphics g, int x, int y,
  243                               int width, int height) {
  244               boolean isPressed = false;
  245               boolean isDefault = false;
  246   
  247               if (c instanceof AbstractButton) {
  248                   AbstractButton b = (AbstractButton)c;
  249                   ButtonModel model = b.getModel();
  250   
  251                   isPressed = model.isPressed() && model.isArmed();
  252   
  253                   if (c instanceof JButton) {
  254                       isDefault = ((JButton)c).isDefaultButton();
  255                   }
  256               }
  257               BasicGraphicsUtils.drawBezel(g, x, y, width, height,
  258                                      isPressed, isDefault, shadow,
  259                                      darkShadow, highlight, lightHighlight);
  260           }
  261   
  262           public Insets getBorderInsets(Component c, Insets insets)       {
  263               // leave room for default visual
  264               insets.set(2, 3, 3, 3);
  265               return insets;
  266           }
  267   
  268       }
  269   
  270       public static class ToggleButtonBorder extends ButtonBorder {
  271   
  272           public ToggleButtonBorder(Color shadow, Color darkShadow,
  273                                     Color highlight, Color lightHighlight) {
  274               super(shadow, darkShadow, highlight, lightHighlight);
  275           }
  276   
  277           public void paintBorder(Component c, Graphics g, int x, int y,
  278                                   int width, int height) {
  279                   BasicGraphicsUtils.drawBezel(g, x, y, width, height,
  280                                                false, false,
  281                                                shadow, darkShadow,
  282                                                highlight, lightHighlight);
  283           }
  284   
  285           public Insets getBorderInsets(Component c, Insets insets)       {
  286               insets.set(2, 2, 2, 2);
  287               return insets;
  288           }
  289       }
  290   
  291       public static class RadioButtonBorder extends ButtonBorder {
  292   
  293           public RadioButtonBorder(Color shadow, Color darkShadow,
  294                                    Color highlight, Color lightHighlight) {
  295               super(shadow, darkShadow, highlight, lightHighlight);
  296           }
  297   
  298   
  299           public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
  300   
  301               if (c instanceof AbstractButton) {
  302                   AbstractButton b = (AbstractButton)c;
  303                   ButtonModel model = b.getModel();
  304   
  305                   if (model.isArmed() && model.isPressed() || model.isSelected()) {
  306                       BasicGraphicsUtils.drawLoweredBezel(g, x, y, width, height,
  307                                                           shadow, darkShadow,
  308                                                           highlight, lightHighlight);
  309                   } else {
  310                       BasicGraphicsUtils.drawBezel(g, x, y, width, height,
  311                                                  false, b.isFocusPainted() && b.hasFocus(),
  312                                                    shadow, darkShadow,
  313                                                    highlight, lightHighlight);
  314                   }
  315               } else {
  316                   BasicGraphicsUtils.drawBezel(g, x, y, width, height, false, false,
  317                                                shadow, darkShadow, highlight, lightHighlight);
  318               }
  319           }
  320   
  321           public Insets getBorderInsets(Component c, Insets insets)       {
  322               insets.set(2, 2, 2, 2);
  323               return insets;
  324           }
  325       }
  326   
  327       public static class MenuBarBorder extends AbstractBorder implements UIResource {
  328           private Color shadow;
  329           private Color highlight;
  330   
  331           public MenuBarBorder(Color shadow, Color highlight) {
  332               this.shadow = shadow;
  333               this.highlight = highlight;
  334           }
  335   
  336           public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
  337               Color oldColor = g.getColor();
  338               g.translate(x, y);
  339               g.setColor(shadow);
  340               g.drawLine(0, height-2, width, height-2);
  341               g.setColor(highlight);
  342               g.drawLine(0, height-1, width, height-1);
  343               g.translate(-x,-y);
  344               g.setColor(oldColor);
  345           }
  346   
  347           public Insets getBorderInsets(Component c, Insets insets)       {
  348               insets.set(0, 0, 2, 0);
  349               return insets;
  350           }
  351       }
  352   
  353       public static class MarginBorder extends AbstractBorder implements UIResource {
  354           public Insets getBorderInsets(Component c, Insets insets)       {
  355               Insets margin = null;
  356               //
  357               // Ideally we'd have an interface defined for classes which
  358               // support margins (to avoid this hackery), but we've
  359               // decided against it for simplicity
  360               //
  361              if (c instanceof AbstractButton) {
  362                  AbstractButton b = (AbstractButton)c;
  363                  margin = b.getMargin();
  364              } else if (c instanceof JToolBar) {
  365                  JToolBar t = (JToolBar)c;
  366                  margin = t.getMargin();
  367              } else if (c instanceof JTextComponent) {
  368                  JTextComponent t = (JTextComponent)c;
  369                  margin = t.getMargin();
  370              }
  371              insets.top = margin != null? margin.top : 0;
  372              insets.left = margin != null? margin.left : 0;
  373              insets.bottom = margin != null? margin.bottom : 0;
  374              insets.right = margin != null? margin.right : 0;
  375   
  376              return insets;
  377           }
  378       }
  379   
  380       public static class FieldBorder extends AbstractBorder implements UIResource {
  381           protected Color shadow;
  382           protected Color darkShadow;
  383           protected Color highlight;
  384           protected Color lightHighlight;
  385   
  386           public FieldBorder(Color shadow, Color darkShadow,
  387                              Color highlight, Color lightHighlight) {
  388               this.shadow = shadow;
  389               this.highlight = highlight;
  390               this.darkShadow = darkShadow;
  391               this.lightHighlight = lightHighlight;
  392           }
  393   
  394           public void paintBorder(Component c, Graphics g, int x, int y,
  395                               int width, int height) {
  396               BasicGraphicsUtils.drawEtchedRect(g, x, y, width, height,
  397                                                 shadow, darkShadow,
  398                                                 highlight, lightHighlight);
  399           }
  400   
  401           public Insets getBorderInsets(Component c, Insets insets) {
  402               Insets margin = null;
  403               if (c instanceof JTextComponent) {
  404                   margin = ((JTextComponent)c).getMargin();
  405               }
  406               insets.top = margin != null? 2+margin.top : 2;
  407               insets.left = margin != null? 2+margin.left : 2;
  408               insets.bottom = margin != null? 2+margin.bottom : 2;
  409               insets.right = margin != null? 2+margin.right : 2;
  410   
  411               return insets;
  412           }
  413       }
  414   
  415   
  416       /**
  417        * Draws the border around the divider in a splitpane
  418        * (when BasicSplitPaneUI is used). To get the appropriate effect, this
  419        * needs to be used with a SplitPaneBorder.
  420        */
  421       static class SplitPaneDividerBorder implements Border, UIResource {
  422           Color highlight;
  423           Color shadow;
  424   
  425           SplitPaneDividerBorder(Color highlight, Color shadow) {
  426               this.highlight = highlight;
  427               this.shadow = shadow;
  428           }
  429   
  430           public void paintBorder(Component c, Graphics g, int x, int y,
  431                                   int width, int height) {
  432               if (!(c instanceof BasicSplitPaneDivider)) {
  433                   return;
  434               }
  435               Component          child;
  436               Rectangle          cBounds;
  437               JSplitPane         splitPane = ((BasicSplitPaneDivider)c).
  438                                            getBasicSplitPaneUI().getSplitPane();
  439               Dimension          size = c.getSize();
  440   
  441               child = splitPane.getLeftComponent();
  442               // This is needed for the space between the divider and end of
  443               // splitpane.
  444               g.setColor(c.getBackground());
  445               g.drawRect(x, y, width - 1, height - 1);
  446               if(splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
  447                   if(child != null) {
  448                       g.setColor(highlight);
  449                       g.drawLine(0, 0, 0, size.height);
  450                   }
  451                   child = splitPane.getRightComponent();
  452                   if(child != null) {
  453                       g.setColor(shadow);
  454                       g.drawLine(size.width - 1, 0, size.width - 1, size.height);
  455                   }
  456               } else {
  457                   if(child != null) {
  458                       g.setColor(highlight);
  459                       g.drawLine(0, 0, size.width, 0);
  460                   }
  461                   child = splitPane.getRightComponent();
  462                   if(child != null) {
  463                       g.setColor(shadow);
  464                       g.drawLine(0, size.height - 1, size.width,
  465                                  size.height - 1);
  466                   }
  467               }
  468           }
  469           public Insets getBorderInsets(Component c) {
  470               Insets insets = new Insets(0,0,0,0);
  471               if (c instanceof BasicSplitPaneDivider) {
  472                   BasicSplitPaneUI bspui = ((BasicSplitPaneDivider)c).
  473                                            getBasicSplitPaneUI();
  474   
  475                   if (bspui != null) {
  476                       JSplitPane splitPane = bspui.getSplitPane();
  477   
  478                       if (splitPane != null) {
  479                           if (splitPane.getOrientation() ==
  480                               JSplitPane.HORIZONTAL_SPLIT) {
  481                               insets.top = insets.bottom = 0;
  482                               insets.left = insets.right = 1;
  483                               return insets;
  484                           }
  485                           // VERTICAL_SPLIT
  486                           insets.top = insets.bottom = 1;
  487                           insets.left = insets.right = 0;
  488                           return insets;
  489                       }
  490                   }
  491               }
  492               insets.top = insets.bottom = insets.left = insets.right = 1;
  493               return insets;
  494           }
  495           public boolean isBorderOpaque() { return true; }
  496       }
  497   
  498   
  499       /**
  500        * Draws the border around the splitpane. To work correctly you shoudl
  501        * also install a border on the divider (property SplitPaneDivider.border).
  502        */
  503       public static class SplitPaneBorder implements Border, UIResource {
  504           protected Color highlight;
  505           protected Color shadow;
  506   
  507           public SplitPaneBorder(Color highlight, Color shadow) {
  508               this.highlight = highlight;
  509               this.shadow = shadow;
  510           }
  511   
  512           public void paintBorder(Component c, Graphics g, int x, int y,
  513                                   int width, int height) {
  514               if (!(c instanceof JSplitPane)) {
  515                   return;
  516               }
  517               // The only tricky part with this border is that the divider is
  518               // not positioned at the top (for horizontal) or left (for vert),
  519               // so this border draws to where the divider is:
  520               // -----------------
  521               // |xxxxxxx xxxxxxx|
  522               // |x     ---     x|
  523               // |x     | |     x|
  524               // |x     |D|     x|
  525               // |x     | |     x|
  526               // |x     ---     x|
  527               // |xxxxxxx xxxxxxx|
  528               // -----------------
  529               // The above shows (rather excessively) what this looks like for
  530               // a horizontal orientation. This border then draws the x's, with
  531               // the SplitPaneDividerBorder drawing its own border.
  532   
  533               Component          child;
  534               Rectangle          cBounds;
  535   
  536               JSplitPane splitPane = (JSplitPane)c;
  537   
  538               child = splitPane.getLeftComponent();
  539               // This is needed for the space between the divider and end of
  540               // splitpane.
  541               g.setColor(c.getBackground());
  542               g.drawRect(x, y, width - 1, height - 1);
  543               if(splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
  544                   if(child != null) {
  545                       cBounds = child.getBounds();
  546                       g.setColor(shadow);
  547                       g.drawLine(0, 0, cBounds.width + 1, 0);
  548                       g.drawLine(0, 1, 0, cBounds.height + 1);
  549   
  550                       g.setColor(highlight);
  551                       g.drawLine(0, cBounds.height + 1, cBounds.width + 1,
  552                                  cBounds.height + 1);
  553                   }
  554                   child = splitPane.getRightComponent();
  555                   if(child != null) {
  556                       cBounds = child.getBounds();
  557   
  558                       int             maxX = cBounds.x + cBounds.width;
  559                       int             maxY = cBounds.y + cBounds.height;
  560   
  561                       g.setColor(shadow);
  562                       g.drawLine(cBounds.x - 1, 0, maxX, 0);
  563                       g.setColor(highlight);
  564                       g.drawLine(cBounds.x - 1, maxY, maxX, maxY);
  565                       g.drawLine(maxX, 0, maxX, maxY + 1);
  566                   }
  567               } else {
  568                   if(child != null) {
  569                       cBounds = child.getBounds();
  570                       g.setColor(shadow);
  571                       g.drawLine(0, 0, cBounds.width + 1, 0);
  572                       g.drawLine(0, 1, 0, cBounds.height);
  573                       g.setColor(highlight);
  574                       g.drawLine(1 + cBounds.width, 0, 1 + cBounds.width,
  575                                  cBounds.height + 1);
  576                       g.drawLine(0, cBounds.height + 1, 0, cBounds.height + 1);
  577                   }
  578                   child = splitPane.getRightComponent();
  579                   if(child != null) {
  580                       cBounds = child.getBounds();
  581   
  582                       int             maxX = cBounds.x + cBounds.width;
  583                       int             maxY = cBounds.y + cBounds.height;
  584   
  585                       g.setColor(shadow);
  586                       g.drawLine(0, cBounds.y - 1, 0, maxY);
  587                       g.drawLine(maxX, cBounds.y - 1, maxX, cBounds.y - 1);
  588                       g.setColor(highlight);
  589                       g.drawLine(0, maxY, cBounds.width + 1, maxY);
  590                       g.drawLine(maxX, cBounds.y, maxX, maxY);
  591                   }
  592               }
  593           }
  594           public Insets getBorderInsets(Component c) {
  595               return new Insets(1, 1, 1, 1);
  596           }
  597           public boolean isBorderOpaque() { return true; }
  598       }
  599   
  600   }

Home » openjdk-7 » javax » swing » plaf » basic » [javadoc | source]