Документация интерфейса
- Все известные подинтерфейсы:
StyledDocument
- Все известные реализующие классы:
-
AbstractDocument,DefaultStyledDocument,HTMLDocument,PlainDocument
public interface Document
Интерфейс Document представляет собой контейнер для текста, служащий моделью для компонентов Swing для отображения текста. Цель этого интерфейса — масштабироваться от простых потребностей (простого текстового поля) до сложных (например, HTML- или XML-документа).
Содержимое
На самом простом уровне текст может быть представлен как линейная последовательность символов. Для поддержки интернационализации модель текста Swing использует символы Юникода. Последовательность символов, отображаемая в компоненте текста, обычно называется содержимым компонента.
Для обозначения местоположений в последовательности используются координаты между двумя символами. Как показано на диаграмме ниже, положение в текстовом документе может быть представлено как позиция или смещение. Эта позиция нумеруется с нуля.
В примере, если содержимое документа — последовательность "The quick brown fox", как показано на предыдущей диаграмме, местоположение перед словом "The" равно 0, а местоположение после слова "The" и перед последующим пробелом равно 3. Вся последовательность символов в последовательности "The" называется диапазоном.
Следующие методы обеспечивают доступ к данным символов, составляющих содержимое.
Структура
Текст редко представляется просто как бесструктурное содержимое. Обычно текст имеет какую-то структуру. Точная структура, которая моделируется, зависит от конкретной реализации Document. Она может быть такой же простой, как отсутствие структуры (т.е. простое текстовое поле), или же такой сложной, как на диаграмме ниже.
Единицей структуры (т.е. узлом дерева) является интерфейс Element. Каждый элемент может быть помечен набором атрибутов. Эти атрибуты (пар ключ/значение) определяются интерфейсом AttributeSet.
Следующие методы обеспечивают доступ к структуре документа.
Изменения
Все документы должны иметь возможность добавлять и удалять простой текст. Обычно текст вставляется и удаляется с помощью действий с клавиатуры или мыши. Влияние вставки или удаления на структуру документа полностью зависит от реализации документа.
Следующие методы связаны с изменениями содержимого документа:
-
insertString(int, java.lang.String, javax.swing.text.AttributeSet) -
remove(int, int) -
createPosition(int)
Уведомления
Изменения в Document должны передаваться заинтересованным наблюдателям. Уведомление об изменениях следует правилам модели событий, указанным для JavaBeans. В модели событий JavaBeans, после отправки уведомления об событии, все слушатели должны быть уведомлены, прежде чем будут произведены дальнейшие изменения в источнике события. Порядок доставки не гарантируется.
Уведомления предоставляются в виде двух отдельных событий, DocumentEvent и UndoableEditEvent. Если изменение вносится в Document через его API, будет отправлено событие DocumentEvent всем зарегистрированным DocumentListeners. Если реализация Document поддерживает возможности отмены/повторного выполнения, будет отправлено событие UndoableEditEvent всем зарегистрированным UndoableEditListener. Если действие, подлежащее отмене, отменено, из документа должно быть отправлено событие DocumentEvent, чтобы указать, что он снова изменился. В этом случае не должно генерироваться UndoableEditEvent, так как это действие является источником изменения, а не изменением в Document, произведённым через его API.
Обращаясь к диаграмме выше, предположим, что компонент слева изменяет объект документа, представленный синим прямоугольником. Документ реагирует, отправляя событие DocumentEvent как компонентам, так и слушающей логике, которая поддерживает буфер истории.
Теперь предположим, что компонент справа изменяет тот же документ. Опять же, документ отправляет событие DocumentEvent и слушающей логике, поддерживающей буфер истории.
Если буфер истории откатывается (т.е. последнее UndoableEdit отменяется), событие DocumentEvent отправляется обоим представлениям, заставляя их отразить отменённое изменение в документе (т.е. удаление изменения правого компонента). Если буфер истории снова откатывает другое изменение, отправляется ещё одно событие DocumentEvent обоим представлениям, заставляя их отразить отменённое изменение в документе — то есть удаление изменения левого компонента.
Методы, связанные с наблюдением за изменениями в документе:
-
addDocumentListener(DocumentListener) -
removeDocumentListener(DocumentListener) -
addUndoableEditListener(UndoableEditListener) -
removeUndoableEditListener(UndoableEditListener)
Свойства
Реализации документа обычно имеют набор свойств, связанных с ними во время выполнения. Два известных свойства — StreamDescriptionProperty, которое можно использовать для описания источника Document, и TitleProperty, которое можно использовать для именования Document. Методы, связанные со свойствами:
Обзор и советы по программированию
Element — важный интерфейс, используемый при построении документа. Он может описывать различные структурные части документа, такие как абзацы, строки текста или даже (в HTML-документах) элементы списков. По сути, интерфейс Element вбирает в себя некоторые идеи SGML-документа. Поэтому, если вы знакомы с SGML, вы, возможно, уже имеете некоторое представление об интерфейсе Element Swing.
В модели документа API Swing для текста интерфейс Element определяет структурный фрагмент документа, такой как абзац, строка текста или элемент списка в HTML-документе.
Каждый элемент является либо ветвью, либо листом. Если элемент является ветвью, метод isLeaf() возвращает false. Если элемент является листом, isLeaf() возвращает true.
Ветки могут иметь любое количество дочерних элементов. Листья не имеют дочерних элементов. Чтобы определить количество дочерних элементов ветки, можно вызвать getElementCount(). Чтобы определить родителя элемента, можно вызвать getParentElement(). У корневых элементов нет родителей, поэтому вызов getParentElement() для корня возвращает null.
Элемент представляет собой конкретный регион в документе, который начинается с startOffset и заканчивается перед endOffset. Начальное смещение элемента-ветки обычно является начальным смещением его первого дочернего элемента. Аналогично, конечное смещение элемента-ветки обычно является конечным смещением его последнего дочернего элемента.
Каждый элемент связан с набором атрибутов, к которому вы можете получить доступ, вызвав getAttributes(). В элементе набор атрибутов — это набор пар ключ/значение. Эти пары обычно используются для разметки — например, для определения цвета переднего плана элемента, размера шрифта и так далее. Но именно модели и разработчикам решать, что хранится в AttributeSet.
Вы можете получить корневой элемент (или элементы) документа, вызвав методы getDefaultRootElement() и getRootElements(), которые определены в интерфейсе Document.
Интерфейс Document отвечает за перевод линейного представления символов в операции с элементами. Каждая реализация Document определяет структуру элементов.
Класс PlainDocument
Класс PlainDocument определяет структуру элементов, в которой корневой узел имеет дочерний узел для каждой строки текста в модели. Рисунок 1 показывает, как две строки текста будут смоделированы в PlainDocument
Рисунок 2 показывает, как эти же две строки текста могут быть отображены в фактическое содержимое:
Вставка текста в PlainDocument
Как только что упоминалось, PlainDocument содержит корневой элемент, который в свою очередь содержит элемент для каждой строки текста. При вставке текста в PlainDocument создаются необходимые элементы для каждого элемента новой строки. Предположим, вы хотите вставить новую строку в смещении 2 на Рисунке 2 выше. Для этого можно использовать метод документа insertString(), используя следующий синтаксис:
document.insertString(2, "\n", null); После вызова метода insertString() структура элемента будет выглядеть как на Рисунке 3.
В качестве ещё одного примера, предположим, что вы хотите вставить шаблон "new\ntext\n" в смещении 2, как показано ранее на Рисунке 2. В результате этой операции структура будет выглядеть как на Рисунке 4.
На предшествующих иллюстрациях имя элементов строки изменяется после вставки, чтобы соответствовать номерам строк. Но обратите внимание, что при этом наборы атрибутов остаются неизменными. Например, на Рисунке 2 набор атрибутов строки 2 совпадает с набором атрибутов строки 4 на Рисунке 4.
Удаление текста из PlainDocument
Удаление текста приводит к изменению структуры, если удаление затрагивает более одной строки. Рассмотрим удаление семи символов, начиная со смещения 1 на Рисунке 3. В этом случае элемент, представляющий строку 2, полностью удаляется, так как область, которую он представляет, содержится в удаляемой области. Элементы, представляющие строки 1 и 3, объединяются, так как они частично содержатся в удаляемой области. Таким образом, получаем результат:
Класс Default StyledDocument
Класс DefaultStyledDocument, используемый для форматированного текста, содержит ещё один уровень элементов. Этот дополнительный уровень необходим для того, чтобы каждый абзац мог содержать разные стили текста. В двух абзацах, показанных на рисунке 6, первый абзац содержит два стиля, а второй — три стиля.
Рисунок 7 показывает, как те же самые элементы могут отображаться в содержимом.
Вставка текста в DefaultStyledDocument
Как уже упоминалось, DefaultStyledDocument поддерживает структуру элементов таким образом, что корневой элемент содержит дочерний элемент для каждого абзаца. В свою очередь, каждый из этих элементов абзаца содержит элемент для каждого стиля текста в абзаце. Например, предположим, что у вас есть документ, содержащий один абзац, и этот абзац содержит два стиля, как показано на рисунке 8.
Если затем вы захотите вставить символ новой строки в позиции 2, вы снова используете метод insertString(), как показано ниже:
styledDocument.insertString(2, "\n",
styledDocument.getCharacterElement(0).getAttributes()); Этот оператор приведет к результату, показанному на рисунке 9.
Важно отметить, что атрибуты, переданные в insertString(), соответствуют атрибутам стиля 1. Если атрибуты, переданные в insertString(), не совпадали, результат был бы таким, как показано на рисунке 10.
Удаление текста из DefaultStyledDocument
Удаление текста из DefaultStyledDocument аналогично удалению текста из PlainDocument. Единственное отличие — дополнительный уровень элементов. Представьте, что произойдет, если вы удалите два символа в позиции 1 с рисунка 10 выше. Поскольку второй элемент абзаца 1 полностью находится в удаляемой области, он будет удален. Предполагая, что атрибуты первого дочернего элемента абзаца 1 соответствуют атрибутам первого дочернего элемента абзаца 2, результаты будут такими, как показано на рисунке 11.
Если атрибуты не совпадают, мы получим результаты, показанные на рисунке 12.
Класс StyledDocument
Класс StyledDocument предоставляет метод setCharacterAttributes(), который позволяет задать атрибуты элементов символов в заданном диапазоне:
public void setCharacterAttributes
(int offset, int length, AttributeSet s, boolean replace); Напомним, что на диаграммах, показанных в предыдущем разделе, все листья, показанные на рисунках, также являются элементами символов. Это означает, что метод setCharacterAttributes() можно использовать для задания их атрибутов.
Метод setCharacterAttributes() принимает четыре аргумента. Первый и второй аргументы идентифицируют область в документе, которая должна быть изменена. Третий аргумент определяет новые атрибуты (как AttributeSet), а четвёртый определяет, должны ли новые атрибуты быть добавлены к существующим (значение false) или элемент символов должен заменить свои существующие атрибуты новыми атрибутами (значение true).
Например, предположим, что вы хотите изменить атрибуты первых трех символов на рисунке 9, показанном ранее. Первые два аргумента, переданные в setCharacterAttributes(), будут 0 и 3. Третий аргумент будет содержать AttributeSet с новыми атрибутами. В рассматриваемом примере значение четвёртого аргумента не имеет значения.
Поскольку начальные и конечные смещения изменённой области (0 и 3) попадают на границы элементов символов, изменение структуры не требуется. То есть изменятся только атрибуты элемента стиля символа 1.
Теперь рассмотрим пример, требующий изменения структуры. Вместо изменения первых трех символов, показанных на рисунке 9, давайте изменим первые два символа. Так как конечное смещение изменения (2) не попадает на границу элемента символа, элемент в позиции 2 должен быть разделен таким образом, чтобы позиция 2 была границей двух элементов. Вызов setCharacterAttributes() с начальным смещением 0 и длиной 2 приводит к результату, показанному ранее на рисунке 10.
Изменение атрибутов абзаца в StyledDocument
Класс StyledDocument предоставляет метод setParagraphAttributes(), который можно использовать для изменения атрибутов элемента абзаца:
public void setParagraphAttributes
(int offset, int length, AttributeSet s, boolean replace); Этот метод похож на setCharacterAttributes(), но он позволяет изменять атрибуты элементов абзацев. Реализация StyledDocument определяет, какие элементы являются абзацами. DefaultStyledDocument интерпретирует элементы абзацев как родительские элементы элемента символов. Вызов этого метода не приводит к изменению структуры; изменяются только атрибуты элемента абзаца.
Рекомендуется изучить EditorKit и View. View отвечает за отображение конкретного элемента, а EditorKit отвечает за ViewFactory, который может определить, какой View должен быть создан на основе элемента.
- См. также:
Краткое описание полей
| Модификатор и тип | Поле | Описание |
|---|---|---|
static final String |
StreamDescriptionProperty |
Имя свойства для описания потока, используемого для инициализации документа. |
static final String |
TitleProperty |
Имя свойства для заголовка документа, если таковой имеется. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
void |
addDocumentListener |
Регистрирует заданного наблюдателя, чтобы он начал получать уведомления при внесении изменений в документ. |
void |
addUndoableEditListener |
Регистрирует заданного наблюдателя, чтобы он начал получать уведомления при выполнении отменяемых действий в документе. |
Position |
createPosition |
Этот метод позволяет приложению пометить место в последовательности символьного содержимого. |
Element |
getDefaultRootElement() |
Возвращает корневой элемент, на котором должны основываться представления, если не предоставлен другой механизм назначения представлений элементам. |
Position |
getEndPosition() |
Возвращает позицию, представляющую конец документа. |
int |
getLength() |
Возвращает количество символов содержимого, текущего в документе. |
Object |
getProperty |
Получает свойства, связанные с документом. |
Element[] |
getRootElements() |
Возвращает все определённые корневые элементы. |
Position |
getStartPosition() |
Возвращает позицию, представляющую начало документа. |
String |
getText |
Получает текст, содержащийся в заданной части документа. |
void |
getText |
Получает текст, содержащийся в заданной части документа. |
void |
insertString |
Вставляет строку содержимого. |
void |
putProperty |
Связывает свойство с документом. |
void |
remove |
Удаляет часть содержимого документа. |
void |
removeDocumentListener |
Отменяет регистрацию заданного наблюдателя из списка уведомлений, чтобы он больше не получал обновлений при изменениях. |
void |
removeUndoableEditListener |
Отменяет регистрацию заданного наблюдателя из списка уведомлений, чтобы он больше не получал обновления. |
void |
render |
Позволяет безопасно отображать модель при одновременном выполнении, если модель поддерживает асинхронное обновление. |
Подробное описание полей
СвойствоStreamDescriptionProperty
static final String StreamDescriptionProperty
- См. также:
СвойствоTitleProperty
static final String TitleProperty
- См. также:
Подробное описание методов
getLength
int getLength()
- Возвращает:
- количество символов >= 0
addDocumentListener
void addDocumentListener(DocumentListener listener)
- Параметры:
-
listener- наблюдатель для регистрации - См. также:
removeDocumentListener
void removeDocumentListener(DocumentListener listener)
- Параметры:
-
listener- наблюдатель для регистрации - См. также:
addUndoableEditListener
void addUndoableEditListener(UndoableEditListener listener)
- Параметры:
-
listener- наблюдатель для регистрации - См. также:
removeUndoableEditListener
void removeUndoableEditListener(UndoableEditListener listener)
- Параметры:
-
listener- наблюдатель для регистрации - См. также:
getProperty
Object getProperty(Object key)
- Параметры:
-
key- ключ свойства, не являющийсяnull - Возвращает:
- свойства
- См. также:
putProperty
void putProperty(Object key, Object value)
StreamDescriptionProperty и TitleProperty. Также могут быть определены и другие свойства, такие как автор.- Параметры:
-
key- ключ свойства, не являющийсяnull -
value- значение свойства - См. также:
remove
void remove(int offs, int len) throws BadLocationException
DocumentEvent типа DocumentEvent.EventType.REMOVE зарегистрированным DocumentListener, если не будет выброшено исключение. Уведомление будет отправлено слушателям, вызвав метод removeUpdate на DocumentListener. Для обеспечения разумного поведения в условиях конкурентного доступа, событие отправляется после того, как произошла мутация. Это означает, что к моменту отправки уведомления об удалении документ уже был обновлен, и любые метки, созданные createPosition, уже изменились. При удалении конец диапазона удаления сворачивается до начала диапазона, а любые метки в диапазоне удаления сворачиваются до начала диапазона.
Например, если документ содержит текст ‘Лиса быстрого рыжего цвета’, вызов remove(4, 6) удалит слово ‘быстрого’ и последующий пробел из текста, а все метки в диапазоне 4–10 будут свернуты до 4.
Если структура документа изменилась в результате удаления, детали о том, какие Element были вставлены и удалены в ответ на изменение, также будут содержаться в сгенерированном DocumentEvent. Реализация Document решает, как структура должна измениться в ответ на удаление.
Если документ поддерживает отмену/повтор, также будет сгенерировано UndoableEditEvent.
- Параметры:
-
offs- смещение от начала >= 0 -
len- количество символов для удаления >= 0 - Исключения:
-
BadLocationException- некоторая часть диапазона удаления не была допустимой частью документа. Положение в исключении - это первая встреченная неверная позиция. - См. также:
insertString
void insertString(int offset, String str, AttributeSet a) throws BadLocationException
DocumentEvent типа DocumentEvent.EventType.INSERT зарегистрированным DocumentListener, если не будет выброшено исключение. DocumentEvent будет доставлено путем вызова метода insertUpdate на DocumentListener. Смещение и длина сгенерированного DocumentEvent укажут на то, какое изменение фактически было внесено в Document. Например, если документ содержит текст ‘Рыжий лиса’, вызов insert(4, "quick ", null) вставит слово ‘быстрого’ и последующий пробел в текст, а все метки на 4 и выше будут смещены на 6 (количество вставленных символов).
Если структура Document изменилась в результате вставки, детали о том, какие Element были вставлены и удалены в ответ на изменение, также будут содержаться в сгенерированном DocumentEvent. Реализация Document решает, как структура должна измениться в ответ на вставку.
Если Document поддерживает отмену/повтор, также будет сгенерировано UndoableEditEvent.
- Параметры:
-
offset- смещение в документе для вставки содержимого >= 0. Все позиции, отслеживающие изменения на данном или последующих местах, будут смещены. -
str- строка для вставки -
a- атрибуты, которые нужно ассоциировать с вставленным содержимым. Может бытьnull, если атрибутов нет. - Исключения:
-
BadLocationException- заданная позиция вставки не является допустимой позицией в документе - См. также:
getText
String getText(int offset, int length) throws BadLocationException
- Параметры:
-
offset- смещение в документе, представляющее желаемое начало текста >= 0 -
length- длина желаемой строки >= 0 - Возвращает:
- текст, в строке длины >= 0
- Исключения:
-
BadLocationException- некоторая часть заданного диапазона не являлась допустимой частью документа. Позиция в исключении — первая встреченная неверная позиция.
getText
void getText(int offset, int length, Segment txt) throws BadLocationException
Если свойство partialReturn параметра txt равно false, возвращаемые данные в объекте Segment будут иметь полную запрошенную длину и могут быть или не быть копией, в зависимости от способа хранения данных. Если свойство partialReturn равно true, возвращается только то количество текста, которое можно вернуть без создания копии. Использование частичных возвратов обеспечит лучшую производительность в ситуациях, когда сканируются большие части документа. Приведенный ниже пример демонстрирует использование частичного возврата для доступа ко всему документу:
int nleft = doc.getDocumentLength();
Segment text = new Segment();
int offs = 0;
text.setPartialReturn(true);
while (nleft > 0) {
doc.getText(offs, nleft, text);
// do something with text
nleft -= text.count;
offs += text.count;
}
- Parameters:
-
offset- смещение в документе, представляющее желаемый начальный текст >= 0 -
length- длина желаемой строки >= 0 -
txt- объект Segment для возврата текста - Throws:
-
BadLocationException- некоторая часть заданного диапазона не является допустимой частью документа. Позиция в исключении — первая встреченная неверная позиция.
getStartPosition
Position getStartPosition()
- Returns:
- позиция
getEndPosition
Position getEndPosition()
- Returns:
- позиция
createPosition
Position createPosition(int offs) throws BadLocationException
- Parameters:
-
offs- смещение от начала документа >= 0 - Returns:
- позиция
- Throws:
-
BadLocationException- если заданная позиция не представляет допустимое местоположение в связанном документе
getRootElements
Element[] getRootElements()
Обычно существует только одна структура документа, но интерфейс поддерживает создание произвольного количества структурных проекций над текстовыми данными. Документ может иметь несколько корневых элементов для поддержки нескольких структур документа. Примеры могут включать:
- Направление текста.
- Потоки лексических токенов.
- Деревья разбора.
- Преобразования в форматы, отличные от родного.
- Спецификации изменений.
- Аннотации.
- Returns:
- корневой элемент
getDefaultRootElement
Element getDefaultRootElement()
- Returns:
- корневой элемент
render
void render(Runnable r)
- Parameters:
-
r-Runnableдля отображения модели
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://download.java.net/java/early_access/jdk24/docs/api/java.desktop/javax/swing/text/Document.html