Spec-Zone.ru › OpenJDK 21

Документ интерфейса

Все известные подинтерфейсы:
StyledDocument
Все известные реализующие классы:
AbstractDocument, DefaultStyledDocument, HTMLDocument, PlainDocument
public interface Document

Интерфейс Document служит контейнером для текста, являющимся моделью для компонентов Swing, отображающих текст. Цель этого интерфейса — масштабирование от очень простых задач (простого текстового поля) до сложных (например, HTML или XML документа).

Содержимое

На самом простом уровне текст может быть представлен как линейная последовательность символов. Для поддержки локализации модель Swing для текста использует символы Юникода. Последовательность символов, отображаемых в текстовом компоненте, обычно называется содержимым компонента.

Для обозначения местоположений в последовательности используются координаты между двумя символами. Как показано на диаграмме ниже, местоположение в текстовом документе может обозначаться как позиция или смещение. Эта позиция нулевая.

The following text describes this graphic.

В примере, если содержимое документа — последовательность "Быстрая коричневая лиса", как показано на предыдущей диаграмме, местоположение перед словом "Быстрая" равно 0, а местоположение после слова "Быстрая" и перед последующим пробелом равно 3. Вся последовательность символов в последовательности "Быстрая" называется диапазоном.

Следующие методы предоставляют доступ к данным символов, составляющих содержимое.

  • getLength()
  • getText(int, int)
  • getText(int, int, javax.swing.text.Segment)

Структура

Текст редко представляется просто как бессвязное содержимое. Обычно текст имеет некоторую структуру. Точная модель структуры зависит от конкретной реализации документа. Она может быть простой (без структуры, т. е. простое текстовое поле) или же, как показано на диаграмме ниже.

Diagram shows Book->Chapter->Paragraph

Единица структуры (т. е. узел дерева) обозначается интерфейсом Element. Каждый элемент может быть помечен набором атрибутов. Эти атрибуты (парные имя/значение) определяются интерфейсом AttributeSet.

Следующие методы обеспечивают доступ к структуре документа.

  • getDefaultRootElement()
  • getRootElements()

Изменения

Все документы должны уметь добавлять и удалять простой текст. Обычно текст вставляется и удаляется через действия с клавиатуры или мыши. Какое влияние вставка или удаление окажут на структуру документа, целиком зависит от реализации документа.

Следующие методы связаны с изменениями содержимого документа:

  • 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.

The preceding text describes this graphic.

Ссылаясь на диаграмму выше, предположим, что компонент слева изменяет объект документа, представленный синим прямоугольником. Документ отвечает, отправляя событие DocumentEvent в оба визуальных компонента и отправляет событие UndoableEditEvent в слушающую логику, которая поддерживает буфер истории.

Теперь предположим, что компонент справа изменяет тот же документ. Опять же, документ отправляет событие DocumentEvent в оба визуальных компонента и отправляет событие UndoableEditEvent в слушающую логику, поддерживающую буфер истории.

Если затем буфер истории откатывается (т. е. последнее UndoableEdit отменено), в оба представления отправляется DocumentEvent, заставляя их отражать отменённое изменение в документе (то есть удаление изменения компонента справа). Если буфер истории ещё раз откатывается назад, то в оба представления отправляется ещё один DocumentEvent, заставляя их отразить отменённое изменение в документе — то есть удаление изменения компонента слева.

Методы, связанные с наблюдением за изменениями в документе:

  • addDocumentListener(DocumentListener)
  • removeDocumentListener(DocumentListener)
  • addUndoableEditListener(UndoableEditListener)
  • removeUndoableEditListener(UndoableEditListener)

Свойства

Реализации документов обычно имеют набор свойств, связанных с ними во время выполнения. Два хорошо известных свойства — StreamDescriptionProperty, которое можно использовать для описания источника Document, и TitleProperty, которое можно использовать для именования Document. Методы, связанные со свойствами:

  • getProperty(java.lang.Object)
  • putProperty(java.lang.Object, java.lang.Object)

