JBuilder для начинающих
Для программиста любой проект- это совокупность файлов, логически связанных между собой одной целью. Среди них могут быть и файлы с исходными текстами на языке программирования, которые впоследствии превратятся в программу, и прочие файлы, необходимые для дальнейшей работы над проектом, и многое другое. JBuilder помогает программистам, ведущим проекты, графически отображать их в навигационной панели и отслеживать момент, когда отдельные файлы из проекта требуют сохранения или перекомпиляции.
Первое, что необходимо сделать при подготовке нового приложения, - создать его проект. Для этого вызовите мастер проектов командой File New Project. На экране возникнет диалоговая панель мастера создания проекта, в которую вы должны ввести необходимые для проекта данные.
После того как вы нажмете на кнопку Finish, JBuilder создаст в указанном вами каталоге новый проект и немедленно откроет его в своей среде. Взглянув на панель навигации (верхняя левая), вы увидите, что проект, который вы только что создали, не пустой. В нем уже есть файл в формате HTML, содержащий заготовки комментариев к проекту. Вы можете просмотреть и отредактировать его, если щелкнете на закладке Source.
На втором этапе устанавливаются опции проекта. Для этого щелкните правой кнопкой мыши на пиктограмме, обозначающей проект, и выберите из появившегося контекстного меню пункт Properties. Другой вариант - выберите команду меню File Project Properties.
Все опции проекта будут показаны в диалоговой панели с двумя закладками.
Рассмотрим опции на закладке Project:
- Browser Source Path - маршруты в файловой системе, по которым среда JBuilder ищет файлы с исходным текстом; если файлы не найдены, среда JBuilder продолжает искать их в маршрутах, заданных в поле Compiler Source Path;
- Compiler Source Path - маршруты, по которым компилятор проверяет, нужно ли перекомпилировать class-файлы; файлы, указанные в поле Browser Source Path, игнорируются;
- Class Path - местоположение библиотечных файлов;
- Out Path - каталог, в котором компилятор сохраняет class-файлы после компиляции исходных текстов проекта;
- Include Debug Info - включает отладочную информацию в получаемые при компиляции class-файлы;
- Show Warnings - включает показ предупреждающих сообщений и ошибок времени компиляции;
- Show Deprecation - включает сообщения обо всех устаревших классах, методах, свойствах, событиях и переменных программного интерфейса Java, использованных в проекте;
- Check Stable Packages - включает проверку "стабильных" пакетов, определяя, нужно ли произвести их перекомпиляцию; под "стабильными" пакетами подразумеваются библиотечные пакеты фирм, из которых ваш проект импортирует классы;
- Make Packages Stable - если данная опция включена, то пакет, который получается в процессе компиляции проекта, проверяется однократно и помечается как "стабильный", что полезно при построении окончательного варианта пакета;
- Obfuscate - если эта опция включена, то внутренние имена, использованные в вашей программе, шифруются, что делает ее менее подверженной дизассемблированию в исходный код; все внутренние имена программы изменяются;
- Exclude Class - исключает заданный class-файл из процесса компиляции;
- Encoding - определяет кодировку символов; если данная опция не установлена, будет использоваться локальная кодировка, заданная в вашей ОС по умолчанию;
- Default - нажатие на эту кнопку устанавливает для всех опций значения по умолчанию.
Следующая закладка Run/Debug предназначена для установки аргументов командной строки, которые будут переданы программе или аплету во время запуска, и некоторые другие параметры:
- Default Runnable File - список, из которого выбирается имя запускаемого файла проекта;
- Command Line Parameters - параметры командной строки, задаваемые для утилиты сборки проектов bmj и компилятора Java bcj;
- Java VM Parameters - параметры командной строки для виртуальной машины Java, на которой будет запущен проект;
- Compile Project before Debugging - если эта опция включена, то перед запуском отладчика проект будет откомпилирован;
- Send Run Output to Execution Log - эта опция посылает весь текстовый вывод программы в специальное окно протокола, которое можно открыть командой View Execution Log;
- Send Run Output to Console Window - отправка всего вывода программы в консольное окно, открываемое в момент запуска программы;
- Default - нажатие на эту кнопку приводит к тому, что все опции и поля будут установлены в значения по умолчанию.
Загрузка имеющегося проекта
Если вам нужно открыть имеющийся проект, можно дважды щелкнуть на пиктограмме проекта JBuilder в окне Explorer (Проводник). Автоматически будет запущен Borland JBuilder, и проект будет открыт в окне AppBrowser. В среде разработки JBuilder проект открывается командой File Open/Create. На экране возникнет диалоговая панель, в которой нужно выбрать требуемый проект.
Добавление и удаление файлов проекта
Для добавления файлов в проект воспользуйтесь уже знакомой диалоговой панелью Open/Create. Откройте ее командой File Open/ Create, выберите файл, который нужно добавить, отметьте флажок Add to Project и нажмите кнопку OK. Выбранный файл будет добавлен в текущий проект и открыт в окне AppBrowser.
Еще один способ добавления файла в проект - нажать в окне AppBrowser кнопку с изображением папки, на которой нарисован знак "плюс". На экране появится та же диалоговая панель Open/Create, в которой нужно выделить добавляемый файл и нажать кнопку OK.
Для удаления файла из проекта выделите нужный файл и нажмите кнопку с изображением папки со знаком "минус" или же выберите из меню File пункт Remove from Project.
Расширение проекта
Когда проект успешно создан, его нужно расширить, добавляя в него файлы с исходными текстами на языке Java и другие файлы, которые предусмотрены вашим проектом. Используйте команду File New, чтобы вызвать диалоговую панель с различными мастерами для создания новых элементов.
В диалоговой панели New несколько страничек с закладками и много разных мастеров. Кратко рассмотрим, как пользоваться каждым из них.
Мастеры закладки New
Application. Создает готовое Java-приложение с графическим окном-наследником класса java.awt.Frame, строкой статуса, меню и кнопками быстрого доступа. На первом шаге этого мастера появляется диалоговое окно, в котором вводится обязательная информация:
- Package - пакет, в который будут добавлены классы приложения;
- Class - имя класса приложения;
- File - имя файла, в котором будет сохранен класс приложения.
Если отметить флажок Generate header comments, то в начало файла с исходным текстом будут добавлены комментарии с указанием авторства и некоторой другой стандартной информацией. На следующем шаге после нажатия кнопки Next, мастер отображает другую страницу, в которой вы вводите дополнительную информацию для создания окна приложения:
- Class - имя класса главного окна приложения;
- File - имя файла для сохранения класса главного окна;
- Title - заголовок для главного окна приложения.
Несколько помечаемых кнопок отвечают за генерацию исходного текста для дополнительных элементов окна приложения:
- Generate menu bar - добавить исходный текст для главного меню приложения;
- Generate tool bar - добавить исходный текст для инструментальной области с командными кнопками быстрого доступа;
- Generate status bar - добавить исходный текст для строки статуса;
- Generate about box - добавить исходный текст для диалоговой панели с информацией о приложении;
- Center frame on screen - расположить окно приложения по центру экрана.
Когда ввод информации завершен, нужно нажать на кнопку Finish. В результате JBuilder сгенерирует два файла с исходными текстами на языке Java, которые добавляются в новый проект.
Applet. Этот мастер создает аплет. На первом шаге мастера нужно ввести основную информацию о создаваемом аплете:
- Package - пакет, в который будет добавлен класс аплета;
- Class - имя класса аплета;
- File - имя файла, в котором будет сохранен класс аплета.
Стиль аплета определяется тремя помечаемыми кнопками:
- Generate header comments - в начале файла с исходным текстом будут добавлены комментарии с указанием авторства и некоторой другой стандартной информацией;
- Can run standalone - создать метод main(), чтобы аплет мог запускаться как самостоятельное приложение без встраивания его в HTML-страницу; это особенно полезно при отладке класса аплета;
- Generate standard methods - генерировать методы аплета show(), close() и dispose().
На втором шаге предполагается задание параметров аплета, которыми можно управлять из HTML-страницы. В результате внутри тега APPLET будут сгенерированы теги PARAM и текст для обработки этих параметров аплетом.
Таблица, в которую вы вводите данные, состоит из нескольких полей:
- Name - имя параметра, которое будет использоваться в HTML-странице;
- Type - тип переменной в аплете, которая ответственна за хранение значения параметра;
- Desc - комментарий к параметру;
- Variable - имя переменной в аплете, в которую будет записано значение параметра;
- Default - значение по умолчанию, которое присваивается переменной параметра.
Звездочкой в таблице параметров обозначаются поля, в которых обязательно должна присутствовать информация. Поле типа - раскрывающийся список, перечисляющий имеющиеся типы переменных.
JBuilder генерирует специальный метод для извлечения значений параметров, переданных аплету Web-страницей
public String getParameter(String key, String def) { return isStandalone ? System.getProperty(key, def) : (getParameter(key) != null ? getParameter(key) : def); }
и фрагмент исходного текста, извлекающий значение параметра или устанавливающий значение параметра по умолчанию:
try { counter = Long.parseLong( this.getParameter("COUNTER", "1000")); } catch (Exception e) { e.printStackTrace(); }
На третьем шаге мастера создания аплета генерируется Web-страница, из которой будет запускаться полученный аплет. Для создания такой страницы нужно отметить кнопку Generate HTML. Далее вам предстоит заполнить следующие поля:
- Title - заголовок HTML-страницы;
- Name - имя аплета для внутреннего использования тегом APPLET;
- Codebase - универсальный адрес ресурса (URL), где располагается аплет, включающий имя сервера, и каталог, откуда аплет загружается на компьютер пользователя;
- Width - ширина окна аплета в пикселах;
- Height - высота окна аплета в пикселах;
- HSpace - определяет свободное пространство в пикселах, которое должно быть оставлено слева и справа от окна аплета;
- VSpace - определяет свободное пространство в пикселах, которое должно быть оставлено сверху и снизу от окна аплета;
- Align - задает выравнивание аплета внутри HTML-страницы.
Сгенерированный и откомпилированный аплет не выполняет никакой полезной функции, но может быть запущен.
Project. С этим мастером вы уже познакомились, когда мы разбирали процесс создания нового проекта вызовом команды File New Project. И эта команда, и запуск мастера делают одно и то же.
Frame. Для создания окна приложения можно использовать мастер Frame, который создает класс-наследник от библиотечного класса java.awt.Frame. Вам нужно заполнить поля всего одной диалоговой панели:
- Package - пакет, в который будет добавлен класс окна;
- Class Name - имя создаваемого класса окна;
- File Name - имя файла, в котором будет сохранен класс окна.
Экземпляр получаемого класса нигде не создается, и даже не устанавливается заголовок окна. Поэтому, если вы хотите использовать его продуктивно, первое, что нужно сделать, - вызвать из программы конструктор сгенерированного мастером Frame класса окна:
BookFrame window = new BookFrame();
Лучше всего вставить эту строку в метод main(), который запускается виртуальной машиной Java cамым первым:
public static void main(String[] args) { BookFrame window = new BookFrame(); window.setSize(400, 200); window.setVisible(true); }
Две другие строки не менее важны. Первая изменяет размер окна до желаемого - без нее вы увидите только заголовок окна. Вторая строка выводит окно на экран, делая его видимым. Для размещения строки создания заголовка лучше всего подходит первая строка метода jbInit():
private void jbInit() throws Exception { this.setTitle("Book Frame Window"); xYLayout1.setWidth(500); xYLayout1.setHeight(300); this.setLayout(xYLayout1); }
Если вы проделаете все эти манипуляции, то получите ожидаемое - нормальное графическое окно приложения.
Dialog. Мастер Dialog предназначен для создания класса диалоговой панели. Мастер запросит у вас стандартные данные:
- Package - пакет, в который будет добавлен класс диалоговой панели;
- Class Name - имя создаваемого класса диалоговой панели;
- File Name - имя файла, в котором будет сохранен класс диалоговой панели.
Созданная диалоговая панель - это просто пустой класс Java. Как и в случае с окном класса Frame, вызов диалоговой панели нужно производить вручную. Разместите в методе main() строку создания экземпляра класса BookDlg:
BookDlg dialog = new BookDlg(new Frame(), "Диалоговая панель BookDlg",true); dialog.show(); // Показать диалоговую панель на экране
В конструкторе класса нужно обратить особое внимание на его первый параметр. Им должна быть ссылка на окно-родитель диалоговой панели. В реальном приложении мы передали бы корректную ссылку, но в нашем примере для простоты передается ссылка на новое невидимое пустое окно. Второй параметр - это текст заголовка окна панели, а третий говорит о том, что создаваемое диалоговое окно модальное, т. е. выполнение приложения останавливается до тех пор, пока диалоговая панель не будет закрыта. Если установить этот параметр в false, то полученное окно диалоговой панели будет немодальным, т. е. независимым от главного окна приложения, самостоятельным. Таким окном, например, является диалоговая панель поиска из замены текстового процессора Microsoft Word.
Panel. Процесс создания панели практически ничем не отличается от создания диалоговой панели (см. выше Dialog). Заметим лишь, что запускать панель на выполнение как самостоятельный класс не рекомендуется. Использовать панели нужно в качестве визуального компонента для окон и аплетов, а также в качестве базового класса для новых компонентов.
Data Module. Модули данных, которые получаются в результате работы мастера Data Module, используются в качестве контейнеров для компонентов доступа к базам данных. Мы рассмотрим их, рассказывая о создании СУБД с помощью Borland JBuilder. Пока же достаточно знать, что мастер Data Module запрашивает стандартную информацию для записи класса файла:
- Package - пакет, в который будет добавлен класс модуля данных;
- Class Name - имя создаваемого класса модуля данных;
- File Name - имя файла, в котором будет сохранен класс модуля данных.
- Class. Каждый раз, когда вам потребуется создать новый класс, воспользуйтесь мастером Class. Он создаст новый класс, запишет его в файл и добавит этот файл в проект. В диалоговой панели, которую открывает мастер Class, есть четыре поля для ввода текста:
Package - пакет, в который будет добавлен новый класс;
- Class Name - имя создаваемого класса;
- File Name - имя файла, в котором будет сохранен созданный класс;
- Extends - полное имя класса, от которого наследуется новый класс (по умолчанию это java.lang.Object).
Некоторые параметры устанавливаются помечаемыми кнопками:
- Generate header comments - сгенерировать в начале файла с исходным текстом заголовок, в котором записываются комментарии: информация об авторстве, версии проекта и т. д.;
- Public - сделать новый класс public;
- Generate parameterless constructor - при включенной опции для класса будет создан пустой конструктор (по умолчанию без параметров);
- Generate main function - внутри класса будет сгенерирован метод main(), внутри которого создается экземпляр класса, созданный мастером Class.
Внутри нового класса имеется специальное поле invokedStandalone. Оно не так уж необходимо, потому что не несет никакой функциональной нагрузки. Но его можно использовать в качестве флага, указывающего, что данный класс запущен как самостоятельное приложение. Это демонстрирует вторая строка метода main(). Впрочем, это может понадобиться в тех редких случаях, когда ваш класс должен работать и как класс для других приложений, и как самостоятельное приложение.
HTML. Этот мастер делает простейшую HTML-страницу, добавляя ее к проекту. Он крайне примитивен, поэтому вам придется самостоятельно даже переименовывать полученные файлы страниц HTML. Исходный текст страницы, получаемый в результате работы мастера HTML, минимален:
<HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251"> <TITLE> The Title </TITLE> </HEAD> <BODY> The text </BODY> </HTML>
Мастеры закладки Panels
Tabbed pages. Этот весьма интересный мастер создает страницы с закладками Tabbed pages. Получаемый в результате работы этого мастера файл с исходным текстом на Java выполняет создание панели с тремя закладками по умолчанию и двумя кнопками - OK и Cancel.
Закладки переключаются, но обработчики нажатия кнопок пустые, рассчитанные на то, что вы сами добавите в них требуемый текст. Чтобы увидеть всю эту конструкцию из панелей, закладок и кнопок, вы, как обычно, должны создать окно-контейнер (Frame, Applet, Dialog и т. д.) и добавить в него соответствующий исходный текст:
window.add( new TabbedPages() );
Обратите внимание на то, что эта строка должна быть расположена где-то до появления окна на экране:
window.setVisible(true);
иначе вы обнаружите мерцание при добавлении всех компонентов в окно.
Dual list box. Этот мастер создает исходный текст, реализующий панель с двумя списками, кнопками OK и Cancel и четырьмя кнопками для переноса элементов из одного списка в другой.
Двойной список должен быть добавлен в окно-контейнер, и с ним также нужно начинать работать из окна визуального дизайнера.
Мастер закладки Menus
StandardMenu. Мастер создает класс StandardMenu, в котором производятся все стандартные действия по созданию и инициализации пунктов меню. В результате вы получаете полноценное меню, состоящее из трех пунктов: File, Edit и Help. Они содержат стандартные подпункты, принятые в основных коммерческих приложениях. Чтобы воспользоваться меню, полученным в результате работы мастера StandardMenu, сначала вставьте в исходный текст окна-контейнера, унаследованного от класса java.awt. Frame, строчку, которая добавит меню в окно:
window.setMenuBar(new StandardMenu());
Далее в панели навигации выберите файл StandardMenu.java и откройте визуальный дизайнер. Добавьте нужные пункты меню и удалите ненужные, после чего приступайте к созданию обработчиков событий от меню.
Мастеры закладки Dialogs
About Box. Мастер About Box предоставляет возможность создать панель с информацией о вашем приложении. После запуска этого мастера в вашем проекте появляется новый файл AboutBox.java с исходным текстом класса диалоговой панели About. Отредактируйте его изображение в визуальном дизайнере как вам нравится. Чтобы показать диалоговую панель на экране, воспользуйтесь такой строкой текста:
AboutBox about = new AboutBox(window, "About", true);
Первый параметр конструктора, который ссылается на главное окно программы, не может быть проигнорирован, иначе будет возбуждена исключительная ситуация.
ПВызывать диалоговую панель About лучше всего из обработчика пункта меню Help About:
about.show();
Standard Dialog1 и Standard Dialog2. Мастер Standard Dialog1 создает обычную диалоговую панель с единственной панелью и кнопками OK и Cancel, располагающимися в нижней части окна. И напротив, мастер Standard Dialog2 размещает кнопки в правой части окна. Зайдя в визуальный дизайнер, вы можете отредактировать полученную диалоговую панель и обработчики нажатия кнопок. Вызов диалоговой панели уже знакомым вам методом show().
Password Dialog. Как вы, наверное, уже догадались, мастер Password Dialog создает исходный текст диалоговой панели для ввода пароля. Это простая диалоговая панель с единственным отличием: текст, который набирает пользователь, заменяется строкой специальных символов, чтобы посторонние не могли увидеть тот текст, который вы набираете.
Мастер закладки Data Modules
Employee Data. Это единственный мастер, представляющий собой готовый модуль данных. Он предназначен для создания базы данных служащих и настроен на базу данных примера, поставляемого вместе с локальной копией сервера InterBase. Используйте его как шаблон для создания своих собственных модулей данных. Вам понадобится перенастроить его на свою задачу, изменив имена баз данных и некоторые другие параметры. В остальном Employee Data - это готовое промежуточное звено для клиент-серверного приложения.
Мастеры закладки BeansExpress
Мастеры этой закладки составляют набор BeansExpress, с помощью которого возможно быстрое создание компонентов JavaBeans:
- New Bean - этот мастер создает новый пустой компонент JavaBeans;
- OK Cancel Bean - создает новый компонент JavaBean с кнопками OK, Cancel, Help;
- DB Bean - мастер создания простейшего компонента JavaBeans для баз данных с сеткой просмотра записей и навигационными кнопками;
- Bean Info - запуск данного мастера вызывает диалоговую панель Paste Snippet с примерным исходным текстом для класса BeanInfo, в котором хранится информация о компоненте JavaBeans;
- New Event Bean - этот мастер также вызывает диалоговую панель с заготовкой исходного текста для создания нового компонента-события.
Мастер закладки Other
Example Snippet. Мастер Example Snippet - это диалоговая панель с примером простейшего исходного текста создания и инициализации визуального класса-наследника от BevelPanel. Он примечателен тем, что предоставляет рабочий фрагмент текста, общего практически для всех визуальных классов. Следовательно, создание нового такого класса упрощается до предела. Запустив мастер, вы изменяете исходный текст, как вам требуется, и, нажав кнопку OK, создаете новый файл с новым классом. Внутри полученного исходного текста уже имеются методы инициализации и установки экранных размеров, строки импорта необходимых компонентов и обработчик исключительной ситуации, возникающей в процессе создания экземпляра класса.
Как ознакомиться с иерархией классов
Среда JBuilder предоставляет пользователю инструмент просмотра иерархии выбранных классов. Если вы укажете на файл с определенным классом и нажмете правую кнопку мыши, то возникнет локальное меню, в котором нужно выбрать команду Class Hierarchy. Откроется дополнительная закладка Hierarchy в окне AppBrowser. В навигационной панели будет показана вся иерархия выбранного класса вплоть до предка всех Java-классов java.lang.Object.
Вы можете изучить устройство классов и их предков, что во многих случаях оказывается весьма полезным, а завершив работу с иерархией, закройте закладку Hierarchy. Для этого щелкните на ней правой кнопкой мыши и выберите пункт меню Drop Hierarhy tab.
Создание аплета
В данной главе мы попрактикуемся в создании аплета с помощью JBuilder. Наш аплет будет сканировать всю файловую систему того диска, с которого он запускается.
Воспользуемся мастером создания аплета, расположенным в диалоговой панели New, вызываемой командой File New New Applet.
На экране появится диалоговая панель, в которой задается основная, формирующая скелет проекта информация.
Для начала нужно заполнить поле Package, в которое будет помещен класс, а затем поле Class (название класса). Можно пренебречь именем пакета. В этом случае будет создана безымянная группа. Однако лучше не игнорировать поле Package и давать пакетам осмысленные имена, иначе спустя некоторое время вы получите форменную свалку из безымянных пакетов и файлов. И уж поверьте, вам придется основательно покопаться в исходных текстах, чтобы разобраться. Мы будем благоразумны и создадим отдельный пакет Applets. Вы можете размещать там все создаваемые аплеты. Класс нашего аплета будет называться скромно - Applet1. После ввода этой информации вы увидите, что в поле File появится полное имя генерируемого файла исходного текста аплета, включая полный путь к каталогу, в котором он будет размещен. Это полезно для контроля правильности действий.
Теперь при желании можно воспользоваться тремя отмечаемыми кнопками, включающими дополнительные полезные возможности. Выбрав кнопку Generate header comments, вы инициируете генерацию специального заголовка, располагающегося в самом начале исходного текста аплета. Заголовок содержит общую информацию о проекте, которая, по вашему мнению, будет интересна тем, кому придется читать ваши исходные тексты. Эта информация пригодится и вам, если спустя некоторое время вы решите снова обратиться к старому проекту.
Следующая кнопка, Can run standalone, будучи включенной, приводит к генерации статического метода main(), в котором происходит вызов класса аплета. Это весьма полезно при отладке класса Java без применения браузера. Кроме того, вы получаете класс, который может запускаться и как аплет, и как приложение. В последнем случае нужно найти в начале исходного текста аплета описание переменной:
boolean isStandalone = false;
и заменить его строкой:
boolean isStandalone = true;
Теперь вы можете запустить аплет как оконное приложение, используя Java-загрузчик с именем java.exe или его отладочную версию java_g.exe. Это приведет к появлению обычного окна класса Frame, внутри которого "вклеен" аплет. Не правда ли, удобный способ?
Последняя кнопка, Generate standard methods, определяет, следует ли мастеру New Applet произвести генерацию стандартных методов, присущих аплету: start(), stop() и destroy(). Два первых вызываются при запуске и остановке аплета соответственно. Метод destroy() будет вызван после того, как выполнение аплета остановлено, и объект аплета должен быть уничтожен. Как правило, эти методы программисты используют для захвата ресурсов и освобождения их по завершении работы. В нашем примере мы включаем кнопку Generate standard methods для создания каркаса метода start() - а зачем он нужен, станет ясно чуть позже. И хотя это мелочь, но из таких тактических мелочей складывается успешная стратегия программирования. Введя информацию, нажимаем Next>, чтобы перейти на следующий этап генерации аплета.
Теперь займемся созданием программного интерфейса передачи параметров, заданных в HTML-странице тегами <PARAM>. Эти теги являются составной частью тега <APPLET>, определяющего класс встраиваемого аплета, его местоположение и другую подобную информацию.
К этому моменту вы уже должны четко представлять себе, какие параметры вы хотите создать. Пропустив хотя бы один из них, впоследствии, завершив генерацию исходных текстов, вы сможете добавить параметры только вручную. Интерфейс диалоговой панели достаточно понятен.
Начнем с того, что введем в поле Name имя планируемого параметра - showFiles. Если присвоить ему значение True, то наш аплет проведет детальное сканирование файловой системы. В свою очередь значение False приведет к сканированию только на уровне каталогов, без учета файлов. Далее определим тип создаваемого параметра. Очевидно, раз этот параметр может иметь лишь два состояния, для него нужно использовать логический тип boolean, который вы выбираете из раскрывающегося списка в поле Type. Следующее поле Desc служит для ввода комментариев к параметрам. В общем-то особой необходимости в его использовании нет, но для порядка напишем в нем Show all (показать все). Если аплет будет запускаться кем-нибудь другим, комментарии помогут определить, для чего нужен тот или иной параметр. В следующем поле - Variable - нужно указать название переменной, в которую будет помещаться значение считанного из HTML-страницы параметра. Исходный текст, производящий считывание параметров и запись их в указанные вами переменные, генерируется средой JBuilder автоматически. Чтобы имя переменной было и в дальнейшем понятным, можно к нему прибавить префикс var - varShowFiles. Данный способ создания имен является личным изобретением автора, которым он пользуется давно и находит его удобным. Вы же можете задавать имя и по-другому, поскольку здесь нет никаких правил. Главное, чтобы вам самим было понятно, для чего предназначена та или иная переменная. Закончив создание параметра, мы нажимаем на кнопку Next>. Если же вам нужен не один, а несколько параметров, то после ввода информации о каждом нажмите кнопку Add Parameter и введите данные для получения следующего параметра.
Последние действия мастера Applet производят создание HTML-страницы, обрамляющей наш аплет. Она позволяет протестировать работу аплета с помощью браузера WWW или утилиты AppletViewer (входит в поставку как пакета JBuilder, так и стандартного набора разработчика JDK).
Для начала нужно проверить, отмечена ли кнопка Generate HTML Page. Если выключить ее, HTML-страница создана не будет. Затем введите заголовок страницы, набрав его текст в поле Title. В следующем поле Name введите имя, которое будет присвоено аплету. Через него вы сможете ссылаться на аплет из скриптовых программ (написанных на языках управления объектами Web-страниц) и программ на языке Java. Наш аплет мы назовем просто - Applet1, однако еще раз напоминаю о необходимости присваивать разумные имена. Параметры, указанные в полях Width и Height, ответственны за изначальный размер окна аплета, а параметры в полях HSpace и VSpace - за промежуток между окном аплета и соседними с ним элементами страницы Web, список Align предложит варианты выравнивания. Поле Codebase опишем отдельно. Его значение не имеет отношения к геометрии. Им задается местоположение файла класса аплета. Это может быть полный URL-адрес сервера с подкаталогом, где лежит откомпилированный файл загружаемого аплета, или же путь к нему относительно Web-страницы, через которую аплет запускается. В простейшем случае, когда и аплет, и его страница располагаются в одном каталоге, в поле Codebase нужно ввести символ "." (текущий каталог) или же сделать его пустым. Когда все поля заполнены, остается лишь нажать кнопку Finish, чтобы сгенерировать проект аплета со всеми его файлами.
В левой верхней панели AppBrowser отобразится дерево только что созданного аплета:
<HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251"> <TITLE> Applet1 Page </TITLE> </HEAD> <BODY> Applet1 will appear below in a Java enabled browser.<BR> <APPLET CODEBASE = "." CODE = "Applets.Applet1.class" NAME = "Applet1" WIDTH = 400 HEIGHT = 300 HSPACE = 0 VSPACE = 0 ALIGN = left > <PARAM NAME = "ShowFiles" VALUE = "False"> </APPLET> </BODY> </HTML>
Обратите внимание: JBuilder, генерируя исходный текст Web-страницы, учел наши локальные настройки и указал в метапараметре заголовка выбранную нами кириллическую кодировку символов ANSI 1251:
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1251">
Кроме того, JBuilder корректно прописывает имя класса аплета:
CODE = "Applets.Applet1.class"
Как видите, имя указано с учетом пакета, в котором сохраняется класс, что избавляет нас от потенциальной ошибки, когда браузер не может обнаружить и запустить аплет. А вот и параметр аплета, который был нами задан ранее:
<PARAM NAME = "ShowFiles" VALUE = "False">
Если теперь переключиться на файл Applet1.java с исходным текстом аплета, то вы обнаружите перекрытый метод getParameter(), который и занят извлечением параметров из HTML-страницы:
public String getParameter(String key, String def) { return isStandalone ? System.getProperty(key, def) : (getParameter(key) != null ? getParameter(key) : def); }
Обратите внимание, что при запуске аплета в качестве самостоятельного приложения (вспомните отмечаемую кнопку Can run standalone) для чтения параметров вместо общепринятого метода getParameter() применяется чтение системных свойств (properties). Но это еще не все. Внутрь метода init() среда JBuilder добавляет строку, которая вызовет перекрытый метод getParameter(), а полученный результат приведет к заданному нами ранее типу параметра:
try { varShowFiles = Boolean.valueOf( this.getParameter("ShowFiles", "True")).booleanValue(); } catch (Exception e) { e.printStackTrace(); }
Продолжим работу над примером созданием визуальной части аплета. Щелкните на закладке Design для входа в визуальный дизайнер. Щелкните в палитре компонентов на пиктограмме TreeControl и затем - на панели. Компонент будет размещен в пустой панели аплета. Затем у панели, которую вы можете обнаружить в дереве компонентов под ярлыком this, нужно изменить свойство layout на BorderLayout. Это приведет к тому, что компонент будет растянут на всю панель.
А сейчас самое время заняться самим исходным текстом аплета. Первое, что требуется предпринять, - отыскать корневой элемент файловой системы, поэтому напишем для этого специальный метод:
private String findFSRoot() throws IOException { File appletDir = new File("."); String curPath = appletDir.getCanonicalPath(); String root; separator = File.separatorChar; int index = curPath.indexOf((int)separator); root = curPath.substring(0, index); if(root.equals("")) root = new String( new char[]{ separator }); return root; }
Создадим объект класса File, который будет отображать элемент текущего каталога (скорее всего, это "песочница", т. е. каталог, отведенный системой для безопасного исполнения аплета), поэтому конструктору объекта передается символ ".", принятый во многих ОС как ссылка на текущий каталог. Класс File нужен для того, чтобы воспользоваться его методами, столь удобными для выполнения нашей задачи. Это видно из второй строчки, где вызывается метод getCanonicalPath(), возвращающий полный путь к текущему каталогу. Четвертой строкой определяется символ-разделитель, используемый операционной системой пользователя (а мы понятия не имеем, где запущен аплет) для разделения каталогов при описании пути. Следующая строка производит поиск первого от начала символа-разделителя в пути к текущему каталогу, начиная с которого метод substring() отрежет остаток строки. Полученный начальный фрагмент пути есть не что иное, как обозначение корня файловой системы. Для тех операционных систем, у которых роль корня выполняет символ-разделитель, как, например, Unix, в предпоследней строке значению корня файловой системы присваивается значение символа-разделителя. Полученный корневой элемент возвращается методом.
Теперь мы подобрались к самому интересному месту - напишем метод сканирования файловой системы. Ему в качестве параметров передаются: каталог, с которого нужно начинать, ссылка на компонент TreeControl и ссылка на текущий узел дерева этого компонента:
private void enumDirTree(String dir, TreeControl tree, GraphLocation node) throws IOException { int i; String[] list; File curDir = new File(dir); GraphLocation curNode = ( node == null ) ? tree.setRoot(dir): tree.addChild(node, curDir.getName()); list = curDir.list(); for(i = 0; i < list.length; i++) { File tmp = new File(curDir, list[i]); if(tmp.isDirectory()) { enumDirTree(dir + separator + list[i], tree, curNode); } else { if(varShowFiles) tree.addChild(curNode, list[i]); else continue; } if(node == null) tree.expand(curNode); } }
Сначала метод enumDirTree() создает на базе переданного ему активного каталога объект класса File. Затем происходит проверка переданного в параметре node узла дерева (который представляет собой ссылку на класс GraphLocation) на значение null. Если это так, то метод вызван для корневого каталога, и вызывается метод setRoot() компонента TreeControl, устанавливающий корневой элемент отображаемого дерева. В противном случае считается, что метод enumDirTree() уже был вызван и переданный ему первым параметром каталог является подветвью корня дерева и для его отображения вызывается метод addChild(). Первым параметром ему передается ссылка на текущий узел дерева, а вторым - строка с именем добавляемого элемента. Правда, в процесс извлечения этого имени вовлекается метод getName() класса File. Он выделяет имя файла или каталога из полного имени. Обратите внимание, что и setRoot() и addChild() возвращают после добавления элемента дерева ссылку на него, которую мы сохраняем до поры до времени.
На следующем этапе вызывается еще один интересный метод класса File. Это метод list(), производящий перечисление всех элементов текущего каталога и возвращающий их имена в массиве строк. С этого момента запускается цикл, перебирающий возвращенные элементы. Если очередной элемент массива представляет собой ссылку на каталог, то enumDirTree() рекурсивно вызывает сам себя, задав в качестве текущего каталог, переданный ему через параметр dir с добавленным к нему символом-разделителем и названием каталога, выбранного из переменной list. Последним параметром передается ссылка на последний добавленный узел каталога, сохраненный нами ранее. Затем процесс повторяется.
Если выбранный из массива элемент является простым файлом, нужно проверить значение переменной varShowFiles, в которую при запуске аплета было записано значение параметра ShowFiles. Если оно равно false, то файл пропускается оператором continue и цикл начинает новую итерацию. В противном случае уже знакомый нам метод addChild() добавляет название файла в текущий узел отображаемого дерева компонента TreeControl. И в довершение всего последняя строчка метода проверяет, не корневой ли узел дерева мы обрабатываем. Если это так, то он раскрывается, чтобы были видны ветви-подэлементы корневого узла. Данное добавление - чисто косметическое, но оно придает нашему аплету профессиональный вид.
И вот, наконец, дошел черед до метода enumDirTree(). По мнению автора, лучшего места, где он должен быть вызван, чем метод start(), просто нельзя придумать:
public void start() { try { enumDirTree( findFSRoot(), treeControl1, null ); }catch (IOException x) { x.printStackTrace(); }; }
Здесь, собственно, наверное, все понятно: методу enumDirTree() в качестве первого параметра (текущий каталог) передается возвращенный методом findFSRoot() корневой каталог, второй параметр - это ссылка на компонент treeControl1, которую среда JBuilder поместила в исходный текст аплета в тот момент, когда мы положили компонент TreeControl в панель, находясь в визуальном дизайнере. Последний параметр устанавливается равным null, показывая, что метод вызван для корневого каталога. Если желаете начать перебор с другого каталога, то передайте его полное название в качестве первого параметра метода enumDirTree(), а третий параметр все равно должен оставаться null. Поскольку enumDirTree() плотно работает с операциями ввода-вывода, то он размещается в блоке try-catch, который в случае сбоя перехватит управление.
Запустите откомпилированный аплет, нажав комбинацию клавиш <Shift>+<F9>. Автор намеренно не приводит вид работающего класса. Пусть это будет вашим "домашним заданием": повторите описанный проект и посмотрите результат сами. И еще. Если вы попробуете запустить этот аплет с помощью браузера, то у вас ничего не получится, поскольку менеджер защиты виртуальной машины Java не разрешает читать дисковую информацию на чужой машине. Компания Sun обещала, что в JDK 1.2 будет предусмотрена возможность устанавливать уровни защиты по желанию пользователя. Пока же вы можете воспользоваться утилитой AppletViewer из комплекта JDK (в каталоге JBuilder\Java\bin). Для нее ограничений защиты не существует.
Итак, мы рассмотрели пример создания аплета средствами JBuilder. Конечно, рекурсия, примененная нами, и частые проверки весьма тормозят выполнение кода. Однако не стоит обращать на это внимания. Главное, чтобы вы поняли, как работает мастер Applet. А на следующем занятии мы поговорим о создании оконных приложений.
Создание оконного приложения
Начну с того, что в предыдущей главе, поясняя, как создаются аплеты, я отметил, что просмотреть изготовленный пример с помощью браузера не удастся из-за несовершенства последних и срабатывания механизмов защиты. Однако уже кое-что успело измениться. На сервере корпорации Sun Microsystems (http://sun.java.сom) появился весьма интересный набор утилит под названием Java Activator. Среди прочих возможностей набор обеспечивает замену виртуальной машины Java в браузерах Internet Explorer 4.x и Netscape Communicator 4.x стандартной виртуальной машиной Java из комплектов Java Development Kit (JDK) и Java Runtime Environment (JRE). Обладая одним из них, можно использовать их виртуальную машину для нужд Java Activator. Что это значит? А то, что аплет, созданный на предыдущем занятии, можно все-таки увидеть в окне браузера, если установить Java Activator и в соответствии с имеющимися инструкциями слегка изменить Web-страницу, в которую встроен класс аплета. Механизм работы Activator весьма прост. Вы заменяете ссылку на аплет внутри Web-страницы ссылкой на ActiveX (тег <OBJECT>) из дистрибутива Java Activator. При запуске ActiveX отыскивает стандартную виртуальную машину Java фирмы Sun и передает ей ваш аплет.
Однако вернемся к теме этой главы: созданию оконных приложений. Свое название они получили оттого, что являются независимыми и имеют свое собственное окно (или несколько окон) в отличие от аплета, который пользуется для своего отображения окном браузера. Оконным Java-приложениям разрешено очень многое, даже то, что аплетам противопоказано, например обращение к файловой системе компьютера или манипуляции с файлами и каталогами. А еще оконные приложения могут иметь свое собственное меню, как и окна любых исполняемых программ, и командное меню, для которого даже предложена пиктограмма в левом верхнем углу заголовка окна. Оконные приложения с успехом используются в интрасетях предприятий, где компьютеры являются элементами одной сетевой файловой системы и такие программы можно запускать с удаленных компьютеров. Хорошим примером оконного приложения можно назвать консоль Java браузера Netscape Communicator 4.x.
Кстати, практически все мастеры пакета JBuilder также являются оконными приложениями Java, о чем свидетельствует пиктограмма с дымящейся чашечкой в заголовке окна. Такую пиктограмму виртуальная машина Java выводит по умолчанию, если вы не указали никакого другого изображения для данного окна.
JBuilder может изготовить оконное приложение тремя основными способами. Первый мы обсудили на прошлом занятии. На одном из этапов мастера New Applet вы отмечаете кнопку Can run standalone и получаете аплет, который можно запускать как самостоятельное оконное приложение. Но это обходной путь. Второй метод: вызвав мастер Frame, вы создаете заготовку оконного класса со всеми элементами. Однако этот мастер не создает метод main(), являющийся точкой входа в оконное приложение и чаще всего запускающий класс окна. Оптимальным, на мой взгляд, является третий метод, предлагающий использовать мастер New Application. С его помощью вы получите полноценное оконное приложение, готовое к запуску.
Для того чтобы воспользоваться мастером New Application, создадим очень компактный редактор системных файлов Autoexec.bat и Сonfig.sys, соответствующий следующим условиям:
- на панели быстрого доступа должны располагаться кнопки с надписями Autoexec.bat и Config.sys, нажатие на которые должно приводить к открытию соответствующего файла в окне редактора;
- при открытии любого из двух файлов должна создаваться его резервная копия (Autoexec.bat.bak или Config.sys. bak);
- при закрытии редактора должно происходить автоматическое сохранение файла;
- если вы открыли один из файлов нажатием на кнопку в панели быстрого доступа, то при нажатии другой кнопки редактируемый файл должен быть сохранен, а в окно должен быть загружен следующий файл, затребованный пользователем.
JBuilder создает оконное приложение в два этапа. Сначала запустите мастер Application командой File New Application. На экране возникнет панель с уже знакомыми нам полями Package и Class. Чтобы получить заголовочный комментарий в начале файла, включите отмечаемую кнопку Generate header comments.
Необходимо отметить, что JBuilder при создании оконного приложения формирует отдельно два класса: класс окна и класс приложения. Класс окна управляет отображением окна приложения и его визуальных элементов, тогда как класс приложения является запускаемой частью, которая после старта показывает окно, размещая его в центре экрана. Это помогает сделать исходные тексты программы модульными и более пригодными для чтения.
На втором этапе определим имя класса окна приложения (в поле Class) и надпись на заголовке окна (поле Title). О других параметрах поговорим отдельно.
Это пять отмечаемых кнопок диалоговой панели, которые заведуют созданием дополнительных возможностей при генерации исходного текста оконного класса.
- Generate menu bar. Эта кнопка отвечает за создание меню и подключение его к главному окну приложения. Меню генерируется с двумя элементами File и Help, содержащими по одному пункту: Exit и About соответственно. В исходном тексте оконного класса вы обнаружите фрагмент исходного текста, манипулирующий объектами класса MenuBar, Menu и MenuItem. Это и есть то место, где происходит добавление меню в окно.
- Generate tool bar. Кнопка отвечает за генерацию исходного текста, отображающего полосу быстрого доступа с кнопками. Если включить данную кнопку, то в процессе работы мастера Application будет сгенерирован экземпляр компонента ButtonBar с несколькими готовыми кнопками, а сама полоса будет размещена в верхней части окна приложения.
- Generate status bar. Отметив эту кнопку, вы добавите к создаваемому приложению панель статуса, что позволит выводить полезную информацию. Программно это делается добавлением к исходному тексту оконного класса экземпляра компонента StatusBar, а через его свойство text вы можете выводить текст, который желаете показать пользователю вашего приложения.
- Generate about box. Если вы обратили внимание, практически невозможно найти ни одного коммерческого приложения, у которого бы не было диалоговой панели About с информацией о самой программе и ее авторах. Кнопка Generate about box предназначается для того, чтобы мастер Application создал заготовку диалоговой панели для показа информации о вашей программе. Причем при включенной кнопке Generate menu bar будет осуществлена привязка информационной диалоговой панели к меню Help About.
- Center frame on screen. Эта кнопка будет полезна в том случае, если вы пожелаете разместить окно программы точно посередине экрана. Это, надо сказать, не самая тривиальная задача в Java. Однако мастер Application знает, как ее решить. Он добавит к классу приложения специальный фрагмент исходного текста, выполняющий центровку окна на экране:
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); if (frameSize.height > screenSize.height) frameSize.height = screenSize.height; if (frameSize.width > screenSize.width) frameSize.width = screenSize.width; frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); frame.setVisible(true);
Изменение пользовательского интерфейса
Итак, запустив мастер Application, задав имя класса приложения SysEditApp и имя класса окна SysEditFrm, определив надпись заголовка окна "System Files Editor" и включив все пять отмечаемых кнопок, мы создали приложение.
Если полученный результат вас устраивает, процесс завершен. Если же интерфейс хочется поменять, действуем дальше. В панели навигации выделите файл, в котором располагается класс окна, и щелчком на закладке Design запустите визуальный дизайнер, но прежде всего уберите рисунки с кнопок быстрого доступа. Для этого в окне инспектора поменяйте значение свойства buttonType на textOnly. Таким образом, все рисунки с кнопок будут убраны и вместо них появятся надписи, заданные свойством labels. Его значение тоже нужно изменить. Щелкните на строке labels в окне инспектора и в появившемся диалоговом окне, нажав на кнопку Remove, уберите все имеющиеся строки. Затем два раза нажмите кнопку Add, чтобы добавить два новых элемента, после чего двойным щелчком по очереди переведите их в режим редактирования и измените текст на Autoexec.bat и Config.sys, соответственно. Когда вы нажмете на кнопку OK, то увидите, что вид кнопок изменился. Картинки исчезли, появились названия, введенные нами, а самих кнопок стало две - по числу текстовых строк, введенных в поле свойства labels.
Теперь нам потребуется создать поле редактирования. Для этой цели хорошо подойдет компонент TextAreaControl из палитры Controls. Но прежде чем добавлять его, удалите большую панель в центре окна. Она была создана JBuilder автоматически, хотя мы в ней и не нуждались. Ненужный компонент - это балласт, который лишь замедляет работу программы и забирает ресурсы. Вместо удаленной панели мы разместим компонент TextAreaControl, который займет все свободное место в окне - от панели кнопок быстрого доступа до панели статуса. Если этого не произошло, стоит проверить значение свойства constraints - оно должно содержать значение Center. В заключение у добавленного компонента измените значение свойства enabled на False. Этим мы отключим компонент, и пользователь не сможет ничего написать в окне редактора до тех пор, пока не загружен какой-нибудь из системных файлов.
Мы чуть не забыли изменить внешний вид диалоговой панели About так, чтобы отображалась информация о нас. К сожалению, в визуальный редактор саму диалоговую панель загрузить не удастся. Однако мы можем сделать это с помощью исходного текста инициализации класса панели, для чего придется вернуться из визуального дизайнера в редактор и исправить несколько строк. В описании класса SysEditFrm_About найдите строки с показываемой текстовой информацией и измените их примерно следующим образом:
String product = "System Files Editor"; String version = "0.99.a"; String copyright = "Copyright (c) 1998"; String comments = "Пользуйтесь на здоровье!";
Конечно, вы можете сами задать необходимые тексты, а предлагаемый вариант служит лишь примером.
Вы обратили внимание, что JBuilder зарезервировал свободное место под символ вашей фирмы или нечто подобное? Однако самого изображения нет. Чтобы добавить его, разыщите в методе jbInit() панели About строку:
imageControl1.setImageName("");
Эта "пустышка" специально оставлена, чтобы мы могли указать имя графического файла в формате JPG или GIF. Нарисуйте свой логотип и сохраните его как logo.gif, а показанную выше строчку установки логотипа измените следующим образом:
imageControl1.setImageName(".\\logo.gif");
На этом процесс изготовления пользовательского интерфейса завершен, и пора переходить к созданию программной "начинки".
Пишем исходный текст
Для начала определим, какие обработчики событий потребуются для выполнения технического задания. Первый и главный обработчик должен срабатывать при нажатии кнопок на панели быстрого доступа. Очевидно, это будет обработчик события actionPerformed компонента ButtonBar. Второй обработчик перехватывает событие actionPerformed, приходящее от главного меню приложения в тот момент, когда пользователь выбрал команду меню File Exit. И третий обработчик должен вызываться, если пользователь закрывает окно не через меню, а с помощью системного меню окна или кнопки закрытия. Этим требованиям вполне отвечает событие windowClosing, возникающее при закрытии окна, но еще до его уничтожения. Перед началом основной работы по созданию исходных текстов добавьте в описание класса окна переменную-поле, которая будет хранить имя открытого для редактирования файла:
String fileName = null;
Начнем с первого обработчика actionPerformed компонента ButtonBar. Откройте визуальный дизайнер для класса окна и произведите двойной щелчок мышью на этом компоненте. JBuilder перенесет вас в редактор исходного текста, где для вас уже изготовлен пустой обработчик требуемого события. Мы с вами будем набирать его исходный текст постепенно и комментировать фрагмент за фрагментом. Для выполнения поставленной задачи потребуются две переменных. Одна будет использоваться для временного хранения считанных байт информации, а вторая, класс StringBuffer, - для хранения и форматирования текстов:
void buttonBar_actionPerformed(ActionEvent e) { int tmp; StringBuffer buff = new StringBuffer();
Далее нужно проверить, было ли присвоено полю fileName имя редактируемого файла. Если значение fileName равно null, то это значит, что в окне редактора нет открытого файла. Если же файл был открыт, то его необходимо сохранить, вызвав метод saveFile(), о котором будет сказано далее:
if( fileName != null ) saveFile();
Теперь, когда приняты все меры предосторожности, требуется определить, какая из кнопок на панели быстрого доступа была нажата. Структура ActionEvent, передаваемая обработчику события actionPerformed, имеет в своем составе поле actionCommand, содержащее надпись, которую вы видите на нажимаемой кнопке. Его можно извлечь методом getActionCommand():
fileName = e.getActionCommand();
Правила хорошего программистского тона требуют от нас создать резервные копии редактируемых файлов. Следовательно, нужно открыть поток вывода, являющийся на самом деле файлом, имя которого аналогично имени файла, загружаемого в редактор, но с добавочным расширением .bak:
try { FileWriter backup = new FileWriter( new File("c:\\", fileName + ".bak"));
Теперь откроем редактируемый файл:
InputStreamReader source = new InputStreamReader( new FileInputStream("c:\\" + fileName));
и байт за байтом перепишем данные из оригинального файла в резервный:
while(true) { if( (tmp = source.read()) == -1 ) break; backup.write(tmp); }
По окончании копирования данные потока вывода должны быть сброшены на диск, а сам поток следует закрыть:
backup.flush(); backup.close();
Может так статься, что в вашей системе нельзя сбросить указатель текущей позиции файла в начало, и тогда возможен лишь один способ, а именно - закрыть поток и открыть его снова:
source.close(); source = new InputStreamReader( new FileInputStream("c:\\" + fileName));
Для удобства мы будем читать данные из потока файла в строковый буфер, добавляя считанные байты друг за другом:
while(true) { if( (tmp = source.read()) == -1) break; buff.append((char)tmp); }
А когда весь файл считан, текст в буфере приводится к типу String и загружается в окно редактора путем присвоения его свойству text:
textArea.setText(buff.toString());
Остается разрешить редактирование текста в окне и закрыть редактируемый файл:
textArea.setEnabled(true); source.close(); } catch( IOException x ) { x.printStackTrace(); } }
Прежде чем мы перейдем к написанию следующих двух обработчиков, сделаем специальный метод, который будет сохранять измененные данные. Такой метод необходим, поскольку обработчики закрытия окон будут вызывать его для сохранения файлов после редактирования. Итак, первое, что должен делать метод saveFile(), - проверять, есть ли открытый файл, а если такого нет, он просто завершает свою работу: void saveFile() { if(fileName == null) return;
Откроем файл, запишем данные из окна редактирования, после чего сбросим поток и закроем его:
try { FileWriter os = new FileWriter( new File("c:\\", fileName)); os.write(textArea.getText()); os.flush(); os.close();
Чтобы отметить закрытие редактируемого файла, присвоим полю fileName значение null, а заодно очистим окно редактора и отключим режим редактирования:
fileName = null; textArea.setText(""); textArea.setEnabled(false); } catch( IOException x ) { x.printStackTrace(); } }
Вернемся к обработчикам actionPerformed и windowClosing. Первый из них создается автоматически, если вы разрешили генерацию главного меню приложения, отметив кнопку Generate menu bar в процессе взаимодействия с мастером Application. Что же касается второго обработчика, то его нужно создать вручную в окне инспектора объектов. В самое начало и первого и второго обработчика добавьте строку сохранения данных:
saveFile();
Итак, программа готова, и ее можно опробовать в действии.
Остается уладить маленькую проблему. Она не коснется программистов, пользующихся средами JBuilder и JDK. Но довольно большая часть Java-сообщества запускает программы в среде Windows и применяет в работе утилиты из привлекательного набора Microsoft Java SDK. Если вы пользуетесь утилитами jview и wjview, вам грозит неприятная ситуация: при вызове команды Help About вместо ожидаемой диалоговой панели с информацией о продукте вы увидите один заголовок. Более того, это приводит к полной блокировке программы. Не стоит винить в этом пакет Microsoft Java SDK, скорее наоборот: с его помощью мы смогли обнаружить внутреннюю ошибку библиотеки классов. Если в момент запуска jview заглянуть в консольное окно, то можно увидеть на экране сообщение об ошибке: параметр constraint менеджера BorderLayout не может быть равен null. Посмотрев все исходные тексты библиотеки Java, я так и не нашел ошибку. По всей видимости, причина кроется внутри архива classes.zip, где упакованы откомпилированные классы библиотеки. Однако с указанной проблемой можно легко справиться. В классе SysEditFrm_AboutBox разыщите метод jbInit(), а в нем строку:
this.add(panel1, null);
Второй параметр метода добавления панели должен содержать строчку, говорящую о предполагаемом местоположении вставляемого в диалоговую панель элемента. Если установлено значение null, то менеджер расположения использует значение по умолчанию (что и подтвердилось изучением исходных текстов). Однако виртуальная машина Java от Microsoft этого не делает, поэтому нужно явно указывать местоположение добавляемого компонента. В нашем примере это будет "Center":
this.add(panel1, "Center");
Эти операции полностью снимают нежелательный эффект.
Вот и подошел к концу наш учебный курс по Borland JBuilder, и теперь вы знаете достаточно для его использования. С этого момента только практика может помочь вам стать мастером своего дела. Успехов вам!