Windows Foundation Classes for Java (WFC) — набор библиотек классов, тесно взаимодействующих со
средствами RAD (Rapid Application Development) Visual J+ + . WFC в сочетании
с RAD упрощает создание быстрых и эффективных приложений и компонентов на языке
Java для операционных систем Microsoft. WFC адаптирует язык Java к платформе
Win32 и модели объектов DHTML (Dynamic HTML), принятой W3C (World Wide Web Consortium)
в качестве стандарта и реализованную в Internet Explorer 4.0. Это значит, что
Вы можете использовать Java в решении реальных задач уже сегодня и быть уверенными
в перспективах своих программ на будущее.
WFC предоставляет
взаимосвязанные модели компонентов и программирования на Java. Поскольку Java
обладает уникальным набором языковых средств, то при использовании новой модели
программирования это лучший язык для разработки Windows- и DHTML-приложений.
WFC позволяет быстро создавать полнофункциональные Win32-пpилoжения и ActiveX-элементы
на Java, при этом для добавления на форму элементов управления, настройки их
свойств и генерации обработчиков событий применяется Forms Designer среды Visual
J+ + . Разработчики могут легко обращаться из своих приложений к данным, находящимся
на сервере, и распространять эти приложения как ЕХЕ-файлы для Windows или в
виде URL, которые ссылаются на файлы, установленные на Web-сервере. А также
создавать собственные WFC-компо-ненты, используя Forms Designer и/или программируя
в текстовом редакторе среды Visual J+ + . Java-классы открывают разработчикам
доступ и к модели объектов DHTML.
В модели
прикладных программ задействованы преимущества технологии J/Direct, которая
не только обеспечивает доступ к Win32 API, но и существенно
облегчает работу, позволяя не беспокоиться о таких деталях, как сообщения, процедуры
их обработки, описатели окон и т. д. Эта модель открыта, и поэтому опытные Win32-программисты
могут смешивать вызовы J/Direct с WFC-классами, дополняя программу любой функциональностью,
доступной на платформе Win32. Если Вы хотите быстро получить первое представление
о практическом применении Visual J+ + в разработке WFC-приложений, прочтите
в главе 1 «Создание проектов» раздел «Создание Windows-приложения
с применением WFC».
Основы
работы с элементами управления и шаблонами
Одна из сильных
сторон модели WFC-компонентов в том, что среда Visual J+ + предоставляет большинство
компонентов, форм, меню и диалоговых окон, часто используемых при создании программ.
При необходимости можно расширять эти компоненты или разрабатывать собственные.
Поскольку Visual J+-I- предоставляет элементы управления, применяемые, как правило,
в Win32-cpefle, их внешний вид, наверное, покажется Вам знакомым.
Среда программирования
Visual J++ тесно интегрирована с WFC-классами, поэтому сведения, необходимые
для работы с элементами управления, формами и меню, Вы найдете в Using Visual
J+ +.
Большинство
окон приложений в WFC представляются формами. Форма применяется, когда надо
выделить один из перекрываемых графических элементов, например главное окно
программы или диалоговое окно. Она служит контейнером элементов управления,
что позволяет визуально конструировать приложения. У форм есть свойства, настраиваемые
через окно Properties. С синтаксической точки зрения, форма — это Java-класс,
производный от com.ms.wfc.ui.Form. А класс Form расширяет com.ms.wfp.ui.Control
— как и элементы управления, размещаемые на форме. Control инкапсулирует Win32-OKHO.
Когда Вы
открываете новый проект, выбирая Windows Application в диалоговом окне
New Projects, за Вас автоматически создается одна форма. Остальные формы
— если нужно — добавляются в проект командой Add Item или Add Form
из меню Project.
Вставленную
в проект форму можно модифицировать визуально (в Forms Designer) и программно
(в текстовом редакторе). Чтобы изменить размер и другие свойства формы на этапе
разработки, откройте Forms Designer. Для этого в окне Project Explorer щелкните
правой кнопкой мыши имя формы и выберите из контекстного меню команду View
Designer. Каждая форма принадлежит невидимому объекту Application,
который представляет основной поток приложения. В то же время формы и элементы
управления представляют визуальные Windows-компоненты. Интеграцию видимых и
невидимых частей окна полностью берет на себя WFC-каркас.
Открыв новую
форму в текстовом редакторе, Вы увидите класс, созданный по шаблону и содержащий
все необходимые синтаксические элементы класса Form, в том числе конструктор
и метод main с кодом, который создает экземпляр Вашей формы. Работая в Forms
Designer, Вы добавляете элементы управления, изменяете свойства и т. д., а он
соответственно модифицирует нужные части этого класса. О том, как добавить форму
в проект, см. раздел «Создание формы» главы 2 «Разработка
форм».
Добавление
элементов управления
Вы вставляете
элемент управления, просто перетаскивая его значок с панели Toolbox на форму,
изменяете его размеры и в окне Properties настраиваете нужные свойства. Visual
J + + позволяет работать как с ActiveX-, так и с WFC-элементами. Подробнее о
вставке элементов управления см. раздел «Добавление элементов управления
на форму» главы 2 «Разработка форм».
Элементы
управления можно разделить на три категории, хотя никакой разницы в принципах
их использования нет.
Все существующие
WFC-элементы являются Java-классами и хранятся в пакете com.ms.wfc.ui.
Если хотите,
создайте свои элементы управления — на основе существующих в пакетах WFC или
с нуля — и добавьте их на панель Toolbox. Модель WFC-компонентов упрощает предоставление
информации о свойствах и событиях Вашего элемента управления, способствуя его
«бесшовной» интеграции с Forms Designer. .
Меню добавляются
по аналогии с элементами управления — в Toolbox они представлены своим элементом.
Чтобы вставить меню, перетащите элемент MainMenu из Toolbox на форму.
После этого Forms Designer позволяет
добавлять команды и подменю, просто набирая их на клавиатуре. С каждым элементом
меню связан обработчик события, который можно задействовать при написании кода
программы. Как и в случае элементов управления, визуальное конструирование меню
приводит к автоматической генерации кода для соответствующих команд меню. Подробнее
о добавлении меню см. раздел «Создание меню для форм» главы 2 «Разработка
форм».
Forms Designer
помогает в создании класса формы на начальном этапе и даже генерирует большую
часть заготовок кода, например, обработчиков событий. Но все равно на какой-то
стадии разработки приложения Вам придется заняться настоящим программированием.
Методы обработки событий вызываются при изменении состояния элемента пользовательского
интерфейса, скажем, щелчке кнопки. Forms Designer создает для этих методов заготовки,
и Вам остается лишь заполнить их кодом, выполняемым при возникновении определенного
события. В модели WFC-компонентов обработка событий базируется на применении
нового ключевого слова delegate компилятора Visual J+ + . Так как при использовании
Forms Designer делегаты связывают обработчики с событиями, их можно задействовать
и в более сложных случаях, например, для создания своих событий. Делегаты, во
многом аналогичные процедурным указателям в других языках программирования,
могут пригодиться и в решении иных задач.
Кроме элементов
управления и обработчиков событий, библиотека WFC обеспечивает:
В этом разделе
дан краткий обзор создания на Visual J + + простого приложения MyNotepad, основанного
на стандартном Windows-приложении Notepad. MyNotepad — это текстовый редактор,
в меню File которого содержатся команды New, Open, Save, Save
As и Exit. Он выполняет простейшие функции любого редактора, позволяя открыть
файл, отредактировать его и сохранить результат в том же или другом файле. Заметьте,
что MyNotepad напоминает приложение JPad, сгенерированное с помощью Application
Wizard среды Visual J + +. Однако MyNotepad создан без мастера — специально
для того, чтобы четче продемонстрировать ряд основных концепций. Разобрав код
MyNotepad, Вам будет гораздо легче понимать код, генерируемый мастером Application
Wizard, так как последний использует практически те же концепции.
В основе
MyNotepad лежит форма (MyNotepad.java) с текстовым полем и меню. Вторая форма
(NewDialog.java) — модальное диалоговое окно, предлагающее пользователю сохранить
текущий файл при его закрытии или при открытии нового файла. Полные листинги
обоих файлов см. в конце главы.
Приложение
разрабатывалось с применением Forms Designer и редактора Text (текстового редактора)
среды Visual J+ + . Значительная часть кода автоматически сгенерирована Forms
Designer. В этом примере Вы увидите, что именно делает и какой код создает Forms
Designer, а также освоите несколько основных концепций программирования WFC-приложений.
Вы узнаете структуру шаблона класса Form в Visual J+ + и научитесь:
Создание
приложения в среде Visual J++
В этом разделе описаны этапы создания приложения MyNotepad с помощью Visual J+ + . Прежде чем рассматривать код, сгенерированный Forms Designer, познакомимся с тем, что, собственно, делается в среде визуального программирования.
Чтобы создать такую
форму, используйте диалоговое окно New Project, которое появляется
при запуске Visual J++ или выборе команды New Projett из меню File.
Выделите в нем значок Windows Application, введите имя приложения
(в данном случае — MyNotepad), щелкните кнопку Open, и Visual J++
создаст проект с этим именем. По умолчанию проект содержит форму с именем
Forml.java, которую следует переименовать в MyNotepad.java.
Разработать форму
в Forms Designer очень легко. Чтобы открыть ее в Forms Designer, в окне
Project Explorer выберите Forml.java, а из меню View — команду
Designer (или из контекстного меню — команду View Designer). В
открытую на экране форму можно добавлять элементы управления с панели Toolbox.
Для доступа к ее элементам управления щелкните ярлычок Toolbox или
выберите одно именную
команду из меню View, а на появившейся панели Toolbox щелкните кнопку
WFC Controls.
В данном примере на форму вставляется текстовое поле (Edit). Добавить меню тоже нетрудно: перетащите элемент MainMenu из Toolbox в любой участок формы, введите название меню в первом поле, а потом — названия его команд в соответствующих полях. Поставив перед нужной буквой знак &, можно определить клавишу доступа. Эта буква в меню будет подчеркнута.
Для этого используйте
.окно Properties. Значения большинства свойств в этом примере для простоты
оставлены теми, которые предлагаются по умолчанию. Изменены следующие свойства
текстового поля: multiline — true, doc — Fill, scrollBars — Vertical,
а в качестве шрифта выбран Fixedsys для большего сходства с Notepad.
Хотите — модифицируйте и другие свойства формы или элементов управления.
Вероятно, Вы предпочтете
переименовать некоторые компоненты, чтобы сделать их имена более осмысленными.
Для этого выберите нужный компонент (форму или элемент управления) и установите
его свойство name. В MyNotepad изменены следующие имена.
Исходное
имя (по умолчанию) |
Новое имя |
||
Editl |
EditBox |
||
MainMenu1 |
Menu |
||
Menultem1 |
FileMenu |
||
Menultem2 |
FileMenuNew |
||
MenuItem3 |
FileMenuOpen |
||
Menultem4 |
FileMenuSave |
||
MenuItem5 |
FileMenuSaveAs |
||
Menultem6 |
FileMenuExit |
||
Menultem7 |
HelpMenu |
||
MenuItem8 |
HelpMenuAbout |
||
При желании главной
форме можно присвоить имя, отличное от Forml.java. Для этого в окне Project
Explorer выделите Forml.java, щелкните правой кнопкой, из контекстного
меню выберите команду Rename и введите новое имя (в данном случае
— MyNotepad.java). После переименования Вам придется самостоятельно заменить
Forml в исходном коде на новое имя. Для этого сначала закройте Forms Designer,
потом откройте текстовый редактор, выбрав из контекстного меню команду View
Code. Теперь выберите из меню Edit команду Find and Replace
и замените все вхождения Forml новым именем (здесь — на MyNotepad).
Диалоговое окно NewDialog
— просто еще одна форма в проекте. Для создания дополнительной формы выберите
из меню Project команду Add Form, в диалоговом окне Add
Item — значок Form, введите имя новой формы (в данном случае
— NewDialog.java) и щелкните кнопку Open.
В диалоговое окно
добавьте три кнопки: YesButton, NoButton и CancelButton с Соответствующими
надписями (&Yes, &No и &Cancel). Как элемент управления, кнопка
обладает свойством dialogResult, очень удобным, когда она используется в
модальном диалоговом окне. Например, если свойству dialogResult элемента
YesButton присвоено значение Yes, то когда пользователь щелкает эту кнопку,
диалоговое окно закрывается и возвращает DialogResult.Yes. В этом примере
свойствам dialogResult трех кнопок присвоены следующие значения.
Кнопка |
Значение
свойства dialogResult |
||
YesButton NoButton CancelButton |
Yes No Cancel |
||
Класс Form имеет свойство acceptButton, которое позволяет задать, какая кнопка сработает, когда пользователь нажмет клавишу Enter. В данном примере свойство acceptButton указывает на YesButton. У класса Form есть и свойство cancelButton — оно определяет, какая кнопка сработает при нажатии клавиши Esc; установите его как CancelButton.
Как и в меню, знак & позволяет связать одну из букв в надписи на кнопке с определенной клавишей (например, надпись на кнопке YesButton — &Yes, поэтому нажатие клавиши У приведет к срабатыванию этой кнопки).
Добавьте на форму две метки для отображения в диалоговом окне текста сообщения и окно рисунка (PictureBox), свойству image которого присвойте растровое изображение — треугольник с восклицательным знаком.
Поскольку на форме появилась картинка, Visual J++ автоматически создает файл ресурсов (NewDialog.resources) и при сохранении формы записывает в него эту картинку. Файл ресурсов в данном примере используется в основном для хранения ресурсов, но позволяет локализовать форму. Если установить свойство формы localizab-1е как true, в файл ресурсов помещаются и текстовые строки.
В пакете
com.ms.wfc.app имеется статический класс Application,, обеспечивающий всю работу
с окнами средствами Win32, например регистрацию, создание экземпляров, поддержку
цикла обработки сообщений и т. д. Главное окно приложения создается при вызове
метода Application, run и передаче ему объекта, производного от класса Form.
Этот вызов осуществляется из метода main класса основной формы, созданного Visual
J++ по шаблону:
public static void main(String args[])
{
Application. run(new MyNotepad());
}
По умолчанию
приложение, созданное Visual J++ по шаблону, завершается щелчком кнопки закрытия
в правом верхнем углу его окна. Однако Вы можете завершить приложение в произвольном
месте программного кода, вызвав метод Application.exit. Данное приложение, например,
заканчивает работу при выборе команды Exit из меню File:
private void FileMenuExit_click(Object sender, Event e)
{
// вызываем
обработчик команды New из меню File,
// который откроет
NewDialog и запросит пользователя,
// следует ли
сохранить текущий текст
this.FileMenuNew_click(sender,
e);
Application.exit();
}
Рассматривая
код, выполняемый при работе программы, стоит упомянуть и о том, как пользователь
запускает приложение. Visual J++ предусматривает множество способов развертывания
проекта, один из которых — создание ЕХЕ-файла Windows, при этом приложение можно
запустить, если на пользовательском компьютере установлены WFC-классы. Они поставляются
с последней версией виртуальной машины Java, и их можно свободно распространять.
Структура
шаблона Form в Visual J++
Форма в WFC
— открытый класс, который расширяет класс Form, содержащий стандартный конструктор
и метод initForm. При создании экземпляра класса Form его конструктор вызывает
метод initForm, где
Forms Designer
размещает весь код, инициализирующий свойства формы и элементов управления.
А код, специфичный для приложения, должен находиться в конструкторе класса после
вызова initForm. В MyNo-tepad здесь задается заголовок окна приложения (хотя
эту строку можно установить и через окно Properties на этапе разработки). Конструктор
в MyNotepad выглядит так:
public HyNotepad()
{
// требуется
для поддержки Form Designer
initForm();
this.setBounds(100,
100, 300, 300);
this.setText("Untitled - MyNotepad");
}
Forms Designer вставляет объявления любых дополнительных элементов управления в тело класса непосредственно перед методом initForm. Вот объявления объектов, образующих форму MyNotepad.java:
/** ПРИМЕЧАНИЕ:
Следующий код требуется для нормальной работы Forms
* Designer.
He модифицируйте его в текстовом редакторе. */
Container components
= new Container();
MainMenu Menu
= new MainMenu();
Menultem FileMenu
= new MenuItem();
Menultem FileMenuNew
= new MenuItem();
Menultem FileMenuOpen
= new MenuItem();
Menultem FileMenuSave
= new MenuItem();
Menultem FileMenuSaveAs
= new MenuItem();
Menultem FileMenuExit
= new MenuItem();
Menultem HelpMenu
= new MenuItem();
Menultem HelpMenuAbout
= new MenuItem();
Edit editbox
= new Edit();
private void
initForm()
Forms Designer
создает не только эти объявления, но и метод initForm, устанавливающий свойства
формы и размещенных на ней элементов управления. Инфраструктура обработки событий
тоже тесно интегрирована с Forms Designer, который в методе initForm увязывает
события и обрабатывающие их методы.
Первые два
оператора метода initForm иллюстрируют, как Forms Designer настраивает свойства
объекта (в данном примере свойству Text элемента меню присваивается значение
&New) и посредством метода addOnClick объекта связывает обработчик с событием
click.
private void initForm()
{
FileMenuNew.setText("&New");
FileMenuNew.addOnClick(riew EventHandler(this.FileMenuNew_click));
}
Основная
часть кода MyNotepad — методы обработки событий, вызываемые при выборе команд
из меню. Forms Designer умеет создавать заготовки этих обработчиков. Так, чтобы
вставить обработчик для события click команды меню, достаточно дважды щелкнуть
нужный элемент в меню формы. (Двойной щелчок кнопки или команды меню создает
метод обработки события click — чтобы создать заготовку обработчика для другого
события, используйте вкладку Events в окне Properties.)
Forms Designer
включает в класс формы заготовку метода обработки события, которую впоследствии
Вы должны заполнить своим кодом, а в метод initForm — вызов MenuItem.addOnClick
соответствующего класса Menultem.
Например,
щелкнув команду меню с именем FileMenuNew, Вы добавите в класс формы метод FileMenuNew_click,
а в метод initForm — строку:
FileMenuNew.addOnClick(new
EventHandler(this.FileMenuNew_click));
Метод MenuItem.addOnClick
принимает в качестве аргумента объект EventHandler. Последний содержит ссылку
на метод, вызываемый при выборе соответствующей команды меню. Объект Menultem
отслеживает щелчки мыши и при возникновении события вызывает по ссылке (т. е.
через делегат) нужный метод обработки.
Все объекты
— обработчики событий являются делегатами, они различаются лишь объектами событий,
передаваемых обработчику. Делегат EventHandler передает ссылку на объект Event,
содержащий информацию о событии. Однако обработчик KeyEventHandler передает,
например, ссылку на объект KeyEvent, расширяющий Event для событий key-down
и keyup. (В KeyEvent имеется дополнительное поле, которое определяет Unicode-символ
и сообщает, была ли одновременно нажата и клавиша-модификатор Ctrl, Shift или
Alt.)
Большинству
программистов незачем знать о делегатах, так как в WFC-пакетах уже есть обработчики
основных событий, a Forms Designer автоматически генерирует для них соответствующий
код.
Ниже приведен
код обработчика в MyNotepad, отслеживающего выбор из меню команды New:
private void FileMenuNew_click(Object sender, Event e)
{
// если в текстовом поле имеется текст,
// проверяем, не следует ли его сохранить
if (editbox.getText().length() i= 0)
{
// открываем
модальное диалоговое окно класса NewDialog
int result =
new NewDialog().showDialog(this);
// получаем
результат;
// если нажата
кнопка Yes, открываем диалоговое окно Save As
if (result ==
DialogResult.YES)
this.FileMenuSaveAs_click(sender,
e);
// а если - кнопка No, очищаем поле и изменяем строку заголовка
else if (result == DialogResult.NO)
{ editbox.setText("");
this.setText("Untitled - MyNotepad");
} } }
Конечно,
Forms Designer создает лишь заготовку обработчика события. Код, открывающий
модальное диалоговое окно, Вы добавляете сами.
Реализация
модального диалогового окна
Когда пользователь
выберет в MyNotepad из меню File команду New, обработчик события определит,
имеется ли текст в окне элемента управления Edit. Если да, откроется модальное
диалоговое окно с запросом, следует ли сохранить текст. При щелчке кнопки Yes
будет вызван метод MyNotepad. FileMenuSaveAs_click, который позволит указать
нужный файл и сохранить текущий текст, А щелчок кнопки No приведет к очистке
текстового поля и замене заголовка основной формы на «Untitled - MyNotepad».
В методе
FileMenuNew_click вызов этого диалогового окна и получение результата требует
одной строки:
int result =
new NewDialog().showDialog(this);
Пока модальное
диалоговое окно открыто, код возврата из него можно задать в классе соответствующей
формы. С'этой целью в классе Dialog-Result предусмотрен набор целочисленных
констант, но можно вернуть и любое другое целое число. В данном случае используются
свойства dialogResult кнопок, играющие ту же роль, что и константы в классе
DialogResult.
Например,
щелчок кнопки yesButton присваивает DialogResult значение Yes, которое метод
showDialog возвращает классу-владельцу при закрытии
диалогового окна. На основе значения, возвращаемого showDialog, программа определяет,
какие действия ей следует предпринять. Форма NewDialog.java создана на основе
того же шаблона Form, что и главная форма приложения. Метод main для модальных
диалоговых окон не нужен, и в данном примере он удален (сохранение его не стало
бы ошибкой, но противоречило бы хорошему стилю программирования). Кроме того,
убраны лишние комментарии.
Использование
MessageBox в качестве модального диалогового окна
В простых
случаях вместо того, чтобы разрабатывать свое модальное диалоговое окно, можно
задействовать окно сообщения. Обработчик события click команды About из
меню Help использует объект Message-Box так:
private void HelpMenuAbout_click(Object sender, Event e)
{
MessageBox.show("Version: Visual J++ 6.0", "MyNotepad");
}
Рассмотрим
теперь код, отвечающий за файловый ввод/вывод и использующий стандартные диалоговые
окна File Open и File Save. Он демонстрирует WFC-классы, значительно упрощающие
поиск, открытие, чтение и сохранение файлов.
В иерархии
WFC классы com.rns.wfc.ui.OpenFileDialog и com.ms.wfc.ui.Save-FileDialog являются
наследниками (т. е. расширяют) com.ms.wfc.ui.FileDialog. Класс FileDialog расширяет
класс CommonDialog, а тот представляет собой оболочку API-интерфейса стандартных
диалоговых окон Win32. Все стандартные диалоговые окна настраиваются такими
свойствами, как setTitle и setFilter, и открываются вызовом метода showDialog.
Эти диалоговые окна позволяют выбирать открываемый или сохраняемый файл.
Пакет com.ms.wfc.io
содержит классы потокового ввода/вывода. Класс File, наследник DataStream, содержит
методы для файлового ввода/вывода. В MyNotepad нам требуется лишь открыть файл,
целиком считать его в текстовое поле (или записать содержимое текстового поля
в файл), а потом закрыть.
В MyNotepad
весь код для файлового ввода/вывода и соответствующих диалоговых окон размещен
в обработчиках команд Open, Save и Save As меню File. Рассмотрим
только один из них — обработчик команды Open, так как он инкапсулирует
функциональность стандартных диалоговых окон и файлового ввода/вывода. Ниже
приведен код метода FileMenuOpen_click.
private void FileMenuOpen_click(Object sender, Event e)
{
// создаем диалоговое
окно File Open
OpenFileDialog
ofd = new OpenFileDialog();
// настраиваем
фильтры и параметры
ofd.setFilter("Text
Docs (*.txt)|*.txt|A11 Files (*.*)!*.*");
ofd.setDefaultExt("txt");
// открываем
диалоговое окно File Open
int OK = ofd.showDialog();
// проверяем
код возврата после закрытия диалогового окна
if (OK == DiaiogResult.OK)
{
// получаем
введенное имя файла
fileName = ofd.getFileName();
// открываем
поток файла по этому имени
currentDoc =
File.open(fileName);
// определяем
размер файла
int ilength
= (int)currentDoc.getLength();
// считываем
ANSI-символы в буфер
editbox.setText(currentDoc.readStringCharsAnsi(ilength));
// закрываем
файл
currentDoc.close();
fileOpen=true;
// устанавливаем
соответствующий заголовок окна приложения
this.setText(File.getName(fileName) + " - MyNotepad");
}
}
Когда пользователь
выбирает из меню File команду Open, вызывается метод обработки
события FileMenuOpen_click. В первых трех строках кода этого метода создается
объект OpenFileDialog и задаются фильтры и расширения, используемые диалоговым
окном. В данном примере эти строки введены вручную, но аналогичного результата
можно добиться и с помощью Forms Designer, вставив на форму объект OpenFileDialog
и настроив его свойства (при этом инициализирующий код будет помещен в initForm).
Для открытия
диалогового окна вызывается метод OpenFileDialog. showDialog. При щелчке кнопки
ОК этот метод возвращает целое значение DiaiogResult.OK, а при щелчке
кнопки Cancel — DialogResult.Cancel. Если была «нажата» кнопка
ОК, из объекта OpenFileDialog извлекается имя файла и передается методу
File.open, который возвращает поток File, открытый для этого файла с доступом
для чтения и записи. File, open — вспомогательный метод, создающий объект класса
File с помощью конструктора: File(fileName, File.OPEN, FileAccess.READWRITE,
FileShare.NONE);
Этот краткий
обзор не претендует на освещение всех концепций разработки приложения — даже
такого простого, как MyNotepad. Однако рассмотренные здесь принципы обработки
событий, использования диалоговых окон и простого файлового ввода/вывода являются
общими для большинства приложений.
В обзоре
не было сказано ни слова о коде обработчиков команд Save и Save As. Но
в этих обработчиках применяются те же концепции, и поэтому просмотр их кода
не принесет никаких сюрпризов. Примечательно, что в этом приложении не используются
стандартные пакеты Java, кроме java.lang. Вместо этого применяются такие пакеты,
как com.ms.wfc.io и com.ms.wfc.ui, способные задействовать всю мощь Windows
APL Это дает значительный выигрыш в эффективности — если, конечно* приложение
рассчитано на платформу Win32. Помните, что MyNotepad написан лишь для демонстрации
ряда концепций. Для краткости и ясности его кода в нем практически нет контроля
ошибок и не поддерживаются многие возможности Notepad и даже JPad. Однако, разобрав
этот пример, Вы почувствуете себя увереннее при создании собственных Windows-приложений
на Visual J + + с применением WFC.
Ниже приведены
листинги двух используемых в MyNotepad классов.
MyNotepad.Java
Пояснения
к коду см. в разделе "Разработка приложения: пример" ранее
в этой главе.
import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;
import com.ms.wfc.io.
*;
public class
MyNotepad extends Form {
private File
currentDoc; // поток файлового ввода/вывода
private String
fileName; // имя последнего использовавшегося файла
private boolean
fileOpen = false; // меняется на true после открытия файла
public MyNotepad()
{
// требуется
для поддержки Forms Designer
initForm();
this.setBounds(100,
100, 300, 300);
this.setText("Untitled - MyNotepad");
}
private void HelpMenuAbout_click(Object sender, Event e)
{
MessageBox.show("Version: Visual J++ 6.0", "MyNotepad");
}
private void FileMenuNew_click(Object sender, Event e)
{
// если в текстовом поле имеется текст,
// проверяем, не следует ли его сохранить
if (editbox.getText().length()
!= 0) <
// открываем
модальное диалоговое окно класса NewDialog
int result =
new NewDialog().showDialog(this);
// получаем
результат;
// если нажата
кнопка Yes, открываем диалоговое окно Save As
if (result ==
DialogResult.YES)
this.FileMenuSaveAs_click(sender,
e);
// а если - кнопка No, очищаем поле и изменяем строку заголовка
else if (result == DialogResult.NO)
{
editbox.setText(""); this.setTextf'Untitled - MyNotepad");
} } }
private void FileMenuOpen_click(Object sender, Event e)
{
// создаем диалоговое
окно File Open
OpenFileDialog
ofd = new OpenFileDialog();
// настраиваем
фильтры и параметры
ofd.setFilter("Text
Docs (*.txt)|*.txt|All Files (*.*)!*.*");
ofd.setDefaultExt("txt");
// открываем
диалоговое окно File Open
int OK = ofd.showDialog();
// проверяем
код возврата после закрытия диалогового окна
if (OK == DialogResult.OK)
{
// получаем
введенное имя файла
fileName = ofd.getFileName(); // открываем поток файла по этому имени
currentDoc = File.open(fileName); // определяем размер файла
int ilength =
(Int)currentDoc.getLength(); // считываем ANSI-символы в буфер
editbox.setText(currentDoc.readStringCharsAnsi(ilength));
// закрываем файл
currentDoc.close();
fileOpen=true;
// устанавливаем соответствующий заголовок окна приложения
this.setText(File.getName(fileName)
+ " - MyNotepad"); }
}
private void
FileMenuSave_click(Object sender, Event e) {
// если файл был открыт или сохранен
if (fileOpen){
// снова открываем текущий файл
currentDoc = File.open(fileName);
// записываем в файл содержимое текстового поля
currentDoc.writeStringCharsAnsi(editbox.getText());
// закрываем файл currentDoc.close();
}
else
this.FileMenuSaveAs_click(sender, e);
}
private void FileMenuSaveAs_click(Object sender, Event e)
{
SaveFileDialog
sfd = new SaveFileDialog();
// настраиваем
параметры
sfd.setFileName
(fileName);
sfd.setTitle("Save
Text File");
sfd.setFilter("Text
Docs (*.txt)|*.txt|All Files (*.*)!*.*");
sfd.setDefaultExt("txt");
// открываем
диалоговое окно
int result =
sfd.showDialog();
if (result ==
DialogResult.OK ) {
// получаем
имя файла, указанное в диалоговом окне
fileName = sfd.getFileName();
// открываем
поток файла (при необходимости создаем файл)
currentDoc = new File(fileName, FileMode.OPEN_OR_CREATE);
// записываем в файл содержимое текстового поля
currentDoc.writeStringCharsAnsi(editbox.getText());
// закрываем файл currentDoc.close();
fileOpen = true;
// записываем имя файла (без пути) в заголовок окна приложения
this.setText(File.getName(fileName) + " - MyNotepad");
} }
private void FileMenuExit_click(Object sender, Event e)
{
// вызываем
обработчик команды New из меню File,
// который откроет
NewDialog и запросит пользователя,
// следует ли
сохранить текущий текст
this.FileMenuNew_click(sender,
e);
Application.exit();
}
/**
* ПРИМЕЧАНИЕ:
Следующий код требуется для нормальной работы Forms
* Designer.
He модифицируйте его в текстовом редакторе. */
Container components
= new Container();
MainMenu Menu
= new MainMenu();
Menultem FileMenu
= new Menultem();
Menultem FileMenuNew
= new MenuItem();
Menultem FileMenuOpen
= new MenuItem();
Menultem FileMenuSave
= new MenuItem();
Menultem FileMenuSaveAs
= new MenuItem();
Menultem FileMenuExit
= new MenuItem();
Menultem HelpMenu
= new MenuItem();
Menultem HelpMenuAbout
= new MenuItem();
Edit editbox
= new Edit();
private void
initForm()
{
FileMenuNew.setText("&New");
FileMenuNew.addOnClick(new
EventHandler(this.FileMenuNew_click));
FileMenuOpen.setText("&0pen");
FileMenuOpen.addOnClick(new
EventHandler(this.FileMenuOpen_click));
FileMenuSave.setText("&Save");
FileMenuSave.addOnClick(new
EventHandler(this.FileMenuSave_click));
FileMenuSaveAs.setText("Save
&As"); FileMenuSaveAs.addOnClick(new
EventHandler(this.FileMenuSaveAs_click));
FileMenuExit.setText("E&xit");
FileMenuExit.addOnClick(new
EventHandler(this.FileMenuExit_click));
FileMenu.setMenuItems(new Menultem[]
{
FileMenuNew,
FileMenuOpen,
FileMenuSave,
FileMenuSaveAs,
FileMenuExit});
FileMenu.setText("&File");
HelpMenuAbout.setText("&About MyNotepad...");
HelpMenuAbout.addOnClick(newEventHandler
(this.HelpMenuAbout_click));
HelpMenu.setMenuItems(new
Menultem[] {
HelpMenuAbout});
HelpMenu.setText("&Help");
Menu.setMenuItems(new
Menultem[] { FileMenu, HelpMenu});
this.setText("MyNotepad");
this.setVisible(false);
this.setAutoSealeBaseSize(13);
this.setClientSize(new
Point(302, 314));
this.setMenu(Menu);
editbox.setDock(ControlDock.FILL);
editbox.setFont(new Font("Fixedsys", 8.Of,FontSize.POINTS,ontWeight.NORMAL, false, false, false,CharacterSet.DEFAULT, 0));
editbox.setSize(new Point(302, 314)); editbox.setTablndex(l); editbox.setText("");
editbox.setMultiline(true);
editbox,setScrollBars(ScrollBars.VERTICAL);
this.setNewControls(new Control[]
{
editbox}); }
/**
* главная точка
входа для приложения
*
* dparam args
Массив параметров, передаваемый приложению
* в командной
строке. */
public static
void main(String args[]) {
Application.
run(new MyNotepad()); } }
NewDialog.Java
Пояснения к
коду см. в разделе "Разработка приложения: пример"
ранее в этой
главе.
Данная форма
представляет простое модальное диалоговое окно.
****************************/
import com.ms.wfc.app. *;
import com.ms.wfc.core. *;
import com.ms.wfc.ui.
*;
public class
NewDialog extends Form {
public NewDialog()
{
// требуется
для поддержки Forms Designer initForm(); }
/**
* ПРИМЕЧАНИЕ:
Следующий код требуется для нормальной работы Forms
* Designer.
He модифицируйте его в текстовом редакторе. */
Container components
= new Container();
Label label1
= new Label();
Label label2
= new Label();
Button yesButton
= new Button();
Button noButton.
= new Button();
Button cancelButton
= new Button();
PictureBox pictureBoxl
= new PictureBox();
private void
initForm()
{
// ПРИМЕЧАНИЕ: Эта форма хранит информацию о ресурсах
// во внешнем файле. Не изменяйте строковый параметр в вызовах
// функции resources.getObject(). Например, в следующей строке
// не трогайте "foo1_location", даже если изменится объект Foo:
// fool.setLocation((Point)resouroes.getObject
("foo1_location"));
IResourceManager
resources = new
ResourcaManager(this, "NewOialog");
label1.setLocation(new Point(90, 20));
label1.setSize(new Point(210, 20));
label1. setTablndex(0);
labell.setTabStop(false);
label1.setText("The
text in the file may have changed.");
label2.setLocation(new
Point(90, 40));
label2.setSize(new
Point(190, 20));
Iabel2.setTab!ndex(1);
label2.setTabStop(false);
label2.setText("Do
you want to save the changes?");
yesButton.setLocation(new
Point(20, 90));
yesButtcm.setSizeCnew
Point(80, 30));
yesButton.setTabIndex(2);
yesButton.setText("&Yes");
yesButton.setDialogResult(DialogResult.YES);
noButton.setLocation(new
Point(110, 90));
noButton.setSize(new
Point(80, 30));
noButton.setTab!ndex(3);
noButton.setText("&No");
noButton.setDialogResult(OialogResult.NO);
cancelButton.setLocation(new
Point(200, 90));
cancelButton.setSize(new
Point(80, 30));
cancelButton.setTabIndex(4);
cancelButton.setText("&Cancel");
cancelButton.setDialogResult(DialogResult.CANCEL);
this.setText("MyNotepad");
this.setAcceptButton(yesButton);
this.setAutoScaleBaseSize(13);
this.setCancelButton(cancelButton);
this.setClientSlze(new
Point(297, 136));
pictureBox1.setLocation(new Point(20, 20));
pictureBox1.setSize(new Point(50, 50));
pictureBoxl.setTablndex(5);
piotureBoxl.setTabStop(false);
pictureBoxl.setText("");
pictureBox1.set!mage((Bitmap)resources.getObject
("pictureBox1_image"));
this.setNewControls(new
Control[] { pictureBoxl, cancelButton, noButton, yesButton, label2, labell});
}
}
Дело в том, что в его постановке и выводах произведена подмена, аналогичная подмене в школьной шуточной задачке на сообразительность, в которой спрашивается:
- Cколько яблок на березе, если на одной ветке их 5, на другой ветке - 10 и так далее
При этом внимание учеников намеренно отвлекается от того основополагающего факта, что на березе яблоки не растут, в принципе.
В эксперименте Майкельсона ставится вопрос о движении эфира относительно покоящегося в лабораторной системе интерферометра. Однако, если мы ищем эфир, как базовую материю, из которой состоит всё вещество интерферометра, лаборатории, да и Земли в целом, то, естественно, эфир тоже будет неподвижен, так как земное вещество есть всего навсего определенным образом структурированный эфир, и никак не может двигаться относительно самого себя.
Удивительно, что этот цирковой трюк овладел на 120 лет умами физиков на полном серьезе, хотя его прототипы есть в сказках-небылицах всех народов всех времен, включая барона Мюнхаузена, вытащившего себя за волосы из болота, и призванных показать детям возможные жульничества и тем защитить их во взрослой жизни. Подробнее читайте в FAQ по эфирной физике.