Обзор и советы по программированию

Element — важный интерфейс, используемый при создании документа. Он может описывать различные структурные части документа, такие как абзацы, строки текста или даже (в HTML-документах) элементы списков. По сути, интерфейс Element воплощает некоторые аспекты SGML-документа. Поэтому, если вы знакомы с SGML, вы, возможно, уже понимаете интерфейс Element Swing.

В модели документа Swing API интерфейс Element определяет структурный фрагмент документа, например, абзац, строку текста или элемент списка в HTML-документе.

Каждый элемент является либо ветвью, либо листом. Если элемент является ветвью, то метод isLeaf() возвращает false. Если элемент является листом, то isLeaf() возвращает true.

Ветви могут иметь любое количество дочерних элементов. У листов нет дочерних элементов. Чтобы определить, сколько дочерних элементов у ветви, можно вызвать getElementCount(). Чтобы определить родителя элемента, можно вызвать getParentElement(). У корневых элементов нет родителей, поэтому вызов getParentElement() для корня возвращает null.

Элемент представляет собой определённый фрагмент документа, начинающийся с startOffset и заканчивающийся перед endOffset. Начальное смещение элемента-ветви обычно совпадает с начальным смещением первого дочернего элемента. Аналогично, конечное смещение элемента-ветви обычно совпадает с конечным смещением последнего дочернего элемента.

Каждый элемент связан с набором атрибутов, к которому можно получить доступ, вызвав getAttributes(). В элементе набор атрибутов — это набор пар ключ/значение. Эти пары обычно используются для разметки — например, для определения цвета фона элемента, размера шрифта и т. д. Но именно модель и разработчик определяют, что хранится в наборе атрибутов.

Корневой (или корневые) элемент документа можно получить, вызвав методы getDefaultRootElement() и getRootElements(), которые определены в интерфейсе Document.

Интерфейс Document отвечает за перевод линейного представления символов в операции с элементами. Каждая реализация документа определяет структуру элементов.

Класс PlainDocument

Класс PlainDocument определяет структуру элементов, в которой корневой узел содержит дочерний узел для каждой строки текста в модели. Рисунок 1 показывает, как две строки текста моделируются с помощью PlainDocument

The preceding text describes this graphic.

Рисунок 2 показывает, как те же две строки текста могут отображаться в фактическом содержимом:

The preceding text describes this graphic.

Вставка текста в PlainDocument

Как уже упоминалось, PlainDocument содержит корневой элемент, который, в свою очередь, содержит элемент для каждой строки текста. Когда текст вставляется в PlainDocument, он создаёт элементы, необходимые для существования элемента для каждой новой строки. Например, предположим, что вы хотите вставить новую строку в позиции 2 на рисунке 2. Для этого можно использовать метод Document insertString(), используя такой синтаксис:

document.insertString(2, "\n", null);

После вызова метода insertString() структура элементов будет выглядеть как на рисунке 3.

The preceding text describes this graphic.

В качестве другого примера, предположим, что вы хотите вставить шаблон "new\ntext\n" в позицию 2, как показано ранее на рисунке 2. Эта операция приведет к результату, показанному на рисунке 4.

The preceding text describes this graphic.

На предыдущих иллюстрациях имя элементов строки изменяется после вставки для соответствия номерам строк. Но обратите внимание, что при этом наборы атрибутов остаются неизменными. Например, на рисунке 2 набор атрибутов строки 2 соответствует набору атрибутов строки 4 на рисунке 4.

Удаление текста из PlainDocument

Удаление текста приводит к изменению структуры, если удаление охватывает более одной строки. Рассмотрим удаление семи символов, начиная с смещения 1 на рисунке 3. В этом случае элемент, представляющий строку 2, полностью удаляется, так как область, которую он представляет, находится в области удаления. Элементы, представляющие строки 1 и 3, объединяются, так как они частично находятся в области удаления. Таким образом, мы получаем результат:

The preceding text describes this graphic.

Класс DefaultStyledDocument

