1  /*
     2   Copyright aswing.org, see the LICENCE.txt.
     3  */
     4   
     5  import org.aswing.ASWingConstants;
     6  import org.aswing.BoundedRangeModel;
     7  import org.aswing.Container;
     8  import org.aswing.DefaultBoundedRangeModel;
     9  import org.aswing.Event;
    10  import org.aswing.plaf.ScrollBarUI;
    11  import org.aswing.UIManager;
    12   
    13  /**
    14   *
    15   * @author iiley
    16   */
    17  class org.aswing.JScrollBar extends Container{
    18      /** 
    19       * Horizontal orientation.
    20       */
    21      public static var HORIZONTAL:Number = ASWingConstants.HORIZONTAL;
    22      /** 
    23       * Vertical orientation.
    24       */
    25      public static var VERTICAL:Number   = ASWingConstants.VERTICAL;
    26  	       
    27  
    28  	/**
    29  	 * When the scrollbar's Adjustment Value Changed.
    30  	 *<br>
    31  	 * onAdjustmentValueChanged Event{source:JScrollBar}
    32  	 */	
    33  	public static var ON_ADJUSTMENT_VALUE_CHANGED:String = "onAdjustmentValueChanged"; 		       
    34          
    35  	private var modelListener:Object;
    36  	
    37  	private var model:BoundedRangeModel;
    38  	private var orientation:Number;
    39  	private var unitIncrement:Number;
    40  	private var blockIncrement:Number;
    41  
    42  	/**
    43  	 * JScrollBar(orientation:Number, value:Number, extent:Number, min:Number, max:Number)<br>
    44  	 * JScrollBar(orientation:Number) default to value=0, extent=10, min=0, max=100<br>
    45  	 * <p>
    46  	 * Creates a scrollbar with the specified orientation, value, extent, minimum, and maximum. 
    47  	 * The "extent" is the size of the viewable area. It is also known as the "visible amount". 
    48  	 * <p>
    49  	 * Note: Use setBlockIncrement to set the block increment to a size slightly smaller than 
    50  	 * the view's extent. That way, when the user jumps the knob to an adjacent position, one 
    51  	 * or two lines of the original contents remain in view. 
    52  	 * 
    53  	 * @param orientation the scrollbar's orientation to either VERTICAL or HORIZONTAL. 
    54  	 * @param value
    55  	 * @param extent
    56  	 * @param min
    57  	 * @param max
    58  	 */
    59  	public function JScrollBar(orientation:Number, value:Number, extent:Number, min:Number, max:Number){
    60  		super();
    61  		if(value == undefined) value = 0;
    62  		if(extent == undefined) extent = 10;
    63  		if(min == undefined) min = 0;
    64  		if(max == undefined) max = 100;
    65  		this.unitIncrement = 1;
    66  		this.blockIncrement = (extent == 0 ? 10 : extent);
    67  		setOrientation(orientation);
    68  		this.model = new DefaultBoundedRangeModel(value, extent, min, max);
    69  		addListenerToModel();
    70  		this.setFocusable(false);
    71  		updateUI();
    72  	}
    73  
    74  	public function setUI(ui:ScrollBarUI):Void{
    75  		super.setUI(ui);
    76  	}
    77  	
    78  	public function getUI():ScrollBarUI{
    79  		return ScrollBarUI(ui);
    80  	}
    81  	
    82  	public function updateUI():Void{
    83  		setUI(ScrollBarUI(UIManager.getUI(this)));
    84  	}
    85  	
    86  	public function getUIClassID():String{
    87  		return "ScrollBarUI";
    88  	}
    89  	
    90  	/**
    91  	 * @return the orientation.
    92  	 */
    93  	public function getOrientation():Number{
    94  		return orientation;
    95  	}
    96  	
    97  	
    98  	private function setOrientation(orientation:Number):Void{
    99  		var oldValue:Number = this.orientation;
   100  		this.orientation = orientation;
   101  		if (orientation != oldValue){
   102  			revalidate();
   103  		}
   104  	}
   105  	
   106  	/**
   107  	 * Returns data model that handles the scrollbar's four fundamental properties: minimum, maximum, value, extent.
   108  	 * @return the data model
   109  	 */
   110  	public function getModel():BoundedRangeModel{
   111  		return model;
   112  	}
   113  	
   114  	/**
   115  	 * Sets the model that handles the scrollbar's four fundamental properties: minimum, maximum, value, extent. 
   116  	 * @param the data model
   117  	 */
   118  	public function setModel(newModel:BoundedRangeModel):Void{
   119  		var oldModel:BoundedRangeModel = model;
   120  		if (model != null){
   121  			model.removeEventListener(modelListener);
   122  		}
   123  		model = newModel;
   124  		if (model != null){
   125  			addListenerToModel();
   126  		}
   127  	}
   128  	
   129  	private function addListenerToModel():Void{
   130  		modelListener = model.addChangeListener(__onModelStateChanged, this);		
   131  	}
   132  	
   133  	private function __onModelStateChanged(event:Event):Void{
   134  		fireAdjustmentValueChanged();
   135  	}
   136  	
   137  	/**
   138  	 * Sets the unit increment
   139  	 * @param unitIncrement the unit increment
   140  	 * @see #getUnitIncrement()
   141  	 */
   142  	public function setUnitIncrement(unitIncrement:Number):Void{
   143  		this.unitIncrement = unitIncrement;
   144  	}
   145  	
   146  	/**
   147  	 * Returns the amount to change the scrollbar's value by, given a unit up/down request. 
   148  	 * A ScrollBarUI implementation typically calls this method when the user clicks on a 
   149  	 * scrollbar up/down arrow and uses the result to update the scrollbar's value. 
   150  	 * Subclasses my override this method to compute a value, e.g. the change required 
   151  	 * to scroll up or down one (variable height) line text or one row in a table.
   152  	 * <p>
   153  	 * The JScrollPane component creates scrollbars (by default) that then
   154  	 * set the unit increment by the viewport, if it has one. The {@link Viewportable} interface 
   155  	 * provides a method to return the unit increment.
   156  	 * 
   157  	 * @return the unit increment
   158  	 * @see JScrollPane
   159  	 * @see Viewportable
   160  	 */
   161  	public function getUnitIncrement():Number{
   162  		return unitIncrement;
   163  	}
   164  	
   165  	/**
   166  	 * Sets the block increment.
   167  	 * @param blockIncrement the block increment.
   168  	 * @see #getBlockIncrement()
   169  	 */
   170  	public function setBlockIncrement(blockIncrement:Number):Void{
   171  		this.blockIncrement = blockIncrement;
   172  	}
   173  	
   174  	/**
   175  	 * Returns the amount to change the scrollbar's value by, given a block (usually "page") 
   176  	 * up/down request. A ScrollBarUI implementation typically calls this method when the 
   177  	 * user clicks above or below the scrollbar "knob" to change the value up or down by 
   178  	 * large amount. Subclasses my override this method to compute a value, e.g. the change 
   179  	 * required to scroll up or down one paragraph in a text document. 
   180  	 * <p>
   181  	 * The JScrollPane component creates scrollbars (by default) that then
   182  	 * set the block increment by the viewport, if it has one. The {@link Viewportable} interface 
   183  	 * provides a method to return the block increment.
   184  	 * 
   185  	 * @return the block increment
   186  	 * @see JScrollPane
   187  	 * @see Viewportable
   188  	 */
   189  	public function getBlockIncrement():Number{
   190  		return blockIncrement;
   191  	}
   192  	
   193  	/**
   194  	 * Returns the scrollbar's value.
   195  	 * @return the scrollbar's value property.
   196  	 * @see #setValue()
   197  	 * @see BoundedRangeModel#getValue()
   198  	 */
   199  	public function getValue():Number{
   200  		return getModel().getValue();
   201  	}
   202  	
   203  	/**
   204  	 * Sets the scrollbar's value. This method just forwards the value to the model.
   205  	 * @param value the value to set.
   206  	 * @see #getValue()
   207  	 * @see BoundedRangeModel#setValue()
   208  	 */
   209  	public function setValue(value:Number):Void{
   210  		var m:BoundedRangeModel = getModel();
   211  		m.setValue(value);
   212  	}
   213  	
   214  	/**
   215  	 * Returns the scrollbar's extent. In many scrollbar look and feel 
   216  	 * implementations the size of the scrollbar "knob" or "thumb" is proportional to the extent. 
   217  	 * @return the scrollbar's extent.
   218  	 * @see #setVisibleAmount()
   219  	 * @see BoundedRangeModel#getExtent()
   220  	 */
   221  	public function getVisibleAmount():Number{
   222  		return getModel().getExtent();
   223  	}
   224  	
   225  	/**
   226  	 * Set the model's extent property.
   227  	 * @param extent the extent to set
   228  	 * @see #getVisibleAmount()
   229  	 * @see BoundedRangeModel#setExtent()
   230  	 */
   231  	public function setVisibleAmount(extent:Number):Void{
   232  		getModel().setExtent(extent);
   233  	}
   234  	
   235  	/**
   236  	 * Returns the minimum value supported by the scrollbar (usually zero). 
   237  	 * @return the minimum value supported by the scrollbar
   238  	 * @see #setMinimum()
   239  	 * @see BoundedRangeModel#getMinimum()
   240  	 */
   241  	public function getMinimum():Number{
   242  		return getModel().getMinimum();
   243  	}
   244  	
   245  	/**
   246  	 * Sets the model's minimum property. 
   247  	 * @param minimum the minimum to set.
   248  	 * @see #getMinimum()
   249  	 * @see BoundedRangeModel#setMinimum()
   250  	 */
   251  	public function setMinimum(minimum:Number):Void{
   252  		getModel().setMinimum(minimum);
   253  	}
   254  	
   255  	/**
   256  	 * Returns the maximum value supported by the scrollbar.
   257  	 * @return the maximum value supported by the scrollbar
   258  	 * @see #setMaximum()
   259  	 * @see BoundedRangeModel#getMaximum()
   260  	 */
   261  	public function getMaximum():Number{
   262  		return getModel().getMaximum();
   263  	}
   264  	
   265  	/**
   266  	 * Sets the model's maximum property.
   267  	 * @param maximum the maximum to set.
   268  	 * @see #getMaximum()
   269  	 * @see BoundedRangeModel#setMaximum()
   270  	 */	
   271  	public function setMaximum(maximum:Number):Void{
   272  		getModel().setMaximum(maximum);
   273  	}
   274  	
   275  	/**
   276  	 * True if the scrollbar knob is being dragged. 
   277  	 * @return the value of the model's valueIsAdjusting property
   278  	 */
   279  	public function getValueIsAdjusting():Boolean{
   280  		return getModel().getValueIsAdjusting();
   281  	}
   282  	
   283  	/**
   284  	 * Sets the model's valueIsAdjusting property. Scrollbar look and feel 
   285  	 * implementations should set this property to true when a knob drag begins, 
   286  	 * and to false when the drag ends. The scrollbar model will not generate 
   287  	 * ChangeEvents while valueIsAdjusting is true. 
   288  	 * @see BoundedRangeModel#setValueIsAdjusting()
   289  	 */
   290  	public function setValueIsAdjusting(b:Boolean):Void{
   291  		var m:BoundedRangeModel = getModel();
   292  		m.setValueIsAdjusting(b);
   293  	}
   294  	
   295  	/**
   296  	 * Sets the four BoundedRangeModel properties after forcing the arguments to 
   297  	 * obey the usual constraints: "minimum le value le value+extent le maximum" 
   298  	 * ("le" means less or equals)
   299  	 */
   300  	public function setValues(newValue:Number, newExtent:Number, newMin:Number, newMax:Number):Void{
   301  		var m:BoundedRangeModel = getModel();
   302  		m.setRangeProperties(newValue, newExtent, newMin, newMax, m.getValueIsAdjusting());
   303  	}
   304  	
   305  	/**
   306  	 * Shortcut to and ON_ADJUSTMENT_VALUE_CHANGED listener.
   307  	 * <p>
   308  	 * addAdjustmentListener(func:Function)<br>
   309  	 * addAdjustmentListener(func:Function, obj:Object)<br>
   310  	 * @param func the function which want to handler the event.
   311  	 * @param obj context in which to run the function of param func.
   312  	 * @see #ON_ADJUSTMENT_VALUE_CHANGED
   313  	 */	
   314  	public function addAdjustmentListener(func:Function, obj:Object):Object{
   315  		return addEventListener(ON_ADJUSTMENT_VALUE_CHANGED, func, obj);
   316  	}
   317  	
   318  	private function fireAdjustmentValueChanged():Void{
   319  		dispatchEvent(ON_ADJUSTMENT_VALUE_CHANGED, createEventObj(ON_ADJUSTMENT_VALUE_CHANGED));
   320  	}
   321  	
   322  	public function setEnabled(b:Boolean):Void{
   323  		if(b != isEnabled()){
   324  			repaint();
   325  		}
   326  		super.setEnabled(b);
   327  		for (var i:Number = 0; i < children.length; i++){
   328  			children[i].setEnabled(b);
   329  		}
   330  	}	
   331  }
   332