1. /*
  2. * @(#)JProgressBar.java 1.93 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import java.awt.Color;
  9. import java.awt.Graphics;
  10. import java.text.Format;
  11. import java.text.NumberFormat;
  12. import java.io.Serializable;
  13. import java.io.ObjectOutputStream;
  14. import java.io.ObjectInputStream;
  15. import java.io.IOException;
  16. import javax.swing.event.*;
  17. import javax.accessibility.*;
  18. import javax.swing.plaf.ProgressBarUI;
  19. /**
  20. * A component that, by default, displays an integer value within a bounded
  21. * interval. A progress bar typically communicates the progress of some
  22. * work by displaying its percentage of completion and possibly a textual
  23. * display of this percentage.
  24. *
  25. * <p>
  26. *
  27. * To indicate that a task of unknown length is executing,
  28. * you can put a progress bar into indeterminate mode.
  29. * While the bar is in indeterminate mode,
  30. * it animates constantly to show that work is occurring.
  31. * As soon as you can determine the task's length and amount of progress,
  32. * you should update the progress bar's value
  33. * and switch it back to determinate mode.
  34. *
  35. * <p>
  36. *
  37. * Here is an example of creating a progress bar,
  38. * where <code>task</code> is an object
  39. * that returns information about the progress of some work:
  40. *
  41. *<pre>
  42. *progressBar = new JProgressBar(0, task.getLengthOfTask());
  43. *progressBar.setValue(0);
  44. *progressBar.setStringPainted(true);
  45. *</pre>
  46. *
  47. * Here is an example of updating the value of the progress bar:
  48. *
  49. *<pre>
  50. *progressBar.setValue(task.getCurrent());
  51. *</pre>
  52. *
  53. * Here is an example of putting a progress bar into
  54. * indeterminate mode,
  55. * and then switching back to determinate mode
  56. * once the length of the task is known:
  57. *
  58. *<pre>
  59. *progressBar = new JProgressBar();
  60. *<em>...//when the task of (initially) unknown length begins:</em>
  61. *progressBar.setIndeterminate(true);
  62. *<em>...//do some work; get length of task...</em>
  63. *progressBar.setMaximum(newLength);
  64. *progressBar.setValue(newValue);
  65. *progressBar.setIndeterminate(false);
  66. *</pre>
  67. *
  68. * <p>
  69. *
  70. * For complete examples and further documentation see
  71. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>,
  72. * a section in <em>The Java Tutorial.</em>
  73. *
  74. * <p>
  75. * <strong>Warning:</strong>
  76. * Serialized objects of this class will not be compatible with
  77. * future Swing releases. The current serialization support is
  78. * appropriate for short term storage or RMI between applications running
  79. * the same version of Swing. As of 1.4, support for long term storage
  80. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  81. * has been added to the <code>java.beans</code> package.
  82. * Please see {@link java.beans.XMLEncoder}.
  83. *
  84. * @see javax.swing.plaf.basic.BasicProgressBarUI
  85. *
  86. * @beaninfo
  87. * attribute: isContainer false
  88. * description: A component that displays an integer value.
  89. *
  90. * @version 1.93 12/19/03
  91. * @author Michael C. Albers
  92. * @author Kathy Walrath
  93. */
  94. public class JProgressBar extends JComponent implements SwingConstants, Accessible
  95. {
  96. /**
  97. * @see #getUIClassID
  98. */
  99. private static final String uiClassID = "ProgressBarUI";
  100. /**
  101. * Whether the progress bar is horizontal or vertical.
  102. * The default is <code>HORIZONTAL</code>.
  103. *
  104. * @see #setOrientation
  105. */
  106. protected int orientation;
  107. /**
  108. * Whether to display a border around the progress bar.
  109. * The default is <code>true</code>.
  110. *
  111. * @see #setBorderPainted
  112. */
  113. protected boolean paintBorder;
  114. /**
  115. * The object that holds the data for the progress bar.
  116. *
  117. * @see #setModel
  118. */
  119. protected BoundedRangeModel model;
  120. /**
  121. * An optional string that can be displayed on the progress bar.
  122. * The default is <code>null</code>. Setting this to a non-<code>null</code>
  123. * value does not imply that the string will be displayed.
  124. *
  125. * @see #setString
  126. */
  127. protected String progressString;
  128. /**
  129. * Whether to textually display a string on the progress bar.
  130. * The default is <code>false</code>.
  131. * Setting this to <code>true</code> causes a textual
  132. * display of the progress to be rendered on the progress bar. If
  133. * the <code>progressString</code> is <code>null</code>,
  134. * the percentage of completion is displayed on the progress bar.
  135. * Otherwise, the <code>progressString</code> is
  136. * rendered on the progress bar.
  137. *
  138. * @see #setStringPainted
  139. */
  140. protected boolean paintString;
  141. /**
  142. * The default minimum for a progress bar is 0.
  143. */
  144. static final private int defaultMinimum = 0;
  145. /**
  146. * The default maximum for a progress bar is 100.
  147. */
  148. static final private int defaultMaximum = 100;
  149. /**
  150. * The default orientation for a progress bar is <code>HORIZONTAL</code>.
  151. */
  152. static final private int defaultOrientation = HORIZONTAL;
  153. /**
  154. * Only one <code>ChangeEvent</code> is needed per instance since the
  155. * event's only interesting property is the immutable source, which
  156. * is the progress bar.
  157. */
  158. protected transient ChangeEvent changeEvent = null;
  159. /**
  160. * Listens for change events sent by the progress bar's model,
  161. * redispatching them
  162. * to change-event listeners registered upon
  163. * this progress bar.
  164. *
  165. * @see #createChangeListener
  166. */
  167. protected ChangeListener changeListener = null;
  168. /**
  169. * Format used when displaying percent complete.
  170. */
  171. private transient Format format;
  172. /**
  173. * Whether the progress bar is indeterminate (<code>true</code>) or
  174. * normal (<code>false</code>); the default is <code>false</code>.
  175. *
  176. * @see #setIndeterminate
  177. * @since 1.4
  178. */
  179. private boolean indeterminate;
  180. /**
  181. * Creates a horizontal progress bar
  182. * that displays a border but no progress string.
  183. * The initial and minimum values are 0,
  184. * and the maximum is 100.
  185. *
  186. * @see #setOrientation
  187. * @see #setBorderPainted
  188. * @see #setStringPainted
  189. * @see #setString
  190. * @see #setIndeterminate
  191. */
  192. public JProgressBar()
  193. {
  194. this(defaultOrientation);
  195. }
  196. /**
  197. * Creates a progress bar with the specified orientation,
  198. * which can be
  199. * either <code>JProgressBar.VERTICAL</code> or
  200. * <code>JProgressBar.HORIZONTAL</code>.
  201. * By default, a border is painted but a progress string is not.
  202. * The initial and minimum values are 0,
  203. * and the maximum is 100.
  204. *
  205. * @param orient the desired orientation of the progress bar
  206. *
  207. * @see #setOrientation
  208. * @see #setBorderPainted
  209. * @see #setStringPainted
  210. * @see #setString
  211. * @see #setIndeterminate
  212. */
  213. public JProgressBar(int orient)
  214. {
  215. this(orient, defaultMinimum, defaultMaximum);
  216. }
  217. /**
  218. * Creates a horizontal progress bar
  219. * with the specified minimum and maximum.
  220. * Sets the initial value of the progress bar to the specified minimum.
  221. * By default, a border is painted but a progress string is not.
  222. * The <code>BoundedRangeModel</code> that holds the progress bar's data
  223. * handles any issues that may arise from improperly setting the
  224. * minimum, initial, and maximum values on the progress bar.
  225. *
  226. * @param min the minimum value of the progress bar
  227. * @param max the maximum value of the progress bar
  228. *
  229. * @see BoundedRangeModel
  230. * @see #setOrientation
  231. * @see #setBorderPainted
  232. * @see #setStringPainted
  233. * @see #setString
  234. * @see #setIndeterminate
  235. */
  236. public JProgressBar(int min, int max)
  237. {
  238. this(defaultOrientation, min, max);
  239. }
  240. /**
  241. * Creates a progress bar using the specified orientation,
  242. * minimum, and maximum.
  243. * By default, a border is painted but a progress string is not.
  244. * Sets the initial value of the progress bar to the specified minimum.
  245. * The <code>BoundedRangeModel</code> that holds the progress bar's data
  246. * handles any issues that may arise from improperly setting the
  247. * minimum, initial, and maximum values on the progress bar.
  248. *
  249. * @param orient the desired orientation of the progress bar
  250. * @param min the minimum value of the progress bar
  251. * @param max the maximum value of the progress bar
  252. *
  253. * @see BoundedRangeModel
  254. * @see #setOrientation
  255. * @see #setBorderPainted
  256. * @see #setStringPainted
  257. * @see #setString
  258. * @see #setIndeterminate
  259. */
  260. public JProgressBar(int orient, int min, int max)
  261. {
  262. // Creating the model this way is a bit simplistic, but
  263. // I believe that it is the the most common usage of this
  264. // component - it's what people will expect.
  265. setModel(new DefaultBoundedRangeModel(min, 0, min, max));
  266. updateUI();
  267. setOrientation(orient); // documented with set/getOrientation()
  268. setBorderPainted(true); // documented with is/setBorderPainted()
  269. setStringPainted(false); // see setStringPainted
  270. setString(null); // see getString
  271. setIndeterminate(false); // see setIndeterminate
  272. }
  273. /**
  274. * Creates a horizontal progress bar
  275. * that uses the specified model
  276. * to hold the progress bar's data.
  277. * By default, a border is painted but a progress string is not.
  278. *
  279. * @param newModel the data model for the progress bar
  280. *
  281. * @see #setOrientation
  282. * @see #setBorderPainted
  283. * @see #setStringPainted
  284. * @see #setString
  285. * @see #setIndeterminate
  286. */
  287. public JProgressBar(BoundedRangeModel newModel)
  288. {
  289. setModel(newModel);
  290. updateUI();
  291. setOrientation(defaultOrientation); // see setOrientation()
  292. setBorderPainted(true); // see setBorderPainted()
  293. setStringPainted(false); // see setStringPainted
  294. setString(null); // see getString
  295. setIndeterminate(false); // see setIndeterminate
  296. }
  297. /**
  298. * Returns <code>JProgressBar.VERTICAL</code> or
  299. * <code>JProgressBar.HORIZONTAL</code>, depending on the orientation
  300. * of the progress bar. The default orientation is
  301. * <code>HORIZONTAL</code>.
  302. *
  303. * @return <code>HORIZONTAL</code> or <code>VERTICAL</code>
  304. * @see #setOrientation
  305. */
  306. public int getOrientation() {
  307. return orientation;
  308. }
  309. /**
  310. * Sets the progress bar's orientation to <code>newOrientation</code>,
  311. * which must be <code>JProgressBar.VERTICAL</code> or
  312. * <code>JProgressBar.HORIZONTAL</code>. The default orientation
  313. * is <code>HORIZONTAL</code>.
  314. *
  315. * @param newOrientation <code>HORIZONTAL</code> or <code>VERTICAL</code>
  316. * @exception IllegalArgumentException if <code>newOrientation</code>
  317. * is an illegal value
  318. * @see #getOrientation
  319. *
  320. * @beaninfo
  321. * preferred: true
  322. * bound: true
  323. * attribute: visualUpdate true
  324. * description: Set the progress bar's orientation.
  325. */
  326. public void setOrientation(int newOrientation) {
  327. if (orientation != newOrientation) {
  328. switch (newOrientation) {
  329. case VERTICAL:
  330. case HORIZONTAL:
  331. int oldOrientation = orientation;
  332. orientation = newOrientation;
  333. firePropertyChange("orientation", oldOrientation, newOrientation);
  334. if (accessibleContext != null) {
  335. accessibleContext.firePropertyChange(
  336. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  337. ((oldOrientation == VERTICAL)
  338. ? AccessibleState.VERTICAL
  339. : AccessibleState.HORIZONTAL),
  340. ((orientation == VERTICAL)
  341. ? AccessibleState.VERTICAL
  342. : AccessibleState.HORIZONTAL));
  343. }
  344. break;
  345. default:
  346. throw new IllegalArgumentException(newOrientation +
  347. " is not a legal orientation");
  348. }
  349. revalidate();
  350. }
  351. }
  352. /**
  353. * Returns the value of the <code>stringPainted</code> property.
  354. *
  355. * @return the value of the <code>stringPainted</code> property
  356. * @see #setStringPainted
  357. * @see #setString
  358. */
  359. public boolean isStringPainted() {
  360. return paintString;
  361. }
  362. /**
  363. * Sets the value of the <code>stringPainted</code> property,
  364. * which determines whether the progress bar
  365. * should render a progress string.
  366. * The default is <code>false</code>:
  367. * no string is painted.
  368. * Some look and feels might not support progress strings
  369. * or might support them only when the progress bar is in determinate mode.
  370. *
  371. * @param b <code>true</code> if the progress bar should render a string
  372. * @see #isStringPainted
  373. * @see #setString
  374. * @beaninfo
  375. * bound: true
  376. * attribute: visualUpdate true
  377. * description: Whether the progress bar should render a string.
  378. */
  379. public void setStringPainted(boolean b) {
  380. //PENDING: specify that string not painted when in indeterminate mode?
  381. // or just leave that to the L&F?
  382. boolean oldValue = paintString;
  383. paintString = b;
  384. firePropertyChange("stringPainted", oldValue, paintString);
  385. if (paintString != oldValue) {
  386. revalidate();
  387. repaint();
  388. }
  389. }
  390. /**
  391. * Returns the current value of the progress string.
  392. * If you are providing a custom progress string
  393. * by overriding this method,
  394. * make sure your implementation calls <code>setString</code> before
  395. * calling <code>super.getString</code>.
  396. *
  397. * @return the value of the percent string
  398. * @see #setString
  399. */
  400. public String getString(){
  401. if (progressString != null) {
  402. return progressString;
  403. } else {
  404. if (format == null) {
  405. format = NumberFormat.getPercentInstance();
  406. }
  407. return format.format(new Double(getPercentComplete()));
  408. }
  409. }
  410. /**
  411. * Sets the value of the progress string. By default,
  412. * this string is <code>null</code>.
  413. * If you have provided a custom progress string and want to revert to
  414. * the built-in behavior, set the string back to <code>null</code>.
  415. * If you are providing a custom progress string
  416. * by overriding this method,
  417. * make sure that you call <code>setString</code> before
  418. * calling <code>getString</code>.
  419. * The progress string is painted only if
  420. * the <code>isStringPainted</code> method returns <code>true</code>.
  421. *
  422. * @param s the value of the percent string
  423. * @see #getString
  424. * @see #setStringPainted
  425. * @see #isStringPainted
  426. * @beaninfo
  427. * bound: true
  428. * attribute: visualUpdate true
  429. * description: Specifies the progress string to paint
  430. */
  431. public void setString(String s){
  432. String oldValue = progressString;
  433. progressString = s;
  434. firePropertyChange("string", oldValue, progressString);
  435. if (progressString == null || oldValue == null || !progressString.equals(oldValue)) {
  436. repaint();
  437. }
  438. }
  439. /**
  440. * Returns the percent complete for the progress bar.
  441. * Note that this number is between 0.0 and 1.0.
  442. *
  443. * @return the percent complete for this progress bar
  444. */
  445. public double getPercentComplete() {
  446. long span = model.getMaximum() - model.getMinimum();
  447. double currentValue = model.getValue();
  448. double pc = (currentValue - model.getMinimum()) / span;
  449. return pc;
  450. }
  451. /**
  452. * Returns the <code>borderPainted</code> property.
  453. *
  454. * @return the value of the <code>borderPainted</code> property
  455. * @see #setBorderPainted
  456. * @beaninfo
  457. * description: Does the progress bar paint its border
  458. */
  459. public boolean isBorderPainted() {
  460. return paintBorder;
  461. }
  462. /**
  463. * Sets the <code>borderPainted</code> property, which is
  464. * <code>true</code> if the progress bar should paint its border.
  465. * The default value for this property is <code>true</code>.
  466. * Some look and feels might not implement painted borders;
  467. * they will ignore this property.
  468. *
  469. * @param b <code>true</code> if the progress bar
  470. * should paint its border;
  471. * otherwise, <code>false</code>
  472. * @see #isBorderPainted
  473. * @beaninfo
  474. * bound: true
  475. * attribute: visualUpdate true
  476. * description: Whether the progress bar should paint its border.
  477. */
  478. public void setBorderPainted(boolean b) {
  479. boolean oldValue = paintBorder;
  480. paintBorder = b;
  481. firePropertyChange("borderPainted", oldValue, paintBorder);
  482. if (paintBorder != oldValue) {
  483. repaint();
  484. }
  485. }
  486. /**
  487. * Paints the progress bar's border if the <code>borderPainted</code>
  488. * property is <code>true</code>.
  489. *
  490. * @param g the <code>Graphics</code> context within which to paint the border
  491. * @see #paint
  492. * @see #setBorder
  493. * @see #isBorderPainted
  494. * @see #setBorderPainted
  495. */
  496. protected void paintBorder(Graphics g) {
  497. if (isBorderPainted()) {
  498. super.paintBorder(g);
  499. }
  500. }
  501. /**
  502. * Returns the look-and-feel object that renders this component.
  503. *
  504. * @return the <code>ProgressBarUI</code> object that renders this component
  505. */
  506. public ProgressBarUI getUI() {
  507. return (ProgressBarUI)ui;
  508. }
  509. /**
  510. * Sets the look-and-feel object that renders this component.
  511. *
  512. * @param ui a <code>ProgressBarUI</code> object
  513. * @see UIDefaults#getUI
  514. * @beaninfo
  515. * bound: true
  516. * hidden: true
  517. * attribute: visualUpdate true
  518. * description: The UI object that implements the Component's LookAndFeel.
  519. */
  520. public void setUI(ProgressBarUI ui) {
  521. super.setUI(ui);
  522. }
  523. /**
  524. * Resets the UI property to a value from the current look and feel.
  525. *
  526. * @see JComponent#updateUI
  527. */
  528. public void updateUI() {
  529. setUI((ProgressBarUI)UIManager.getUI(this));
  530. }
  531. /**
  532. * Returns the name of the look-and-feel class that renders this component.
  533. *
  534. * @return the string "ProgressBarUI"
  535. * @see JComponent#getUIClassID
  536. * @see UIDefaults#getUI
  537. * @beaninfo
  538. * expert: true
  539. * description: A string that specifies the name of the look-and-feel class.
  540. */
  541. public String getUIClassID() {
  542. return uiClassID;
  543. }
  544. /* We pass each Change event to the listeners with the
  545. * the progress bar as the event source.
  546. * <p>
  547. * <strong>Warning:</strong>
  548. * Serialized objects of this class will not be compatible with
  549. * future Swing releases. The current serialization support is
  550. * appropriate for short term storage or RMI between applications running
  551. * the same version of Swing. As of 1.4, support for long term storage
  552. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  553. * has been added to the <code>java.beans</code> package.
  554. * Please see {@link java.beans.XMLEncoder}.
  555. */
  556. private class ModelListener implements ChangeListener, Serializable {
  557. public void stateChanged(ChangeEvent e) {
  558. fireStateChanged();
  559. }
  560. }
  561. /**
  562. * Subclasses that want to handle change events
  563. * from the model differently
  564. * can override this to return
  565. * an instance of a custom <code>ChangeListener</code> implementation.
  566. *
  567. * @see #changeListener
  568. * @see javax.swing.event.ChangeListener
  569. * @see javax.swing.BoundedRangeModel
  570. */
  571. protected ChangeListener createChangeListener() {
  572. return new ModelListener();
  573. }
  574. /**
  575. * Adds the specified <code>ChangeListener</code> to the progress bar.
  576. *
  577. * @param l the <code>ChangeListener</code> to add
  578. */
  579. public void addChangeListener(ChangeListener l) {
  580. listenerList.add(ChangeListener.class, l);
  581. }
  582. /**
  583. * Removes a <code>ChangeListener</code> from the progress bar.
  584. *
  585. * @param l the <code>ChangeListener</code> to remove
  586. */
  587. public void removeChangeListener(ChangeListener l) {
  588. listenerList.remove(ChangeListener.class, l);
  589. }
  590. /**
  591. * Returns an array of all the <code>ChangeListener</code>s added
  592. * to this progress bar with <code>addChangeListener</code>.
  593. *
  594. * @return all of the <code>ChangeListener</code>s added or an empty
  595. * array if no listeners have been added
  596. * @since 1.4
  597. */
  598. public ChangeListener[] getChangeListeners() {
  599. return (ChangeListener[])listenerList.getListeners(
  600. ChangeListener.class);
  601. }
  602. /**
  603. * Notifies all listeners that have registered interest in
  604. * <code>ChangeEvent</code>s.
  605. * The event instance
  606. * is created if necessary.
  607. *
  608. * @see EventListenerList
  609. */
  610. protected void fireStateChanged() {
  611. // Guaranteed to return a non-null array
  612. Object[] listeners = listenerList.getListenerList();
  613. // Process the listeners last to first, notifying
  614. // those that are interested in this event
  615. for (int i = listeners.length-2; i>=0; i-=2) {
  616. if (listeners[i]==ChangeListener.class) {
  617. // Lazily create the event:
  618. if (changeEvent == null)
  619. changeEvent = new ChangeEvent(this);
  620. ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
  621. }
  622. }
  623. }
  624. /**
  625. * Returns the data model used by this progress bar.
  626. *
  627. * @return the <code>BoundedRangeModel</code> currently in use
  628. * @see BoundedRangeModel
  629. */
  630. public BoundedRangeModel getModel() {
  631. return model;
  632. }
  633. /**
  634. * Sets the data model used by the <code>JProgressBar</code>.
  635. *
  636. * @param newModel the <code>BoundedRangeModel</code> to use
  637. *
  638. * @beaninfo
  639. * expert: true
  640. * description: The data model used by the JProgressBar.
  641. */
  642. public void setModel(BoundedRangeModel newModel) {
  643. // PENDING(???) setting the same model to multiple bars is broken; listeners
  644. BoundedRangeModel oldModel = getModel();
  645. if (newModel != oldModel) {
  646. if (oldModel != null) {
  647. oldModel.removeChangeListener(changeListener);
  648. changeListener = null;
  649. }
  650. model = newModel;
  651. if (newModel != null) {
  652. changeListener = createChangeListener();
  653. newModel.addChangeListener(changeListener);
  654. }
  655. if (accessibleContext != null) {
  656. accessibleContext.firePropertyChange(
  657. AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
  658. (oldModel== null
  659. ? null : new Integer(oldModel.getValue())),
  660. (newModel== null
  661. ? null : new Integer(newModel.getValue())));
  662. }
  663. if (model != null) {
  664. model.setExtent(0);
  665. }
  666. repaint();
  667. }
  668. }
  669. /* All of the model methods are implemented by delegation. */
  670. /**
  671. * Returns the progress bar's current value,
  672. * which is stored in the progress bar's <code>BoundedRangeModel</code>.
  673. * The value is always between the
  674. * minimum and maximum values, inclusive. By default, the
  675. * value is initialized to be equal to the minimum value.
  676. *
  677. * @return the current value of the progress bar
  678. * @see #setValue
  679. * @see BoundedRangeModel#getValue
  680. */
  681. public int getValue() { return getModel().getValue(); }
  682. /**
  683. * Returns the progress bar's minimum value,
  684. * which is stored in the progress bar's <code>BoundedRangeModel</code>.
  685. * By default, the minimum value is <code>0</code>.
  686. *
  687. * @return the progress bar's minimum value
  688. * @see #setMinimum
  689. * @see BoundedRangeModel#getMinimum
  690. */
  691. public int getMinimum() { return getModel().getMinimum(); }
  692. /**
  693. * Returns the progress bar's maximum value,
  694. * which is stored in the progress bar's <code>BoundedRangeModel</code>.
  695. * By default, the maximum value is <code>100</code>.
  696. *
  697. * @return the progress bar's maximum value
  698. * @see #setMaximum
  699. * @see BoundedRangeModel#getMaximum
  700. */
  701. public int getMaximum() { return getModel().getMaximum(); }
  702. /**
  703. * Sets the progress bar's current value
  704. * (stored in the progress bar's data model) to <code>n</code>.
  705. * The data model (a <code>BoundedRangeModel</code> instance)
  706. * handles any mathematical
  707. * issues arising from assigning faulty values.
  708. * <p>
  709. * If the new value is different from the previous value,
  710. * all change listeners are notified.
  711. *
  712. * @param n the new value
  713. * @see #getValue
  714. * @see BoundedRangeModel#setValue
  715. * @beaninfo
  716. * preferred: true
  717. * description: The progress bar's current value.
  718. */
  719. public void setValue(int n) {
  720. BoundedRangeModel brm = getModel();
  721. int oldValue = brm.getValue();
  722. brm.setValue(n);
  723. if (accessibleContext != null) {
  724. accessibleContext.firePropertyChange(
  725. AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
  726. new Integer(oldValue),
  727. new Integer(brm.getValue()));
  728. }
  729. }
  730. /**
  731. * Sets the progress bar's minimum value
  732. * (stored in the progress bar's data model) to <code>n</code>.
  733. * The data model (a <code>BoundedRangeModel</code> instance)
  734. * handles any mathematical
  735. * issues arising from assigning faulty values.
  736. * <p>
  737. * If the minimum value is different from the previous minimum,
  738. * all change listeners are notified.
  739. *
  740. * @param n the new minimum
  741. * @see #getMinimum
  742. * @see #addChangeListener
  743. * @see BoundedRangeModel#setMinimum
  744. * @beaninfo
  745. * preferred: true
  746. * description: The progress bar's minimum value.
  747. */
  748. public void setMinimum(int n) { getModel().setMinimum(n); }
  749. /**
  750. * Sets the progress bar's maximum value
  751. * (stored in the progress bar's data model) to <code>n</code>.
  752. * The underlying <code>BoundedRangeModel</code> handles any mathematical
  753. * issues arising from assigning faulty values.
  754. * <p>
  755. * If the maximum value is different from the previous maximum,
  756. * all change listeners are notified.
  757. *
  758. * @param n the new maximum
  759. * @see #getMaximum
  760. * @see #addChangeListener
  761. * @see BoundedRangeModel#setMaximum
  762. * @beaninfo
  763. * preferred: true
  764. * description: The progress bar's maximum value.
  765. */
  766. public void setMaximum(int n) { getModel().setMaximum(n); }
  767. /**
  768. * Sets the <code>indeterminate</code> property of the progress bar,
  769. * which determines whether the progress bar is in determinate
  770. * or indeterminate mode.
  771. * An indeterminate progress bar continuously displays animation
  772. * indicating that an operation of unknown length is occurring.
  773. * By default, this property is <code>false</code>.
  774. * Some look and feels might not support indeterminate progress bars;
  775. * they will ignore this property.
  776. *
  777. * <p>
  778. *
  779. * See
  780. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html" target="_top">How to Monitor Progress</a>
  781. * for examples of using indeterminate progress bars.
  782. *
  783. * @param newValue <code>true</code> if the progress bar
  784. * should change to indeterminate mode;
  785. * <code>false</code> if it should revert to normal.
  786. *
  787. * @see #isIndeterminate
  788. * @see javax.swing.plaf.basic.BasicProgressBarUI
  789. *
  790. * @since 1.4
  791. *
  792. * @beaninfo
  793. * bound: true
  794. * attribute: visualUpdate true
  795. * description: Set whether the progress bar is indeterminate (true)
  796. * or normal (false).
  797. */
  798. public void setIndeterminate(boolean newValue) {
  799. boolean oldValue = indeterminate;
  800. indeterminate = newValue;
  801. firePropertyChange("indeterminate", oldValue, indeterminate);
  802. }
  803. /**
  804. * Returns the value of the <code>indeterminate</code> property.
  805. *
  806. * @return the value of the <code>indeterminate</code> property
  807. * @see #setIndeterminate
  808. *
  809. * @since 1.4
  810. *
  811. * @beaninfo
  812. * description: Is the progress bar indeterminate (true)
  813. * or normal (false)?
  814. */
  815. public boolean isIndeterminate() {
  816. return indeterminate;
  817. }
  818. /**
  819. * See readObject() and writeObject() in JComponent for more
  820. * information about serialization in Swing.
  821. */
  822. private void writeObject(ObjectOutputStream s) throws IOException {
  823. s.defaultWriteObject();
  824. if (getUIClassID().equals(uiClassID)) {
  825. byte count = JComponent.getWriteObjCounter(this);
  826. JComponent.setWriteObjCounter(this, --count);
  827. if (count == 0 && ui != null) {
  828. ui.installUI(this);
  829. }
  830. }
  831. }
  832. /**
  833. * Returns a string representation of this <code>JProgressBar</code>.
  834. * This method is intended to be used only for debugging purposes. The
  835. * content and format of the returned string may vary between
  836. * implementations. The returned string may be empty but may not
  837. * be <code>null</code>.
  838. *
  839. * @return a string representation of this <code>JProgressBar</code>
  840. */
  841. protected String paramString() {
  842. String orientationString = (orientation == HORIZONTAL ?
  843. "HORIZONTAL" : "VERTICAL");
  844. String paintBorderString = (paintBorder ?
  845. "true" : "false");
  846. String progressStringString = (progressString != null ?
  847. progressString : "");
  848. String paintStringString = (paintString ?
  849. "true" : "false");
  850. String indeterminateString = (indeterminate ?
  851. "true" : "false");
  852. return super.paramString() +
  853. ",orientation=" + orientationString +
  854. ",paintBorder=" + paintBorderString +
  855. ",paintString=" + paintStringString +
  856. ",progressString=" + progressStringString +
  857. ",indeterminateString=" + indeterminateString;
  858. }
  859. /////////////////
  860. // Accessibility support
  861. ////////////////
  862. /**
  863. * Gets the <code>AccessibleContext</code> associated with this
  864. * <code>JProgressBar</code>. For progress bars, the
  865. * <code>AccessibleContext</code> takes the form of an
  866. * <code>AccessibleJProgressBar</code>.
  867. * A new <code>AccessibleJProgressBar</code> instance is created if necessary.
  868. *
  869. * @return an <code>AccessibleJProgressBar</code> that serves as the
  870. * <code>AccessibleContext</code> of this <code>JProgressBar</code>
  871. * @beaninfo
  872. * expert: true
  873. * description: The AccessibleContext associated with this ProgressBar.
  874. */
  875. public AccessibleContext getAccessibleContext() {
  876. if (accessibleContext == null) {
  877. accessibleContext = new AccessibleJProgressBar();
  878. }
  879. return accessibleContext;
  880. }
  881. /**
  882. * This class implements accessibility support for the
  883. * <code>JProgressBar</code> class. It provides an implementation of the
  884. * Java Accessibility API appropriate to progress bar user-interface
  885. * elements.
  886. * <p>
  887. * <strong>Warning:</strong>
  888. * Serialized objects of this class will not be compatible with
  889. * future Swing releases. The current serialization support is
  890. * appropriate for short term storage or RMI between applications running
  891. * the same version of Swing. As of 1.4, support for long term storage
  892. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  893. * has been added to the <code>java.beans</code> package.
  894. * Please see {@link java.beans.XMLEncoder}.
  895. */
  896. protected class AccessibleJProgressBar extends AccessibleJComponent
  897. implements AccessibleValue {
  898. /**
  899. * Gets the state set of this object.
  900. *
  901. * @return an instance of AccessibleState containing the current state
  902. * of the object
  903. * @see AccessibleState
  904. */
  905. public AccessibleStateSet getAccessibleStateSet() {
  906. AccessibleStateSet states = super.getAccessibleStateSet();
  907. if (getModel().getValueIsAdjusting()) {
  908. states.add(AccessibleState.BUSY);
  909. }
  910. if (getOrientation() == VERTICAL) {
  911. states.add(AccessibleState.VERTICAL);
  912. } else {
  913. states.add(AccessibleState.HORIZONTAL);
  914. }
  915. return states;
  916. }
  917. /**
  918. * Gets the role of this object.
  919. *
  920. * @return an instance of AccessibleRole describing the role of the
  921. * object
  922. */
  923. public AccessibleRole getAccessibleRole() {
  924. return AccessibleRole.PROGRESS_BAR;
  925. }
  926. /**
  927. * Gets the <code>AccessibleValue</code> associated with this object. In the
  928. * implementation of the Java Accessibility API for this class,
  929. * returns this object, which is responsible for implementing the
  930. * <code>AccessibleValue</code> interface on behalf of itself.
  931. *
  932. * @return this object
  933. */
  934. public AccessibleValue getAccessibleValue() {
  935. return this;
  936. }
  937. /**
  938. * Gets the accessible value of this object.
  939. *
  940. * @return the current value of this object
  941. */
  942. public Number getCurrentAccessibleValue() {
  943. return new Integer(getValue());
  944. }
  945. /**
  946. * Sets the value of this object as a <code>Number</code>.
  947. *
  948. * @return <code>true</code> if the value was set
  949. */
  950. public boolean setCurrentAccessibleValue(Number n) {
  951. // TIGER- 4422535
  952. if (n == null) {
  953. return false;
  954. }
  955. setValue(n.intValue());
  956. return true;
  957. }
  958. /**
  959. * Gets the minimum accessible value of this object.
  960. *
  961. * @return the minimum value of this object
  962. */
  963. public Number getMinimumAccessibleValue() {
  964. return new Integer(getMinimum());
  965. }
  966. /**
  967. * Gets the maximum accessible value of this object.
  968. *
  969. * @return the maximum value of this object
  970. */
  971. public Number getMaximumAccessibleValue() {
  972. // TIGER - 4422362
  973. return new Integer(model.getMaximum() - model.getExtent());
  974. }
  975. } // AccessibleJProgressBar
  976. }