home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / jfc.bin / JProgressBar.java < prev    next >
Text File  |  1998-02-26  |  17KB  |  543 lines

  1. /*
  2.  * @(#)JProgressBar.java    1.48 98/02/05
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20.  
  21. package com.sun.java.swing;
  22.  
  23. import java.awt.Color;
  24. import java.awt.Graphics;
  25. import com.sun.java.swing.event.*;
  26. import com.sun.java.accessibility.*;
  27. import java.io.Serializable;
  28. import com.sun.java.swing.plaf.ProgressBarUI;
  29.  
  30.  
  31. /**
  32.  * A component that displays an integer value graphically within a bounded 
  33.  * interval. A progress bar typically communicates the progress of an 
  34.  * event by displaying its percentage of completion. The orientation of 
  35.  * the progress bar depends on its size. If its height is greater than
  36.  * its width, the progress bar is vertical.
  37.  * <p>
  38.  * Warning: serialized objects of this class will not be compatible with
  39.  * future swing releases.  The current serialization support is appropriate
  40.  * for short term storage or RMI between Swing1.0 applications.  It will
  41.  * not be possible to load serialized Swing1.0 objects with future releases
  42.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  43.  * baseline for the serialized form of Swing objects.
  44.  *
  45.  * @version 1.48 02/05/98
  46.  * @author Rob Davis
  47.  */
  48. public class JProgressBar extends JComponent implements SwingConstants, Accessible
  49. {
  50.     protected int orientation;
  51.     protected boolean paintBorder;
  52.     protected BoundedRangeModel barModel;
  53.  
  54.  
  55.     /**
  56.      * Only one ChangeEvent is needed per instance since the
  57.      * event's only interesting property is the immutable source, which
  58.      * is the progress bar.
  59.      */
  60.     protected transient ChangeEvent changeEvent = null;
  61.     protected ChangeListener changeListener = null;
  62.  
  63.     /**
  64.      * Creates a horizontal progress bar with a border.
  65.      */
  66.     public JProgressBar()
  67.     {
  68.         setModel(new DefaultBoundedRangeModel());
  69.         updateUI();
  70.  
  71.         orientation = HORIZONTAL;  // documented with set/getOrientation()
  72.         paintBorder = true;        // documented with is/setBorderPainted()
  73.     }
  74.  
  75.     /**
  76.      * Overridden to call paint without filling the background.
  77.      */
  78.     public void update(Graphics g) {
  79.         this.paint(g);
  80.     }
  81.  
  82.     /**
  83.      * Returns <code>JProgressBar.VERTICAL</code> or 
  84.      * <code>JProgressBar.HORIZONTAL</code>, depending on the orientation
  85.      * of the progress bar. The default orientation is 
  86.      * <code>HORIZONTAL</code>.
  87.      *
  88.      * @return HORIZONTAL or VERTICAL
  89.      */
  90.     public int getOrientation() {
  91.         return orientation;
  92.     }
  93.  
  94.     /**
  95.      * Sets the progress bar's orientation to <I>newOrientation</I>, which
  96.      * must be <code>JProgressBar.VERTICAL</code> or 
  97.      * <code>JProgressBar.HORIZONTAL</code>. The default orientation 
  98.      * is <code>HORIZONTAL</code>.
  99.      *
  100.      * @param  newOrientation  HORIZONTAL or VERTICAL
  101.      * @exception      IllegalArgumentException    if <I>newOrientation</I>
  102.      *                                              is an illegal value
  103.      * @beaninfo
  104.      *    preferred: true
  105.      *  description: The progress bar's orientation.
  106.      */
  107.     public void setOrientation(int newOrientation) {
  108.         if (orientation != newOrientation) {
  109.             switch (newOrientation) {
  110.             case VERTICAL:
  111.             case HORIZONTAL:
  112.                 int oldorientation = orientation;
  113.                 orientation = newOrientation;
  114.                 if (accessibleContext != null) {
  115.                     accessibleContext.firePropertyChange(
  116.                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  117.                             ((oldorientation == VERTICAL) 
  118.                  ? AccessibleState.VERTICAL 
  119.                  : AccessibleState.HORIZONTAL),
  120.                             ((orientation == VERTICAL) 
  121.                  ? AccessibleState.VERTICAL 
  122.                  : AccessibleState.HORIZONTAL));
  123.             }
  124.                 break;
  125.             default:
  126.                 throw new IllegalArgumentException(newOrientation +
  127.                                              " is not a legal orientation");
  128.             }
  129.             repaint();
  130.         }
  131.     }
  132.  
  133.     /**
  134.      * Returns true if the progress bar has a border or false if it does not.
  135.      *
  136.      * @return whether the progress bar has a border
  137.      * @see    setBorderPainted
  138.      */
  139.     public boolean isBorderPainted() {
  140.         return paintBorder;
  141.     }
  142.  
  143.     /**
  144.      * Sets whether the progress bar should have a border.
  145.      *
  146.      * @param   b       true if the progress bar should have a border
  147.      * @see     isBorderPainted
  148.      * @beaninfo
  149.      *  description: Whether the progress bar should have a border.
  150.      */
  151.     public void setBorderPainted(boolean b) {
  152.         paintBorder = b;
  153.         repaint();
  154.     }
  155.  
  156.     /**
  157.      * Paint the progress bar's border if BorderPainted property is true.
  158.      * 
  159.      * @param g  the Graphics context within which to paint the border
  160.      * @see #paint
  161.      * @see #setBorder
  162.      */
  163.     protected void paintBorder(Graphics g) {    
  164.         if (isBorderPainted()) {
  165.             super.paintBorder(g);
  166.         }
  167.     }
  168.  
  169.  
  170.     /**
  171.      * Returns the L&F object that renders this component.
  172.      *
  173.      * @return the ProgressBarUI object that renders this component
  174.      */
  175.     public ProgressBarUI getUI() {
  176.         return (ProgressBarUI)ui;
  177.     }
  178.  
  179.     /**
  180.      * Sets the L&F object that renders this component.
  181.      *
  182.      * @param ui  the ProgressBarUI L&F object
  183.      * @see UIDefaults#getUI
  184.      * @beaninfo
  185.      *       expert: true
  186.      *  description: The ProgressBarUI implementation that defines the combo box look and feel.
  187.      */
  188.     public void setUI(ProgressBarUI ui) {
  189.         if (this.ui != ui) {
  190.             super.setUI(ui);
  191.             repaint();
  192.         }
  193.     }
  194.  
  195.  
  196.     /**
  197.      * Notification from the UIFactory that the L&F has changed. 
  198.      * Called to replace the UI with the latest version from the 
  199.      * UIFactory.
  200.      *
  201.      * @see JComponent#updateUI
  202.      */
  203.     public void updateUI() {
  204.         setUI((ProgressBarUI)UIManager.getUI(this));
  205.     }
  206.  
  207.  
  208.     /**
  209.      * Returns the name of the L&F class that renders this component.
  210.      *
  211.      * @return "ProgressBarUI"
  212.      * @see JComponent#getUIClassID
  213.      * @see UIDefaults#getUI
  214.      * @beaninfo
  215.      *        expert: true
  216.      *   description: A string that specifies the name of the L&F class.
  217.      */
  218.     public String getUIClassID() {
  219.         return "ProgressBarUI";
  220.     }
  221.  
  222.  
  223.     /* We pass each Change event to the listeners with the
  224.      * the progress bar as the event source.
  225.      * <p>
  226.      * Warning: serialized objects of this class will not be compatible with
  227.      * future swing releases.  The current serialization support is appropriate
  228.      * for short term storage or RMI between Swing1.0 applications.  It will
  229.      * not be possible to load serialized Swing1.0 objects with future releases
  230.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  231.      * baseline for the serialized form of Swing objects.
  232.      */
  233.     protected class ModelListener implements ChangeListener, Serializable {
  234.         public void stateChanged(ChangeEvent e) {
  235.             fireStateChanged();
  236.         }
  237.     }
  238.  
  239.     /* Subclasses that want to handle ChangeEvents differently
  240.      * can override this to return a subclass of ModelListener or
  241.      * another ChangeListener implementation.
  242.      */
  243.     protected ChangeListener createChangeListener() {
  244.         return new ModelListener();
  245.     }
  246.  
  247.     /**
  248.      * Adds a ChangeListener to the button.
  249.      *
  250.      * @param l the ChangeListener to add
  251.      */
  252.     public void addChangeListener(ChangeListener l) {
  253.         listenerList.add(ChangeListener.class, l);
  254.     }
  255.     
  256.     /**
  257.      * Removes a ChangeListener from the button.
  258.      *
  259.      * @param l the ChangeListener to remove
  260.      */
  261.     public void removeChangeListener(ChangeListener l) {
  262.         listenerList.remove(ChangeListener.class, l);
  263.     }
  264.         
  265.     /**
  266.      * Notify all listeners that have registered interest for
  267.      * notification on this event type.  The event instance 
  268.      * is lazily created using the parameters passed into 
  269.      * the fire method.
  270.      * @see EventListenerList
  271.      */
  272.     protected void fireStateChanged() {
  273.         // Guaranteed to return a non-null array
  274.         Object[] listeners = listenerList.getListenerList();
  275.         // Process the listeners last to first, notifying
  276.         // those that are interested in this event
  277.         for (int i = listeners.length-2; i>=0; i-=2) {
  278.             if (listeners[i]==ChangeListener.class) {
  279.                 // Lazily create the event:
  280.                 if (changeEvent == null)
  281.                     changeEvent = new ChangeEvent(this);
  282.                 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
  283.             }          
  284.         }
  285.     } 
  286.       
  287.     /**
  288.      * Returns the data model used by the JProgressBar.
  289.      *
  290.      * @return the BoundedRangeModel currently in use
  291.      * @see    BoundedRangeModel
  292.      */
  293.     public BoundedRangeModel getModel() {
  294.         return barModel;
  295.     }
  296.  
  297.     /**
  298.      * Sets the data model used by the JProgressBar.
  299.      *
  300.      * @param  newModel the BoundedRangeModel to use
  301.      * @see    BoundedRangeModel
  302.      * @beaninfo
  303.      *    expert: true
  304.      * description: The data model used by the JProgressBar.
  305.      */
  306.     public void setModel(BoundedRangeModel newModel) {
  307.         // PENDING(???) setting the same model to multiple bars is broken; listeners
  308.         BoundedRangeModel oldModel = getModel();
  309.  
  310.         if (newModel != oldModel) {
  311.             if (oldModel != null) {
  312.                 oldModel.removeChangeListener(changeListener);
  313.                 changeListener = null;
  314.             }
  315.  
  316.             barModel = newModel;
  317.  
  318.             if (newModel != null) {
  319.                 changeListener = createChangeListener();
  320.                 newModel.addChangeListener(changeListener);
  321.             }
  322.  
  323.         if (accessibleContext != null) {
  324.                 accessibleContext.firePropertyChange(
  325.                 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
  326.                         (oldModel== null 
  327.              ? null : new Integer(oldModel.getValue())),
  328.                         (newModel== null 
  329.              ? null : new Integer(newModel.getValue())));
  330.         }
  331.  
  332.             barModel.setExtent(0);
  333.             repaint();
  334.         }
  335.     }
  336.  
  337.  
  338.     /* All of the model methods are implemented by delegation. */
  339.  
  340.     /**
  341.      * Returns the model's current value. The value is always between the 
  342.      * model's minimum and maximum values, inclusive.
  343.      *
  344.      * @return  the value
  345.      * @see     #setValue
  346.      * @see     BoundedRangeModel
  347.      */
  348.     public int getValue() { return getModel().getValue(); }
  349.  
  350.     /**
  351.      * Returns the model's minimum value.
  352.      *
  353.      * @return  an int -- the model's minimum
  354.      * @see     #setMinimum
  355.      * @see     BoundedRangeModel
  356.      */
  357.     public int getMinimum() { return getModel().getMinimum(); }
  358.  
  359.     /**
  360.      * Returns the model's maximum value.
  361.      *
  362.      * @return  an int -- the model's maximum
  363.      * @see     #setMaximum
  364.      * @see     BoundedRangeModel
  365.      */
  366.     public int getMaximum() { return getModel().getMaximum(); }
  367.  
  368.     /**
  369.      * Sets the model's current value to <I>x</I>. If <I>x</I> is less than the
  370.      * minimum or greater than the maximum, this method throws an
  371.      * <code>IllegalArgumentException</code> and the value is not changed.
  372.      * <p>
  373.      * Notifies any listeners if the data changes.
  374.      *
  375.      * @param   x       the new value
  376.      * @see     #getValue
  377.      * @see     BoundedRangeModel
  378.      * @beaninfo
  379.      *    preferred: true
  380.      *  description: The model's current value.
  381.      */
  382.     public void setValue(int n) { 
  383.         BoundedRangeModel brm = getModel();
  384.     int oldValue = brm.getValue();
  385.  
  386.     brm.setValue(n);
  387.  
  388.     if (accessibleContext != null) {
  389.             accessibleContext.firePropertyChange(
  390.             AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
  391.                     new Integer(oldValue),
  392.                     new Integer(brm.getValue()));
  393.     }
  394.     }
  395.  
  396.     /**
  397.      * Sets the model's minimum to <I>x</I>. If the maximum value or
  398.      * current value is outside of the new minimum, the maximum or 
  399.      * current value is adjusted accordingly.
  400.      * <p>
  401.      * Notifies any listeners if the data changes.
  402.      *
  403.      * @param  x       the new minimum
  404.      * @see    #getMinimum
  405.      * @see    #addChangeListener
  406.      * @see    BoundedRangeModel
  407.      * @beaninfo
  408.      *  preferred: true
  409.      * description: The model's minimum value.
  410.      */
  411.     public void setMinimum(int n) { getModel().setMinimum(n); }
  412.  
  413.     /**
  414.      * Sets the model's maximum to <I>x</I>. If the minimum value or
  415.      * current value is outside of the new maximum, the minimum or 
  416.      * current value is adjusted accordingly.
  417.      * <p>
  418.      * Notifies any listeners if the data changes.
  419.      *
  420.      * @param  x       the new maximum
  421.      * @see    #getMaximum
  422.      * @see    #addChangeListener
  423.      * @see    BoundedRangeModel
  424.      * @beaninfo
  425.      *    preferred: true
  426.      *  description: The model's maximum value.
  427.      */
  428.     public void setMaximum(int n) { getModel().setMaximum(n); }
  429.  
  430. /////////////////
  431. // Accessibility support
  432. ////////////////
  433.  
  434.     /**
  435.      * Get the AccessibleContext associated with this JComponent
  436.      *
  437.      * @return the AccessibleContext of this JComponent
  438.      * @beaninfo
  439.      *       expert: true
  440.      *  description: The AccessibleContext associated with this ProgressBar.
  441.      */
  442.     public AccessibleContext getAccessibleContext() {
  443.         if (accessibleContext == null) {
  444.             accessibleContext = new AccessibleJProgressBar();
  445.         }
  446.         return accessibleContext;
  447.     }
  448.  
  449.     /**
  450.      * The class used to obtain the accessible role for this object.
  451.      * <p>
  452.      * Warning: serialized objects of this class will not be compatible with
  453.      * future swing releases.  The current serialization support is appropriate
  454.      * for short term storage or RMI between Swing1.0 applications.  It will
  455.      * not be possible to load serialized Swing1.0 objects with future releases
  456.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  457.      * baseline for the serialized form of Swing objects.
  458.      */
  459.     protected class AccessibleJProgressBar extends AccessibleJComponent
  460.         implements AccessibleValue {
  461.  
  462.         /**
  463.          * Get the state set of this object.
  464.          *
  465.          * @return an instance of AccessibleState containing the current state 
  466.          * of the object
  467.          * @see AccessibleState
  468.          */
  469.         public AccessibleStateSet getAccessibleStateSet() {
  470.             AccessibleStateSet states = super.getAccessibleStateSet();
  471.             if (getModel().getValueIsAdjusting()) {
  472.                 states.add(AccessibleState.BUSY);
  473.             }
  474.             if (getOrientation() == VERTICAL) {
  475.                 states.add(AccessibleState.VERTICAL);
  476.             } else {
  477.                 states.add(AccessibleState.HORIZONTAL);
  478.             }
  479.             return states;
  480.         }
  481.  
  482.         /**
  483.          * Get the role of this object.
  484.          *
  485.          * @return an instance of AccessibleRole describing the role of the 
  486.          * object
  487.          */
  488.         public AccessibleRole getAccessibleRole() {
  489.             return AccessibleRole.PROGRESS_BAR;
  490.         }
  491.  
  492.         /**
  493.          * Get the AccessibleValue associated with this object if one
  494.          * exists.  Otherwise return null.
  495.          */
  496.         public AccessibleValue getAccessibleValue() {
  497.             return this;
  498.         }
  499.  
  500.         /**
  501.          * Get the accessible value of this object.
  502.          *
  503.          * @return The current value of this object.
  504.          */
  505.         public Number getCurrentAccessibleValue() {
  506.             return new Integer(getValue());
  507.         }
  508.  
  509.         /**
  510.          * Set the value of this object as a Number.
  511.          *
  512.          * @return True if the value was set.
  513.          */
  514.         public boolean setCurrentAccessibleValue(Number n) {
  515.             if (n instanceof Integer) {
  516.                 setValue(n.intValue());
  517.                 return true;
  518.             } else {
  519.                 return false;
  520.             }
  521.         }
  522.  
  523.         /**
  524.          * Get the minimum accessible value of this object.
  525.          *
  526.          * @return The minimum value of this object.
  527.          */
  528.         public Number getMinimumAccessibleValue() {
  529.             return new Integer(getMinimum());
  530.         }
  531.  
  532.         /**
  533.          * Get the maximum accessible value of this object.
  534.          *
  535.          * @return The maximum value of this object.
  536.          */
  537.         public Number getMaximumAccessibleValue() {
  538.             return new Integer(getMaximum());
  539.         }
  540.  
  541.     } // AccessibleJProgressBar
  542. }
  543.