содержание   вперед   назад

12. Класс fileFrame -- текстовый редактор

Начнем изучение полезных классов с текстового редактора, то есть класса fileFrame, который реализует редактор в относительно простой, но достаточной для многих целей конфигурации. Примером более продвинутого редактора является моя программа vkNotepad.jar, которую можно скачать на ее сайте. Как обычно, текст файла с кодом можно получить по указанной выше ссылке. Редактор сделан в отдельном окне, которое является наследником класса JInternalFrame, то есть это внутреннее окно главного окна программы. Редактор имеет свое собственное небольшое меню, имеющее три раздела. Конструктор класса имеет 4 аргумента: (1)имя файла, содержание которого редактируется, (2)режим записи нового текста в файл, (3)начальное положение курсора как номер символа текста (одним числом независимо от строк и колонок) и (4)массив из четырех чисел, определяющий положение окна относительно главного окна программы и его размеры.

Сначала создается объект класса File по имени файла. Если файл существует, то устанавливается заголовок окна по имени файла, возможность менять размеры окна, исходные размеры окна и его положение. После этого устанавливается меню. Запоминается режим записи во внутреннюю переменную класса и определяется пустая строка для поиска. Далее считываются параметры шрифта (фонта), по номеру типа фонта задается сам фонт из пяти встроенных фонтов. Определяется контейнер окна, затем область редактирования как объект класса JTextArea. Устанавливается фонт показа символов как новый объект класса java.awt.Font с тремя параметрами в конструкторе: сам фонт, тип PLAIN (еще бывает BOLD и ITALIC, но здесь все зафиксировано), и размер букв. Затем делается попытка скопировать текст из файла в текстовый массив целиком. Обработка ошибки стандартная. После этого массив байтов преобразуется в символьный массив. При этом вычеркивается символ с номером 13, так как редактор работает по системе UNIX, используя только символ с номером 10 как признак конца строки. И дополнительно отрицательные байты увеличиваются на 1104. Это фактически означает декодировку русских ASCII кодов в Windows кодировке в систему юникодов русских знаков. Для этого байт сначала переписывается в переменную типа short.

Вообще говоря, в Java существует более элегантная система кодировки, а на Windows компьютерах кодировка происходит автоматически при правильном задании локальных переменных. Но в других виртуальных машинах, поддерживающих Java, (например в Eve) это не работает автоматически. А использовать более универсальную систему не хочется. Поэтому здесь реализована принудительная перекодировка русских ASCII файлов в Windows кодировке и для многих пользователей этого будет достаточно. После того, как массив юникодов определен, он преобразуется в строку с использованием конструктора класса String и строка записывается в область редактирования. Затем эта область вставляется в объект класса JScrollPane, который автоматически осуществляет появление линеек прокрутки, когда текст вылезает за заданные размеры, и последний объект добавляется в контейнер в центр. Я уже говорил, что для компоновки используются различные схемы - объекты классов Layout. Но мы пока все время используем компоновку по умолчанию, то есть BorderLayout. В учебниках этому вопросу уделяется очень много внимания, но реально это не столь важная материя и ее можно будет обсудить как нибудь потом. Если же файл не существует, выдается диагностика и на этом все заканчивается.

Далее идет код, создающий меню. Но тут вам уже все знакомо, так что мы это пропустим. Рассмотрим функции, которые выполняются по различным разделам меню. Первая функция реализует поиск текста по заданной комбинации символов. Прежде всего необходимо спросить у пользователя какой текст искать. Это делается заданием нового объекта класса inpForm. Это диалог. Конструктор этого класса в качестве аргументов имеет: окно программы, название окна диалога, массив текстов-комментариев, массив исходных текстов в окнах ввода, число окон ввода, параметр задающий ширину окна диалога и параметр, определяющий конфигурацию окон ввода, когда их много. В нашем случае только одно окно ввода. Исходный текст в окне ввода определяется строкой с названием tefi, а текст-комментарий вы можете прочитать. Конструктор составлен так, что он сам окно не показывает. Можно делать различным образом и это один из них. Поэтому после конструктора вызывается метод show(), который как раз показывает окно.

Это более старый метод. Раньше мы для этих целей использовали более новый метод setVisible(true). Метод show() работает для многих классов, хотя, например, для класса Dialog компилятор его указывает как deprecated, то есть не рекомендуемый к использованию, и рекомендуют заменить на первый. Такие методы видимо не будут поддерживаться в будущем. Но для класса JInternalFrame можно и так и так. После того, как окно отработает, его объект надо ликвидировать, что делает метод dispose(). Реально объект убирает сборщик мусора, но мы ему помогли. Диалог окон ввода выдает результат, то есть введенные тексты во все окна ввода, в массив строк MyPro.tt. Кроме того, выход можно осуществить нажимая либо кнопку [OK] либо [Cancel]. Информация о том, какая кнопка была нажата, передается в переменную MyPro.ok. Получив нужную информацию, мы методом getCaretPosition() получаем текущую позицию курсора, методом getText() получаем весь текст редактора, выделяем из него часть текста от позиции курсора до конца (второй индекс не указан) и находим позицию нашей строки в этом тексте. После этого увеличиваем позицию курсора и устанавливаем курсор в новое место. Вот и все. Найденное слово указывает новая позиция курсора.

Второй раздел меню позволяет изменить параметры фонта. Параметры вводятся двумя числами. Поэтому из полученной обратно строки надо выделить два числа. Это делается методом MyPro.ttiarr(), который мы уже рассматривали. Остальное так же, как уже было в других местах. Наконец, третий раздел меню записывает новое содержание (при заданном условии на запись) в файл. При этом массив юникодов обратно преобразуется в массив байтов по указанной схеме и массив байтов записывается. Обратите внимание на метод bout.flush(). Он необходим, потому что запись в файл идет через буфер, когда последний заполняется полностью. Остаток текста может не заполнить буфер до конца и тогда он не попадет в файл. Можете это проверить. И как раз метод bout.flush() реализует принудительную очистку буфера, то есть запись его в файл, даже если он и не полный.

В меню редактора нет разделов [Copy] [Cut] [Paste] [Select All]. Но эти функции выполняются по горячим клавишам Ctrl+C, Ctrl+X, Ctrl+V, Ctrl+A автоматически. Этого вполне достаточно. Более того, буфер является общим для операционной системы и позволяет переносить тексты из других программ в нашу программу и наоборот.

содержание   вперед   назад


.