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

13. Класс webFrame -- встроенный браузер

Рассмотрим теперь класс webFrame, который позволяет просматривать html-форматированные файлы, иначе говоря, вэб-страницы. Браузер сделан в режиме разумной достаточности, ничего лишнего. Все установки по умолчанию. Все гиперссылки открываются в новом окне, которое накладывается на предыдущее, но затем может быть сдвинуто в любое место. Размеры любого окна можно менять, но следующее окно открывается стандартным образом, как было вначале. Естественно, что прибавив дополнительный код можно прибавить браузеру функциональности. Но следует отметить, что он поддерживает только основные конструкции языка html первых версий и неспособен показывать правильно любую страницу в интернете. Однако для показа вашей собственной информации, должным образом сформатированной, он вполне годится и даже очень удобен. Данный браузер основан на встроенном классе JEditorPane. В документации к 6 версии сказано, что он поддерживает стандарт HTML 3.2, но без Javascript. Кроме того, он поддерживает RTF формат текста, но это мы использовать не будем.

Итак, открываем код класса по ссылке и начинаем смотреть, что там написано. Как видите, кода совсем немного. Это опять следствие наличия виртуальной машины. Конструктор имеет два аргумента: путь к файлу и параметры окна. Параметры окна копируются во внутренние переменные класса для использования в других внутренних методах. Затем формируется объект класса URL, который хранит гиперссылки. В нашем случае предполагается чтение файла с локальной машины, поэтому вместо конструкции http:// мы добавляем file:. Наклонные черты писать не надо, так устроен браузер Java. После этого мы просто вызываем метод createInternalFrame(), у которого два аргумента: первым является объект, возвращаемый методом createEditorPane(fileUrl), у которого аргументом является гиперссылка, а вторым - название окна, для которого мы используем путь к файлу. И все. Но оба этих метода надо еще написать, так как их нет в JRE.

Метод createInternalFrame(Component c, String t), как мы теперь видим имеет первым аргументом объект класса Component. Этот класс является прямым наследником прародителя - класса Object -- и в свою очередь является родителем всех классов, реализующих графический интерфейс с пользователем. С таким аргументом мы может использовать все полезные для нас классы. Первой командой мы заказываем объект уже знакомого нам класса JInternalFrame, но в данном случае мы его не расширяем, а используем непосредственно конструктор. У конструктора первым аргументом стоит имя окна, а затем 4 логические переменные, устанавливающие режимы изменения размеров окна, закрытия окна крестиком, способность максимально открыть окно, или свернуть его в иконку. Чтобы не перепутать, в нижней строке написан комментарий -- подсказка, строка комментария должна иметь в начале два символа наклонной черты. Мы заказали первые два свойства и отказались от последних двух. При желании это можно изменить. Даже можно вынести эти свойства в файл Second.ini как входные параметры. Но мне и так хорошо, а вы можете попробовать по другому. Далее мы передаем внутреннюю панель окна прямо объекту ifr. Раньше, как вы помните, мы для этого открывали объект класса Container. С контейнером нагляднее читать, но можно и так. И сразу передаем этой панели наш объект класса Component из аргументов. Остальной код вам уже знаком. Кстати объект ifr объявлен как final. Это просто означает, что мы не намерены его переопределять. Это указание позволяет компилятору оптимизировать работу программы, но и без него все бы прекрасно работало.

Таким образом, первый метод достаточно прост и понятен. Рассмотрим второй метод createEditorPane(URL u). Он возвращает объект класса Component, как написано в заголовке. На самом деле он возвращает объект класса JScrollPane(new JEditorPane()), как следует из оператора return. Это нормально, так как последний класс является наследником первого класса. Просто в такой постановке код удобно переписывать в будущем на любые другие объекты. Итак мы возвращаем объект класса JEditorPane, вставленный при необходимости в рамку из линеек прокрутки, которую генерирует объект класса JScrollPane. Класс JEditorPane специально сделан как программа, способная показывать не только простой текст, но и html-форматированный текст, а также RTF-форматированный текст. Это и есть наш браузер в готовом виде. Мы устанавливаем свойство только показа текста методом setEditable(false). Но нам необходимо еще обеспечить работу по разрешению гиперссылок. Вот здесь как раз используется достаточно сложная конструкция

Попробуем разобраться. Вызывается метод addHyperlinkListener, аргументом которого является объект класса HyperlinkListener. Но сразу, после указания конструктора этого класса, записан в фигурных скобках сам класс. Это и есть самый внутренний класс, который только может быть. Я упоминал о них в самом начале курса. Так как он достаточно компактный, то для него не делается формальной атрибутики, а он сразу записывается после конструктора. В этом классе есть только один метод public void hyperlinkUpdate(HyperlinkEvent event), и в этом методе отслеживается событие по использованию гиперссылки. Если гиперссылка вызывается (клик левой клавиши мыши), то повторно запускается уже известный нам метод createInternalFrame(createEditorPane(event.getURL()),event.getURL().toString()), но у которого теперь другие аргументы, а именно, адрес файла взят из события.

В чем тут сложность для понимания. Мы видим рекурсию. Одна подпрограмма вызывает другую, а та в свою очередь, вызывает первую, которая ее вызвала. В старых языках программирования такое было бы невозможно. Но в объектно-ориентированном языке это нормально. Ведь внутренняя подпрограмма вызывает новый объект внешнего класса. Старый объект этого класса (объявленный final) остается на экране и с ним ничего не происходит. Но появляется новое окно, вот и все. То есть реально никакой рекурсии нет, а есть размножение объектов, в нашем случае окон с веб-страницами. Остаток кода просто устанавливает содержание файла по гиперссылке в окно браузера методом setPage. Как видите, код очень компактный и практически все делается виртуальной машиной. При желании можно было бы добавить разных настроек, но это в другой раз. А пока с этим классом все.

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


.