Класс DefaultStyledDocument, используемый для форматированного текста, содержит ещё один уровень элементов. Этот дополнительный уровень необходим для того, чтобы каждый абзац мог содержать различные стили текста. В двух абзацах, показанных на рисунке 6, первый абзац содержит два стиля, а второй — три стиля.

The preceding text describes this graphic.

Рисунок 7 показывает, как эти же элементы могут быть отображены в содержании.

The preceding text describes this graphic.

Вставка текста в DefaultStyledDocument

Как уже упоминалось, DefaultStyledDocument поддерживает структуру элементов таким образом, что корневой элемент содержит дочерний элемент для каждого абзаца. В свою очередь, каждый из этих элементов абзаца содержит элемент для каждого стиля текста в абзаце. Например, предположим, что у вас есть документ, содержащий один абзац, и этот абзац содержит два стиля, как показано на рисунке 8.

The preceding text describes this graphic.

Если затем вы захотите вставить перевод строки в позиции 2, вы снова используете метод insertString(), как показано ниже:

 styledDocument.insertString(2, "\n",
                styledDocument.getCharacterElement(0).getAttributes());

Этот операция приведет к результату, показанному на рисунке 9.

The preceding text describes this graphic.

Важно отметить, что AttributeSet, переданный в insertString(), соответствует атрибутам стиля 1. Если AttributeSet, переданный в insertString(), не соответствует, результат будет таким, как показано на рисунке 10.

The preceding text describes this graphic.

Удаление текста из DefaultStyledDocument

Удаление текста из DefaultStyledDocument аналогично удалению текста из PlainDocument. Единственное различие заключается в дополнительном уровне элементов. Представьте, что произойдет, если вы удалите два символа в позиции 1 на рисунке 10 выше. Поскольку второй элемент абзаца 1 полностью находится в области удаления, он будет удален. Предполагая, что атрибуты первого дочернего элемента абзаца 1 соответствуют атрибутам первого дочернего элемента абзаца 2, результатом будет то, что показано на рисунке 11.

The preceding text describes this graphic.

Если атрибуты не совпадают, мы получим результаты, показанные на рисунке 12.

The preceding text describes this graphic.

Класс 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 должен быть создан на основе элемента.

См. также:
  • DocumentEvent
  • DocumentListener
  • UndoableEditEvent
  • UndoableEditListener
  • Element
  • Position
  • AttributeSet

Краткое описание полей

Модификатор и тип Поле Описание
static final String StreamDescriptionProperty
Имя свойства для описания потока, используемого для инициализации документа.
static final String TitleProperty
Имя свойства для заголовка документа, если он есть.

Краткое описание методов

Модификатор и тип Метод Описание
void addDocumentListener(DocumentListener listener)
Регистрирует данного наблюдателя для получения уведомлений об изменениях в документе.
void addUndoableEditListener(UndoableEditListener listener)
Регистрирует данного наблюдателя для получения уведомлений об обратимых изменениях в документе.
Position createPosition(int offs)
Этот метод позволяет приложению отмечать место в последовательности текстового контента.
Element getDefaultRootElement()
Возвращает корневой элемент, на основе которого должны быть созданы представления, если не указан другой механизм для назначения представлений элементам.
Position getEndPosition()
Возвращает позицию, представляющую конец документа.
int getLength()
Возвращает количество символов в документе.
Object getProperty(Object key)
Получает свойства, связанные с документом.
Element[] getRootElements()
Возвращает все определённые корневые элементы.
Position getStartPosition()
Возвращает позицию, представляющую начало документа.
String getText(int offset, int length)
Получает текст, содержащийся в заданной части документа.
void getText(int offset, int length, Segment txt)
Получает текст, содержащийся в заданной части документа.
void insertString(int offset, String str, AttributeSet a)
Вставляет строку контента.
void putProperty(Object key, Object value)
Связывает свойство с документом.
void remove(int offs, int len)
Удаляет часть контента документа.
void removeDocumentListener(DocumentListener listener)
Отписывает данного наблюдателя от списка уведомлений, чтобы он больше не получал обновлений об изменениях.
void removeUndoableEditListener(UndoableEditListener listener)
Отписывает данного наблюдателя от списка уведомлений, чтобы он больше не получал обновлений.
void render(Runnable r)
Позволяет безопасно отображать модель в условиях конкурентного доступа, если модель поддерживает асинхронное обновление.

