Пакет Borland JBuilder 2 справляется с изготовлением компонентов JavaBeans на "пять".

Когда на отечественном рынке появилась первая версия пакета Borland JBuilder, многие программисты были несказанно рады этому: подумать только, каркас любого компонента JavaBean генерируется автоматически! Однако до совершенства было все еще очень далеко. Трудно сказать, обладают ли разработчики из компании Borland телепатическими способностями, но желания адептов Java они явно угадали. Новая версия пакета JBuilder 2 содержит средства, значительно облегчающие процесс создания компонентов JavaBeans.

За закладкой Bean находится инструмент, необычайно искусно вмонтированный в среду AppBrowser — окна, в котором редактируются проекты JBuilder (рис. 1).

Мастер Beans Express, представленный закладкой Bean, включает в себя четыре инструмента:

? дизайнер свойств (Properties Designer);

? дизайнер событий (Events Designer);

? дизайнер редакторов свойств (Properties Editors Designer);

? дизайнер информации о компонентах (BeanInfo Designer).

Для каждого инструмента отведена своя собственная закладка в окне AppBrowser. Еще одна закладка предназначена для включения двух важных опций и показа основной информации о текущем создаваемом компоненте (рис. 1): имя класса создаваемого компонента, его пакет, имя класса—предка компонента, опция, разрешающая использовать только основные классы JDK и Swing, а также опция включения поддержки сериализации* компонента.

*Сериализация - сохранение и восстановление текущего состояния компонента. Как правило, значение внутренних переменных записывается в файл на диске. Далее, при необходимости этот файл может быть прочитан, и переменным компонента возвращаются их прежние значения.

Свойства

Как правило, создание свойств компонента и методов для их чтения и записи происходит на первом этапе. Закладка Properties мастера Beans Express служит именно для этого, здесь перечислены все свойства конструируемого компонента вместе с их атрибутами (рис. 2).

В верхней части панели располагаются кнопки для создания нового свойства (Add Property) и удаления уже имеющихся свойств (Remove Property). Удалить свойства несложно. Нужно лишь выбрать его и нажать на кнопку Remove Property. Имя свойства исчезнет из списка, а вместе с ним из исходных текстов пропадут и описание переменной, хранящей значения этого свойства, и методы доступа к ней.

Добавление свойств — процесс более творческий. Следует определить, какого типа свойства вы создаете и будут ли они изменяемыми, и, нажав кнопку Add Property, заполнить поля появившейся диалоговой панели (рис. 3).

Введенное в поле Property Name имя свойства дублируется в полях Display Name и Short Description. Первое из них определяет текст, отображаемый для данного свойства в окне параметров компонента среды разработчика. Текст из второго поля служит в качестве краткого комментария к создаваемому свойству. (Разные продукты по-разному показывают это значение. JBuilder выводит их как всплывающую подсказку, если навести указатель мыши на имя свойства в окне инспектора свойств.)

Для любого свойства следует задать тип хранимого значения в поле Type. Для облегчения работы можно нажать на кнопку с тремя точками справа от поля Type, и JBuilder предложит средство Pacage Browser (рис. 4), позволяющее, как обычный файловый менеджер Explorer, отыскать и выделить класс, который вы желаете использовать в качестве типа свойства.

Отмечаемые кнопки Getter и Setter (рис. 3) включают генерацию методов чтения и установки значения свойства соответственно. Это важно, поскольку свойство можно сделать неизменяемым (тогда не нужен метод установки) или нечитаемым (тогда не определяется метод чтения).

Следует обратить внимание на опции Binding создаваемого свойства. С их помощью свойство может быть несколько изменено. Свойства c модификатором Bound обязуются извещать о своем изменении все заинтересованные в этом классы. Свойства же с модификатором Constrained отличаются тем, что операция смены значения может быть запрещена извещаемыми компонентами, которые генерируют исключительную ситуацию PropertyVetoException.

Важной опцией настройки свойства является отмечаемая кнопка Expose through BeanInfo. При ее включении отдельные параметры свойства записываются в файл информации о компоненте (BeanInfo), который впоследствии будет "прочитан" средой разработки, использующей данный компонент в создании приложений.

И наконец, поле, точнее раскрывающийся список, задает редактор свойства. Такого рода редакторы служат для удобства отображения значений свойства в палитре при настройке компонента. По умолчанию программа, используемая разработчиком, рисует значение свойства определенным способом. Скажем, тип Color может быть показан полоской цвета, соответствующего значению свойства. Но часто создатель компонента желает показать это значение в нестандартном формате. Тот же самый цвет может быть отображен и как число, определяющее значения красного, зеленого и синего, из которых складывается итоговый цвет. И здесь уже без собственного редактора свойства не обойтись. В этом случае из списка Editor выбирается подходящий редактор свойств.

