return TextComponentPrintable.getPrintable( this, headerFormat, footerFormat); } /////////////////// Accessibility support//////////////// /** * Gets the <code>AccessibleContext</code> associated with this * <code>JTextComponent</code>. For text components, * the <code>AccessibleContext</code> takes the form of an * <code>AccessibleJTextComponent</code>. * A new <code>AccessibleJTextComponent</code> instance * is created if necessary. * * @return an <code>AccessibleJTextComponent</code> that serves as the * <code>AccessibleContext</code> of this * <code>JTextComponent</code> */ public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessibleJTextComponent(); } return accessibleContext; } /** * This class implements accessibility support for the * <code>JTextComponent</code> class. It provides an implementation of * the Java Accessibility API appropriate to menu user-interface elements. * <p> * <strong>Warning:</strong> * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing. As of 1.4, support for long term storage * of all JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */ public class AccessibleJTextComponent extends AccessibleJComponent implements AccessibleText, CaretListener, DocumentListener, AccessibleAction, AccessibleEditableText, AccessibleExtendedText { int caretPos; Point oldLocationOnScreen; /** * Constructs an AccessibleJTextComponent. Adds a listener to track * caret change. */ public AccessibleJTextComponent() { Document doc = JTextComponent.this.getDocument(); if (doc != null) { doc.addDocumentListener(this); } JTextComponent.this.addCaretListener(this); caretPos = getCaretPosition(); try { oldLocationOnScreen = getLocationOnScreen(); } catch (IllegalComponentStateException iae) { } // Fire a ACCESSIBLE_VISIBLE_DATA_PROPERTY PropertyChangeEvent // when the text component moves (e.g., when scrolling). // Using an anonymous class since making AccessibleJTextComponent // implement ComponentListener would be an API change. JTextComponent.this.addComponentListener(new ComponentAdapter() { public void componentMoved(ComponentEvent e) { try { Point newLocationOnScreen = getLocationOnScreen(); firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, oldLocationOnScreen, newLocationOnScreen); oldLocationOnScreen = newLocationOnScreen; } catch (IllegalComponentStateException iae) { } } }); } /** * Handles caret updates (fire appropriate property change event, * which are AccessibleContext.ACCESSIBLE_CARET_PROPERTY and * AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY). * This keeps track of the dot position internally. When the caret * moves, the internal position is updated after firing the event. * * @param e the CaretEvent */ public void caretUpdate(CaretEvent e) { int dot = e.getDot(); int mark = e.getMark(); if (caretPos != dot) { // the caret moved firePropertyChange(ACCESSIBLE_CARET_PROPERTY, new Integer(caretPos), new Integer(dot)); caretPos = dot; try { oldLocationOnScreen = getLocationOnScreen(); } catch (IllegalComponentStateException iae) { } } if (mark != dot) { // there is a selection firePropertyChange(ACCESSIBLE_SELECTION_PROPERTY, null, getSelectedText()); } } // DocumentListener methods /** * Handles document insert (fire appropriate property change event * which is AccessibleContext.ACCESSIBLE_TEXT_PROPERTY). * This tracks the changed offset via the event. * * @param e the DocumentEvent */ public void insertUpdate(DocumentEvent e) { final Integer pos = new Integer (e.getOffset()); if (SwingUtilities.isEventDispatchThread()) { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } else { Runnable doFire = new Runnable() { public void run() { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } }; SwingUtilities.invokeLater(doFire); } } /** * Handles document remove (fire appropriate property change event, * which is AccessibleContext.ACCESSIBLE_TEXT_PROPERTY). * This tracks the changed offset via the event. * * @param e the DocumentEvent */ public void removeUpdate(DocumentEvent e) { final Integer pos = new Integer (e.getOffset()); if (SwingUtilities.isEventDispatchThread()) { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } else { Runnable doFire = new Runnable() { public void run() { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } }; SwingUtilities.invokeLater(doFire); } } /** * Handles document remove (fire appropriate property change event, * which is AccessibleContext.ACCESSIBLE_TEXT_PROPERTY). * This tracks the changed offset via the event. * * @param e the DocumentEvent */ public void changedUpdate(DocumentEvent e) { final Integer pos = new Integer (e.getOffset()); if (SwingUtilities.isEventDispatchThread()) { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } else { Runnable doFire = new Runnable() { public void run() { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } }; SwingUtilities.invokeLater(doFire); } } /** * Gets the state set of the JTextComponent. * The AccessibleStateSet of an object is composed of a set of * unique AccessibleState's. A change in the AccessibleStateSet * of an object will cause a PropertyChangeEvent to be fired * for the AccessibleContext.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() { AccessibleStateSet states = super.getAccessibleStateSet(); if (JTextComponent.this.isEditable()) { states.add(AccessibleState.EDITABLE); } return states; } /** * Gets the role of this object. * * @return an instance of AccessibleRole describing the role of the * object (AccessibleRole.TEXT) * @see AccessibleRole */ public AccessibleRole getAccessibleRole() { return AccessibleRole.TEXT; } /** * Get the AccessibleText associated with this object. In the * implementation of the Java Accessibility API for this class, * return this object, which is responsible for implementing the * AccessibleText interface on behalf of itself. * * @return this object */ public AccessibleText getAccessibleText() { return this; } // --- interface AccessibleText methods ------------------------ /** * Many of these methods are just convenience methods; they * just call the equivalent on the parent */ /** * 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. */ public int getIndexAtPoint(Point p) { if (p == null) { return -1; } return JTextComponent.this.viewToModel(p); } /** * Gets the editor's drawing rectangle. Stolen * from the unfortunately named * BasicTextUI.getVisibleEditorRect() * * @return the bounding box for the root view */ Rectangle getRootEditorRect() { Rectangle alloc = JTextComponent.this.getBounds(); if ((alloc.width > 0) && (alloc.height > 0)) { alloc.x = alloc.y = 0; Insets insets = JTextComponent.this.getInsets(); alloc.x += insets.left; alloc.y += insets.top; alloc.width -= insets.left + insets.right; alloc.height -= insets.top + insets.bottom; return alloc; } return null; } /** * 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 a null rectangle * is returned. * * The screen coordinates returned are "unscrolled coordinates" * if the JTextComponent is contained in a JScrollPane in which * case the resulting rectangle should be composed with the parent * coordinates. A good algorithm to use is: * <nf> * Accessible a: * AccessibleText at = a.getAccessibleText(); * AccessibleComponent ac = a.getAccessibleComponent(); * Rectangle r = at.getCharacterBounds(); * Point p = ac.getLocation(); * r.x += p.x; * r.y += p.y; * </nf> * * Note: the JTextComponent must have a valid size (e.g. have * been added to a parent container whose ancestor container * is a valid top-level window) for this method to be able * to return a meaningful (non-null) value. * * @param i the index into the String >= 0 * @return the screen coordinates of the character's bounding box */ public Rectangle getCharacterBounds(int i) { if (i < 0 || i > model.getLength()-1) { return null; } TextUI ui = getUI(); if (ui == null) { return null; } Rectangle rect = null; Rectangle alloc = getRootEditorRect(); if (alloc == null) { return null; } if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { View rootView = ui.getRootView(JTextComponent.this); if (rootView != null) { rootView.setSize(alloc.width, alloc.height); Shape bounds = rootView.modelToView(i, Position.Bias.Forward, i+1, Position.Bias.Backward, alloc); rect = (bounds instanceof Rectangle) ? (Rectangle)bounds : bounds.getBounds(); } } catch (BadLocationException e) { } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return rect; } /** * Returns the number of characters (valid indices) * * @return the number of characters >= 0 */ public int getCharCount() { return model.getLength(); } /** * Returns the zero-based offset of the caret. * * Note: The character 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() { return JTextComponent.this.getCaretPosition(); } /** * 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) { Element e = null; if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { for (e = model.getDefaultRootElement(); ! e.isLeaf(); ) { int index = e.getElementIndex(i); e = e.getElement(index); } } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return e.getAttributes(); } /** * 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 0 if the text is empty, or the caret position * if no selection. * * @return the index into the text of the start of the selection >= 0 */ public int getSelectionStart() { return JTextComponent.this.getSelectionStart(); } /** * 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 0 if the text is empty, or the caret position * if no selection. * * @return the index into teh text of the end of the selection >= 0 */ public int getSelectionEnd() { return JTextComponent.this.getSelectionEnd(); } /** * Returns the portion of the text that is selected. * * @return the text, null if no selection */ public String getSelectedText() { return JTextComponent.this.getSelectedText(); } /** * IndexedSegment extends Segment adding the offset into the * the model the <code>Segment</code> was asked for. */ private class IndexedSegment extends Segment { /** * Offset into the model that the position represents. */ public int modelOffset; } // TIGER - 4170173 /** * Returns the String at a given index. Whitespace * between words is treated as a word. * * @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) { return getAtIndex(part, index, 0); } /** * Returns the String after a given index. Whitespace * between words is treated as a word. * * @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) { return getAtIndex(part, index, 1); } /** * Returns the String before a given index. Whitespace * between words is treated a word. * * @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) { return getAtIndex(part, index, -1); } /** * Gets the word, sentence, or character at <code>index</code>. * If <code>direction</code> is non-null this will find the * next/previous word/sentence/character. */ private String getAtIndex(int part, int index, int direction) { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { if (index < 0 || index >= model.getLength()) { return null; } switch (part) { case AccessibleText.CHARACTER: if (index + direction < model.getLength() && index + direction >= 0) { return model.getText(index + direction, 1); } break; case AccessibleText.WORD: case AccessibleText.SENTENCE:Lines 2501–3000 of 5073. Previous lines Load more
return TextComponentPrintable.getPrintable( this, headerFormat, footerFormat); } ///////////////// // Accessibility support //////////////// /** * Gets the <code>AccessibleContext</code> associated with this * <code>JTextComponent</code>. For text components, * the <code>AccessibleContext</code> takes the form of an * <code>AccessibleJTextComponent</code>. * A new <code>AccessibleJTextComponent</code> instance * is created if necessary. * * @return an <code>AccessibleJTextComponent</code> that serves as the * <code>AccessibleContext</code> of this * <code>JTextComponent</code> */ public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessibleJTextComponent(); } return accessibleContext; } /** * This class implements accessibility support for the * <code>JTextComponent</code> class. It provides an implementation of * the Java Accessibility API appropriate to menu user-interface elements. * <p> * <strong>Warning:</strong> * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing. As of 1.4, support for long term storage * of all JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */ public class AccessibleJTextComponent extends AccessibleJComponent implements AccessibleText, CaretListener, DocumentListener, AccessibleAction, AccessibleEditableText, AccessibleExtendedText { int caretPos; Point oldLocationOnScreen; /** * Constructs an AccessibleJTextComponent. Adds a listener to track * caret change. */ public AccessibleJTextComponent() { Document doc = JTextComponent.this.getDocument(); if (doc != null) { doc.addDocumentListener(this); } JTextComponent.this.addCaretListener(this); caretPos = getCaretPosition(); try { oldLocationOnScreen = getLocationOnScreen(); } catch (IllegalComponentStateException iae) { } // Fire a ACCESSIBLE_VISIBLE_DATA_PROPERTY PropertyChangeEvent // when the text component moves (e.g., when scrolling). // Using an anonymous class since making AccessibleJTextComponent // implement ComponentListener would be an API change. JTextComponent.this.addComponentListener(new ComponentAdapter() { public void componentMoved(ComponentEvent e) { try { Point newLocationOnScreen = getLocationOnScreen(); firePropertyChange(ACCESSIBLE_VISIBLE_DATA_PROPERTY, oldLocationOnScreen, newLocationOnScreen); oldLocationOnScreen = newLocationOnScreen; } catch (IllegalComponentStateException iae) { } } }); } /** * Handles caret updates (fire appropriate property change event, * which are AccessibleContext.ACCESSIBLE_CARET_PROPERTY and * AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY). * This keeps track of the dot position internally. When the caret * moves, the internal position is updated after firing the event. * * @param e the CaretEvent */ public void caretUpdate(CaretEvent e) { int dot = e.getDot(); int mark = e.getMark(); if (caretPos != dot) { // the caret moved firePropertyChange(ACCESSIBLE_CARET_PROPERTY, new Integer(caretPos), new Integer(dot)); caretPos = dot; try { oldLocationOnScreen = getLocationOnScreen(); } catch (IllegalComponentStateException iae) { } } if (mark != dot) { // there is a selection firePropertyChange(ACCESSIBLE_SELECTION_PROPERTY, null, getSelectedText()); } } // DocumentListener methods /** * Handles document insert (fire appropriate property change event * which is AccessibleContext.ACCESSIBLE_TEXT_PROPERTY). * This tracks the changed offset via the event. * * @param e the DocumentEvent */ public void insertUpdate(DocumentEvent e) { final Integer pos = new Integer (e.getOffset()); if (SwingUtilities.isEventDispatchThread()) { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } else { Runnable doFire = new Runnable() { public void run() { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } }; SwingUtilities.invokeLater(doFire); } } /** * Handles document remove (fire appropriate property change event, * which is AccessibleContext.ACCESSIBLE_TEXT_PROPERTY). * This tracks the changed offset via the event. * * @param e the DocumentEvent */ public void removeUpdate(DocumentEvent e) { final Integer pos = new Integer (e.getOffset()); if (SwingUtilities.isEventDispatchThread()) { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } else { Runnable doFire = new Runnable() { public void run() { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } }; SwingUtilities.invokeLater(doFire); } } /** * Handles document remove (fire appropriate property change event, * which is AccessibleContext.ACCESSIBLE_TEXT_PROPERTY). * This tracks the changed offset via the event. * * @param e the DocumentEvent */ public void changedUpdate(DocumentEvent e) { final Integer pos = new Integer (e.getOffset()); if (SwingUtilities.isEventDispatchThread()) { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } else { Runnable doFire = new Runnable() { public void run() { firePropertyChange(ACCESSIBLE_TEXT_PROPERTY, null, pos); } }; SwingUtilities.invokeLater(doFire); } } /** * Gets the state set of the JTextComponent. * The AccessibleStateSet of an object is composed of a set of * unique AccessibleState's. A change in the AccessibleStateSet * of an object will cause a PropertyChangeEvent to be fired * for the AccessibleContext.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() { AccessibleStateSet states = super.getAccessibleStateSet(); if (JTextComponent.this.isEditable()) { states.add(AccessibleState.EDITABLE); } return states; } /** * Gets the role of this object. * * @return an instance of AccessibleRole describing the role of the * object (AccessibleRole.TEXT) * @see AccessibleRole */ public AccessibleRole getAccessibleRole() { return AccessibleRole.TEXT; } /** * Get the AccessibleText associated with this object. In the * implementation of the Java Accessibility API for this class, * return this object, which is responsible for implementing the * AccessibleText interface on behalf of itself. * * @return this object */ public AccessibleText getAccessibleText() { return this; } // --- interface AccessibleText methods ------------------------ /** * Many of these methods are just convenience methods; they * just call the equivalent on the parent */ /** * 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. */ public int getIndexAtPoint(Point p) { if (p == null) { return -1; } return JTextComponent.this.viewToModel(p); } /** * Gets the editor's drawing rectangle. Stolen * from the unfortunately named * BasicTextUI.getVisibleEditorRect() * * @return the bounding box for the root view */ Rectangle getRootEditorRect() { Rectangle alloc = JTextComponent.this.getBounds(); if ((alloc.width > 0) && (alloc.height > 0)) { alloc.x = alloc.y = 0; Insets insets = JTextComponent.this.getInsets(); alloc.x += insets.left; alloc.y += insets.top; alloc.width -= insets.left + insets.right; alloc.height -= insets.top + insets.bottom; return alloc; } return null; } /** * 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 a null rectangle * is returned. * * The screen coordinates returned are "unscrolled coordinates" * if the JTextComponent is contained in a JScrollPane in which * case the resulting rectangle should be composed with the parent * coordinates. A good algorithm to use is: * <nf> * Accessible a: * AccessibleText at = a.getAccessibleText(); * AccessibleComponent ac = a.getAccessibleComponent(); * Rectangle r = at.getCharacterBounds(); * Point p = ac.getLocation(); * r.x += p.x; * r.y += p.y; * </nf> * * Note: the JTextComponent must have a valid size (e.g. have * been added to a parent container whose ancestor container * is a valid top-level window) for this method to be able * to return a meaningful (non-null) value. * * @param i the index into the String >= 0 * @return the screen coordinates of the character's bounding box */ public Rectangle getCharacterBounds(int i) { if (i < 0 || i > model.getLength()-1) { return null; } TextUI ui = getUI(); if (ui == null) { return null; } Rectangle rect = null; Rectangle alloc = getRootEditorRect(); if (alloc == null) { return null; } if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { View rootView = ui.getRootView(JTextComponent.this); if (rootView != null) { rootView.setSize(alloc.width, alloc.height); Shape bounds = rootView.modelToView(i, Position.Bias.Forward, i+1, Position.Bias.Backward, alloc); rect = (bounds instanceof Rectangle) ? (Rectangle)bounds : bounds.getBounds(); } } catch (BadLocationException e) { } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return rect; } /** * Returns the number of characters (valid indices) * * @return the number of characters >= 0 */ public int getCharCount() { return model.getLength(); } /** * Returns the zero-based offset of the caret. * * Note: The character 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() { return JTextComponent.this.getCaretPosition(); } /** * 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) { Element e = null; if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { for (e = model.getDefaultRootElement(); ! e.isLeaf(); ) { int index = e.getElementIndex(i); e = e.getElement(index); } } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return e.getAttributes(); } /** * 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 0 if the text is empty, or the caret position * if no selection. * * @return the index into the text of the start of the selection >= 0 */ public int getSelectionStart() { return JTextComponent.this.getSelectionStart(); } /** * 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 0 if the text is empty, or the caret position * if no selection. * * @return the index into teh text of the end of the selection >= 0 */ public int getSelectionEnd() { return JTextComponent.this.getSelectionEnd(); } /** * Returns the portion of the text that is selected. * * @return the text, null if no selection */ public String getSelectedText() { return JTextComponent.this.getSelectedText(); } /** * IndexedSegment extends Segment adding the offset into the * the model the <code>Segment</code> was asked for. */ private class IndexedSegment extends Segment { /** * Offset into the model that the position represents. */ public int modelOffset; } // TIGER - 4170173 /** * Returns the String at a given index. Whitespace * between words is treated as a word. * * @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) { return getAtIndex(part, index, 0); } /** * Returns the String after a given index. Whitespace * between words is treated as a word. * * @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) { return getAtIndex(part, index, 1); } /** * Returns the String before a given index. Whitespace * between words is treated a word. * * @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) { return getAtIndex(part, index, -1); } /** * Gets the word, sentence, or character at <code>index</code>. * If <code>direction</code> is non-null this will find the * next/previous word/sentence/character. */ private String getAtIndex(int part, int index, int direction) { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { if (index < 0 || index >= model.getLength()) { return null; } switch (part) { case AccessibleText.CHARACTER: if (index + direction < model.getLength() && index + direction >= 0) { return model.getText(index + direction, 1); } break; case AccessibleText.WORD: case AccessibleText.SENTENCE: