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
  23  * questions.
  24  */
  25 
  26 package com.sun.java.swing.plaf.windows;
  27 
  28 import javax.swing.*;
  29 import javax.swing.border.*;
  30 import javax.swing.plaf.*;
  31 import javax.swing.plaf.basic.*;
  32 
  33 import java.awt.Component;
  34 import java.awt.Insets;
  35 import java.awt.Color;
  36 import java.awt.Graphics;
  37 
  38 import static com.sun.java.swing.plaf.windows.TMSchema.*;
  39 import static com.sun.java.swing.plaf.windows.XPStyle.Skin;
  40 
  41 /**
  42  * Factory object that can vend Borders appropriate for the Windows 95 {@literal L & F}.
  43  * @author Rich Schiavi
  44  */
  45 
  46 public class WindowsBorders {
  47 
  48     /**
  49      * Returns a  border instance for a Windows Progress Bar
  50      * @since 1.4
  51      */
  52     public static Border getProgressBarBorder() {
  53         UIDefaults table = UIManager.getLookAndFeelDefaults();
  54         Border progressBarBorder = new BorderUIResource.CompoundBorderUIResource(
  55                                          new WindowsBorders.ProgressBarBorder(
  56                                               table.getColor("ProgressBar.shadow"),
  57                                               table.getColor("ProgressBar.highlight")),
  58                                               new EmptyBorder(1,1,1,1)
  59                                         );
  60         return progressBarBorder;
  61     }
  62 
  63     /**
  64      * Returns a border instance for a Windows ToolBar
  65      *
  66      * @return a border used for the toolbar
  67      * @since 1.4
  68      */
  69     public static Border getToolBarBorder() {
  70         UIDefaults table = UIManager.getLookAndFeelDefaults();
  71         Border toolBarBorder = new WindowsBorders.ToolBarBorder(
  72                                         table.getColor("ToolBar.shadow"),
  73                                         table.getColor("ToolBar.highlight"));
  74         return toolBarBorder;
  75     }
  76 
  77     /**
  78      * Returns an new instance of a border used to indicate which cell item
  79      * has focus.
  80      *
  81      * @return a border to indicate which cell item has focus
  82      * @since 1.4
  83      */
  84     public static Border getFocusCellHighlightBorder() {
  85         return new ComplementDashedBorder();
  86     }
  87 
  88     public static Border getTableHeaderBorder() {
  89         UIDefaults table = UIManager.getLookAndFeelDefaults();
  90         Border tableHeaderBorder = new BorderUIResource.CompoundBorderUIResource(
  91                            new BasicBorders.ButtonBorder(
  92                                            table.getColor("Table.shadow"),
  93                                            table.getColor("Table.darkShadow"),
  94                                            table.getColor("Table.light"),
  95                                            table.getColor("Table.highlight")),
  96                                      new BasicBorders.MarginBorder());
  97         return tableHeaderBorder;
  98     }
  99 
 100     public static Border getInternalFrameBorder() {
 101         UIDefaults table = UIManager.getLookAndFeelDefaults();
 102         Border internalFrameBorder = new
 103             BorderUIResource.CompoundBorderUIResource(
 104                 BorderFactory.createBevelBorder(BevelBorder.RAISED,
 105                     table.getColor("InternalFrame.borderColor"),
 106                     table.getColor("InternalFrame.borderHighlight"),
 107                     table.getColor("InternalFrame.borderDarkShadow"),
 108                     table.getColor("InternalFrame.borderShadow")),
 109                 new WindowsBorders.InternalFrameLineBorder(
 110                     table.getColor("InternalFrame.activeBorderColor"),
 111                     table.getColor("InternalFrame.inactiveBorderColor"),
 112                     table.getInt("InternalFrame.borderWidth")));
 113 
 114         return internalFrameBorder;
 115     }
 116 
 117     @SuppressWarnings("serial") // Superclass is not serializable across versions
 118     public static class ProgressBarBorder extends AbstractBorder implements UIResource {
 119         protected Color shadow;
 120         protected Color highlight;
 121 
 122         public ProgressBarBorder(Color shadow, Color highlight) {
 123             this.highlight = highlight;
 124             this.shadow = shadow;
 125         }
 126 
 127         public void paintBorder(Component c, Graphics g, int x, int y,
 128                                 int width, int height) {
 129             g.setColor(shadow);
 130             g.drawLine(x,y, width-1,y); // draw top
 131             g.drawLine(x,y, x,height-1); // draw left
 132             g.setColor(highlight);
 133             g.drawLine(x,height-1, width-1,height-1); // draw bottom
 134             g.drawLine(width-1,y, width-1,height-1); // draw right
 135         }
 136 
 137         public Insets getBorderInsets(Component c, Insets insets) {
 138             insets.set(1,1,1,1);
 139             return insets;
 140         }
 141     }
 142 
 143     /**
 144      * A border for the ToolBar. If the ToolBar is floatable then the handle grip is drawn
 145      *
 146      * @since 1.4
 147      */
 148     @SuppressWarnings("serial") // Superclass is not serializable across versions
 149     public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants {
 150         protected Color shadow;
 151         protected Color highlight;
 152 
 153         public ToolBarBorder(Color shadow, Color highlight) {
 154             this.highlight = highlight;
 155             this.shadow = shadow;
 156         }
 157 
 158         public void paintBorder(Component c, Graphics g, int x, int y,
 159                                 int width, int height) {
 160             if (!(c instanceof JToolBar)) {
 161                 return;
 162             }
 163             g.translate(x, y);
 164 
 165             XPStyle xp = XPStyle.getXP();
 166             if (xp != null) {
 167                 Border xpBorder = xp.getBorder(c, Part.TP_TOOLBAR);
 168                 if (xpBorder != null) {
 169                     xpBorder.paintBorder(c, g, 0, 0, width, height);
 170                 }
 171             }
 172             if (((JToolBar)c).isFloatable()) {
 173                 boolean vertical = ((JToolBar)c).getOrientation() == VERTICAL;
 174 
 175                 if (xp != null) {
 176                     Part part = vertical ? Part.RP_GRIPPERVERT : Part.RP_GRIPPER;
 177                     Skin skin = xp.getSkin(c, part);
 178                     int dx, dy, dw, dh;
 179                     if (vertical) {
 180                         dx = 0;
 181                         dy = 2;
 182                         dw = width - 1;
 183                         dh = skin.getHeight();
 184                     } else {
 185                         dw = skin.getWidth();
 186                         dh = height - 1;
 187                         dx = c.getComponentOrientation().isLeftToRight() ? 2 : (width-dw-2);
 188                         dy = 0;
 189                     }
 190                     skin.paintSkin(g, dx, dy, dw, dh, State.NORMAL);
 191 
 192                 } else {
 193 
 194                     if (!vertical) {
 195                         if (c.getComponentOrientation().isLeftToRight()) {
 196                             g.setColor(shadow);
 197                             g.drawLine(4, 3, 4, height - 4);
 198                             g.drawLine(4, height - 4, 2, height - 4);
 199 
 200                             g.setColor(highlight);
 201                             g.drawLine(2, 3, 3, 3);
 202                             g.drawLine(2, 3, 2, height - 5);
 203                         } else {
 204                             g.setColor(shadow);
 205                             g.drawLine(width - 3, 3, width - 3, height - 4);
 206                             g.drawLine(width - 4, height - 4, width - 4, height - 4);
 207 
 208                             g.setColor(highlight);
 209                             g.drawLine(width - 5, 3, width - 4, 3);
 210                             g.drawLine(width - 5, 3, width - 5, height - 5);
 211                         }
 212                     } else { // Vertical
 213                         g.setColor(shadow);
 214                         g.drawLine(3, 4, width - 4, 4);
 215                         g.drawLine(width - 4, 2, width - 4, 4);
 216 
 217                         g.setColor(highlight);
 218                         g.drawLine(3, 2, width - 4, 2);
 219                         g.drawLine(3, 2, 3, 3);
 220                     }
 221                 }
 222             }
 223 
 224             g.translate(-x, -y);
 225         }
 226 
 227         public Insets getBorderInsets(Component c, Insets insets) {
 228             insets.set(1,1,1,1);
 229             if (!(c instanceof JToolBar)) {
 230                 return insets;
 231             }
 232             if (((JToolBar)c).isFloatable()) {
 233                 int gripInset = (XPStyle.getXP() != null) ? 12 : 9;
 234                 if (((JToolBar)c).getOrientation() == HORIZONTAL) {
 235                     if (c.getComponentOrientation().isLeftToRight()) {
 236                         insets.left = gripInset;
 237                     } else {
 238                         insets.right = gripInset;
 239                     }
 240                 } else {
 241                     insets.top = gripInset;
 242                 }
 243             }
 244             return insets;
 245         }
 246     }
 247 
 248     /**
 249      * This class is an implementation of a dashed border.
 250      * @since 1.4
 251      */
 252     @SuppressWarnings("serial") // Superclass is not serializable across versions
 253     public static class DashedBorder extends LineBorder implements UIResource {
 254         public DashedBorder(Color color) {
 255             super(color);
 256         }
 257 
 258         public DashedBorder(Color color, int thickness)  {
 259             super(color, thickness);
 260         }
 261 
 262         public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
 263             Color oldColor = g.getColor();
 264             int i;
 265 
 266             g.setColor(lineColor);
 267             for(i = 0; i < thickness; i++)  {
 268                 BasicGraphicsUtils.drawDashedRect(g, x+i, y+i, width-i-i, height-i-i);
 269             }
 270             g.setColor(oldColor);
 271         }
 272     }
 273 
 274     /**
 275      * A dashed border that paints itself in the complementary color
 276      * of the component's background color.
 277      */
 278     @SuppressWarnings("serial") // Superclass is not serializable across versions
 279     static class ComplementDashedBorder extends LineBorder implements UIResource {
 280         private Color origColor;
 281         private Color paintColor;
 282 
 283         public ComplementDashedBorder() {
 284             super(null);
 285         }
 286 
 287         public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
 288             Color color = c.getBackground();
 289 
 290             if (origColor != color) {
 291                 origColor = color;
 292                 paintColor = new Color(~origColor.getRGB());
 293             }
 294 
 295             g.setColor(paintColor);
 296             BasicGraphicsUtils.drawDashedRect(g, x, y, width, height);
 297         }
 298     }
 299 
 300     /**
 301      * This class is an implementation of the InternalFrameLine border.
 302      * @since 1.4
 303      */
 304     @SuppressWarnings("serial") // Superclass is not serializable across versions
 305     public static class InternalFrameLineBorder extends LineBorder implements
 306             UIResource {
 307         protected Color activeColor;
 308         protected Color inactiveColor;
 309 
 310         public InternalFrameLineBorder(Color activeBorderColor,
 311                                        Color inactiveBorderColor,
 312                                        int thickness) {
 313             super(activeBorderColor, thickness);
 314             activeColor = activeBorderColor;
 315             inactiveColor = inactiveBorderColor;
 316         }
 317 
 318         public void paintBorder(Component c, Graphics g, int x, int y,
 319                 int width, int height) {
 320 
 321             JInternalFrame jif = null;
 322             if (c instanceof JInternalFrame) {
 323                 jif = (JInternalFrame)c;
 324             } else if (c instanceof JInternalFrame.JDesktopIcon) {
 325                 jif = ((JInternalFrame.JDesktopIcon)c).getInternalFrame();
 326             } else {
 327                 return;
 328             }
 329 
 330             if (jif.isSelected()) {
 331                 // Set the line color so the line border gets the correct
 332                 // color.
 333                 lineColor = activeColor;
 334                 super.paintBorder(c, g, x, y, width, height);
 335             } else {
 336                 lineColor = inactiveColor;
 337                 super.paintBorder(c, g, x, y, width, height);
 338             }
 339         }
 340     }
 341 }