IndexedSegment seg = getSegmentAt(part, index); if (seg != null) { if (direction != 0) { int next; if (direction < 0) { next = seg.modelOffset - 1; } else { next = seg.modelOffset + direction * seg.count; } if (next >= 0 && next <= model.getLength()) { seg = getSegmentAt(part, next); } else { seg = null; } } if (seg != null) { return new String(seg.array, seg.offset, seg.count); } } break; default: break; } } catch (BadLocationException e) { } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return null; } /* * Returns the paragraph element for the specified index. */ private Element getParagraphElement(int index) { if (model instanceof PlainDocument ) { PlainDocument sdoc = (PlainDocument)model; return sdoc.getParagraphElement(index); } else if (model instanceof StyledDocument) { StyledDocument sdoc = (StyledDocument)model; return sdoc.getParagraphElement(index); } else { Element para; for (para = model.getDefaultRootElement(); ! para.isLeaf(); ) { int pos = para.getElementIndex(index); para = para.getElement(pos); } if (para == null) { return null; } return para.getParentElement(); } } /* * Returns a <code>Segment</code> containing the paragraph text * at <code>index</code>, or null if <code>index</code> isn't * valid. */ private IndexedSegment getParagraphElementText(int index) throws BadLocationException { Element para = getParagraphElement(index); if (para != null) { IndexedSegment segment = new IndexedSegment(); try { int length = para.getEndOffset() - para.getStartOffset(); model.getText(para.getStartOffset(), length, segment); } catch (BadLocationException e) { return null; } segment.modelOffset = para.getStartOffset(); return segment; } return null; } /** * Returns the Segment at <code>index</code> representing either * the paragraph or sentence as identified by <code>part</code>, or * null if a valid paragraph/sentence can't be found. The offset * will point to the start of the word/sentence in the array, and * the modelOffset will point to the location of the word/sentence * in the model. */ private IndexedSegment getSegmentAt(int part, int index) throws BadLocationException { IndexedSegment seg = getParagraphElementText(index); if (seg == null) { return null; } BreakIterator iterator; switch (part) { case AccessibleText.WORD: iterator = BreakIterator.getWordInstance(getLocale()); break; case AccessibleText.SENTENCE: iterator = BreakIterator.getSentenceInstance(getLocale()); break; default: return null; } seg.first(); iterator.setText(seg); int end = iterator.following(index - seg.modelOffset + seg.offset); if (end == BreakIterator.DONE) { return null; } if (end > seg.offset + seg.count) { return null; } int begin = iterator.previous(); if (begin == BreakIterator.DONE || begin >= seg.offset + seg.count) { return null; } seg.modelOffset = seg.modelOffset + begin - seg.offset; seg.offset = begin; seg.count = end - begin; return seg; } // begin AccessibleEditableText methods ----- /** * Returns the AccessibleEditableText interface for * this text component. * * @return the AccessibleEditableText interface * @since 1.4 */ public AccessibleEditableText getAccessibleEditableText() { return this; } /** * Sets the text contents to the specified string. * * @param s the string to set the text contents * @since 1.4 */ public void setTextContents(String s) { JTextComponent.this.setText(s); } /** * Inserts the specified string at the given index * * @param index the index in the text where the string will * be inserted * @param s the string to insert in the text * @since 1.4 */ public void insertTextAtIndex(int index, String s) { Document doc = JTextComponent.this.getDocument(); if (doc != null) { try { if (s != null && s.length() > 0) { boolean composedTextSaved = saveComposedText(index); doc.insertString(index, s, null); if (composedTextSaved) { restoreComposedText(); } } } catch (BadLocationException e) { UIManager.getLookAndFeel().provideErrorFeedback(JTextComponent.this); } } } /** * Returns the text string between two indices. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @return the text string between the indices * @since 1.4 */ public String getTextRange(int startIndex, int endIndex) { String txt = null; int p0 = Math.min(startIndex, endIndex); int p1 = Math.max(startIndex, endIndex); if (p0 != p1) { try { Document doc = JTextComponent.this.getDocument(); txt = doc.getText(p0, p1 - p0); } catch (BadLocationException e) { throw new IllegalArgumentException(e.getMessage()); } } return txt; } /** * Deletes the text between two indices * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @since 1.4 */ public void delete(int startIndex, int endIndex) { if (isEditable() && isEnabled()) { try { int p0 = Math.min(startIndex, endIndex); int p1 = Math.max(startIndex, endIndex); if (p0 != p1) { Document doc = getDocument(); doc.remove(p0, p1 - p0); } } catch (BadLocationException e) { } } else { UIManager.getLookAndFeel().provideErrorFeedback(JTextComponent.this); } } /** * Cuts the text between two indices into the system clipboard. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @since 1.4 */ public void cut(int startIndex, int endIndex) { selectText(startIndex, endIndex); JTextComponent.this.cut(); } /** * Pastes the text from the system clipboard into the text * starting at the specified index. * * @param startIndex the starting index in the text * @since 1.4 */ public void paste(int startIndex) { setCaretPosition(startIndex); JTextComponent.this.paste(); } /** * Replaces the text between two indices with the specified * string. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @param s the string to replace the text between two indices * @since 1.4 */ public void replaceText(int startIndex, int endIndex, String s) { selectText(startIndex, endIndex); JTextComponent.this.replaceSelection(s); } /** * Selects the text between two indices. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @since 1.4 */ public void selectText(int startIndex, int endIndex) { JTextComponent.this.select(startIndex, endIndex); } /** * Sets attributes for the text between two indices. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @param as the attribute set * @see AttributeSet * @since 1.4 */ public void setAttributes(int startIndex, int endIndex, AttributeSet as) { // Fixes bug 4487492 Document doc = JTextComponent.this.getDocument(); if (doc != null && doc instanceof StyledDocument) { StyledDocument sDoc = (StyledDocument)doc; int offset = startIndex; int length = endIndex - startIndex; sDoc.setCharacterAttributes(offset, length, as, true); } } // ----- end AccessibleEditableText methods // ----- begin AccessibleExtendedText methods // Probably should replace the helper method getAtIndex() to return// instead an AccessibleTextSequence also for LINE & ATTRIBUTE_RUN// and then make the AccessibleText methods get[At|After|Before]Point// call this new method instead and return only the string portion /** * Returns the AccessibleTextSequence at a given <code>index</code>. * If <code>direction</code> is non-null this will find the * next/previous word/sentence/character. * * @param part the <code>CHARACTER</code>, <code>WORD</code>, * <code>SENTENCE</code>, <code>LINE</code> or * <code>ATTRIBUTE_RUN</code> to retrieve * @param index an index within the text * @param direction is either -1, 0, or 1 * @return an <code>AccessibleTextSequence</code> specifying the text * if <code>part</code> and <code>index</code> are valid. Otherwise, * <code>null</code> is returned. * * @see javax.accessibility.AccessibleText#CHARACTER * @see javax.accessibility.AccessibleText#WORD * @see javax.accessibility.AccessibleText#SENTENCE * @see javax.accessibility.AccessibleExtendedText#LINE * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN * * @since 1.6 */ private AccessibleTextSequence getSequenceAtIndex(int part, int index, int direction) { if (index < 0 || index >= model.getLength()) { return null; } if (direction < -1 || direction > 1) { return null; // direction must be 1, 0, or -1 } switch (part) { case AccessibleText.CHARACTER: if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } AccessibleTextSequence charSequence = null; try { if (index + direction < model.getLength() && index + direction >= 0) { charSequence = new AccessibleTextSequence(index + direction, index + direction + 1, model.getText(index + direction, 1)); } } catch (BadLocationException e) { // we are intentionally silent; our contract says we return // null if there is any failure in this method } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return charSequence; case AccessibleText.WORD: case AccessibleText.SENTENCE: if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } AccessibleTextSequence rangeSequence = null; try { IndexedSegment seg = getSegmentAt(part, index); if (seg != null) { if (direction != 0) { int next; if (direction < 0) { next = seg.modelOffset - 1; } else { next = seg.modelOffset + seg.count; } if (next >= 0 && next <= model.getLength()) { seg = getSegmentAt(part, next); } else { seg = null; } } if (seg != null && (seg.offset + seg.count) <= model.getLength()) { rangeSequence = new AccessibleTextSequence (seg.offset, seg.offset + seg.count, new String(seg.array, seg.offset, seg.count)); } // else we leave rangeSequence set to null } } catch(BadLocationException e) { // we are intentionally silent; our contract says we return // null if there is any failure in this method } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return rangeSequence; case AccessibleExtendedText.LINE: AccessibleTextSequence lineSequence = null; if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { int startIndex = Utilities.getRowStart(JTextComponent.this, index); int endIndex = Utilities.getRowEnd(JTextComponent.this, index); if (startIndex >= 0 && endIndex >= startIndex) { if (direction == 0) { lineSequence = new AccessibleTextSequence(startIndex, endIndex, model.getText(startIndex, endIndex - startIndex + 1)); } else if (direction == -1 && startIndex > 0) { endIndex = Utilities.getRowEnd(JTextComponent.this, startIndex - 1); startIndex = Utilities.getRowStart(JTextComponent.this, startIndex - 1); if (startIndex >= 0 && endIndex >= startIndex) { lineSequence = new AccessibleTextSequence(startIndex, endIndex, model.getText(startIndex, endIndex - startIndex + 1)); } } else if (direction == 1 && endIndex < model.getLength()) { startIndex = Utilities.getRowStart(JTextComponent.this, endIndex + 1); endIndex = Utilities.getRowEnd(JTextComponent.this, endIndex + 1); if (startIndex >= 0 && endIndex >= startIndex) { lineSequence = new AccessibleTextSequence(startIndex, endIndex, model.getText(startIndex, endIndex - startIndex + 1)); } } // already validated 'direction' above... } } catch(BadLocationException e) { // we are intentionally silent; our contract says we return // null if there is any failure in this method } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return lineSequence; case AccessibleExtendedText.ATTRIBUTE_RUN: // assumptions: (1) that all characters in a single element // share the same attribute set; (2) that adjacent elements // *may* share the same attribute set int attributeRunStartIndex, attributeRunEndIndex; String runText = null; if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { attributeRunStartIndex = attributeRunEndIndex = Integer.MIN_VALUE; int tempIndex = index; switch (direction) { case -1: // going backwards, so find left edge of this run - // that'll be the end of the previous run // (off-by-one counting) attributeRunEndIndex = getRunEdge(index, direction); // now set ourselves up to find the left edge of the // prev. run tempIndex = attributeRunEndIndex - 1; break; case 1: // going forward, so find right edge of this run - // that'll be the start of the next run // (off-by-one counting) attributeRunStartIndex = getRunEdge(index, direction); // now set ourselves up to find the right edge of the // next run tempIndex = attributeRunStartIndex; break; case 0: // interested in the current run, so nothing special toLines 3001–3500 of 5073. Previous lines Load more
IndexedSegment seg = getSegmentAt(part, index); if (seg != null) { if (direction != 0) { int next; if (direction < 0) { next = seg.modelOffset - 1; } else { next = seg.modelOffset + direction * seg.count; } if (next >= 0 && next <= model.getLength()) { seg = getSegmentAt(part, next); } else { seg = null; } } if (seg != null) { return new String(seg.array, seg.offset, seg.count); } } break; default: break; } } catch (BadLocationException e) { } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return null; } /* * Returns the paragraph element for the specified index. */ private Element getParagraphElement(int index) { if (model instanceof PlainDocument ) { PlainDocument sdoc = (PlainDocument)model; return sdoc.getParagraphElement(index); } else if (model instanceof StyledDocument) { StyledDocument sdoc = (StyledDocument)model; return sdoc.getParagraphElement(index); } else { Element para; for (para = model.getDefaultRootElement(); ! para.isLeaf(); ) { int pos = para.getElementIndex(index); para = para.getElement(pos); } if (para == null) { return null; } return para.getParentElement(); } } /* * Returns a <code>Segment</code> containing the paragraph text * at <code>index</code>, or null if <code>index</code> isn't * valid. */ private IndexedSegment getParagraphElementText(int index) throws BadLocationException { Element para = getParagraphElement(index); if (para != null) { IndexedSegment segment = new IndexedSegment(); try { int length = para.getEndOffset() - para.getStartOffset(); model.getText(para.getStartOffset(), length, segment); } catch (BadLocationException e) { return null; } segment.modelOffset = para.getStartOffset(); return segment; } return null; } /** * Returns the Segment at <code>index</code> representing either * the paragraph or sentence as identified by <code>part</code>, or * null if a valid paragraph/sentence can't be found. The offset * will point to the start of the word/sentence in the array, and * the modelOffset will point to the location of the word/sentence * in the model. */ private IndexedSegment getSegmentAt(int part, int index) throws BadLocationException { IndexedSegment seg = getParagraphElementText(index); if (seg == null) { return null; } BreakIterator iterator; switch (part) { case AccessibleText.WORD: iterator = BreakIterator.getWordInstance(getLocale()); break; case AccessibleText.SENTENCE: iterator = BreakIterator.getSentenceInstance(getLocale()); break; default: return null; } seg.first(); iterator.setText(seg); int end = iterator.following(index - seg.modelOffset + seg.offset); if (end == BreakIterator.DONE) { return null; } if (end > seg.offset + seg.count) { return null; } int begin = iterator.previous(); if (begin == BreakIterator.DONE || begin >= seg.offset + seg.count) { return null; } seg.modelOffset = seg.modelOffset + begin - seg.offset; seg.offset = begin; seg.count = end - begin; return seg; } // begin AccessibleEditableText methods ----- /** * Returns the AccessibleEditableText interface for * this text component. * * @return the AccessibleEditableText interface * @since 1.4 */ public AccessibleEditableText getAccessibleEditableText() { return this; } /** * Sets the text contents to the specified string. * * @param s the string to set the text contents * @since 1.4 */ public void setTextContents(String s) { JTextComponent.this.setText(s); } /** * Inserts the specified string at the given index * * @param index the index in the text where the string will * be inserted * @param s the string to insert in the text * @since 1.4 */ public void insertTextAtIndex(int index, String s) { Document doc = JTextComponent.this.getDocument(); if (doc != null) { try { if (s != null && s.length() > 0) { boolean composedTextSaved = saveComposedText(index); doc.insertString(index, s, null); if (composedTextSaved) { restoreComposedText(); } } } catch (BadLocationException e) { UIManager.getLookAndFeel().provideErrorFeedback(JTextComponent.this); } } } /** * Returns the text string between two indices. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @return the text string between the indices * @since 1.4 */ public String getTextRange(int startIndex, int endIndex) { String txt = null; int p0 = Math.min(startIndex, endIndex); int p1 = Math.max(startIndex, endIndex); if (p0 != p1) { try { Document doc = JTextComponent.this.getDocument(); txt = doc.getText(p0, p1 - p0); } catch (BadLocationException e) { throw new IllegalArgumentException(e.getMessage()); } } return txt; } /** * Deletes the text between two indices * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @since 1.4 */ public void delete(int startIndex, int endIndex) { if (isEditable() && isEnabled()) { try { int p0 = Math.min(startIndex, endIndex); int p1 = Math.max(startIndex, endIndex); if (p0 != p1) { Document doc = getDocument(); doc.remove(p0, p1 - p0); } } catch (BadLocationException e) { } } else { UIManager.getLookAndFeel().provideErrorFeedback(JTextComponent.this); } } /** * Cuts the text between two indices into the system clipboard. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @since 1.4 */ public void cut(int startIndex, int endIndex) { selectText(startIndex, endIndex); JTextComponent.this.cut(); } /** * Pastes the text from the system clipboard into the text * starting at the specified index. * * @param startIndex the starting index in the text * @since 1.4 */ public void paste(int startIndex) { setCaretPosition(startIndex); JTextComponent.this.paste(); } /** * Replaces the text between two indices with the specified * string. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @param s the string to replace the text between two indices * @since 1.4 */ public void replaceText(int startIndex, int endIndex, String s) { selectText(startIndex, endIndex); JTextComponent.this.replaceSelection(s); } /** * Selects the text between two indices. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @since 1.4 */ public void selectText(int startIndex, int endIndex) { JTextComponent.this.select(startIndex, endIndex); } /** * Sets attributes for the text between two indices. * * @param startIndex the starting index in the text * @param endIndex the ending index in the text * @param as the attribute set * @see AttributeSet * @since 1.4 */ public void setAttributes(int startIndex, int endIndex, AttributeSet as) { // Fixes bug 4487492 Document doc = JTextComponent.this.getDocument(); if (doc != null && doc instanceof StyledDocument) { StyledDocument sDoc = (StyledDocument)doc; int offset = startIndex; int length = endIndex - startIndex; sDoc.setCharacterAttributes(offset, length, as, true); } } // ----- end AccessibleEditableText methods // ----- begin AccessibleExtendedText methods // Probably should replace the helper method getAtIndex() to return // instead an AccessibleTextSequence also for LINE & ATTRIBUTE_RUN // and then make the AccessibleText methods get[At|After|Before]Point // call this new method instead and return only the string portion /** * Returns the AccessibleTextSequence at a given <code>index</code>. * If <code>direction</code> is non-null this will find the * next/previous word/sentence/character. * * @param part the <code>CHARACTER</code>, <code>WORD</code>, * <code>SENTENCE</code>, <code>LINE</code> or * <code>ATTRIBUTE_RUN</code> to retrieve * @param index an index within the text * @param direction is either -1, 0, or 1 * @return an <code>AccessibleTextSequence</code> specifying the text * if <code>part</code> and <code>index</code> are valid. Otherwise, * <code>null</code> is returned. * * @see javax.accessibility.AccessibleText#CHARACTER * @see javax.accessibility.AccessibleText#WORD * @see javax.accessibility.AccessibleText#SENTENCE * @see javax.accessibility.AccessibleExtendedText#LINE * @see javax.accessibility.AccessibleExtendedText#ATTRIBUTE_RUN * * @since 1.6 */ private AccessibleTextSequence getSequenceAtIndex(int part, int index, int direction) { if (index < 0 || index >= model.getLength()) { return null; } if (direction < -1 || direction > 1) { return null; // direction must be 1, 0, or -1 } switch (part) { case AccessibleText.CHARACTER: if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } AccessibleTextSequence charSequence = null; try { if (index + direction < model.getLength() && index + direction >= 0) { charSequence = new AccessibleTextSequence(index + direction, index + direction + 1, model.getText(index + direction, 1)); } } catch (BadLocationException e) { // we are intentionally silent; our contract says we return // null if there is any failure in this method } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return charSequence; case AccessibleText.WORD: case AccessibleText.SENTENCE: if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } AccessibleTextSequence rangeSequence = null; try { IndexedSegment seg = getSegmentAt(part, index); if (seg != null) { if (direction != 0) { int next; if (direction < 0) { next = seg.modelOffset - 1; } else { next = seg.modelOffset + seg.count; } if (next >= 0 && next <= model.getLength()) { seg = getSegmentAt(part, next); } else { seg = null; } } if (seg != null && (seg.offset + seg.count) <= model.getLength()) { rangeSequence = new AccessibleTextSequence (seg.offset, seg.offset + seg.count, new String(seg.array, seg.offset, seg.count)); } // else we leave rangeSequence set to null } } catch(BadLocationException e) { // we are intentionally silent; our contract says we return // null if there is any failure in this method } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return rangeSequence; case AccessibleExtendedText.LINE: AccessibleTextSequence lineSequence = null; if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { int startIndex = Utilities.getRowStart(JTextComponent.this, index); int endIndex = Utilities.getRowEnd(JTextComponent.this, index); if (startIndex >= 0 && endIndex >= startIndex) { if (direction == 0) { lineSequence = new AccessibleTextSequence(startIndex, endIndex, model.getText(startIndex, endIndex - startIndex + 1)); } else if (direction == -1 && startIndex > 0) { endIndex = Utilities.getRowEnd(JTextComponent.this, startIndex - 1); startIndex = Utilities.getRowStart(JTextComponent.this, startIndex - 1); if (startIndex >= 0 && endIndex >= startIndex) { lineSequence = new AccessibleTextSequence(startIndex, endIndex, model.getText(startIndex, endIndex - startIndex + 1)); } } else if (direction == 1 && endIndex < model.getLength()) { startIndex = Utilities.getRowStart(JTextComponent.this, endIndex + 1); endIndex = Utilities.getRowEnd(JTextComponent.this, endIndex + 1); if (startIndex >= 0 && endIndex >= startIndex) { lineSequence = new AccessibleTextSequence(startIndex, endIndex, model.getText(startIndex, endIndex - startIndex + 1)); } } // already validated 'direction' above... } } catch(BadLocationException e) { // we are intentionally silent; our contract says we return // null if there is any failure in this method } finally { if (model instanceof AbstractDocument) { ((AbstractDocument)model).readUnlock(); } } return lineSequence; case AccessibleExtendedText.ATTRIBUTE_RUN: // assumptions: (1) that all characters in a single element // share the same attribute set; (2) that adjacent elements // *may* share the same attribute set int attributeRunStartIndex, attributeRunEndIndex; String runText = null; if (model instanceof AbstractDocument) { ((AbstractDocument)model).readLock(); } try { attributeRunStartIndex = attributeRunEndIndex = Integer.MIN_VALUE; int tempIndex = index; switch (direction) { case -1: // going backwards, so find left edge of this run - // that'll be the end of the previous run // (off-by-one counting) attributeRunEndIndex = getRunEdge(index, direction); // now set ourselves up to find the left edge of the // prev. run tempIndex = attributeRunEndIndex - 1; break; case 1: // going forward, so find right edge of this run - // that'll be the start of the next run // (off-by-one counting) attributeRunStartIndex = getRunEdge(index, direction); // now set ourselves up to find the right edge of the // next run tempIndex = attributeRunStartIndex; break; case 0: // interested in the current run, so nothing special to