Заканчивая обзор класса Segment, скажем, что для большей надежности выполнения метода getText(int, int, Segment) в класс Segment введен метод setPartialReturn(boolean). Если в этом методе задать параметр true, то передача текста методом getText () в экземпляр класса Segment будет происходить, по возможности, без дополнительного копирования. Значение параметра по умолчанию — false. С учетом этого, работа с классом Segment начинается примерно так:
Segment seg = new Segment(); seg.setPartialReturn(true); doc.getText(0, doc.getLength(), seg);
// Работаем с объектом seg...
Запись текста в документ
Прежде чем использовать текст документа, его надо записать в документ. Запись выполняется методом
void insertString(int offset, String text, AttributeSet attr);
Новый текст text вставляется перед символом с позицией offset, позиция этого и следующих символов увеличивается на длину вставленного текста.
Атрибуты текста
Как видно из сигнатуры метода insertString(), у вносимого текста могут быть атрибуты, например: имя шрифта, размер шрифта, цвет. Если у текста нет атрибутов, то третьему параметру метода надо дать значение null.
Атрибуты записываются в виде пар "имя — значение" в объект, реализующий интерфейс AttributeSet. Этот интерфейс описывает неизменяемое множество атрибутов, в нем не описаны методы добавления и удаления атрибутов. Такие методы внесены в его расширение — интерфейс MutableAttributeSet. В библиотеке Swing есть реализация данного интерфейса — класс SimpleAttributeSet. С помощью этого класса можно определить любые пары "имя — значение", но общепринятые атрибуты удобнее задавать с использованием констант и статических методов класса StyleConstants и четырех его подклассов, которые в то же время вложены в него: CharacterConstants, ColorConstants, FontConstants и ParagraphConstants.
Объект, реализующий интерфейс AttributeSet, может содержать ссылку на другой, "родительский" объект того же типа. Ссылка хранится как значение атрибута, имеющего имя ResolveAttribute. Так можно получить цепочку объектов, содержащих атрибуты текста. Если какая-то пара "имя — значение" не найдена в первом объекте методом getAttribute (Object), то она отыскивается в родительском объекте, который определяется методом getResolveParent (), затем поиск идет далее по цепочке.
У интерфейса MutableAttributeSet есть свое расширение- интерфейс Style. Это расши
рение дает возможность получить имя множества атрибутов методом getName ( ), создав так называемый
ChangeEvent методом
void addChangeListener(ChangeListener chl);
Заданное имя затем можно использовать как значение другого атрибута, а с помощью слушателя отслеживать добавление и удаление атрибутов.
Для создания стилей и работы с ними очень полезен класс StyleContext. Его экземпляр с общепринятым набором атрибутов можно получить следующим образом:
StyleContext stc = StyleContext.getDefaultStyleContext();
Затем в полученный объект stc можно добавить новые атрибуты методами addAttribute (), удалить атрибуты методами removeAttribute(), создать цепочку стилей.
Удаление текста из документа
Обратная операция — удаление части или всего текста из документа — выполняется методом
remove(int offset, int length);
Он удаляет length символов, начиная от символа, находящегося в позиции offset.
Фильтрация документа
Операции занесения текста в документ методом insertString() и удаления методом remove () можно изменить так, чтобы они производили различные проверки и модификации, фильтруя таким способом вставляемый или удаляемый текст. Это можно сделать прямым расширением класса, реализующего Document, и переопределением его методов insertString () и remove (). Но есть еще один способ, не изменяющий документ.
Сначала надо расширить класс DocumentFilter, переопределив его методы. В классе DocumentFilter всего три метода:
void insertString(DocumentFilter.FilterBypass fb, int offset,
String text, AttributeSet attr);
void remove(DocumentFilter.FilterBypass fb, int offset, int length); void replace(DocumentFilter.FilterBypass fb, int offset, int length,
String text, AttributeSet attr);
Их стандартная реализация просто вызывает соответствующие методы вложенного абстрактного класса FilterBypass, которые оставлены абстрактными.
После расширения класса DocumentFilter, вызванного переопределением методов, полученный фильтр надо установить в документ методом
void setDocumentFilter(DocumentFilter filter);
класса AbstractDocument. Далее всякое обращение к методам insertString () и remove () документа будет пропускаться через методы созданного фильтра.
Пример использования фильтра, пропускающего только цифры, приведен в листинге 12.1.
Внесение структуры в документ