/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.swing;
import java.io.*;
import java.awt.
BorderLayout;
import java.awt.
Frame;
import java.awt.
Dialog;
import java.awt.
Window;
import java.awt.
Component;
import java.awt.
Container;
import java.beans.
PropertyChangeEvent;
import java.beans.
PropertyChangeListener;
import java.awt.event.
WindowListener;
import java.awt.event.
WindowAdapter;
import java.awt.event.
WindowEvent;
import java.awt.
IllegalComponentStateException;
import java.awt.
Point;
import java.awt.
Rectangle;
import java.text.*;
import java.util.
Locale;
import javax.accessibility.*;
import javax.swing.event.*;
import javax.swing.text.*;
/** A class to monitor the progress of some operation. If it looks
* like the operation will take a while, a progress dialog will be popped up.
* When the ProgressMonitor is created it is given a numeric range and a
* descriptive string. As the operation progresses, call the setProgress method
* to indicate how far along the [min,max] range the operation is.
* Initially, there is no ProgressDialog. After the first millisToDecideToPopup
* milliseconds (default 500) the progress monitor will predict how long
* the operation will take. If it is longer than millisToPopup (default 2000,
* 2 seconds) a ProgressDialog will be popped up.
* <p>
* From time to time, when the Dialog box is visible, the progress bar will
* be updated when setProgress is called. setProgress won't always update
* the progress bar, it will only be done if the amount of progress is
* visibly significant.
*
* <p>
*
* For further documentation and examples see
* <a
href="https://docs.oracle.com/javase/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
* a section in <em>The Java Tutorial.</em>
*
* @see ProgressMonitorInputStream
* @author James Gosling
* @author Lynn Monsanto (accessibility)
*/
public class
ProgressMonitor implements
Accessible
{
private
ProgressMonitor root;
private
JDialog dialog;
private
JOptionPane pane;
private
JProgressBar myBar;
private
JLabel noteLabel;
private
Component parentComponent;
private
String note;
private
Object[]
cancelOption = null;
private
Object message;
private long
T0;
private int
millisToDecideToPopup = 500;
private int
millisToPopup = 2000;
private int
min;
private int
max;
/**
* Constructs a graphic object that shows progress, typically by filling
* in a rectangular bar as the process nears completion.
*
* @param parentComponent the parent component for the dialog box
* @param message a descriptive message that will be shown
* to the user to indicate what operation is being monitored.
* This does not change as the operation progresses.
* See the message parameters to methods in
* {@link JOptionPane#message}
* for the range of values.
* @param note a short note describing the state of the
* operation. As the operation progresses, you can call
* setNote to change the note displayed. This is used,
* for example, in operations that iterate through a
* list of files to show the name of the file being processes.
* If note is initially null, there will be no note line
* in the dialog box and setNote will be ineffective
* @param min the lower bound of the range
* @param max the upper bound of the range
* @see JDialog
* @see JOptionPane
*/
public
ProgressMonitor(
Component parentComponent,
Object message,
String note,
int
min,
int
max) {
this(
parentComponent,
message,
note,
min,
max, null);
}
private
ProgressMonitor(
Component parentComponent,
Object message,
String note,
int
min,
int
max,
ProgressMonitor group) {
this.
min =
min;
this.
max =
max;
this.
parentComponent =
parentComponent;
cancelOption = new
Object[1];
cancelOption[0] =
UIManager.
getString("OptionPane.cancelButtonText");
this.
message =
message;
this.
note =
note;
if (
group != null) {
root = (
group.
root != null) ?
group.
root :
group;
T0 =
root.
T0;
dialog =
root.
dialog;
}
else {
T0 =
System.
currentTimeMillis();
}
}
private class
ProgressOptionPane extends
JOptionPane
{
ProgressOptionPane(
Object messageList) {
super(
messageList,
JOptionPane.
INFORMATION_MESSAGE,
JOptionPane.
DEFAULT_OPTION,
null,
ProgressMonitor.this.
cancelOption,
null);
}
public int
getMaxCharactersPerLineCount() {
return 60;
}
// Equivalent to JOptionPane.createDialog,
// but create a modeless dialog.
// This is necessary because the Solaris implementation doesn't
// support Dialog.setModal yet.
public
JDialog createDialog(
Component parentComponent,
String title) {
final
JDialog dialog;
Window window =
JOptionPane.
getWindowForComponent(
parentComponent);
if (
window instanceof
Frame) {
dialog = new
JDialog((
Frame)
window,
title, false);
} else {
dialog = new
JDialog((
Dialog)
window,
title, false);
}
if (
window instanceof
SwingUtilities.
SharedOwnerFrame) {
WindowListener ownerShutdownListener =
SwingUtilities.
getSharedOwnerFrameShutdownListener();
dialog.
addWindowListener(
ownerShutdownListener);
}
Container contentPane =
dialog.
getContentPane();
contentPane.
setLayout(new
BorderLayout());
contentPane.
add(this,
BorderLayout.
CENTER);
dialog.
pack();
dialog.
setLocationRelativeTo(
parentComponent);
dialog.
addWindowListener(new
WindowAdapter() {
boolean
gotFocus = false;
public void
windowClosing(
WindowEvent we) {
setValue(
cancelOption[0]);
}
public void
windowActivated(
WindowEvent we) {
// Once window gets focus, set initial focus
if (!
gotFocus) {
selectInitialValue();
gotFocus = true;
}
}
});
addPropertyChangeListener(new
PropertyChangeListener() {
public void
propertyChange(
PropertyChangeEvent event) {
if(
dialog.
isVisible() &&
event.
getSource() ==
ProgressOptionPane.this &&
(
event.
getPropertyName().
equals(
VALUE_PROPERTY) ||
event.
getPropertyName().
equals(
INPUT_VALUE_PROPERTY))){
dialog.
setVisible(false);
dialog.
dispose();
}
}
});
return
dialog;
}
/////////////////
// Accessibility support for ProgressOptionPane
////////////////
/**
* Gets the AccessibleContext for the ProgressOptionPane
*
* @return the AccessibleContext for the ProgressOptionPane
* @since 1.5
*/
public
AccessibleContext getAccessibleContext() {
return
ProgressMonitor.this.
getAccessibleContext();
}
/*
* Returns the AccessibleJOptionPane
*/
private
AccessibleContext getAccessibleJOptionPane() {
return super.getAccessibleContext();
}
}
/**
* Indicate the progress of the operation being monitored.
* If the specified value is >= the maximum, the progress
* monitor is closed.
* @param nv an int specifying the current value, between the
* maximum and minimum specified for this component
* @see #setMinimum
* @see #setMaximum
* @see #close
*/
public void
setProgress(int
nv) {
if (
nv >=
max) {
close();
}
else {
if (
myBar != null) {
myBar.
setValue(
nv);
}
else {
long
T =
System.
currentTimeMillis();
long
dT = (int)(
T-
T0);
if (
dT >=
millisToDecideToPopup) {
int
predictedCompletionTime;
if (
nv >
min) {
predictedCompletionTime = (int)(
dT *
(
max -
min) /
(
nv -
min));
}
else {
predictedCompletionTime =
millisToPopup;
}
if (
predictedCompletionTime >=
millisToPopup) {
myBar = new
JProgressBar();
myBar.
setMinimum(
min);
myBar.
setMaximum(
max);
myBar.
setValue(
nv);
if (
note != null)
noteLabel = new
JLabel(
note);
pane = new
ProgressOptionPane(new
Object[] {
message,
noteLabel,
myBar});
dialog =
pane.
createDialog(
parentComponent,
UIManager.
getString(
"ProgressMonitor.progressText"));
dialog.
show();
}
}
}
}
}
/**
* Indicate that the operation is complete. This happens automatically
* when the value set by setProgress is >= max, but it may be called
* earlier if the operation ends early.
*/
public void
close() {
if (
dialog != null) {
dialog.
setVisible(false);
dialog.
dispose();
dialog = null;
pane = null;
myBar = null;
}
}
/**
* Returns the minimum value -- the lower end of the progress value.
*
* @return an int representing the minimum value
* @see #setMinimum
*/
public int
getMinimum() {
return
min;
}
/**
* Specifies the minimum value.
*
* @param m an int specifying the minimum value
* @see #getMinimum
*/
public void
setMinimum(int
m) {
if (
myBar != null) {
myBar.
setMinimum(
m);
}
min =
m;
}
/**
* Returns the maximum value -- the higher end of the progress value.
*
* @return an int representing the maximum value
* @see #setMaximum
*/
public int
getMaximum() {
return
max;
}
/**
* Specifies the maximum value.
*
* @param m an int specifying the maximum value
* @see #getMaximum
*/
public void
setMaximum(int
m) {
if (
myBar != null) {
myBar.
setMaximum(
m);
}
max =
m;
}
/**
* Returns true if the user hits the Cancel button in the progress dialog.
*/
public boolean
isCanceled() {
if (
pane == null) return false;
Object v =
pane.
getValue();
return ((
v != null) &&
(
cancelOption.length == 1) &&
(
v.
equals(
cancelOption[0])));
}
/**
* Specifies the amount of time to wait before deciding whether or
* not to popup a progress monitor.
*
* @param millisToDecideToPopup an int specifying the time to wait,
* in milliseconds
* @see #getMillisToDecideToPopup
*/
public void
setMillisToDecideToPopup(int
millisToDecideToPopup) {
this.
millisToDecideToPopup =
millisToDecideToPopup;
}
/**
* Returns the amount of time this object waits before deciding whether
* or not to popup a progress monitor.
*
* @see #setMillisToDecideToPopup
*/
public int
getMillisToDecideToPopup() {
return
millisToDecideToPopup;
}
/**
* Specifies the amount of time it will take for the popup to appear.
* (If the predicted time remaining is less than this time, the popup
* won't be displayed.)
*
* @param millisToPopup an int specifying the time in milliseconds
* @see #getMillisToPopup
*/
public void
setMillisToPopup(int
millisToPopup) {
this.
millisToPopup =
millisToPopup;
}
/**
* Returns the amount of time it will take for the popup to appear.
*
* @see #setMillisToPopup
*/
public int
getMillisToPopup() {
return
millisToPopup;
}
/**
* Specifies the additional note that is displayed along with the
* progress message. Used, for example, to show which file the
* is currently being copied during a multiple-file copy.
*
* @param note a String specifying the note to display
* @see #getNote
*/
public void
setNote(
String note) {
this.
note =
note;
if (
noteLabel != null) {
noteLabel.
setText(
note);
}
}
/**
* Specifies the additional note that is displayed along with the
* progress message.
*
* @return a String specifying the note to display
* @see #setNote
*/
public
String getNote() {
return
note;
}
/////////////////
// Accessibility support
////////////////
/**
* The <code>AccessibleContext</code> for the <code>ProgressMonitor</code>
* @since 1.5
*/
protected
AccessibleContext accessibleContext = null;
private
AccessibleContext accessibleJOptionPane = null;
/**
* Gets the <code>AccessibleContext</code> for the
* <code>ProgressMonitor</code>
*
* @return the <code>AccessibleContext</code> for the
* <code>ProgressMonitor</code>
* @since 1.5
*/
public
AccessibleContext getAccessibleContext() {
if (
accessibleContext == null) {
accessibleContext = new
AccessibleProgressMonitor();
}
if (
pane != null &&
accessibleJOptionPane == null) {
// Notify the AccessibleProgressMonitor that the
// ProgressOptionPane was created. It is necessary
// to poll for ProgressOptionPane creation because
// the ProgressMonitor does not have a Component
// to add a listener to until the ProgressOptionPane
// is created.
if (
accessibleContext instanceof
AccessibleProgressMonitor) {
((
AccessibleProgressMonitor)
accessibleContext).
optionPaneCreated();
}
}
return
accessibleContext;
}
/**
* <code>AccessibleProgressMonitor</code> implements accessibility
* support for the <code>ProgressMonitor</code> class.
* @since 1.5
*/
protected class
AccessibleProgressMonitor extends
AccessibleContext
implements
AccessibleText,
ChangeListener,
PropertyChangeListener {
/*
* The accessibility hierarchy for ProgressMonitor is a flattened
* version of the ProgressOptionPane component hierarchy.
*
* The ProgressOptionPane component hierarchy is:
* JDialog
* ProgressOptionPane
* JPanel
* JPanel
* JLabel
* JLabel
* JProgressBar
*
* The AccessibleProgessMonitor accessibility hierarchy is:
* AccessibleJDialog
* AccessibleProgressMonitor
* AccessibleJLabel
* AccessibleJLabel
* AccessibleJProgressBar
*
* The abstraction presented to assitive technologies by
* the AccessibleProgressMonitor is that a dialog contains a
* progress monitor with three children: a message, a note
* label and a progress bar.
*/
private
Object oldModelValue;
/**
* AccessibleProgressMonitor constructor
*/
protected
AccessibleProgressMonitor() {
}
/*
* Initializes the AccessibleContext now that the ProgressOptionPane
* has been created. Because the ProgressMonitor is not a Component
* implementing the Accessible interface, an AccessibleContext
* must be synthesized from the ProgressOptionPane and its children.
*
* For other AWT and Swing classes, the inner class that implements
* accessibility for the class extends the inner class that implements
* implements accessibility for the super class. AccessibleProgressMonitor
* cannot extend AccessibleJOptionPane and must therefore delegate calls
* to the AccessibleJOptionPane.
*/
private void
optionPaneCreated() {
accessibleJOptionPane =
((
ProgressOptionPane)
pane).
getAccessibleJOptionPane();
// add a listener for progress bar ChangeEvents
if (
myBar != null) {
myBar.
addChangeListener(this);
}
// add a listener for note label PropertyChangeEvents
if (
noteLabel != null) {
noteLabel.
addPropertyChangeListener(this);
}
}
/**
* Invoked when the target of the listener has changed its state.
*
* @param e a <code>ChangeEvent</code> object. Must not be null.
* @throws NullPointerException if the parameter is null.
*/
public void
stateChanged(
ChangeEvent e) {
if (
e == null) {
return;
}
if (
myBar != null) {
// the progress bar value changed
Object newModelValue =
myBar.
getValue();
firePropertyChange(
ACCESSIBLE_VALUE_PROPERTY,
oldModelValue,
newModelValue);
oldModelValue =
newModelValue;
}
}
/**
* This method gets called when a bound property is changed.
*
* @param e A <code>PropertyChangeEvent</code> object describing
* the event source and the property that has changed. Must not be null.
* @throws NullPointerException if the parameter is null.
*/
public void
propertyChange(
PropertyChangeEvent e) {
if (
e.
getSource() ==
noteLabel &&
e.
getPropertyName() == "text") {
// the note label text changed
firePropertyChange(
ACCESSIBLE_TEXT_PROPERTY, null, 0);
}
}
/* ===== Begin AccessileContext ===== */
/**
* Gets the accessibleName property of this object. The accessibleName
* property of an object is a localized String that designates the purpose
* of the object. For example, the accessibleName property of a label
* or button might be the text of the label or button itself. In the
* case of an object that doesn't display its name, the accessibleName
* should still be set. For example, in the case of a text field used
* to enter the name of a city, the accessibleName for the en_US locale
* could be 'city.'
*
* @return the localized name of the object; null if this
* object does not have a name
*
* @see #setAccessibleName
*/
public
String getAccessibleName() {
if (
accessibleName != null) { // defined in AccessibleContext
return
accessibleName;
} else if (
accessibleJOptionPane != null) {
// delegate to the AccessibleJOptionPane
return
accessibleJOptionPane.
getAccessibleName();
}
return null;
}
/**
* Gets the accessibleDescription property of this object. The
* accessibleDescription property of this object is a short localized
* phrase describing the purpose of the object. For example, in the
* case of a 'Cancel' button, the accessibleDescription could be
* 'Ignore changes and close dialog box.'
*
* @return the localized description of the object; null if
* this object does not have a description
*
* @see #setAccessibleDescription
*/
public
String getAccessibleDescription() {
if (
accessibleDescription != null) { // defined in AccessibleContext
return
accessibleDescription;
} else if (
accessibleJOptionPane != null) {
// delegate to the AccessibleJOptionPane
return
accessibleJOptionPane.
getAccessibleDescription();
}
return null;
}
/**
* Gets the role of this object. The role of the object is the generic
* purpose or use of the class of this object. For example, the role
* of a push button is AccessibleRole.PUSH_BUTTON. The roles in
* AccessibleRole are provided so component developers can pick from
* a set of predefined roles. This enables assistive technologies to
* provide a consistent interface to various tweaked subclasses of
* components (e.g., use AccessibleRole.PUSH_BUTTON for all components
* that act like a push button) as well as distinguish between subclasses
* that behave differently (e.g., AccessibleRole.CHECK_BOX for check boxes
* and AccessibleRole.RADIO_BUTTON for radio buttons).
* <p>Note that the AccessibleRole class is also extensible, so
* custom component developers can define their own AccessibleRole's
* if the set of predefined roles is inadequate.
*
* @return an instance of AccessibleRole describing the role of the object
* @see AccessibleRole
*/
public
AccessibleRole getAccessibleRole() {
return
AccessibleRole.
PROGRESS_MONITOR;
}
/**
* Gets the state set of this object. The AccessibleStateSet of an object
* is composed of a set of unique AccessibleStates. A change in the
* AccessibleStateSet of an object will cause a PropertyChangeEvent to
* be fired for the ACCESSIBLE_STATE_PROPERTY property.
*
* @return an instance of AccessibleStateSet containing the
* current state set of the object
* @see AccessibleStateSet
* @see AccessibleState
* @see #addPropertyChangeListener
*/
public
AccessibleStateSet getAccessibleStateSet() {
if (
accessibleJOptionPane != null) {
// delegate to the AccessibleJOptionPane
return
accessibleJOptionPane.
getAccessibleStateSet();
}
return null;
}
/**
* Gets the Accessible parent of this object.
*
* @return the Accessible parent of this object; null if this
* object does not have an Accessible parent
*/
public
Accessible getAccessibleParent() {
return
dialog;
}
/*
* Returns the parent AccessibleContext
*/
private
AccessibleContext getParentAccessibleContext() {
if (
dialog != null) {
return
dialog.
getAccessibleContext();
}
return null;
}
/**
* Gets the 0-based index of this object in its accessible parent.
*
* @return the 0-based index of this object in its parent; -1 if this
* object does not have an accessible parent.
*
* @see #getAccessibleParent
* @see #getAccessibleChildrenCount
* @see #getAccessibleChild
*/
public int
getAccessibleIndexInParent() {
if (
accessibleJOptionPane != null) {
// delegate to the AccessibleJOptionPane
return
accessibleJOptionPane.
getAccessibleIndexInParent();
}
return -1;
}
/**
* Returns the number of accessible children of the object.
*
* @return the number of accessible children of the object.
*/
public int
getAccessibleChildrenCount() {
// return the number of children in the JPanel containing
// the message, note label and progress bar
AccessibleContext ac =
getPanelAccessibleContext();
if (
ac != null) {
return
ac.
getAccessibleChildrenCount();
}
return 0;
}
/**
* Returns the specified Accessible child of the object. The Accessible
* children of an Accessible object are zero-based, so the first child
* of an Accessible child is at index 0, the second child is at index 1,
* and so on.
*
* @param i zero-based index of child
* @return the Accessible child of the object
* @see #getAccessibleChildrenCount
*/
public
Accessible getAccessibleChild(int
i) {
// return a child in the JPanel containing the message, note label
// and progress bar
AccessibleContext ac =
getPanelAccessibleContext();
if (
ac != null) {
return
ac.
getAccessibleChild(
i);
}
return null;
}
/*
* Returns the AccessibleContext for the JPanel containing the
* message, note label and progress bar
*/
private
AccessibleContext getPanelAccessibleContext() {
if (
myBar != null) {
Component c =
myBar.
getParent();
if (
c instanceof
Accessible) {
return
c.
getAccessibleContext();
}
}
return null;
}
/**
* Gets the locale of the component. If the component does not have a
* locale, then the locale of its parent is returned.
*
* @return this component's locale. If this component does not have
* a locale, the locale of its parent is returned.
*
* @exception IllegalComponentStateException
* If the Component does not have its own locale and has not yet been
* added to a containment hierarchy such that the locale can be
* determined from the containing parent.
*/
public
Locale getLocale() throws
IllegalComponentStateException {
if (
accessibleJOptionPane != null) {
// delegate to the AccessibleJOptionPane
return
accessibleJOptionPane.
getLocale();
}
return null;
}
/* ===== end AccessibleContext ===== */
/**
* Gets the AccessibleComponent associated with this object that has a
* graphical representation.
*
* @return AccessibleComponent if supported by object; else return null
* @see AccessibleComponent
*/
public
AccessibleComponent getAccessibleComponent() {
if (
accessibleJOptionPane != null) {
// delegate to the AccessibleJOptionPane
return
accessibleJOptionPane.
getAccessibleComponent();
}
return null;
}
/**
* Gets the AccessibleValue associated with this object that supports a
* Numerical value.
*
* @return AccessibleValue if supported by object; else return null
* @see AccessibleValue
*/
public
AccessibleValue getAccessibleValue() {
if (
myBar != null) {
// delegate to the AccessibleJProgressBar
return
myBar.
getAccessibleContext().
getAccessibleValue();
}
return null;
}
/**
* Gets the AccessibleText associated with this object presenting
* text on the display.
*
* @return AccessibleText if supported by object; else return null
* @see AccessibleText
*/
public
AccessibleText getAccessibleText() {
if (
getNoteLabelAccessibleText() != null) {
return this;
}
return null;
}
/*
* Returns the note label AccessibleText
*/
private
AccessibleText getNoteLabelAccessibleText() {
if (
noteLabel != null) {
// AccessibleJLabel implements AccessibleText if the
// JLabel contains HTML text
return
noteLabel.
getAccessibleContext().
getAccessibleText();
}
return null;
}
/* ===== Begin AccessibleText impl ===== */
/**
* Given a point in local coordinates, return the zero-based index
* of the character under that Point. If the point is invalid,
* this method returns -1.
*
* @param p the Point in local coordinates
* @return the zero-based index of the character under Point p; if
* Point is invalid return -1.
*/
public int
getIndexAtPoint(
Point p) {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null &&
sameWindowAncestor(
pane,
noteLabel)) {
// convert point from the option pane bounds
// to the note label bounds.
Point noteLabelPoint =
SwingUtilities.
convertPoint(
pane,
p,
noteLabel);
if (
noteLabelPoint != null) {
return
at.
getIndexAtPoint(
noteLabelPoint);
}
}
return -1;
}
/**
* Determines the bounding box of the character at the given
* index into the string. The bounds are returned in local
* coordinates. If the index is invalid an empty rectangle is returned.
*
* @param i the index into the String
* @return the screen coordinates of the character's bounding box,
* if index is invalid return an empty rectangle.
*/
public
Rectangle getCharacterBounds(int
i) {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null &&
sameWindowAncestor(
pane,
noteLabel)) {
// return rectangle in the option pane bounds
Rectangle noteLabelRect =
at.
getCharacterBounds(
i);
if (
noteLabelRect != null) {
return
SwingUtilities.
convertRectangle(
noteLabel,
noteLabelRect,
pane);
}
}
return null;
}
/*
* Returns whether source and destination components have the
* same window ancestor
*/
private boolean
sameWindowAncestor(
Component src,
Component dest) {
if (
src == null ||
dest == null) {
return false;
}
return
SwingUtilities.
getWindowAncestor(
src) ==
SwingUtilities.
getWindowAncestor(
dest);
}
/**
* Returns the number of characters (valid indicies)
*
* @return the number of characters
*/
public int
getCharCount() {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getCharCount();
}
return -1;
}
/**
* Returns the zero-based offset of the caret.
*
* Note: That to the right of the caret will have the same index
* value as the offset (the caret is between two characters).
* @return the zero-based offset of the caret.
*/
public int
getCaretPosition() {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getCaretPosition();
}
return -1;
}
/**
* Returns the String at a given index.
*
* @param part the CHARACTER, WORD, or SENTENCE to retrieve
* @param index an index within the text
* @return the letter, word, or sentence
*/
public
String getAtIndex(int
part, int
index) {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getAtIndex(
part,
index);
}
return null;
}
/**
* Returns the String after a given index.
*
* @param part the CHARACTER, WORD, or SENTENCE to retrieve
* @param index an index within the text
* @return the letter, word, or sentence
*/
public
String getAfterIndex(int
part, int
index) {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getAfterIndex(
part,
index);
}
return null;
}
/**
* Returns the String before a given index.
*
* @param part the CHARACTER, WORD, or SENTENCE to retrieve
* @param index an index within the text
* @return the letter, word, or sentence
*/
public
String getBeforeIndex(int
part, int
index) {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getBeforeIndex(
part,
index);
}
return null;
}
/**
* Returns the AttributeSet for a given character at a given index
*
* @param i the zero-based index into the text
* @return the AttributeSet of the character
*/
public
AttributeSet getCharacterAttribute(int
i) {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getCharacterAttribute(
i);
}
return null;
}
/**
* Returns the start offset within the selected text.
* If there is no selection, but there is
* a caret, the start and end offsets will be the same.
*
* @return the index into the text of the start of the selection
*/
public int
getSelectionStart() {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getSelectionStart();
}
return -1;
}
/**
* Returns the end offset within the selected text.
* If there is no selection, but there is
* a caret, the start and end offsets will be the same.
*
* @return the index into the text of the end of the selection
*/
public int
getSelectionEnd() {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getSelectionEnd();
}
return -1;
}
/**
* Returns the portion of the text that is selected.
*
* @return the String portion of the text that is selected
*/
public
String getSelectedText() {
AccessibleText at =
getNoteLabelAccessibleText();
if (
at != null) { // JLabel contains HTML text
return
at.
getSelectedText();
}
return null;
}
/* ===== End AccessibleText impl ===== */
}
// inner class AccessibleProgressMonitor
}