1 /*
   2  * Copyright (c) 1998, 2004, 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.metal;
  27 
  28 import java.awt.Dimension;
  29 import java.awt.Graphics;
  30 import java.awt.Color;
  31 import java.awt.Polygon;
  32 
  33 import javax.swing.*;
  34 
  35 import javax.swing.plaf.basic.BasicArrowButton;
  36 
  37 
  38 /**
  39  * JButton object for Metal scrollbar arrows.
  40  * <p>
  41  * <strong>Warning:</strong>
  42  * Serialized objects of this class will not be compatible with
  43  * future Swing releases. The current serialization support is
  44  * appropriate for short term storage or RMI between applications running
  45  * the same version of Swing.  As of 1.4, support for long term storage
  46  * of all JavaBeans&trade;
  47  * has been added to the <code>java.beans</code> package.
  48  * Please see {@link java.beans.XMLEncoder}.
  49  *
  50  * @author Tom Santos
  51  * @author Steve Wilson
  52  */
  53 public class MetalScrollButton extends BasicArrowButton
  54 {
  55   private static Color shadowColor;
  56   private static Color highlightColor;
  57   private boolean isFreeStanding = false;
  58 
  59   private int buttonWidth;
  60 
  61         public MetalScrollButton( int direction, int width, boolean freeStanding )
  62         {
  63             super( direction );
  64 
  65             shadowColor = UIManager.getColor("ScrollBar.darkShadow");
  66             highlightColor = UIManager.getColor("ScrollBar.highlight");
  67 
  68             buttonWidth = width;
  69             isFreeStanding = freeStanding;
  70         }
  71 
  72         public void setFreeStanding( boolean freeStanding )
  73         {
  74             isFreeStanding = freeStanding;
  75         }
  76 
  77         public void paint( Graphics g )
  78         {
  79             boolean leftToRight = MetalUtils.isLeftToRight(this);
  80             boolean isEnabled = getParent().isEnabled();
  81 
  82             Color arrowColor = isEnabled ? MetalLookAndFeel.getControlInfo() : MetalLookAndFeel.getControlDisabled();
  83             boolean isPressed = getModel().isPressed();
  84             int width = getWidth();
  85             int height = getHeight();
  86             int w = width;
  87             int h = height;
  88             int arrowHeight = (height+1) / 4;
  89             int arrowWidth = (height+1) / 2;
  90 
  91             if ( isPressed )
  92             {
  93                 g.setColor( MetalLookAndFeel.getControlShadow() );
  94             }
  95             else
  96             {
  97                 g.setColor( getBackground() );
  98             }
  99 
 100             g.fillRect( 0, 0, width, height );
 101 
 102             if ( getDirection() == NORTH )
 103             {
 104                 if ( !isFreeStanding ) {
 105                     height +=1;
 106                     g.translate( 0, -1 );
 107                     width += 2;
 108                     if ( !leftToRight ) {
 109                         g.translate( -1, 0 );
 110                     }
 111                 }
 112 
 113                 // Draw the arrow
 114                 g.setColor( arrowColor );
 115                 int startY = ((h+1) - arrowHeight) / 2;
 116                 int startX = (w / 2);
 117                 //                  System.out.println( "startX :" + startX + " startY :"+startY);
 118                 for (int line = 0; line < arrowHeight; line++) {
 119                     g.drawLine( startX-line, startY+line, startX +line+1, startY+line);
 120                 }
 121         /*      g.drawLine( 7, 6, 8, 6 );
 122                 g.drawLine( 6, 7, 9, 7 );
 123                 g.drawLine( 5, 8, 10, 8 );
 124                 g.drawLine( 4, 9, 11, 9 );*/
 125 
 126                 if (isEnabled) {
 127                     g.setColor( highlightColor );
 128 
 129                     if ( !isPressed )
 130                     {
 131                         g.drawLine( 1, 1, width - 3, 1 );
 132                         g.drawLine( 1, 1, 1, height - 1 );
 133                     }
 134 
 135                     g.drawLine( width - 1, 1, width - 1, height - 1 );
 136 
 137                     g.setColor( shadowColor );
 138                     g.drawLine( 0, 0, width - 2, 0 );
 139                     g.drawLine( 0, 0, 0, height - 1 );
 140                     g.drawLine( width - 2, 2, width - 2, height - 1 );
 141                 } else {
 142                     MetalUtils.drawDisabledBorder(g, 0, 0, width, height+1);
 143                 }
 144                 if ( !isFreeStanding ) {
 145                     height -= 1;
 146                     g.translate( 0, 1 );
 147                     width -= 2;
 148                     if ( !leftToRight ) {
 149                         g.translate( 1, 0 );
 150                     }
 151                 }
 152             }
 153             else if ( getDirection() == SOUTH )
 154             {
 155                 if ( !isFreeStanding ) {
 156                     height += 1;
 157                     width += 2;
 158                     if ( !leftToRight ) {
 159                         g.translate( -1, 0 );
 160                     }
 161                 }
 162 
 163                 // Draw the arrow
 164                 g.setColor( arrowColor );
 165 
 166                 int startY = (((h+1) - arrowHeight) / 2)+ arrowHeight-1;
 167                 int startX = (w / 2);
 168 
 169                 //          System.out.println( "startX2 :" + startX + " startY2 :"+startY);
 170 
 171                 for (int line = 0; line < arrowHeight; line++) {
 172                     g.drawLine( startX-line, startY-line, startX +line+1, startY-line);
 173                 }
 174 
 175         /*      g.drawLine( 4, 5, 11, 5 );
 176                 g.drawLine( 5, 6, 10, 6 );
 177                 g.drawLine( 6, 7, 9, 7 );
 178                 g.drawLine( 7, 8, 8, 8 ); */
 179 
 180                 if (isEnabled) {
 181                     g.setColor( highlightColor );
 182 
 183                     if ( !isPressed )
 184                     {
 185                         g.drawLine( 1, 0, width - 3, 0 );
 186                         g.drawLine( 1, 0, 1, height - 3 );
 187                     }
 188 
 189                     g.drawLine( 1, height - 1, width - 1, height - 1 );
 190                     g.drawLine( width - 1, 0, width - 1, height - 1 );
 191 
 192                     g.setColor( shadowColor );
 193                     g.drawLine( 0, 0, 0, height - 2 );
 194                     g.drawLine( width - 2, 0, width - 2, height - 2 );
 195                     g.drawLine( 2, height - 2, width - 2, height - 2 );
 196                 } else {
 197                     MetalUtils.drawDisabledBorder(g, 0,-1, width, height+1);
 198                 }
 199 
 200                 if ( !isFreeStanding ) {
 201                     height -= 1;
 202                     width -= 2;
 203                     if ( !leftToRight ) {
 204                         g.translate( 1, 0 );
 205                     }
 206                 }
 207             }
 208             else if ( getDirection() == EAST )
 209             {
 210                 if ( !isFreeStanding ) {
 211                     height += 2;
 212                     width += 1;
 213                 }
 214 
 215                 // Draw the arrow
 216                 g.setColor( arrowColor );
 217 
 218                 int startX = (((w+1) - arrowHeight) / 2) + arrowHeight-1;
 219                 int startY = (h / 2);
 220 
 221                 //System.out.println( "startX2 :" + startX + " startY2 :"+startY);
 222 
 223                 for (int line = 0; line < arrowHeight; line++) {
 224                     g.drawLine( startX-line, startY-line, startX -line, startY+line+1);
 225                 }
 226 
 227 
 228 /*              g.drawLine( 5, 4, 5, 11 );
 229                 g.drawLine( 6, 5, 6, 10 );
 230                 g.drawLine( 7, 6, 7, 9 );
 231                 g.drawLine( 8, 7, 8, 8 );*/
 232 
 233                 if (isEnabled) {
 234                     g.setColor( highlightColor );
 235 
 236                     if ( !isPressed )
 237                     {
 238                         g.drawLine( 0, 1, width - 3, 1 );
 239                         g.drawLine( 0, 1, 0, height - 3 );
 240                     }
 241 
 242                     g.drawLine( width - 1, 1, width - 1, height - 1 );
 243                     g.drawLine( 0, height - 1, width - 1, height - 1 );
 244 
 245                     g.setColor( shadowColor );
 246                     g.drawLine( 0, 0,width - 2, 0 );
 247                     g.drawLine( width - 2, 2, width - 2, height - 2 );
 248                     g.drawLine( 0, height - 2, width - 2, height - 2 );
 249                 } else {
 250                     MetalUtils.drawDisabledBorder(g,-1,0, width+1, height);
 251                 }
 252                 if ( !isFreeStanding ) {
 253                     height -= 2;
 254                     width -= 1;
 255                 }
 256             }
 257             else if ( getDirection() == WEST )
 258             {
 259                 if ( !isFreeStanding ) {
 260                     height += 2;
 261                     width += 1;
 262                     g.translate( -1, 0 );
 263                 }
 264 
 265                 // Draw the arrow
 266                 g.setColor( arrowColor );
 267 
 268                 int startX = (((w+1) - arrowHeight) / 2);
 269                 int startY = (h / 2);
 270 
 271 
 272                 for (int line = 0; line < arrowHeight; line++) {
 273                     g.drawLine( startX+line, startY-line, startX +line, startY+line+1);
 274                 }
 275 
 276         /*      g.drawLine( 6, 7, 6, 8 );
 277                 g.drawLine( 7, 6, 7, 9 );
 278                 g.drawLine( 8, 5, 8, 10 );
 279                 g.drawLine( 9, 4, 9, 11 );*/
 280 
 281                 if (isEnabled) {
 282                     g.setColor( highlightColor );
 283 
 284 
 285                     if ( !isPressed )
 286                     {
 287                         g.drawLine( 1, 1, width - 1, 1 );
 288                         g.drawLine( 1, 1, 1, height - 3 );
 289                     }
 290 
 291                     g.drawLine( 1, height - 1, width - 1, height - 1 );
 292 
 293                     g.setColor( shadowColor );
 294                     g.drawLine( 0, 0, width - 1, 0 );
 295                     g.drawLine( 0, 0, 0, height - 2 );
 296                     g.drawLine( 2, height - 2, width - 1, height - 2 );
 297                 } else {
 298                     MetalUtils.drawDisabledBorder(g,0,0, width+1, height);
 299                 }
 300 
 301                 if ( !isFreeStanding ) {
 302                     height -= 2;
 303                     width -= 1;
 304                     g.translate( 1, 0 );
 305                 }
 306             }
 307         }
 308 
 309         public Dimension getPreferredSize()
 310         {
 311             if ( getDirection() == NORTH )
 312             {
 313                 return new Dimension( buttonWidth, buttonWidth - 2 );
 314             }
 315             else if ( getDirection() == SOUTH )
 316             {
 317                 return new Dimension( buttonWidth, buttonWidth - (isFreeStanding ? 1 : 2) );
 318             }
 319             else if ( getDirection() == EAST )
 320             {
 321                 return new Dimension( buttonWidth - (isFreeStanding ? 1 : 2), buttonWidth );
 322             }
 323             else if ( getDirection() == WEST )
 324             {
 325                 return new Dimension( buttonWidth - 2, buttonWidth );
 326             }
 327             else
 328             {
 329                 return new Dimension( 0, 0 );
 330             }
 331         }
 332 
 333         public Dimension getMinimumSize()
 334         {
 335             return getPreferredSize();
 336         }
 337 
 338         public Dimension getMaximumSize()
 339         {
 340             return new Dimension( Integer.MAX_VALUE, Integer.MAX_VALUE );
 341         }
 342 
 343         public int getButtonWidth() {
 344             return buttonWidth;
 345         }
 346 }