1 /*
   2  * Copyright (c) 1998, 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 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 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     public static class ProgressBarBorder extends AbstractBorder implements UIResource {
 118         protected Color shadow;
 119         protected Color highlight;
 120 
 121         public ProgressBarBorder(Color shadow, Color highlight) {
 122             this.highlight = highlight;
 123             this.shadow = shadow;
 124         }
 125 
 126         public void paintBorder(Component c, Graphics g, int x, int y,
 127                                 int width, int height) {
 128             g.setColor(shadow);
 129             g.drawLine(x,y, width-1,y); // draw top
 130             g.drawLine(x,y, x,height-1); // draw left
 131             g.setColor(highlight);
 132             g.drawLine(x,height-1, width-1,height-1); // draw bottom
 133             g.drawLine(width-1,y, width-1,height-1); // draw right
 134         }
 135 
 136         public Insets getBorderInsets(Component c, Insets insets) {
 137             insets.set(1,1,1,1);
 138             return insets;
 139         }
 140     }
 141 
 142     /**
 143      * A border for the ToolBar. If the ToolBar is floatable then the handle grip is drawn
 144      * <p>
 145      * @since 1.4
 146      */
 147     public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants {
 148         protected Color shadow;
 149         protected Color highlight;
 150 
 151         public ToolBarBorder(Color shadow, Color highlight) {
 152             this.highlight = highlight;
 153             this.shadow = shadow;
 154         }
 155 
 156         public void paintBorder(Component c, Graphics g, int x, int y,
 157                                 int width, int height) {
 158             if (!(c instanceof JToolBar)) {
 159                 return;
 160             }
 161             g.translate(x, y);
 162 
 163             XPStyle xp = XPStyle.getXP();
 164             if (xp != null) {
 165                 Border xpBorder = xp.getBorder(c, Part.TP_TOOLBAR);
 166                 if (xpBorder != null) {
 167                     xpBorder.paintBorder(c, g, 0, 0, width, height);
 168                 }
 169             }
 170             if (((JToolBar)c).isFloatable()) {
 171                 boolean vertical = ((JToolBar)c).getOrientation() == VERTICAL;
 172 
 173                 if (xp != null) {
 174                     Part part = vertical ? Part.RP_GRIPPERVERT : Part.RP_GRIPPER;
 175                     Skin skin = xp.getSkin(c, part);
 176                     int dx, dy, dw, dh;
 177                     if (vertical) {
 178                         dx = 0;
 179                         dy = 2;
 180                         dw = width - 1;
 181                         dh = skin.getHeight();
 182                     } else {
 183                         dw = skin.getWidth();
 184                         dh = height - 1;
 185                         dx = c.getComponentOrientation().isLeftToRight() ? 2 : (width-dw-2);
 186                         dy = 0;
 187                     }
 188                     skin.paintSkin(g, dx, dy, dw, dh, State.NORMAL);
 189 
 190                 } else {
 191 
 192                     if (!vertical) {
 193                         if (c.getComponentOrientation().isLeftToRight()) {
 194                             g.setColor(shadow);
 195                             g.drawLine(4, 3, 4, height - 4);
 196                             g.drawLine(4, height - 4, 2, height - 4);
 197 
 198                             g.setColor(highlight);
 199                             g.drawLine(2, 3, 3, 3);
 200                             g.drawLine(2, 3, 2, height - 5);
 201                         } else {
 202                             g.setColor(shadow);
 203                             g.drawLine(width - 3, 3, width - 3, height - 4);
 204                             g.drawLine(width - 4, height - 4, width - 4, height - 4);
 205 
 206                             g.setColor(highlight);
 207                             g.drawLine(width - 5, 3, width - 4, 3);
 208                             g.drawLine(width - 5, 3, width - 5, height - 5);
 209                         }
 210                     } else { // Vertical
 211                         g.setColor(shadow);
 212                         g.drawLine(3, 4, width - 4, 4);
 213                         g.drawLine(width - 4, 2, width - 4, 4);
 214 
 215                         g.setColor(highlight);
 216                         g.drawLine(3, 2, width - 4, 2);
 217                         g.drawLine(3, 2, 3, 3);
 218                     }
 219                 }
 220             }
 221 
 222             g.translate(-x, -y);
 223         }
 224 
 225         public Insets getBorderInsets(Component c, Insets insets) {
 226             insets.set(1,1,1,1);
 227             if (!(c instanceof JToolBar)) {
 228                 return insets;
 229             }
 230             if (((JToolBar)c).isFloatable()) {
 231                 int gripInset = (XPStyle.getXP() != null) ? 12 : 9;
 232                 if (((JToolBar)c).getOrientation() == HORIZONTAL) {
 233                     if (c.getComponentOrientation().isLeftToRight()) {
 234                         insets.left = gripInset;
 235                     } else {
 236                         insets.right = gripInset;
 237                     }
 238                 } else {
 239                     insets.top = gripInset;
 240                 }
 241             }
 242             return insets;
 243         }
 244     }
 245 
 246     /**
 247      * This class is an implementation of a dashed border.
 248      * @since 1.4
 249      */
 250     public static class DashedBorder extends LineBorder implements UIResource {
 251         public DashedBorder(Color color) {
 252             super(color);
 253         }
 254 
 255         public DashedBorder(Color color, int thickness)  {
 256             super(color, thickness);
 257         }
 258 
 259         public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
 260             Color oldColor = g.getColor();
 261             int i;
 262 
 263             g.setColor(lineColor);
 264             for(i = 0; i < thickness; i++)  {
 265                 BasicGraphicsUtils.drawDashedRect(g, x+i, y+i, width-i-i, height-i-i);
 266             }
 267             g.setColor(oldColor);
 268         }
 269     }
 270 
 271     /**
 272      * A dashed border that paints itself in the complementary color
 273      * of the component's background color.
 274      */
 275     static class ComplementDashedBorder extends LineBorder implements UIResource {
 276         private Color origColor;
 277         private Color paintColor;
 278 
 279         public ComplementDashedBorder() {
 280             super(null);
 281         }
 282 
 283         public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
 284             Color color = c.getBackground();
 285 
 286             if (origColor != color) {
 287                 origColor = color;
 288                 paintColor = new Color(~origColor.getRGB());
 289             }
 290 
 291             g.setColor(paintColor);
 292             BasicGraphicsUtils.drawDashedRect(g, x, y, width, height);
 293         }
 294     }
 295 
 296     /**
 297      * This class is an implementation of the InternalFrameLine border.
 298      * @since 1.4
 299      */
 300     public static class InternalFrameLineBorder extends LineBorder implements
 301             UIResource {
 302         protected Color activeColor;
 303         protected Color inactiveColor;
 304 
 305         public InternalFrameLineBorder(Color activeBorderColor,
 306                                        Color inactiveBorderColor,
 307                                        int thickness) {
 308             super(activeBorderColor, thickness);
 309             activeColor = activeBorderColor;
 310             inactiveColor = inactiveBorderColor;
 311         }
 312 
 313         public void paintBorder(Component c, Graphics g, int x, int y,
 314                 int width, int height) {
 315 
 316             JInternalFrame jif = null;
 317             if (c instanceof JInternalFrame) {
 318                 jif = (JInternalFrame)c;
 319             } else if (c instanceof JInternalFrame.JDesktopIcon) {
 320                 jif = ((JInternalFrame.JDesktopIcon)c).getInternalFrame();
 321             } else {
 322                 return;
 323             }
 324 
 325             if (jif.isSelected()) {
 326                 // Set the line color so the line border gets the correct
 327                 // color.
 328                 lineColor = activeColor;
 329                 super.paintBorder(c, g, x, y, width, height);
 330             } else {
 331                 lineColor = inactiveColor;
 332                 super.paintBorder(c, g, x, y, width, height);
 333             }
 334         }
 335     }
 336 }