Подробное описание полей

StreamDescriptionProperty

static final String StreamDescriptionProperty
Имя свойства для описания потока, используемого для инициализации документа. Это следует использовать, если документ был инициализирован из потока и что-то известно о потоке.
См. также:
  • Значения постоянных полей

TitleProperty

static final String TitleProperty
Имя свойства для заголовка документа, если он есть.
См. также:
  • Значения постоянных полей

Подробное описание методов

getLength

int getLength()
Возвращает количество символов содержимого, в настоящее время находящегося в документе.
Возвращает:
количество символов >= 0

addDocumentListener

void addDocumentListener(DocumentListener listener)
Регистрирует данного наблюдателя, чтобы начать получать уведомления при внесении изменений в документ.
Параметры:
listener - наблюдатель для регистрации
См. также:
  • removeDocumentListener(javax.swing.event.DocumentListener)

removeDocumentListener

void removeDocumentListener(DocumentListener listener)
Отменяет регистрацию данного наблюдателя из списка уведомлений, чтобы он больше не получал обновлений изменений.
Параметры:
listener - наблюдатель для регистрации
См. также:
  • addDocumentListener(javax.swing.event.DocumentListener)

addUndoableEditListener

void addUndoableEditListener(UndoableEditListener listener)
Регистрирует данного наблюдателя, чтобы начать получать уведомления при выполнении отменяемых изменений в документе.
Параметры:
listener - наблюдатель для регистрации
См. также:
  • UndoableEditEvent

removeUndoableEditListener

void removeUndoableEditListener(UndoableEditListener listener)
Отменяет регистрацию данного наблюдателя из списка уведомлений, чтобы он больше не получал обновлений.
Параметры:
listener - наблюдатель для регистрации
См. также:
  • UndoableEditEvent

getProperty

Object getProperty(Object key)
Получает свойства, связанные с документом.
Параметры:
key - ключ свойства, не являющегося null
Возвращает:
свойства
См. также:
  • putProperty(Object, Object)

putProperty

void putProperty(Object key, Object value)
Связывает свойство с документом. Два стандартных ключа свойств — StreamDescriptionProperty и TitleProperty. Также могут быть определены другие свойства, например, автор.
Параметры:
key - ключ свойства, не являющегося null
value - значение свойства
См. также:
  • getProperty(Object)

remove

void remove(int offs, int len) throws BadLocationException
Удаляет часть содержимого документа. Это приведет к отправке DocumentEvent типа DocumentEvent.EventType.REMOVE зарегистрированным DocumentListeners, если не будет выброшено исключение. Уведомление будет отправлено слушателям, вызвав метод removeUpdate на DocumentListeners.

Для обеспечения приемлемого поведения в условиях конкурентного доступа, событие рассылается после того, как произошла мутация. Это означает, что к моменту отправки уведомления об удалении документ уже обновлен, а любые метки, созданные createPosition, уже изменены. При удалении конец диапазона удаления сворачивается до начала диапазона, а все метки в диапазоне удаления сворачиваются до начала диапазона.

Diagram shows removal of 'quick' from 'The quick brown fox.'

Если структура документа изменилась в результате удаления, подробности о том, какие элементы были вставлены и удалены в ответ на изменение, также будут содержаться в сгенерированном DocumentEvent. Реализация документа сама решает, как должна измениться структура в ответ на удаление.

Если документ поддерживает отмену/повтор, также будет сгенерировано UndoableEditEvent.

Параметры:
offs - смещение от начала >= 0
len - количество символов для удаления >= 0
Исключения:
BadLocationException - какая-то часть диапазона удаления не являлась действительной частью документа. Положение в исключении - первая встреченная неверная позиция.
См. также:
  • DocumentEvent
  • DocumentListener
  • UndoableEditEvent
  • UndoableEditListener