Генерируемый исходный текст создает полноценный шаблон свойств, и на плечи программиста ложится только создание логики выполнения компонента. Возвратившись к свойствам, которые видны на рис. 2, мы можем увидеть как выглядит сгенерированный исходный текст для свойств:

private java.awt.Color textColor;
private String message;

и методы чтения и установки (getters и setters):

public String getMessage()
{
  return message;
}
public void setMessage(String newMessage)
{
  message = newMessage;
}
public Color getTextColor()
{
  return textColor;
}
public void setTextColor(java.awt.Color
 newTextColor)
{
  java.awt.Color oldTextColor = textColor;
  textColor = newTextColor;
  firePropertyChange(?textColor?,
 oldTextColor,newTextColor);
}

В этом фрагменте также видно, как выглядит метод установки свойства, отмеченного как bind (см. выше метод setTextColor).

События

События — это основные элементы интерфейса при общении между Java-компонентами и приложениями, созданными на их основе. Обработчик событий пакета JBuilder 2 способен автоматически создавать интерфейсы для входящих в компонент и выходящих из него наборов событий, а если есть необходимость, то и новые наборы событий.

Работать с обработчиком событий чрезвычайно просто, особенно если вы не собираетесь создавать свои собственные наборы событий. Нужно лишь отметить в левом списке (рис. 5) те наборы, которые ваш компонент будет рассылать, а в правом списке отметить наборы, которые компонент планирует получать извне.

Список наборов готовых событий велик. Здесь и стандартные сообщения Java AWT, и сообщения, уникальные для библиотеки JBCL, наборы событий, предопределенные в новой библиотеке Swing, и наборы событий, созданные вашими собственными руками. В девяти случаях из десяти вам будет достаточно набора готовых событий. Если же он вас не удовлетворяет, стоит обратить внимание на две кнопки вверху панели — Create Custom Event и Import Event Set. С помощью первой создается абсолютно новый набор на базе прародителя всех событий класса EventObject. Нажав на вторую кнопку, вы сможете задать событийный класс для импорта.

Если вы выбрали готовые события, JBuilder сгенерирует методы, посылающие выбранные события другим компонентам, и методы для регистрации и отключения слушателей этих событий. Соответственно в класс компонента для получения событий будут добавлены интерфейсы-слушатели. Здесь все ясно. А вот процесс создания своих собственных наборов событий нужно прокомментировать.

Нажатие на кнопку Create Custom Event приводит к появлению на экране диалоговой панели, показанной на рис. 6. В первом поле вы вводите название создаваемого набора событий, после чего, последовательно нажимая на кнопку Add New Event, одно за другим добавляете события, включаемые в создаваемый набор. JBuilder, заботясь о вас, изначально добавляет в создаваемый набор событие с названием dataChanged. Если оно вам не нужно, переименуйте его в другое событие или удалите, нажав на кнопку Remove Event.

Как только создание нового набора событий завершится, в проект будут добавлены два новых файла с исходными текстами событийного класса и его слушателя. Этакая "сладкая парочка", представляющая собой модель обработки событий в Java. Класс слушателя не нуждается в редактировании, поскольку он описан как интерфейс, а вот событийный класс, вполне возможно, вы захотите немного расширить, дописав к нему собственные вспомогательные методы.

Редакторы свойств

Создание редакторов свойств — редкая и непростая операция. Программист должен создать класс редактора свойств, наследующий класс PropertyEditorSupport, и реализовать свою версию методов последнего. Операция, прямо скажем, занудная и повторяющаяся при создании редакторов. К тому же, если вы задумаете реализовать свою собственную диалоговую панель для установки значения свойства, вы должны будете создать еще один класс. Конечно, полностью избежать ручной работы не удастся, но с помощью JBuilder 2 создание своих редакторов свойств значительно упрощается.

Так же как при создании событий, в вашем распоряжении кнопки создания и импорта (правда, применительно к редакторам свойств) и тот же список имеющихся элементов (рис. 7).

Если вам приглянулся чужой редактор свойств, вы импортируете его (кнопка Import Property Editor), введя предварительно имя нужного класса. Если же требуется нечто новое, нажмите Create Custom Editor и задайте имя класса редактора в поле Editor Name (рис. 8).

Затем укажите, какого типа редактор вы создаете. В JBuilder 2 имеются три предопределенных класса: String List, String Tag List и Integer Tag List. Тип String List задает список со строками выбора. Если пользователь указывает на конкретную строку, она присваивается редактируемому свойству. Тип String Tag List работает схожим образом, только вместо текста выбранной строки свойству присваивается заранее заданная пользователем строка исходного текста. К примеру, если пользователь выбрал из списка слово "Красный", то можно присвоить свойству значение "new Color(Color.red)". Это особенно важно, если тип хранимого в свойстве значения не String. Тип редакторов Integer Tag List также отображает список из пунктов, связанных с числовыми значениями и заранее заданными строками исходного текста. Они идеально подходят для управления целочисленными свойствами посредством удобного интерфейса.

