В модель данных можно внести структуру дерева, например разбить документ на главы, параграфы, разделы. Каждый элемент разбиения описывается интерфейсом Element. Элемент занимает какую-то область текста с начальной позицией, возвращаемой методом getStartOffset (), и конечной позицией getEndOffset (). У элемента может быть родительский элемент, который легко получить методом getParentElement(). Область текста, занимаемая родительским элементом, полностью включает в себя область исходного элемента. У элемента могут быть дочерние элементы, чья область текста полностью лежит внутри области самого элемента. Их можно получить методом getElement(int). Число дочерних элементов возвращает метод getElementCount (), а индекс дочернего элемента — метод getElementIndex (int). Элементу можно дать имя, а затем получить его методом getName ().

Интерфейс Element частично реализован абстрактным классом AbstractElement, вложенным в класс AbstractDocument, и полностью реализован еще двумя вложенными

в AbstractDocument классами — BranchElement и LeafElement, расширяющими класс AbstractElement. Основная разница между ними в том, что у класса BranchElement могут быть дочерние элементы, а у класса LeafElement — нет.

Класс BranchElement, в свою очередь, расширяется классом SectionElement, вложенным в класс DefaultStyledElement, и классом BlockElement, вложенным в класс HTMLDocument.

Класс LeafElement расширяется классом RunElement, вложенным в класс HTMLDocument. Элементы создаются методами

Element createLeafElement(Element parent, AttributeSet attr,

int pos1, int pos2);

Element createBranchElement(Element parent, AttributeSet attr);

Для каждого структурного элемента можно задать свое множество атрибутов методом

addAttribute(Object name, Object value) или методом addAttributes(AttributeSet).

В документе допускается задание нескольких независимых структур. Их корневые элементы можно получить методом getRootElements ( ), возвращающим массив типа Element [ ]. Один из корневых элементов можно сделать корневым элементом по умолчанию и получать его методом getDefaultRootElement(), возвращающим элемент в виде объекта, реализующего интерфейс Element. Получив корневые элементы структурного дерева, легко обойти его, используя метод getElement(int) интерфейса Element или метод children (), имеющийся в его реализациях.

События в документе

При всяком изменении документа или его структуры происходит событие, описанное интерфейсом DocumentEvent. Он предлагает метод getDocument ( ), позволяющий узнать, в каком документе произошло событие, методы getOffset () и getLength (), сообщающие о начальной позиции и длине измененного текста. Вложенный интерфейс ElementChange содержит метод getElement (), позволяющий узнать элемент, в котором произошло событие, и методы, помогающие отследить добавление и удаление элемента из документа.

Реализация интерфейса DocumentEvent — класс DefaultDocumentEvent, вложенный в класс AbstractDocument, — добавляет к методам интерфейса метод undo (), отменяющий изменения, метод redo (), восстанавливающий изменения, и еще несколько информационных методов.

Если модель данных позволяет отменять и восстанавливать изменения (undo/redo), то при каждом таком действии в ней происходит событие класса UndoableEditEvent.

Реализации документа

Интерфейс Document частично реализован абстрактным классом AbstractDocument. Этот класс вносит понятие блокировки документа. Документ могут просматривать несколько подпроцессов-"читателей" и один подпроцесс-"писатель". Доступ их к документу блокируется методами readLock() и writeLock(). Блокировки снимаются методами

readUnlock() и writeUnlock().

Класс AbstractDocument обычно не расширяется непосредственно, а используются или расширяются его подклассы PlainDocument и DefaultStyledDocument.

Класс PlainDocument задает модель простого документа с "плоским" текстом, которая используется полями ввода JTextField, JPasswordField, JTextArea. Текст в этой модели имеет структуру: структурные элементы текста — это строки. Корневой элемент структуры можно получить методом getDefaultRootElement(). Метод getParagraphElement(int offset) возвращает элемент структуры — строку в виде объекта типа Element, к которому принадлежит позиция offset. Каждой строке, как любому элементу структуры, можно придать атрибуты. Отдельные символы атрибутов не имеют.

Более сложную структуру вносит в документ модель класса DefaultStyledDocument, используемая в текстовом редакторе JTextPane. В этой модели не только строке, но и каждому символу текста можно задать свой стиль.

Наконец, класс DefaultStyledDocument расширяется классом HTMLDocument. Это модель разметки языка HTML. В ней можно определить таблицы стилей (style sheets).

Установка модели данных

После того как новая модель данных определена, ее надо установить в компонент методом setDocument(Document) класса JTextComponent.

Вид
Перейти на страницу:

Все книги серии В подлиннике

Похожие книги