insertString

void insertString(int offset, String str, AttributeSet a) throws BadLocationException
Вставляет строку содержимого. Это приведет к отправке DocumentEvent типа DocumentEvent.EventType.INSERT зарегистрированным DocumentListeners, если не будет выброшено исключение. DocumentEvent будет доставлен путем вызова метода insertUpdate на DocumentListener. Смещение и длина сгенерированного DocumentEvent будут указывать, какое изменение фактически было внесено в документ.

Diagram shows insertion of 'quick' in 'The quick brown fox'

Если структура документа изменилась в результате вставки, подробности о том, какие элементы были вставлены и удалены в ответ на изменение, также будут содержаться в сгенерированном DocumentEvent. Реализация документа сама решает, как должна измениться структура в ответ на вставку.

Если документ поддерживает отмену/повтор, также будет сгенерировано UndoableEditEvent.

Параметры:
offset - смещение в документе для вставки содержимого >= 0. Все позиции, отслеживающие изменения в или после заданной позиции, будут перемещены.
str - строка для вставки
a - атрибуты, связанные с вставляемым содержимым. Может быть null, если атрибутов нет.
Исключения:
BadLocationException - заданная позиция вставки не является допустимой позицией в документе
См. также:
  • DocumentEvent
  • DocumentListener
  • UndoableEditEvent
  • UndoableEditListener

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;
   }

 
Параметры:
offset - смещение в документе, представляющее желаемый старт текста >= 0
length - длина желаемой строки >= 0
txt - объект Segment для возврата текста в
Исключения:
BadLocationException - какая-то часть заданного диапазона не являлась действительной частью документа. Положение в исключении - первая встреченная неверная позиция.

getStartPosition

Position getStartPosition()
Возвращает позицию, представляющую начало документа. Возвращенная позиция может быть использована для отслеживания изменений и сохранения расположения в начале документа.
Возвращает:
позицию

getEndPosition

Position getEndPosition()
Возвращает позицию, представляющую конец документа. Возвращённую позицию можно использовать для отслеживания изменений и её расположения в конце документа.
Возвращает:
позицию

createPosition

Position createPosition(int offs) throws BadLocationException
Этот метод позволяет приложению пометить место в последовательности символьного содержимого. Эта метка может быть использована для отслеживания изменений при вставках и удалениях в содержимом. Вставка всегда происходит перед текущей позицией (самый распространённый случай), за исключением случая, когда место вставки равно нулю. В этом случае вставка производится после исходной позиции.
Параметры:
offs - смещение от начала документа >= 0
Возвращает:
позицию
Исключения:
BadLocationException - если заданная позиция не представляет действительное местоположение в связанном документе

getRootElements

Element[] getRootElements()
Возвращает все определённые корневые элементы.

Как правило, существует только одна структура документа, но интерфейс поддерживает создание произвольного числа структурных проекций над текстовыми данными. Документ может иметь несколько корневых элементов для поддержки нескольких структур документа. Примерами могут служить:

  • Направление текста.
  • Потоки лексем.
  • Деревья разбора.
  • Преобразования в форматы, отличные от родного.
  • Спецификации изменений.
  • Аннотации.
Возвращает:
корневой элемент

getDefaultRootElement

Element getDefaultRootElement()
Возвращает корневой элемент, на котором должны основываться представления, если не предоставлен какой-либо другой механизм назначения представлений элементам структуры.
Возвращает:
корневой элемент

render

void render(Runnable r)
Позволяет безопасно отрисовать модель при наличии конкурентного доступа, если модель поддерживает асинхронное обновление. Указанный объект Runnable будет выполнен таким образом, чтобы он мог безопасно прочитать модель без изменений во время выполнения объекта Runnable. Сам объект Runnable не должен вносить какие-либо изменения.
Параметры:
r - объект Runnable для отрисовки модели

© 1993, 2023, 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://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/swing/text/Document.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API