History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/ProgressMonitor.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/swing/ProgressMonitor.java+1046−0
@@ -0,0 +1,1046 @@
1+/*
2+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+
27+
28+package javax.swing;
29+
30+
31+
32+import java.io.*;
33+import java.awt.BorderLayout;
34+import java.awt.Frame;
35+import java.awt.Dialog;
36+import java.awt.Window;
37+import java.awt.Component;
38+import java.awt.Container;
39+import java.beans.PropertyChangeEvent;
40+import java.beans.PropertyChangeListener;
41+import java.awt.event.WindowListener;
42+import java.awt.event.WindowAdapter;
43+import java.awt.event.WindowEvent;
44+
45+import java.awt.IllegalComponentStateException;
46+import java.awt.Point;
47+import java.awt.Rectangle;
48+import java.text.*;
49+import java.util.Locale;
50+import javax.accessibility.*;
51+import javax.swing.event.*;
52+import javax.swing.text.*;
53+
54+
55+/** A class to monitor the progress of some operation. If it looks
56+ * like the operation will take a while, a progress dialog will be popped up.
57+ * When the ProgressMonitor is created it is given a numeric range and a
58+ * descriptive string. As the operation progresses, call the setProgress method
59+ * to indicate how far along the [min,max] range the operation is.
60+ * Initially, there is no ProgressDialog. After the first millisToDecideToPopup
61+ * milliseconds (default 500) the progress monitor will predict how long
62+ * the operation will take. If it is longer than millisToPopup (default 2000,
63+ * 2 seconds) a ProgressDialog will be popped up.
64+ * <p>
65+ * From time to time, when the Dialog box is visible, the progress bar will
66+ * be updated when setProgress is called. setProgress won't always update
67+ * the progress bar, it will only be done if the amount of progress is
68+ * visibly significant.
69+ *
70+ * <p>
71+ *
72+ * For further documentation and examples see
73+ * <a
74+ href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
75+ * a section in <em>The Java Tutorial.</em>
76+ *
77+ * @see ProgressMonitorInputStream
78+ * @author James Gosling
79+ * @author Lynn Monsanto (accessibility)
80+ */
81+public class ProgressMonitor implements Accessible
82+{
83+ private ProgressMonitor root;
84+ private JDialog dialog;
85+ private JOptionPane pane;
86+ private JProgressBar myBar;
87+ private JLabel noteLabel;
88+ private Component parentComponent;
89+ private String note;
90+ private Object[] cancelOption = null;
91+ private Object message;
92+ private long T0;
93+ private int millisToDecideToPopup = 500;
94+ private int millisToPopup = 2000;
95+ private int min;
96+ private int max;
97+
98+
99+ /**
100+ * Constructs a graphic object that shows progress, typically by filling
101+ * in a rectangular bar as the process nears completion.
102+ *
103+ * @param parentComponent the parent component for the dialog box
104+ * @param message a descriptive message that will be shown
105+ * to the user to indicate what operation is being monitored.
106+ * This does not change as the operation progresses.
107+ * See the message parameters to methods in
108+ * {@link JOptionPane#message}
109+ * for the range of values.
110+ * @param note a short note describing the state of the
111+ * operation. As the operation progresses, you can call
112+ * setNote to change the note displayed. This is used,
113+ * for example, in operations that iterate through a
114+ * list of files to show the name of the file being processes.
115+ * If note is initially null, there will be no note line
116+ * in the dialog box and setNote will be ineffective
117+ * @param min the lower bound of the range
118+ * @param max the upper bound of the range
119+ * @see JDialog
120+ * @see JOptionPane
121+ */
122+ public ProgressMonitor(Component parentComponent,
123+ Object message,
124+ String note,
125+ int min,
126+ int max) {
127+ this(parentComponent, message, note, min, max, null);
128+ }
129+
130+
131+ private ProgressMonitor(Component parentComponent,
132+ Object message,
133+ String note,
134+ int min,
135+ int max,
136+ ProgressMonitor group) {
137+ this.min = min;
138+ this.max = max;
139+ this.parentComponent = parentComponent;
140+
141+ cancelOption = new Object[1];
142+ cancelOption[0] = UIManager.getString("OptionPane.cancelButtonText");
143+
144+ this.message = message;
145+ this.note = note;
146+ if (group != null) {
147+ root = (group.root != null) ? group.root : group;
148+ T0 = root.T0;
149+ dialog = root.dialog;
150+ }
151+ else {
152+ T0 = System.currentTimeMillis();
153+ }
154+ }
155+
156+
157+ private class ProgressOptionPane extends JOptionPane
158+ {
159+ ProgressOptionPane(Object messageList) {
160+ super(messageList,
161+ JOptionPane.INFORMATION_MESSAGE,
162+ JOptionPane.DEFAULT_OPTION,
163+ null,
164+ ProgressMonitor.this.cancelOption,
165+ null);
166+ }
167+
168+
169+ public int getMaxCharactersPerLineCount() {
170+ return 60;
171+ }
172+
173+
174+ // Equivalent to JOptionPane.createDialog,
175+ // but create a modeless dialog.
176+ // This is necessary because the Solaris implementation doesn't
177+ // support Dialog.setModal yet.
178+ public JDialog createDialog(Component parentComponent, String title) {
179+ final JDialog dialog;
180+
181+ Window window = JOptionPane.getWindowForComponent(parentComponent);
182+ if (window instanceof Frame) {
183+ dialog = new JDialog((Frame)window, title, false);
184+ } else {
185+ dialog = new JDialog((Dialog)window, title, false);
186+ }
187+ if (window instanceof SwingUtilities.SharedOwnerFrame) {
188+ WindowListener ownerShutdownListener =
189+ SwingUtilities.getSharedOwnerFrameShutdownListener();
190+ dialog.addWindowListener(ownerShutdownListener);
191+ }
192+ Container contentPane = dialog.getContentPane();
193+
194+ contentPane.setLayout(new BorderLayout());
195+ contentPane.add(this, BorderLayout.CENTER);
196+ dialog.pack();
197+ dialog.setLocationRelativeTo(parentComponent);
198+ dialog.addWindowListener(new WindowAdapter() {
199+ boolean gotFocus = false;
200+
201+ public void windowClosing(WindowEvent we) {
202+ setValue(cancelOption[0]);
203+ }
204+
205+ public void windowActivated(WindowEvent we) {
206+ // Once window gets focus, set initial focus
207+ if (!gotFocus) {
208+ selectInitialValue();
209+ gotFocus = true;
210+ }
211+ }
212+ });
213+
214+ addPropertyChangeListener(new PropertyChangeListener() {
215+ public void propertyChange(PropertyChangeEvent event) {
216+ if(dialog.isVisible() &&
217+ event.getSource() == ProgressOptionPane.this &&
218+ (event.getPropertyName().equals(VALUE_PROPERTY) ||
219+ event.getPropertyName().equals(INPUT_VALUE_PROPERTY))){
220+ dialog.setVisible(false);
221+ dialog.dispose();
222+ }
223+ }
224+ });
225+
226+ return dialog;
227+ }
228+
229+ /////////////////
230+ // Accessibility support for ProgressOptionPane
231+ ////////////////
232+
233+ /**
234+ * Gets the AccessibleContext for the ProgressOptionPane
235+ *
236+ * @return the AccessibleContext for the ProgressOptionPane
237+ * @since 1.5
238+ */
239+ public AccessibleContext getAccessibleContext() {
240+ return ProgressMonitor.this.getAccessibleContext();
241+ }
242+
243+ /*
244+ * Returns the AccessibleJOptionPane
245+ */
246+ private AccessibleContext getAccessibleJOptionPane() {
247+ return super.getAccessibleContext();
248+ }
249+ }
250+
251+
252+ /**
253+ * Indicate the progress of the operation being monitored.
254+ * If the specified value is >= the maximum, the progress
255+ * monitor is closed.
256+ * @param nv an int specifying the current value, between the
257+ * maximum and minimum specified for this component
258+ * @see #setMinimum
259+ * @see #setMaximum
260+ * @see #close
261+ */
262+ public void setProgress(int nv) {
263+ if (nv >= max) {
264+ close();
265+ }
266+ else {
267+ if (myBar != null) {
268+ myBar.setValue(nv);
269+ }
270+ else {
271+ long T = System.currentTimeMillis();
272+ long dT = (int)(T-T0);
273+ if (dT >= millisToDecideToPopup) {
274+ int predictedCompletionTime;
275+ if (nv > min) {
276+ predictedCompletionTime = (int)(dT *
277+ (max - min) /
278+ (nv - min));
279+ }
280+ else {
281+ predictedCompletionTime = millisToPopup;
282+ }
283+ if (predictedCompletionTime >= millisToPopup) {
284+ myBar = new JProgressBar();
285+ myBar.setMinimum(min);
286+ myBar.setMaximum(max);
287+ myBar.setValue(nv);
288+ if (note != null) noteLabel = new JLabel(note);
289+ pane = new ProgressOptionPane(new Object[] {message,
290+ noteLabel,
291+ myBar});
292+ dialog = pane.createDialog(parentComponent,
293+ UIManager.getString(
294+ "ProgressMonitor.progressText"));
295+ dialog.show();
296+ }
297+ }
298+ }
299+ }
300+ }
301+
302+
303+ /**
304+ * Indicate that the operation is complete. This happens automatically
305+ * when the value set by setProgress is >= max, but it may be called
306+ * earlier if the operation ends early.
307+ */
308+ public void close() {
309+ if (dialog != null) {
310+ dialog.setVisible(false);
311+ dialog.dispose();
312+ dialog = null;
313+ pane = null;
314+ myBar = null;
315+ }
316+ }
317+
318+
319+ /**
320+ * Returns the minimum value -- the lower end of the progress value.
321+ *
322+ * @return an int representing the minimum value
323+ * @see #setMinimum
324+ */
325+ public int getMinimum() {
326+ return min;
327+ }
328+
329+
330+ /**
331+ * Specifies the minimum value.
332+ *
333+ * @param m an int specifying the minimum value
334+ * @see #getMinimum
335+ */
336+ public void setMinimum(int m) {
337+ if (myBar != null) {
338+ myBar.setMinimum(m);
339+ }
340+ min = m;
341+ }
342+
343+
344+ /**
345+ * Returns the maximum value -- the higher end of the progress value.
346+ *
347+ * @return an int representing the maximum value
348+ * @see #setMaximum
349+ */
350+ public int getMaximum() {
351+ return max;
352+ }
353+
354+
355+ /**
356+ * Specifies the maximum value.
357+ *
358+ * @param m an int specifying the maximum value
359+ * @see #getMaximum
360+ */
361+ public void setMaximum(int m) {
362+ if (myBar != null) {
363+ myBar.setMaximum(m);
364+ }
365+ max = m;
366+ }
367+
368+
369+ /**
370+ * Returns true if the user hits the Cancel button in the progress dialog.
371+ */
372+ public boolean isCanceled() {
373+ if (pane == null) return false;
374+ Object v = pane.getValue();
375+ return ((v != null) &&
376+ (cancelOption.length == 1) &&
377+ (v.equals(cancelOption[0])));
378+ }
379+
380+
381+ /**
382+ * Specifies the amount of time to wait before deciding whether or
383+ * not to popup a progress monitor.
384+ *
385+ * @param millisToDecideToPopup an int specifying the time to wait,
386+ * in milliseconds
387+ * @see #getMillisToDecideToPopup
388+ */
389+ public void setMillisToDecideToPopup(int millisToDecideToPopup) {
390+ this.millisToDecideToPopup = millisToDecideToPopup;
391+ }
392+
393+
394+ /**
395+ * Returns the amount of time this object waits before deciding whether
396+ * or not to popup a progress monitor.
397+ *
398+ * @see #setMillisToDecideToPopup
399+ */
400+ public int getMillisToDecideToPopup() {
401+ return millisToDecideToPopup;
402+ }
403+
404+
405+ /**
406+ * Specifies the amount of time it will take for the popup to appear.
407+ * (If the predicted time remaining is less than this time, the popup
408+ * won't be displayed.)
409+ *
410+ * @param millisToPopup an int specifying the time in milliseconds
411+ * @see #getMillisToPopup
412+ */
413+ public void setMillisToPopup(int millisToPopup) {
414+ this.millisToPopup = millisToPopup;
415+ }
416+
417+
418+ /**
419+ * Returns the amount of time it will take for the popup to appear.
420+ *
421+ * @see #setMillisToPopup
422+ */
423+ public int getMillisToPopup() {
424+ return millisToPopup;
425+ }
426+
427+
428+ /**
429+ * Specifies the additional note that is displayed along with the
430+ * progress message. Used, for example, to show which file the
431+ * is currently being copied during a multiple-file copy.
432+ *
433+ * @param note a String specifying the note to display
434+ * @see #getNote
435+ */
436+ public void setNote(String note) {
437+ this.note = note;
438+ if (noteLabel != null) {
439+ noteLabel.setText(note);
440+ }
441+ }
442+
443+
444+ /**
445+ * Specifies the additional note that is displayed along with the
446+ * progress message.
447+ *
448+ * @return a String specifying the note to display
449+ * @see #setNote
450+ */
451+ public String getNote() {
452+ return note;
453+ }
454+
455+ /////////////////
456+ // Accessibility support
457+ ////////////////
458+
459+ /**
460+ * The <code>AccessibleContext</code> for the <code>ProgressMonitor</code>
461+ * @since 1.5
462+ */
463+ protected AccessibleContext accessibleContext = null;
464+
465+ private AccessibleContext accessibleJOptionPane = null;
466+
467+ /**
468+ * Gets the <code>AccessibleContext</code> for the
469+ * <code>ProgressMonitor</code>
470+ *
471+ * @return the <code>AccessibleContext</code> for the
472+ * <code>ProgressMonitor</code>
473+ * @since 1.5
474+ */
475+ public AccessibleContext getAccessibleContext() {
476+ if (accessibleContext == null) {
477+ accessibleContext = new AccessibleProgressMonitor();
478+ }
479+ if (pane != null && accessibleJOptionPane == null) {
480+ // Notify the AccessibleProgressMonitor that the
481+ // ProgressOptionPane was created. It is necessary
482+ // to poll for ProgressOptionPane creation because
483+ // the ProgressMonitor does not have a Component
484+ // to add a listener to until the ProgressOptionPane
485+ // is created.
486+ if (accessibleContext instanceof AccessibleProgressMonitor) {
487+ ((AccessibleProgressMonitor)accessibleContext).optionPaneCreated();
488+ }
489+ }
490+ return accessibleContext;
491+ }
492+
493+ /**
494+ * <code>AccessibleProgressMonitor</code> implements accessibility
495+ * support for the <code>ProgressMonitor</code> class.
496+ * @since 1.5
497+ */
498+ protected class AccessibleProgressMonitor extends AccessibleContext
499+ implements AccessibleText, ChangeListener, PropertyChangeListener {
500+
501+ /*
502+ * The accessibility hierarchy for ProgressMonitor is a flattened
503+ * version of the ProgressOptionPane component hierarchy.
504+ *
505+ * The ProgressOptionPane component hierarchy is:
506+ * JDialog
507+ * ProgressOptionPane
508+ * JPanel
509+ * JPanel
510+ * JLabel
511+ * JLabel
512+ * JProgressBar
513+ *
514+ * The AccessibleProgessMonitor accessibility hierarchy is:
515+ * AccessibleJDialog
516+ * AccessibleProgressMonitor
517+ * AccessibleJLabel
518+ * AccessibleJLabel
519+ * AccessibleJProgressBar
520+ *
521+ * The abstraction presented to assitive technologies by
522+ * the AccessibleProgressMonitor is that a dialog contains a
523+ * progress monitor with three children: a message, a note
524+ * label and a progress bar.
525+ */
526+
527+ private Object oldModelValue;
528+
529+ /**
530+ * AccessibleProgressMonitor constructor
531+ */
532+ protected AccessibleProgressMonitor() {
533+ }
534+
535+ /*
536+ * Initializes the AccessibleContext now that the ProgressOptionPane
537+ * has been created. Because the ProgressMonitor is not a Component
538+ * implementing the Accessible interface, an AccessibleContext
539+ * must be synthesized from the ProgressOptionPane and its children.
540+ *
541+ * For other AWT and Swing classes, the inner class that implements
542+ * accessibility for the class extends the inner class that implements
543+ * implements accessibility for the super class. AccessibleProgressMonitor
544+ * cannot extend AccessibleJOptionPane and must therefore delegate calls
545+ * to the AccessibleJOptionPane.
546+ */
547+ private void optionPaneCreated() {
548+ accessibleJOptionPane =
549+ ((ProgressOptionPane)pane).getAccessibleJOptionPane();
550+
551+ // add a listener for progress bar ChangeEvents
552+ if (myBar != null) {
553+ myBar.addChangeListener(this);
554+ }
555+
556+ // add a listener for note label PropertyChangeEvents
557+ if (noteLabel != null) {
558+ noteLabel.addPropertyChangeListener(this);
559+ }
560+ }
561+
562+ /**
563+ * Invoked when the target of the listener has changed its state.
564+ *
565+ * @param e a <code>ChangeEvent</code> object. Must not be null.
566+ * @throws NullPointerException if the parameter is null.
567+ */
568+ public void stateChanged(ChangeEvent e) {
569+ if (e == null) {
570+ return;
571+ }
572+ if (myBar != null) {
573+ // the progress bar value changed
574+ Object newModelValue = myBar.getValue();
575+ firePropertyChange(ACCESSIBLE_VALUE_PROPERTY,
576+ oldModelValue,
577+ newModelValue);
578+ oldModelValue = newModelValue;
579+ }
580+ }
581+
582+ /**
583+ * This method gets called when a bound property is changed.
584+ *
585+ * @param e A <code>PropertyChangeEvent</code> object describing
586+ * the event source and the property that has changed. Must not be null.
587+ * @throws NullPointerException if the parameter is null.
588+ */
589+ public void propertyChange(PropertyChangeEvent e) {
590+ if (e.getSource() == noteLabel && e.getPropertyName() == "text") {
591+ // the note label text changed
592+ firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, 0);
593+ }
594+ }
595+
596+ /* ===== Begin AccessileContext ===== */
597+
598+ /**
599+ * Gets the accessibleName property of this object. The accessibleName
600+ * property of an object is a localized String that designates the purpose
601+ * of the object. For example, the accessibleName property of a label
602+ * or button might be the text of the label or button itself. In the
603+ * case of an object that doesn't display its name, the accessibleName
604+ * should still be set. For example, in the case of a text field used
605+ * to enter the name of a city, the accessibleName for the en_US locale
606+ * could be 'city.'
607+ *
608+ * @return the localized name of the object; null if this
609+ * object does not have a name
610+ *
611+ * @see #setAccessibleName
612+ */
613+ public String getAccessibleName() {
614+ if (accessibleName != null) { // defined in AccessibleContext
615+ return accessibleName;
616+ } else if (accessibleJOptionPane != null) {
617+ // delegate to the AccessibleJOptionPane
618+ return accessibleJOptionPane.getAccessibleName();
619+ }
620+ return null;
621+ }
622+
623+ /**
624+ * Gets the accessibleDescription property of this object. The
625+ * accessibleDescription property of this object is a short localized
626+ * phrase describing the purpose of the object. For example, in the
627+ * case of a 'Cancel' button, the accessibleDescription could be
628+ * 'Ignore changes and close dialog box.'
629+ *
630+ * @return the localized description of the object; null if
631+ * this object does not have a description
632+ *
633+ * @see #setAccessibleDescription
634+ */
635+ public String getAccessibleDescription() {
636+ if (accessibleDescription != null) { // defined in AccessibleContext
637+ return accessibleDescription;
638+ } else if (accessibleJOptionPane != null) {
639+ // delegate to the AccessibleJOptionPane
640+ return accessibleJOptionPane.getAccessibleDescription();
641+ }
642+ return null;
643+ }
644+
645+ /**
646+ * Gets the role of this object. The role of the object is the generic
647+ * purpose or use of the class of this object. For example, the role
648+ * of a push button is AccessibleRole.PUSH_BUTTON. The roles in
649+ * AccessibleRole are provided so component developers can pick from
650+ * a set of predefined roles. This enables assistive technologies to
651+ * provide a consistent interface to various tweaked subclasses of
652+ * components (e.g., use AccessibleRole.PUSH_BUTTON for all components
653+ * that act like a push button) as well as distinguish between sublasses
654+ * that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
655+ * and AccessibleRole.RADIO_BUTTON for radio buttons).
656+ * <p>Note that the AccessibleRole class is also extensible, so
657+ * custom component developers can define their own AccessibleRole's
658+ * if the set of predefined roles is inadequate.
659+ *
660+ * @return an instance of AccessibleRole describing the role of the object
661+ * @see AccessibleRole
662+ */
663+ public AccessibleRole getAccessibleRole() {
664+ return AccessibleRole.PROGRESS_MONITOR;
665+ }
666+
667+ /**
668+ * Gets the state set of this object. The AccessibleStateSet of an object
669+ * is composed of a set of unique AccessibleStates. A change in the
670+ * AccessibleStateSet of an object will cause a PropertyChangeEvent to
671+ * be fired for the ACCESSIBLE_STATE_PROPERTY property.
672+ *
673+ * @return an instance of AccessibleStateSet containing the
674+ * current state set of the object
675+ * @see AccessibleStateSet
676+ * @see AccessibleState
677+ * @see #addPropertyChangeListener
678+ */
679+ public AccessibleStateSet getAccessibleStateSet() {
680+ if (accessibleJOptionPane != null) {
681+ // delegate to the AccessibleJOptionPane
682+ return accessibleJOptionPane.getAccessibleStateSet();
683+ }
684+ return null;
685+ }
686+
687+ /**
688+ * Gets the Accessible parent of this object.
689+ *
690+ * @return the Accessible parent of this object; null if this
691+ * object does not have an Accessible parent
692+ */
693+ public Accessible getAccessibleParent() {
694+ return dialog;
695+ }
696+
697+ /*
698+ * Returns the parent AccessibleContext
699+ */
700+ private AccessibleContext getParentAccessibleContext() {
701+ if (dialog != null) {
702+ return dialog.getAccessibleContext();
703+ }
704+ return null;
705+ }
706+
707+ /**
708+ * Gets the 0-based index of this object in its accessible parent.
709+ *
710+ * @return the 0-based index of this object in its parent; -1 if this
711+ * object does not have an accessible parent.
712+ *
713+ * @see #getAccessibleParent
714+ * @see #getAccessibleChildrenCount
715+ * @see #getAccessibleChild
716+ */
717+ public int getAccessibleIndexInParent() {
718+ if (accessibleJOptionPane != null) {
719+ // delegate to the AccessibleJOptionPane
720+ return accessibleJOptionPane.getAccessibleIndexInParent();
721+ }
722+ return -1;
723+ }
724+
725+ /**
726+ * Returns the number of accessible children of the object.
727+ *
728+ * @return the number of accessible children of the object.
729+ */
730+ public int getAccessibleChildrenCount() {
731+ // return the number of children in the JPanel containing
732+ // the message, note label and progress bar
733+ AccessibleContext ac = getPanelAccessibleContext();
734+ if (ac != null) {
735+ return ac.getAccessibleChildrenCount();
736+ }
737+ return 0;
738+ }
739+
740+ /**
741+ * Returns the specified Accessible child of the object. The Accessible
742+ * children of an Accessible object are zero-based, so the first child
743+ * of an Accessible child is at index 0, the second child is at index 1,
744+ * and so on.
745+ *
746+ * @param i zero-based index of child
747+ * @return the Accessible child of the object
748+ * @see #getAccessibleChildrenCount
749+ */
750+ public Accessible getAccessibleChild(int i) {
751+ // return a child in the JPanel containing the message, note label
752+ // and progress bar
753+ AccessibleContext ac = getPanelAccessibleContext();
754+ if (ac != null) {
755+ return ac.getAccessibleChild(i);
756+ }
757+ return null;
758+ }
759+
760+ /*
761+ * Returns the AccessibleContext for the JPanel containing the
762+ * message, note label and progress bar
763+ */
764+ private AccessibleContext getPanelAccessibleContext() {
765+ if (myBar != null) {
766+ Component c = myBar.getParent();
767+ if (c instanceof Accessible) {
768+ return c.getAccessibleContext();
769+ }
770+ }
771+ return null;
772+ }
773+
774+ /**
775+ * Gets the locale of the component. If the component does not have a
776+ * locale, then the locale of its parent is returned.
777+ *
778+ * @return this component's locale. If this component does not have
779+ * a locale, the locale of its parent is returned.
780+ *
781+ * @exception IllegalComponentStateException
782+ * If the Component does not have its own locale and has not yet been
783+ * added to a containment hierarchy such that the locale can be
784+ * determined from the containing parent.
785+ */
786+ public Locale getLocale() throws IllegalComponentStateException {
787+ if (accessibleJOptionPane != null) {
788+ // delegate to the AccessibleJOptionPane
789+ return accessibleJOptionPane.getLocale();
790+ }
791+ return null;
792+ }
793+
794+ /* ===== end AccessibleContext ===== */
795+
796+ /**
797+ * Gets the AccessibleComponent associated with this object that has a
798+ * graphical representation.
799+ *
800+ * @return AccessibleComponent if supported by object; else return null
801+ * @see AccessibleComponent
802+ */
803+ public AccessibleComponent getAccessibleComponent() {
804+ if (accessibleJOptionPane != null) {
805+ // delegate to the AccessibleJOptionPane
806+ return accessibleJOptionPane.getAccessibleComponent();
807+ }
808+ return null;
809+ }
810+
811+ /**
812+ * Gets the AccessibleValue associated with this object that supports a
813+ * Numerical value.
814+ *
815+ * @return AccessibleValue if supported by object; else return null
816+ * @see AccessibleValue
817+ */
818+ public AccessibleValue getAccessibleValue() {
819+ if (myBar != null) {
820+ // delegate to the AccessibleJProgressBar
821+ return myBar.getAccessibleContext().getAccessibleValue();
822+ }
823+ return null;
824+ }
825+
826+ /**
827+ * Gets the AccessibleText associated with this object presenting
828+ * text on the display.
829+ *
830+ * @return AccessibleText if supported by object; else return null
831+ * @see AccessibleText
832+ */
833+ public AccessibleText getAccessibleText() {
834+ if (getNoteLabelAccessibleText() != null) {
835+ return this;
836+ }
837+ return null;
838+ }
839+
840+ /*
841+ * Returns the note label AccessibleText
842+ */
843+ private AccessibleText getNoteLabelAccessibleText() {
844+ if (noteLabel != null) {
845+ // AccessibleJLabel implements AccessibleText if the
846+ // JLabel contains HTML text
847+ return noteLabel.getAccessibleContext().getAccessibleText();
848+ }
849+ return null;
850+ }
851+
852+ /* ===== Begin AccessibleText impl ===== */
853+
854+ /**
855+ * Given a point in local coordinates, return the zero-based index
856+ * of the character under that Point. If the point is invalid,
857+ * this method returns -1.
858+ *
859+ * @param p the Point in local coordinates
860+ * @return the zero-based index of the character under Point p; if
861+ * Point is invalid return -1.
862+ */
863+ public int getIndexAtPoint(Point p) {
864+ AccessibleText at = getNoteLabelAccessibleText();
865+ if (at != null && sameWindowAncestor(pane, noteLabel)) {
866+ // convert point from the option pane bounds
867+ // to the note label bounds.
868+ Point noteLabelPoint = SwingUtilities.convertPoint(pane,
869+ p,
870+ noteLabel);
871+ if (noteLabelPoint != null) {
872+ return at.getIndexAtPoint(noteLabelPoint);
873+ }
874+ }
875+ return -1;
876+ }
877+
878+ /**
879+ * Determines the bounding box of the character at the given
880+ * index into the string. The bounds are returned in local
881+ * coordinates. If the index is invalid an empty rectangle is returned.
882+ *
883+ * @param i the index into the String
884+ * @return the screen coordinates of the character's bounding box,
885+ * if index is invalid return an empty rectangle.
886+ */
887+ public Rectangle getCharacterBounds(int i) {
888+ AccessibleText at = getNoteLabelAccessibleText();
889+ if (at != null && sameWindowAncestor(pane, noteLabel)) {
890+ // return rectangle in the option pane bounds
891+ Rectangle noteLabelRect = at.getCharacterBounds(i);
892+ if (noteLabelRect != null) {
893+ return SwingUtilities.convertRectangle(noteLabel,
894+ noteLabelRect,
895+ pane);
896+ }
897+ }
898+ return null;
899+ }
900+
901+ /*
902+ * Returns whether source and destination components have the
903+ * same window ancestor
904+ */
905+ private boolean sameWindowAncestor(Component src, Component dest) {
906+ if (src == null || dest == null) {
907+ return false;
908+ }
909+ return SwingUtilities.getWindowAncestor(src) ==
910+ SwingUtilities.getWindowAncestor(dest);
911+ }
912+
913+ /**
914+ * Returns the number of characters (valid indicies)
915+ *
916+ * @return the number of characters
917+ */
918+ public int getCharCount() {
919+ AccessibleText at = getNoteLabelAccessibleText();
920+ if (at != null) { // JLabel contains HTML text
921+ return at.getCharCount();
922+ }
923+ return -1;
924+ }
925+
926+ /**
927+ * Returns the zero-based offset of the caret.
928+ *
929+ * Note: That to the right of the caret will have the same index
930+ * value as the offset (the caret is between two characters).
931+ * @return the zero-based offset of the caret.
932+ */
933+ public int getCaretPosition() {
934+ AccessibleText at = getNoteLabelAccessibleText();
935+ if (at != null) { // JLabel contains HTML text
936+ return at.getCaretPosition();
937+ }
938+ return -1;
939+ }
940+
941+ /**
942+ * Returns the String at a given index.
943+ *
944+ * @param part the CHARACTER, WORD, or SENTENCE to retrieve
945+ * @param index an index within the text
946+ * @return the letter, word, or sentence
947+ */
948+ public String getAtIndex(int part, int index) {
949+ AccessibleText at = getNoteLabelAccessibleText();
950+ if (at != null) { // JLabel contains HTML text
951+ return at.getAtIndex(part, index);
952+ }
953+ return null;
954+ }
955+
956+ /**
957+ * Returns the String after a given index.
958+ *
959+ * @param part the CHARACTER, WORD, or SENTENCE to retrieve
960+ * @param index an index within the text
961+ * @return the letter, word, or sentence
962+ */
963+ public String getAfterIndex(int part, int index) {
964+ AccessibleText at = getNoteLabelAccessibleText();
965+ if (at != null) { // JLabel contains HTML text
966+ return at.getAfterIndex(part, index);
967+ }
968+ return null;
969+ }
970+
971+ /**
972+ * Returns the String before a given index.
973+ *
974+ * @param part the CHARACTER, WORD, or SENTENCE to retrieve
975+ * @param index an index within the text
976+ * @return the letter, word, or sentence
977+ */
978+ public String getBeforeIndex(int part, int index) {
979+ AccessibleText at = getNoteLabelAccessibleText();
980+ if (at != null) { // JLabel contains HTML text
981+ return at.getBeforeIndex(part, index);
982+ }
983+ return null;
984+ }
985+
986+ /**
987+ * Returns the AttributeSet for a given character at a given index
988+ *
989+ * @param i the zero-based index into the text
990+ * @return the AttributeSet of the character
991+ */
992+ public AttributeSet getCharacterAttribute(int i) {
993+ AccessibleText at = getNoteLabelAccessibleText();
994+ if (at != null) { // JLabel contains HTML text
995+ return at.getCharacterAttribute(i);
996+ }
997+ return null;
998+ }
999+
1000+ /**
1001+ * Returns the start offset within the selected text.
1002+ * If there is no selection, but there is
1003+ * a caret, the start and end offsets will be the same.
1004+ *
1005+ * @return the index into the text of the start of the selection
1006+ */
1007+ public int getSelectionStart() {
1008+ AccessibleText at = getNoteLabelAccessibleText();
1009+ if (at != null) { // JLabel contains HTML text
1010+ return at.getSelectionStart();
1011+ }
1012+ return -1;
1013+ }
1014+
1015+ /**
1016+ * Returns the end offset within the selected text.
1017+ * If there is no selection, but there is
1018+ * a caret, the start and end offsets will be the same.
1019+ *
1020+ * @return the index into teh text of the end of the selection
1021+ */
1022+ public int getSelectionEnd() {
1023+ AccessibleText at = getNoteLabelAccessibleText();
1024+ if (at != null) { // JLabel contains HTML text
1025+ return at.getSelectionEnd();
1026+ }
1027+ return -1;
1028+ }
1029+
1030+ /**
1031+ * Returns the portion of the text that is selected.
1032+ *
1033+ * @return the String portion of the text that is selected
1034+ */
1035+ public String getSelectedText() {
1036+ AccessibleText at = getNoteLabelAccessibleText();
1037+ if (at != null) { // JLabel contains HTML text
1038+ return at.getSelectedText();
1039+ }
1040+ return null;
1041+ }
1042+ /* ===== End AccessibleText impl ===== */
1043+ }
1044+ // inner class AccessibleProgressMonitor
1045+
1046+}