Если все три готовых редактора свойств не подходят для решения ваших задач, JBuilder передает вам бразды правления. Тогда из списка Editor Type можно выбрать пункт Custom Editor Component. Диалоговая панель слегка изменит внешний вид (рис. 9) и попросит ввести имя редактора свойств, имя специализированного (custom) редактора, а также позволит включить опцию Support paintValue().

Специализированный редактор — это самостоятельная диалоговая панель, отображаемая средствами разработки при попытке пользователя изменить значения свойства. Многим программистам она хорошо знакома. К примеру, когда вы производите смену шрифта компонента, то после обращения к палитре свойств на экране возникает диалоговая панель специализированного редактора, заполнив поля которого можно поменять тип шрифта, его размер, цвет и прочие атрибуты. В данном случае вызов редактора происходит с помощью палитры свойств, но само редактирование выносится за ее пределы.

По вашему заказу JBuilder 2 создаст два класса: один для редактора свойства и один для специализированного редактора. Первый расширяет класс PropertyEditorSupport и по требованию среды разработчика методом getCustomEditor вызывает специализированный редактор, как показано на примере:

public Component getCustomEditor()
{
  if (editor == null)
  {
    editor = new TextColorCustomEditor(this);
  }
  return editor;
}

Этот метод сгенерирован полностью автоматически по информации, предоставленной пользователем. Заодно создается метод, вызывая который среда разработчика определяет, поддерживается ли специализированный редактор:

public boolean supportsCustomEditor()
{
  return true;
}

Если отметить кнопку Support paintValue(), то в редакторе свойств будет создан одноименный метод, модифицируя который можно добиться необычного вида значения свойства в палитре. Примером тому может служить редактор цвета, изображающий выбранный цвет в виде цветного прямоугольника, и текстовое название (рис. 10).

Методу paintValue передаются графический контекст и координаты прямоугольника, в рамках которого нужно произвести рисование:

public void paintValue(Graphics g, Rectangle r)
{
		...
}

Информация о компонентах

На первый взгляд может показаться странным то, что описание информации о компонентах помещено в конец статьи. Однако в этом есть определенная логика. Дело в том, что для генерации класса информации о компоненте нужна информация и о свойствах, и о событиях, и о редакторах свойств, пусть даже они существуют только в каркасном виде.

Среди множества данных о компоненте программист должен отобрать такие, которые будут видны потребителю создаваемого компонента. Все свойства компонента перечислены в списке на закладке BeanInfo (рис. 11).

Имена свойств, точнее переменных, хранящих их значения, показаны в столбце Name. Столбец Display Name служит для задания того имени свойства, которое программист увидит в палитре свойств среды разработки. Поле Short Description связано со свойством комментарием. Последнее поле, Editor, связано со свойством определенным редактором. Если дважды щелкнуть на нем мышью, раскроется список со всеми имеющимися в проекте редакторами свойств. Чтобы сделать свойство видимым для потребителей, напротив его имени нужно включить кнопку Expose. Часто бывает нужно показать информацию о компоненте-суперклассе, если такой имеется. В этом случае можно отметить кнопку Expose superclass BeanInfo.

Обычно все компоненты JavaBeans хранят в себе несколько пиктограмм. При добавлении компонентов в среду разработки одна из пиктограмм компонента становится видна в палитре. Таким способом отображаются пиктограммы всех компонентов JBuilder. Всего компонент может иметь четыре пиктограммы — две черно-белых и две цветных. В свою очередь эти пары образуются из одной пиктограммы 16x16 пикселов и 32x32 пиксела. Создавая компоненты, можно задать пиктограммы: в нижней части панели имеются четыре специальных поля, в которые нужно ввести имена файлов пиктограмм.

Завершающий этап — генерация класса информации о компоненте, выполняемая автоматически. Нужно лишь нажать кнопку Generate Bean Info. Все остальное сделает JBuilder. И ваш проект станет больше на один файл. Если взглянуть на его содержимое, то окажется, что в результате всех стараний получен класс-наследник SimpleBeanInfo. При использовании компонента среда разработки вызывает метод getPropertyDescriptors этого класса, возвращающий массив дескрипторов свойств (PropertyDescriptor). Внутри этого метода создаются сами дескрипторы, и их поля с помощью набора специальных методов заполняются информацией, которую вы вводили в окне с закладкой Bean Info. Задача еще одного метода — getAdditionalBeanInfo — состоит в том, чтобы считать информацию о классе-предке компонента и передать ее среде разработки, в которую добавляется компонент.

К сожалению, информация о методах и событиях компонента автоматически не генерируется — придется поработать руками. И тем не менее, воспользовавшись Borland JBuilder 2, легко оценить, насколько простым может быть процесс разработки компонентов.