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