0001 /*
0002 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package javax.swing;
0027
0028 import java.io.*;
0029 import java.awt.BorderLayout;
0030 import java.awt.Frame;
0031 import java.awt.Dialog;
0032 import java.awt.Window;
0033 import java.awt.Component;
0034 import java.awt.Container;
0035 import java.beans.PropertyChangeEvent;
0036 import java.beans.PropertyChangeListener;
0037 import java.awt.event.WindowListener;
0038 import java.awt.event.WindowAdapter;
0039 import java.awt.event.WindowEvent;
0040
0041 import java.awt.IllegalComponentStateException;
0042 import java.awt.Point;
0043 import java.awt.Rectangle;
0044 import java.text.*;
0045 import java.util.Locale;
0046 import javax.accessibility.*;
0047 import javax.swing.event.*;
0048 import javax.swing.text.*;
0049
0050 /** A class to monitor the progress of some operation. If it looks
0051 * like the operation will take a while, a progress dialog will be popped up.
0052 * When the ProgressMonitor is created it is given a numeric range and a
0053 * descriptive string. As the operation progresses, call the setProgress method
0054 * to indicate how far along the [min,max] range the operation is.
0055 * Initially, there is no ProgressDialog. After the first millisToDecideToPopup
0056 * milliseconds (default 500) the progress monitor will predict how long
0057 * the operation will take. If it is longer than millisToPopup (default 2000,
0058 * 2 seconds) a ProgressDialog will be popped up.
0059 * <p>
0060 * From time to time, when the Dialog box is visible, the progress bar will
0061 * be updated when setProgress is called. setProgress won't always update
0062 * the progress bar, it will only be done if the amount of progress is
0063 * visibly significant.
0064 *
0065 * <p>
0066 *
0067 * For further documentation and examples see
0068 * <a
0069 href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
0070 * a section in <em>The Java Tutorial.</em>
0071 *
0072 * @see ProgressMonitorInputStream
0073 * @author James Gosling
0074 * @author Lynn Monsanto (accessibility)
0075 * @version 1.43 05/05/07
0076 */
0077 public class ProgressMonitor extends Object implements Accessible {
0078 private ProgressMonitor root;
0079 private JDialog dialog;
0080 private JOptionPane pane;
0081 private JProgressBar myBar;
0082 private JLabel noteLabel;
0083 private Component parentComponent;
0084 private String note;
0085 private Object[] cancelOption = null;
0086 private Object message;
0087 private long T0;
0088 private int millisToDecideToPopup = 500;
0089 private int millisToPopup = 2000;
0090 private int min;
0091 private int max;
0092
0093 /**
0094 * Constructs a graphic object that shows progress, typically by filling
0095 * in a rectangular bar as the process nears completion.
0096 *
0097 * @param parentComponent the parent component for the dialog box
0098 * @param message a descriptive message that will be shown
0099 * to the user to indicate what operation is being monitored.
0100 * This does not change as the operation progresses.
0101 * See the message parameters to methods in
0102 * {@link JOptionPane#message}
0103 * for the range of values.
0104 * @param note a short note describing the state of the
0105 * operation. As the operation progresses, you can call
0106 * setNote to change the note displayed. This is used,
0107 * for example, in operations that iterate through a
0108 * list of files to show the name of the file being processes.
0109 * If note is initially null, there will be no note line
0110 * in the dialog box and setNote will be ineffective
0111 * @param min the lower bound of the range
0112 * @param max the upper bound of the range
0113 * @see JDialog
0114 * @see JOptionPane
0115 */
0116 public ProgressMonitor(Component parentComponent, Object message,
0117 String note, int min, int max) {
0118 this (parentComponent, message, note, min, max, null);
0119 }
0120
0121 private ProgressMonitor(Component parentComponent, Object message,
0122 String note, int min, int max, ProgressMonitor group) {
0123 this .min = min;
0124 this .max = max;
0125 this .parentComponent = parentComponent;
0126
0127 cancelOption = new Object[1];
0128 cancelOption[0] = UIManager
0129 .getString("OptionPane.cancelButtonText");
0130
0131 this .message = message;
0132 this .note = note;
0133 if (group != null) {
0134 root = (group.root != null) ? group.root : group;
0135 T0 = root.T0;
0136 dialog = root.dialog;
0137 } else {
0138 T0 = System.currentTimeMillis();
0139 }
0140 }
0141
0142 private class ProgressOptionPane extends JOptionPane {
0143 ProgressOptionPane(Object messageList) {
0144 super (messageList, JOptionPane.INFORMATION_MESSAGE,
0145 JOptionPane.DEFAULT_OPTION, null,
0146 ProgressMonitor.this .cancelOption, null);
0147 }
0148
0149 public int getMaxCharactersPerLineCount() {
0150 return 60;
0151 }
0152
0153 // Equivalent to JOptionPane.createDialog,
0154 // but create a modeless dialog.
0155 // This is necessary because the Solaris implementation doesn't
0156 // support Dialog.setModal yet.
0157 public JDialog createDialog(Component parentComponent,
0158 String title) {
0159 final JDialog dialog;
0160
0161 Window window = JOptionPane
0162 .getWindowForComponent(parentComponent);
0163 if (window instanceof Frame) {
0164 dialog = new JDialog((Frame) window, title, false);
0165 } else {
0166 dialog = new JDialog((Dialog) window, title, false);
0167 }
0168 if (window instanceof SwingUtilities.SharedOwnerFrame) {
0169 WindowListener ownerShutdownListener = (WindowListener) SwingUtilities
0170 .getSharedOwnerFrameShutdownListener();
0171 dialog.addWindowListener(ownerShutdownListener);
0172 }
0173 Container contentPane = dialog.getContentPane();
0174
0175 contentPane.setLayout(new BorderLayout());
0176 contentPane.add(this , BorderLayout.CENTER);
0177 dialog.pack();
0178 dialog.setLocationRelativeTo(parentComponent);
0179 dialog.addWindowListener(new WindowAdapter() {
0180 boolean gotFocus = false;
0181
0182 public void windowClosing(WindowEvent we) {
0183 setValue(cancelOption[0]);
0184 }
0185
0186 public void windowActivated(WindowEvent we) {
0187 // Once window gets focus, set initial focus
0188 if (!gotFocus) {
0189 selectInitialValue();
0190 gotFocus = true;
0191 }
0192 }
0193 });
0194
0195 addPropertyChangeListener(new PropertyChangeListener() {
0196 public void propertyChange(PropertyChangeEvent event) {
0197 if (dialog.isVisible()
0198 && event.getSource() == ProgressOptionPane.this
0199 && (event.getPropertyName().equals(
0200 VALUE_PROPERTY) || event
0201 .getPropertyName().equals(
0202 INPUT_VALUE_PROPERTY))) {
0203 dialog.setVisible(false);
0204 dialog.dispose();
0205 }
0206 }
0207 });
0208
0209 return dialog;
0210 }
0211
0212 /////////////////
0213 // Accessibility support for ProgressOptionPane
0214 ////////////////
0215
0216 /**
0217 * Gets the AccessibleContext for the ProgressOptionPane
0218 *
0219 * @return the AccessibleContext for the ProgressOptionPane
0220 * @since 1.5
0221 */
0222 public AccessibleContext getAccessibleContext() {
0223 return ProgressMonitor.this .getAccessibleContext();
0224 }
0225
0226 /*
0227 * Returns the AccessibleJOptionPane
0228 */
0229 private AccessibleContext getAccessibleJOptionPane() {
0230 return super .getAccessibleContext();
0231 }
0232 }
0233
0234 /**
0235 * Indicate the progress of the operation being monitored.
0236 * If the specified value is >= the maximum, the progress
0237 * monitor is closed.
0238 * @param nv an int specifying the current value, between the
0239 * maximum and minimum specified for this component
0240 * @see #setMinimum
0241 * @see #setMaximum
0242 * @see #close
0243 */
0244 public void setProgress(int nv) {
0245 if (nv >= max) {
0246 close();
0247 } else {
0248 if (myBar != null) {
0249 myBar.setValue(nv);
0250 } else {
0251 long T = System.currentTimeMillis();
0252 long dT = (int) (T - T0);
0253 if (dT >= millisToDecideToPopup) {
0254 int predictedCompletionTime;
0255 if (nv > min) {
0256 predictedCompletionTime = (int) ((long) dT
0257 * (max - min) / (nv - min));
0258 } else {
0259 predictedCompletionTime = millisToPopup;
0260 }
0261 if (predictedCompletionTime >= millisToPopup) {
0262 myBar = new JProgressBar();
0263 myBar.setMinimum(min);
0264 myBar.setMaximum(max);
0265 myBar.setValue(nv);
0266 if (note != null)
0267 noteLabel = new JLabel(note);
0268 pane = new ProgressOptionPane(new Object[] {
0269 message, noteLabel, myBar });
0270 dialog = pane
0271 .createDialog(
0272 parentComponent,
0273 UIManager
0274 .getString("ProgressMonitor.progressText"));
0275 dialog.show();
0276 }
0277 }
0278 }
0279 }
0280 }
0281
0282 /**
0283 * Indicate that the operation is complete. This happens automatically
0284 * when the value set by setProgress is >= max, but it may be called
0285 * earlier if the operation ends early.
0286 */
0287 public void close() {
0288 if (dialog != null) {
0289 dialog.setVisible(false);
0290 dialog.dispose();
0291 dialog = null;
0292 pane = null;
0293 myBar = null;
0294 }
0295 }
0296
0297 /**
0298 * Returns the minimum value -- the lower end of the progress value.
0299 *
0300 * @return an int representing the minimum value
0301 * @see #setMinimum
0302 */
0303 public int getMinimum() {
0304 return min;
0305 }
0306
0307 /**
0308 * Specifies the minimum value.
0309 *
0310 * @param m an int specifying the minimum value
0311 * @see #getMinimum
0312 */
0313 public void setMinimum(int m) {
0314 if (myBar != null) {
0315 myBar.setMinimum(m);
0316 }
0317 min = m;
0318 }
0319
0320 /**
0321 * Returns the maximum value -- the higher end of the progress value.
0322 *
0323 * @return an int representing the maximum value
0324 * @see #setMaximum
0325 */
0326 public int getMaximum() {
0327 return max;
0328 }
0329
0330 /**
0331 * Specifies the maximum value.
0332 *
0333 * @param m an int specifying the maximum value
0334 * @see #getMaximum
0335 */
0336 public void setMaximum(int m) {
0337 if (myBar != null) {
0338 myBar.setMaximum(m);
0339 }
0340 max = m;
0341 }
0342
0343 /**
0344 * Returns true if the user hits the Cancel button in the progress dialog.
0345 */
0346 public boolean isCanceled() {
0347 if (pane == null)
0348 return false;
0349 Object v = pane.getValue();
0350 return ((v != null) && (cancelOption.length == 1) && (v
0351 .equals(cancelOption[0])));
0352 }
0353
0354 /**
0355 * Specifies the amount of time to wait before deciding whether or
0356 * not to popup a progress monitor.
0357 *
0358 * @param millisToDecideToPopup an int specifying the time to wait,
0359 * in milliseconds
0360 * @see #getMillisToDecideToPopup
0361 */
0362 public void setMillisToDecideToPopup(int millisToDecideToPopup) {
0363 this .millisToDecideToPopup = millisToDecideToPopup;
0364 }
0365
0366 /**
0367 * Returns the amount of time this object waits before deciding whether
0368 * or not to popup a progress monitor.
0369 *
0370 * @see #setMillisToDecideToPopup
0371 */
0372 public int getMillisToDecideToPopup() {
0373 return millisToDecideToPopup;
0374 }
0375
0376 /**
0377 * Specifies the amount of time it will take for the popup to appear.
0378 * (If the predicted time remaining is less than this time, the popup
0379 * won't be displayed.)
0380 *
0381 * @param millisToPopup an int specifying the time in milliseconds
0382 * @see #getMillisToPopup
0383 */
0384 public void setMillisToPopup(int millisToPopup) {
0385 this .millisToPopup = millisToPopup;
0386 }
0387
0388 /**
0389 * Returns the amount of time it will take for the popup to appear.
0390 *
0391 * @see #setMillisToPopup
0392 */
0393 public int getMillisToPopup() {
0394 return millisToPopup;
0395 }
0396
0397 /**
0398 * Specifies the additional note that is displayed along with the
0399 * progress message. Used, for example, to show which file the
0400 * is currently being copied during a multiple-file copy.
0401 *
0402 * @param note a String specifying the note to display
0403 * @see #getNote
0404 */
0405 public void setNote(String note) {
0406 this .note = note;
0407 if (noteLabel != null) {
0408 noteLabel.setText(note);
0409 }
0410 }
0411
0412 /**
0413 * Specifies the additional note that is displayed along with the
0414 * progress message.
0415 *
0416 * @return a String specifying the note to display
0417 * @see #setNote
0418 */
0419 public String getNote() {
0420 return note;
0421 }
0422
0423 /////////////////
0424 // Accessibility support
0425 ////////////////
0426
0427 /**
0428 * The <code>AccessibleContext</code> for the <code>ProgressMonitor</code>
0429 * @since 1.5
0430 */
0431 protected AccessibleContext accessibleContext = null;
0432
0433 private AccessibleContext accessibleJOptionPane = null;
0434
0435 /**
0436 * Gets the <code>AccessibleContext</code> for the
0437 * <code>ProgressMonitor</code>
0438 *
0439 * @return the <code>AccessibleContext</code> for the
0440 * <code>ProgressMonitor</code>
0441 * @since 1.5
0442 */
0443 public AccessibleContext getAccessibleContext() {
0444 if (accessibleContext == null) {
0445 accessibleContext = new AccessibleProgressMonitor();
0446 }
0447 if (pane != null && accessibleJOptionPane == null) {
0448 // Notify the AccessibleProgressMonitor that the
0449 // ProgressOptionPane was created. It is necessary
0450 // to poll for ProgressOptionPane creation because
0451 // the ProgressMonitor does not have a Component
0452 // to add a listener to until the ProgressOptionPane
0453 // is created.
0454 if (accessibleContext instanceof AccessibleProgressMonitor) {
0455 ((AccessibleProgressMonitor) accessibleContext)
0456 .optionPaneCreated();
0457 }
0458 }
0459 return accessibleContext;
0460 }
0461
0462 /**
0463 * <code>AccessibleProgressMonitor</code> implements accessibility
0464 * support for the <code>ProgressMonitor</code> class.
0465 * @since 1.5
0466 */
0467 protected class AccessibleProgressMonitor extends AccessibleContext
0468 implements AccessibleText, ChangeListener,
0469 PropertyChangeListener {
0470
0471 /*
0472 * The accessibility hierarchy for ProgressMonitor is a flattened
0473 * version of the ProgressOptionPane component hierarchy.
0474 *
0475 * The ProgressOptionPane component hierarchy is:
0476 * JDialog
0477 * ProgressOptionPane
0478 * JPanel
0479 * JPanel
0480 * JLabel
0481 * JLabel
0482 * JProgressBar
0483 *
0484 * The AccessibleProgessMonitor accessibility hierarchy is:
0485 * AccessibleJDialog
0486 * AccessibleProgressMonitor
0487 * AccessibleJLabel
0488 * AccessibleJLabel
0489 * AccessibleJProgressBar
0490 *
0491 * The abstraction presented to assitive technologies by
0492 * the AccessibleProgressMonitor is that a dialog contains a
0493 * progress monitor with three children: a message, a note
0494 * label and a progress bar.
0495 */
0496
0497 private Object oldModelValue;
0498
0499 /**
0500 * AccessibleProgressMonitor constructor
0501 */
0502 protected AccessibleProgressMonitor() {
0503 }
0504
0505 /*
0506 * Initializes the AccessibleContext now that the ProgressOptionPane
0507 * has been created. Because the ProgressMonitor is not a Component
0508 * implementing the Accessible interface, an AccessibleContext
0509 * must be synthesized from the ProgressOptionPane and its children.
0510 *
0511 * For other AWT and Swing classes, the inner class that implements
0512 * accessibility for the class extends the inner class that implements
0513 * implements accessibility for the super class. AccessibleProgressMonitor
0514 * cannot extend AccessibleJOptionPane and must therefore delegate calls
0515 * to the AccessibleJOptionPane.
0516 */
0517 private void optionPaneCreated() {
0518 accessibleJOptionPane = ((ProgressOptionPane) pane)
0519 .getAccessibleJOptionPane();
0520
0521 // add a listener for progress bar ChangeEvents
0522 if (myBar != null) {
0523 myBar.addChangeListener(this );
0524 }
0525
0526 // add a listener for note label PropertyChangeEvents
0527 if (noteLabel != null) {
0528 noteLabel.addPropertyChangeListener(this );
0529 }
0530 }
0531
0532 /**
0533 * Invoked when the target of the listener has changed its state.
0534 *
0535 * @param e a <code>ChangeEvent</code> object. Must not be null.
0536 * @throws NullPointerException if the parameter is null.
0537 */
0538 public void stateChanged(ChangeEvent e) {
0539 if (e == null) {
0540 return;
0541 }
0542 if (myBar != null) {
0543 // the progress bar value changed
0544 Object newModelValue = myBar.getValue();
0545 firePropertyChange(ACCESSIBLE_VALUE_PROPERTY,
0546 oldModelValue, newModelValue);
0547 oldModelValue = newModelValue;
0548 }
0549 }
0550
0551 /**
0552 * This method gets called when a bound property is changed.
0553 *
0554 * @param e A <code>PropertyChangeEvent</code> object describing
0555 * the event source and the property that has changed. Must not be null.
0556 * @throws NullPointerException if the parameter is null.
0557 */
0558 public void propertyChange(PropertyChangeEvent e) {
0559 if (e.getSource() == noteLabel
0560 && e.getPropertyName() == "text") {
0561 // the note label text changed
0562 firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, 0);
0563 }
0564 }
0565
0566 /* ===== Begin AccessileContext ===== */
0567
0568 /**
0569 * Gets the accessibleName property of this object. The accessibleName
0570 * property of an object is a localized String that designates the purpose
0571 * of the object. For example, the accessibleName property of a label
0572 * or button might be the text of the label or button itself. In the
0573 * case of an object that doesn't display its name, the accessibleName
0574 * should still be set. For example, in the case of a text field used
0575 * to enter the name of a city, the accessibleName for the en_US locale
0576 * could be 'city.'
0577 *
0578 * @return the localized name of the object; null if this
0579 * object does not have a name
0580 *
0581 * @see #setAccessibleName
0582 */
0583 public String getAccessibleName() {
0584 if (accessibleName != null) { // defined in AccessibleContext
0585 return accessibleName;
0586 } else if (accessibleJOptionPane != null) {
0587 // delegate to the AccessibleJOptionPane
0588 return accessibleJOptionPane.getAccessibleName();
0589 }
0590 return null;
0591 }
0592
0593 /**
0594 * Gets the accessibleDescription property of this object. The
0595 * accessibleDescription property of this object is a short localized
0596 * phrase describing the purpose of the object. For example, in the
0597 * case of a 'Cancel' button, the accessibleDescription could be
0598 * 'Ignore changes and close dialog box.'
0599 *
0600 * @return the localized description of the object; null if
0601 * this object does not have a description
0602 *
0603 * @see #setAccessibleDescription
0604 */
0605 public String getAccessibleDescription() {
0606 if (accessibleDescription != null) { // defined in AccessibleContext
0607 return accessibleDescription;
0608 } else if (accessibleJOptionPane != null) {
0609 // delegate to the AccessibleJOptionPane
0610 return accessibleJOptionPane.getAccessibleDescription();
0611 }
0612 return null;
0613 }
0614
0615 /**
0616 * Gets the role of this object. The role of the object is the generic
0617 * purpose or use of the class of this object. For example, the role
0618 * of a push button is AccessibleRole.PUSH_BUTTON. The roles in
0619 * AccessibleRole are provided so component developers can pick from
0620 * a set of predefined roles. This enables assistive technologies to
0621 * provide a consistent interface to various tweaked subclasses of
0622 * components (e.g., use AccessibleRole.PUSH_BUTTON for all components
0623 * that act like a push button) as well as distinguish between sublasses
0624 * that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
0625 * and AccessibleRole.RADIO_BUTTON for radio buttons).
0626 * <p>Note that the AccessibleRole class is also extensible, so
0627 * custom component developers can define their own AccessibleRole's
0628 * if the set of predefined roles is inadequate.
0629 *
0630 * @return an instance of AccessibleRole describing the role of the object
0631 * @see AccessibleRole
0632 */
0633 public AccessibleRole getAccessibleRole() {
0634 return AccessibleRole.PROGRESS_MONITOR;
0635 }
0636
0637 /**
0638 * Gets the state set of this object. The AccessibleStateSet of an object
0639 * is composed of a set of unique AccessibleStates. A change in the
0640 * AccessibleStateSet of an object will cause a PropertyChangeEvent to
0641 * be fired for the ACCESSIBLE_STATE_PROPERTY property.
0642 *
0643 * @return an instance of AccessibleStateSet containing the
0644 * current state set of the object
0645 * @see AccessibleStateSet
0646 * @see AccessibleState
0647 * @see #addPropertyChangeListener
0648 */
0649 public AccessibleStateSet getAccessibleStateSet() {
0650 if (accessibleJOptionPane != null) {
0651 // delegate to the AccessibleJOptionPane
0652 return accessibleJOptionPane.getAccessibleStateSet();
0653 }
0654 return null;
0655 }
0656
0657 /**
0658 * Gets the Accessible parent of this object.
0659 *
0660 * @return the Accessible parent of this object; null if this
0661 * object does not have an Accessible parent
0662 */
0663 public Accessible getAccessibleParent() {
0664 if (dialog != null) {
0665 return (Accessible) dialog;
0666 }
0667 return null;
0668 }
0669
0670 /*
0671 * Returns the parent AccessibleContext
0672 */
0673 private AccessibleContext getParentAccessibleContext() {
0674 if (dialog != null) {
0675 return dialog.getAccessibleContext();
0676 }
0677 return null;
0678 }
0679
0680 /**
0681 * Gets the 0-based index of this object in its accessible parent.
0682 *
0683 * @return the 0-based index of this object in its parent; -1 if this
0684 * object does not have an accessible parent.
0685 *
0686 * @see #getAccessibleParent
0687 * @see #getAccessibleChildrenCount
0688 * @see #getAccessibleChild
0689 */
0690 public int getAccessibleIndexInParent() {
0691 if (accessibleJOptionPane != null) {
0692 // delegate to the AccessibleJOptionPane
0693 return accessibleJOptionPane
0694 .getAccessibleIndexInParent();
0695 }
0696 return -1;
0697 }
0698
0699 /**
0700 * Returns the number of accessible children of the object.
0701 *
0702 * @return the number of accessible children of the object.
0703 */
0704 public int getAccessibleChildrenCount() {
0705 // return the number of children in the JPanel containing
0706 // the message, note label and progress bar
0707 AccessibleContext ac = getPanelAccessibleContext();
0708 if (ac != null) {
0709 return ac.getAccessibleChildrenCount();
0710 }
0711 return 0;
0712 }
0713
0714 /**
0715 * Returns the specified Accessible child of the object. The Accessible
0716 * children of an Accessible object are zero-based, so the first child
0717 * of an Accessible child is at index 0, the second child is at index 1,
0718 * and so on.
0719 *
0720 * @param i zero-based index of child
0721 * @return the Accessible child of the object
0722 * @see #getAccessibleChildrenCount
0723 */
0724 public Accessible getAccessibleChild(int i) {
0725 // return a child in the JPanel containing the message, note label
0726 // and progress bar
0727 AccessibleContext ac = getPanelAccessibleContext();
0728 if (ac != null) {
0729 return ac.getAccessibleChild(i);
0730 }
0731 return null;
0732 }
0733
0734 /*
0735 * Returns the AccessibleContext for the JPanel containing the
0736 * message, note label and progress bar
0737 */
0738 private AccessibleContext getPanelAccessibleContext() {
0739 if (myBar != null) {
0740 Component c = myBar.getParent();
0741 if (c instanceof Accessible) {
0742 return ((Accessible) c).getAccessibleContext();
0743 }
0744 }
0745 return null;
0746 }
0747
0748 /**
0749 * Gets the locale of the component. If the component does not have a
0750 * locale, then the locale of its parent is returned.
0751 *
0752 * @return this component's locale. If this component does not have
0753 * a locale, the locale of its parent is returned.
0754 *
0755 * @exception IllegalComponentStateException
0756 * If the Component does not have its own locale and has not yet been
0757 * added to a containment hierarchy such that the locale can be
0758 * determined from the containing parent.
0759 */
0760 public Locale getLocale() throws IllegalComponentStateException {
0761 if (accessibleJOptionPane != null) {
0762 // delegate to the AccessibleJOptionPane
0763 return accessibleJOptionPane.getLocale();
0764 }
0765 return null;
0766 }
0767
0768 /* ===== end AccessibleContext ===== */
0769
0770 /**
0771 * Gets the AccessibleComponent associated with this object that has a
0772 * graphical representation.
0773 *
0774 * @return AccessibleComponent if supported by object; else return null
0775 * @see AccessibleComponent
0776 */
0777 public AccessibleComponent getAccessibleComponent() {
0778 if (accessibleJOptionPane != null) {
0779 // delegate to the AccessibleJOptionPane
0780 return accessibleJOptionPane.getAccessibleComponent();
0781 }
0782 return null;
0783 }
0784
0785 /**
0786 * Gets the AccessibleValue associated with this object that supports a
0787 * Numerical value.
0788 *
0789 * @return AccessibleValue if supported by object; else return null
0790 * @see AccessibleValue
0791 */
0792 public AccessibleValue getAccessibleValue() {
0793 if (myBar != null) {
0794 // delegate to the AccessibleJProgressBar
0795 return myBar.getAccessibleContext()
0796 .getAccessibleValue();
0797 }
0798 return null;
0799 }
0800
0801 /**
0802 * Gets the AccessibleText associated with this object presenting
0803 * text on the display.
0804 *
0805 * @return AccessibleText if supported by object; else return null
0806 * @see AccessibleText
0807 */
0808 public AccessibleText getAccessibleText() {
0809 if (getNoteLabelAccessibleText() != null) {
0810 return this ;
0811 }
0812 return null;
0813 }
0814
0815 /*
0816 * Returns the note label AccessibleText
0817 */
0818 private AccessibleText getNoteLabelAccessibleText() {
0819 if (noteLabel != null) {
0820 // AccessibleJLabel implements AccessibleText if the
0821 // JLabel contains HTML text
0822 return noteLabel.getAccessibleContext()
0823 .getAccessibleText();
0824 }
0825 return null;
0826 }
0827
0828 /* ===== Begin AccessibleText impl ===== */
0829
0830 /**
0831 * Given a point in local coordinates, return the zero-based index
0832 * of the character under that Point. If the point is invalid,
0833 * this method returns -1.
0834 *
0835 * @param p the Point in local coordinates
0836 * @return the zero-based index of the character under Point p; if
0837 * Point is invalid return -1.
0838 */
0839 public int getIndexAtPoint(Point p) {
0840 AccessibleText at = getNoteLabelAccessibleText();
0841 if (at != null && sameWindowAncestor(pane, noteLabel)) {
0842 // convert point from the option pane bounds
0843 // to the note label bounds.
0844 Point noteLabelPoint = SwingUtilities.convertPoint(
0845 pane, p, noteLabel);
0846 if (noteLabelPoint != null) {
0847 return at.getIndexAtPoint(noteLabelPoint);
0848 }
0849 }
0850 return -1;
0851 }
0852
0853 /**
0854 * Determines the bounding box of the character at the given
0855 * index into the string. The bounds are returned in local
0856 * coordinates. If the index is invalid an empty rectangle is returned.
0857 *
0858 * @param i the index into the String
0859 * @return the screen coordinates of the character's bounding box,
0860 * if index is invalid return an empty rectangle.
0861 */
0862 public Rectangle getCharacterBounds(int i) {
0863 AccessibleText at = getNoteLabelAccessibleText();
0864 if (at != null && sameWindowAncestor(pane, noteLabel)) {
0865 // return rectangle in the option pane bounds
0866 Rectangle noteLabelRect = at.getCharacterBounds(i);
0867 if (noteLabelRect != null) {
0868 return SwingUtilities.convertRectangle(noteLabel,
0869 noteLabelRect, pane);
0870 }
0871 }
0872 return null;
0873 }
0874
0875 /*
0876 * Returns whether source and destination components have the
0877 * same window ancestor
0878 */
0879 private boolean sameWindowAncestor(Component src, Component dest) {
0880 if (src == null || dest == null) {
0881 return false;
0882 }
0883 return SwingUtilities.getWindowAncestor(src) == SwingUtilities
0884 .getWindowAncestor(dest);
0885 }
0886
0887 /**
0888 * Returns the number of characters (valid indicies)
0889 *
0890 * @return the number of characters
0891 */
0892 public int getCharCount() {
0893 AccessibleText at = getNoteLabelAccessibleText();
0894 if (at != null) { // JLabel contains HTML text
0895 return at.getCharCount();
0896 }
0897 return -1;
0898 }
0899
0900 /**
0901 * Returns the zero-based offset of the caret.
0902 *
0903 * Note: That to the right of the caret will have the same index
0904 * value as the offset (the caret is between two characters).
0905 * @return the zero-based offset of the caret.
0906 */
0907 public int getCaretPosition() {
0908 AccessibleText at = getNoteLabelAccessibleText();
0909 if (at != null) { // JLabel contains HTML text
0910 return at.getCaretPosition();
0911 }
0912 return -1;
0913 }
0914
0915 /**
0916 * Returns the String at a given index.
0917 *
0918 * @param part the CHARACTER, WORD, or SENTENCE to retrieve
0919 * @param index an index within the text
0920 * @return the letter, word, or sentence
0921 */
0922 public String getAtIndex(int part, int index) {
0923 AccessibleText at = getNoteLabelAccessibleText();
0924 if (at != null) { // JLabel contains HTML text
0925 return at.getAtIndex(part, index);
0926 }
0927 return null;
0928 }
0929
0930 /**
0931 * Returns the String after a given index.
0932 *
0933 * @param part the CHARACTER, WORD, or SENTENCE to retrieve
0934 * @param index an index within the text
0935 * @return the letter, word, or sentence
0936 */
0937 public String getAfterIndex(int part, int index) {
0938 AccessibleText at = getNoteLabelAccessibleText();
0939 if (at != null) { // JLabel contains HTML text
0940 return at.getAfterIndex(part, index);
0941 }
0942 return null;
0943 }
0944
0945 /**
0946 * Returns the String before a given index.
0947 *
0948 * @param part the CHARACTER, WORD, or SENTENCE to retrieve
0949 * @param index an index within the text
0950 * @return the letter, word, or sentence
0951 */
0952 public String getBeforeIndex(int part, int index) {
0953 AccessibleText at = getNoteLabelAccessibleText();
0954 if (at != null) { // JLabel contains HTML text
0955 return at.getBeforeIndex(part, index);
0956 }
0957 return null;
0958 }
0959
0960 /**
0961 * Returns the AttributeSet for a given character at a given index
0962 *
0963 * @param i the zero-based index into the text
0964 * @return the AttributeSet of the character
0965 */
0966 public AttributeSet getCharacterAttribute(int i) {
0967 AccessibleText at = getNoteLabelAccessibleText();
0968 if (at != null) { // JLabel contains HTML text
0969 return at.getCharacterAttribute(i);
0970 }
0971 return null;
0972 }
0973
0974 /**
0975 * Returns the start offset within the selected text.
0976 * If there is no selection, but there is
0977 * a caret, the start and end offsets will be the same.
0978 *
0979 * @return the index into the text of the start of the selection
0980 */
0981 public int getSelectionStart() {
0982 AccessibleText at = getNoteLabelAccessibleText();
0983 if (at != null) { // JLabel contains HTML text
0984 return at.getSelectionStart();
0985 }
0986 return -1;
0987 }
0988
0989 /**
0990 * Returns the end offset within the selected text.
0991 * If there is no selection, but there is
0992 * a caret, the start and end offsets will be the same.
0993 *
0994 * @return the index into teh text of the end of the selection
0995 */
0996 public int getSelectionEnd() {
0997 AccessibleText at = getNoteLabelAccessibleText();
0998 if (at != null) { // JLabel contains HTML text
0999 return at.getSelectionEnd();
1000 }
1001 return -1;
1002 }
1003
1004 /**
1005 * Returns the portion of the text that is selected.
1006 *
1007 * @return the String portion of the text that is selected
1008 */
1009 public String getSelectedText() {
1010 AccessibleText at = getNoteLabelAccessibleText();
1011 if (at != null) { // JLabel contains HTML text
1012 return at.getSelectedText();
1013 }
1014 return null;
1015 }
1016 /* ===== End AccessibleText impl ===== */
1017 }
1018 // inner class AccessibleProgressMonitor
1019
1020 }
|