Source for javax.swing.plaf.metal.MetalSliderUI

   1: /* MetalSliderUI.java
   2:    Copyright (C) 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing.plaf.metal;
  40: 
  41: import java.awt.Color;
  42: import java.awt.Dimension;
  43: import java.awt.Graphics;
  44: import java.awt.Rectangle;
  45: import java.beans.PropertyChangeListener;
  46: import java.util.HashMap;
  47: 
  48: import javax.swing.Icon;
  49: import javax.swing.JComponent;
  50: import javax.swing.JSlider;
  51: import javax.swing.UIManager;
  52: import javax.swing.plaf.ComponentUI;
  53: import javax.swing.plaf.basic.BasicGraphicsUtils;
  54: import javax.swing.plaf.basic.BasicSliderUI;
  55: 
  56: /**
  57:  * A UI delegate for the {@link JSlider} component.
  58:  */
  59: public class MetalSliderUI
  60:   extends BasicSliderUI
  61: {
  62:   // TODO: find a use for this
  63:   protected static Color thumbColor;
  64:   
  65:   // TODO: find a use for this
  66:   protected static Color highlightColor;
  67:   
  68:   // TODO: find a use for this
  69:   protected static Color darkShadowColor;
  70:   
  71:   /** The track width. */
  72:   protected static int trackWidth = UIManager.getInt("Slider.trackWidth");
  73:   
  74:   /** The length of the major tick marks. */
  75:   protected static int tickLength = UIManager.getInt("Slider.majorTickLength");
  76:   
  77:   /** The icon used for the thumb control of horizontally oriented sliders. */
  78:   protected static Icon horizThumbIcon = UIManager.getIcon(
  79:           "Slider.horizontalThumbIcon");
  80:   
  81:   /** The icon used for the thumb control of vertically oriented sliders. */
  82:   protected static Icon vertThumbIcon = UIManager.getIcon(
  83:           "Slider.verticalThumbIcon");
  84: 
  85:   /** The gap between the track and the tick marks. */
  86:   protected final int TICK_BUFFER = 4;
  87: 
  88:   /** 
  89:    * A flag that controls whether or not the track is filled up to the value
  90:    * of the slider.
  91:    */
  92:   protected boolean filledSlider;
  93:     
  94:   /** A key to look up the filledSlider setting in the {@link UIManager}. */
  95:   protected final String SLIDER_FILL = "JSlider.isFilled";
  96:   
  97:   /** The UI instances for MetalSliderUIs */
  98:   private static HashMap instances;
  99: 
 100:   /**
 101:    * Constructs a new instance.
 102:    */
 103:   public MetalSliderUI()
 104:   {
 105:     super(null);
 106:     filledSlider = UIManager.getBoolean(SLIDER_FILL);
 107:   }
 108: 
 109:   /**
 110:    * Returns an instance of MetalSliderUI.
 111:    *
 112:    * @param component the component for which we return an UI instance
 113:    *
 114:    * @return an instance of MetalSliderUI
 115:    */
 116:   public static ComponentUI createUI(JComponent component)
 117:   {
 118:     if (instances == null)
 119:       instances = new HashMap();
 120: 
 121:     Object o = instances.get(component);
 122:     MetalSliderUI instance;
 123:     if (o == null)
 124:       {
 125:         instance = new MetalSliderUI();
 126:         instances.put(component, instance);
 127:       }
 128:     else
 129:       instance = (MetalSliderUI) o;
 130: 
 131:     return instance;
 132:   }
 133:   
 134:   public void installUI(JComponent c)
 135:   {
 136:     super.installUI(c);
 137:     Boolean b = (Boolean) c.getClientProperty(SLIDER_FILL);
 138:     if (b != null) 
 139:       filledSlider = b.booleanValue();
 140:   }
 141: 
 142:   /**
 143:    * Paints the thumb icon for the slider.
 144:    * 
 145:    * @param g  the graphics device.
 146:    */
 147:   public void paintThumb(Graphics g) 
 148:   {
 149:     if (slider.getOrientation() == JSlider.HORIZONTAL)
 150:       horizThumbIcon.paintIcon(slider, g, thumbRect.x, thumbRect.y);
 151:     else
 152:       vertThumbIcon.paintIcon(slider, g, thumbRect.x, thumbRect.y);
 153:   }
 154:   
 155:   /**
 156:    * Creates a property change listener for the slider.
 157:    * 
 158:    * @param slider  the slider.
 159:    */
 160:   protected PropertyChangeListener createPropertyChangeListener(JSlider slider)
 161:   {
 162:     // TODO: try to figure out why it might be necessary to override this 
 163:     // method as is done in Sun's implementation
 164:     return super.createPropertyChangeListener(slider);    
 165:   }
 166:   
 167:   /**
 168:    * Paints the track along which the thumb control moves.
 169:    * 
 170:    * @param g  the graphics device.
 171:    */
 172:   public void paintTrack(Graphics g)
 173:   {
 174:     if (slider.getOrientation() == JSlider.HORIZONTAL)
 175:     {
 176:       if (filledSlider) 
 177:       {
 178:         // TODO: fill the track
 179:       }
 180:       BasicGraphicsUtils.drawEtchedRect(g, trackRect.x, trackRect.y 
 181:           + (trackRect.height - getTrackWidth()) / 2, trackRect.width - 1, 
 182:           getTrackWidth(), Color.darkGray, Color.gray, Color.darkGray, 
 183:           Color.white);
 184:     }
 185:     else
 186:     {
 187:       if (filledSlider) 
 188:       {
 189:         // TODO: fill the track
 190:       }
 191:       BasicGraphicsUtils.drawEtchedRect(g, trackRect.x  + (trackRect.width 
 192:           - getTrackWidth()) / 2, trackRect.y, getTrackWidth(), 
 193:           trackRect.height - 1, Color.darkGray, Color.gray, Color.darkGray, 
 194:           Color.white);
 195:     }
 196:   }
 197:   
 198:   /**
 199:    * Draws the focus rectangle for the slider.  The Metal look and feel 
 200:    * indicates that the {@link JSlider} has the focus by changing the color of 
 201:    * the thumb control - this is handled elsewhere and so this method is empty 
 202:    * (it overrides the method in the {@link BasicSliderUI} class to prevent
 203:    * a default focus highlight from being drawn).
 204:    * 
 205:    * @param g  the graphics device.
 206:    */
 207:   public void paintFocus(Graphics g)
 208:   {
 209:     // do nothing as focus is shown by different color on thumb control
 210:   }
 211:   
 212:   /**
 213:    * Returns the size of the thumb icon.
 214:    * 
 215:    * @return The size of the thumb icon.
 216:    */
 217:   protected Dimension getThumbSize()
 218:   {
 219:     if (slider.getOrientation() == JSlider.HORIZONTAL)
 220:       return new Dimension(horizThumbIcon.getIconWidth(), 
 221:               horizThumbIcon.getIconHeight());
 222:     else
 223:       return new Dimension(vertThumbIcon.getIconWidth(), 
 224:               vertThumbIcon.getIconHeight());
 225:   }
 226:   
 227:   /**
 228:    * Returns the length of the major tick marks.
 229:    * 
 230:    * @return The length of the major tick marks.
 231:    */
 232:   public int getTickLength()
 233:   {
 234:     return tickLength + TICK_BUFFER;
 235:   }
 236:   
 237:   /**
 238:    * Returns the track width.
 239:    * 
 240:    * @return The track width.
 241:    */
 242:   protected int getTrackWidth()
 243:   {
 244:     return trackWidth;
 245:   }
 246:   
 247:   /**
 248:    * Returns the track length.
 249:    * 
 250:    * @return The track length.
 251:    */
 252:   protected int getTrackLength()
 253:   {
 254:     return (slider.getOrientation() == JSlider.HORIZONTAL 
 255:             ? tickRect.width : tickRect.height);
 256:   }
 257:   
 258:   /**
 259:    * Returns the thumb overhang.
 260:    * 
 261:    * @return The thumb overhang.
 262:    */
 263:   protected int getThumbOverhang()
 264:   {
 265:     // TODO: figure out what this is used for
 266:     return 0;
 267:   }
 268:   
 269:   protected void scrollDueToClickInTrack(int dir)
 270:   {
 271:     super.scrollDueToClickInTrack(dir);
 272:   }
 273:   
 274:   /**
 275:    * Paints the minor ticks for a slider with a horizontal orientation.
 276:    * 
 277:    * @param g  the graphics device.
 278:    * @param tickBounds  the tick bounds.
 279:    * @param x  the x value for the tick.
 280:    */
 281:   protected void paintMinorTickForHorizSlider(Graphics g, Rectangle tickBounds,
 282:                                               int x)
 283:   {
 284:     // Note the incoming 'g' has a translation in place to get us to the 
 285:     // start of the tick rect already...
 286:     // TODO: get color from UIManager...
 287:     g.setColor(new Color(153, 153, 204));
 288:     g.drawLine(x, TICK_BUFFER, x, TICK_BUFFER + tickLength / 2);
 289:   }
 290:  
 291:   /**
 292:    * Paints the major ticks for a slider with a horizontal orientation.
 293:    * 
 294:    * @param g  the graphics device.
 295:    * @param tickBounds  the tick bounds.
 296:    * @param x  the x value for the tick.
 297:    */
 298:   protected void paintMajorTickForHorizSlider(Graphics g, Rectangle tickBounds,
 299:                                               int x)
 300:   {
 301:     // Note the incoming 'g' has a translation in place to get us to the 
 302:     // start of the tick rect already...
 303:     // TODO: get color from UIManager...
 304:     g.setColor(new Color(153, 153, 204));
 305:     g.drawLine(x, TICK_BUFFER, x, TICK_BUFFER + tickLength);
 306:   }
 307:   
 308:   /**
 309:    * Paints the minor ticks for a slider with a vertical orientation.
 310:    * 
 311:    * @param g  the graphics device.
 312:    * @param tickBounds  the tick bounds.
 313:    * @param y  the y value for the tick.
 314:    */
 315:   protected void paintMinorTickForVertSlider(Graphics g, Rectangle tickBounds,
 316:                                              int y)
 317:   {
 318:     // Note the incoming 'g' has a translation in place to get us to the 
 319:     // start of the tick rect already...
 320:     // TODO: get color from UIManager...
 321:     g.setColor(new Color(153, 153, 204));
 322:     g.drawLine(TICK_BUFFER - 1, y, TICK_BUFFER - 1 + tickLength / 2, y);
 323:   }
 324:   
 325:   /**
 326:    * Paints the major ticks for a slider with a vertical orientation.
 327:    * 
 328:    * @param g  the graphics device.
 329:    * @param tickBounds  the tick bounds.
 330:    * @param y  the y value for the tick.
 331:    */
 332:   protected void paintMajorTickForVertSlider(Graphics g, Rectangle tickBounds,
 333:                                              int y)
 334:   {
 335:     // Note the incoming 'g' has a translation in place to get us to the 
 336:     // start of the tick rect already...
 337:     // TODO: get color from UIManager...
 338:     g.setColor(new Color(153, 153, 204));
 339:     g.drawLine(TICK_BUFFER - 1, y, TICK_BUFFER - 1 + tickLength, y);
 340:   }
 341:   
 342: }