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 26package javax.swing.plaf.metal; 27 28import java.awt.Dimension; 29import java.awt.Graphics; 30import java.awt.Color; 31import java.awt.Polygon; 32 33import javax.swing.*; 34 35import 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</code> 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 54public 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 g.translate(startX, startY); 132 g.fillPolygon(new int[]{0, 1, arrowHeight + 1, -arrowHeight}, 133 new int[]{0, 0, arrowHeight, arrowHeight}, 4); 134 g.translate(-startX, -startY); 135 136 if (isEnabled) { 137 g.setColor( highlightColor ); 138 139 if ( !isPressed ) 140 { 141 g.drawLine( 1, 1, width - 3, 1 ); 142 g.drawLine( 1, 1, 1, height - 1 ); 143 } 144 145 g.drawLine( width - 1, 1, width - 1, height - 1 ); 146 147 g.setColor( shadowColor ); 148 g.drawLine( 0, 0, width - 2, 0 ); 149 g.drawLine( 0, 0, 0, height - 1 ); 150 g.drawLine( width - 2, 2, width - 2, height - 1 ); 151 } else { 152 MetalUtils.drawDisabledBorder(g, 0, 0, width, height+1); 153 } 154 if ( !isFreeStanding ) { 155 height -= 1; 156 g.translate( 0, 1 ); 157 width -= 2; 158 if ( !leftToRight ) { 159 g.translate( 1, 0 ); 160 } 161 } 162 } 163 else if ( getDirection() == SOUTH ) 164 { 165 if ( !isFreeStanding ) { 166 height += 1; 167 width += 2; 168 if ( !leftToRight ) { 169 g.translate( -1, 0 ); 170 } 171 } 172 173 // Draw the arrow 174 g.setColor( arrowColor ); 175 176 int startY = (((h+1) - arrowHeight) / 2)+ arrowHeight-1; 177 int startX = (w / 2); 178 g.translate(startX, startY); 179 g.fillPolygon(new int[]{0, 1, arrowHeight + 1, -arrowHeight}, 180 new int[]{0, 0, -arrowHeight, -arrowHeight}, 4); 181 g.translate(-startX, -startY); 182 183 if (isEnabled) { 184 g.setColor( highlightColor ); 185 186 if ( !isPressed ) 187 { 188 g.drawLine( 1, 0, width - 3, 0 ); 189 g.drawLine( 1, 0, 1, height - 3 ); 190 } 191 192 g.drawLine( 1, height - 1, width - 1, height - 1 ); 193 g.drawLine( width - 1, 0, width - 1, height - 1 ); 194 195 g.setColor( shadowColor ); 196 g.drawLine( 0, 0, 0, height - 2 ); 197 g.drawLine( width - 2, 0, width - 2, height - 2 ); 198 g.drawLine( 2, height - 2, width - 2, height - 2 ); 199 } else { 200 MetalUtils.drawDisabledBorder(g, 0,-1, width, height+1); 201 } 202 203 if ( !isFreeStanding ) { 204 height -= 1; 205 width -= 2; 206 if ( !leftToRight ) { 207 g.translate( 1, 0 ); 208 } 209 } 210 } 211 else if ( getDirection() == EAST ) 212 { 213 if ( !isFreeStanding ) { 214 height += 2; 215 width += 1; 216 } 217 218 // Draw the arrow 219 g.setColor( arrowColor ); 220 221 int startX = (((w+1) - arrowHeight) / 2) + arrowHeight-1; 222 int startY = (h / 2); 223 224 g.translate(startX, startY); 225 g.fillPolygon(new int[]{0, 0, -arrowHeight, -arrowHeight}, 226 new int[]{0, 1, arrowHeight + 1, -arrowHeight}, 4); 227 g.translate(-startX, -startY); 228 229 if (isEnabled) { 230 g.setColor( highlightColor ); 231 232 if ( !isPressed ) 233 { 234 g.drawLine( 0, 1, width - 3, 1 ); 235 g.drawLine( 0, 1, 0, height - 3 ); 236 } 237 238 g.drawLine( width - 1, 1, width - 1, height - 1 ); 239 g.drawLine( 0, height - 1, width - 1, height - 1 ); 240 241 g.setColor( shadowColor ); 242 g.drawLine( 0, 0,width - 2, 0 ); 243 g.drawLine( width - 2, 2, width - 2, height - 2 ); 244 g.drawLine( 0, height - 2, width - 2, height - 2 ); 245 } else { 246 MetalUtils.drawDisabledBorder(g,-1,0, width+1, height); 247 } 248 if ( !isFreeStanding ) { 249 height -= 2; 250 width -= 1; 251 } 252 } 253 else if ( getDirection() == WEST ) 254 { 255 if ( !isFreeStanding ) { 256 height += 2; 257 width += 1; 258 g.translate( -1, 0 ); 259 } 260 261 // Draw the arrow 262 g.setColor( arrowColor ); 263 264 int startX = (((w+1) - arrowHeight) / 2); 265 int startY = (h / 2); 266 267 g.translate(startX, startY); 268 g.fillPolygon(new int[]{0, 0, arrowHeight, arrowHeight}, 269 new int[]{0, 1, arrowHeight + 1, -arrowHeight}, 4); 270 g.translate(-startX, -startY); 271 272 if (isEnabled) { 273 g.setColor( highlightColor ); 274 275 276 if ( !isPressed ) 277 { 278 g.drawLine( 1, 1, width - 1, 1 ); 279 g.drawLine( 1, 1, 1, height - 3 ); 280 } 281 282 g.drawLine( 1, height - 1, width - 1, height - 1 ); 283 284 g.setColor( shadowColor ); 285 g.drawLine( 0, 0, width - 1, 0 ); 286 g.drawLine( 0, 0, 0, height - 2 ); 287 g.drawLine( 2, height - 2, width - 1, height - 2 ); 288 } else { 289 MetalUtils.drawDisabledBorder(g,0,0, width+1, height); 290 } 291 292 if ( !isFreeStanding ) { 293 height -= 2; 294 width -= 1; 295 g.translate( 1, 0 ); 296 } 297 } 298 } 299 300 public Dimension getPreferredSize() 301 { 302 if ( getDirection() == NORTH ) 303 { 304 return new Dimension( buttonWidth, buttonWidth - 2 ); 305 } 306 else if ( getDirection() == SOUTH ) 307 { 308 return new Dimension( buttonWidth, buttonWidth - (isFreeStanding ? 1 : 2) ); 309 } 310 else if ( getDirection() == EAST ) 311 { 312 return new Dimension( buttonWidth - (isFreeStanding ? 1 : 2), buttonWidth ); 313 } 314 else if ( getDirection() == WEST ) 315 { 316 return new Dimension( buttonWidth - 2, buttonWidth ); 317 } 318 else 319 { 320 return new Dimension( 0, 0 ); 321 } 322 } 323 324 public Dimension getMinimumSize() 325 { 326 return getPreferredSize(); 327 } 328 329 public Dimension getMaximumSize() 330 { 331 return new Dimension( Integer.MAX_VALUE, Integer.MAX_VALUE ); 332 } 333 334 /** 335 * Returns the width of the button. 336 * 337 * @return the width of the button 338 */ 339 public int getButtonWidth() { 340 return buttonWidth; 341 } 342} 343