Конструктор пользовательского интерфейса

В

данной главе вы ознакомитесь с основными понятиями, необходимыми для конструирования интерфейса приложения. JBuilder облегчает эту задачу, пре­доставляя для создания интерфейса программы набор WYSIWYG-инструментов (“WYSIWYG” означает “What You See Is What You Get”, τ.e. “то, что вы видите (на эк­ране), то и получаете (в коде)” — технология полного соответствия). Но, возможно, вы обнаружите, что использование конструктора пользовательского интерфейса не всегда так просто и очевидно, как кажется на первый взгляд.

примечаниеСоздание пользовательского интерфейса в JBuilder происходит в рамках инстру­мента, называемого Конструктором пользовательского интерфейса (UI Designer) или просто Конструктором. C его помощью разработчики помещают в экземпляр JFrame, JPanel или другой визуальный контейнер кнопки, списки, флажки и другие элементы пользовательского интерфейса. В JBuilder вам не придется создавать их, вводя вручную множество строк кода: вместо этого вы можете "рисовать" эти эле­менты с помощью мыши. Другой способ предполагает визуальное размещение этих инструментов внутри панели структуры. Конечно, если вы захотите, можете напи­сать код пользовательского интерфейса вручную, но обычно с помощью визуальных средств эту задачу можно решить гораздо проще. В любом случае вы получите похо­жий код; отличие состоит лишь в способе его получения.

Когда я говорю, что вы получите похожий код, это не значит, что конст­руктор все сделает именно так, как сделали бы вы, если бы писали код вручную. В таком сложном языке, как Java, зачастую существует великое множество способов сделать одно и то же. Поэтому разработчики JBuiIder были вынуждены ввести некоторые сте­реотипы. Иногда JBuiIder может сгенерировать код, идентичный тому, что вы ввели бы вручную, а иногда код будет существенно отличаться. Если вам не нравится автоматичес­ки генерируемый JBuiIder код, вы всегда можете поправить его вручную так, как вам нравится. Если ваши исправления не внесут ошибок в Java-код, то JBuiIder сможет отком­Пилировать и выполнить вашу программу.

Вообще говоря, пользоваться конструктором пользовательского интерфейса ис­ключительно легко. Но для полного использования его возможностей вам понадо­бится освоить несколько не вполне очевидных приемов. Сказанное касается и опытных пользователей других сред визуального проектирования, вроде Delphi, VB или C++ Builder. Эти бывалые пользователи могут прийти к JBuilder со своими при­вычками, и многих из них может постигнуть разочарование, если они не узнают не­которых важных сведений об использовании визуальных конструкторов JBuilder.

Как упоминалось ранее, визуальные компоненты Java не были разработаны спе­циально для использования в таких средствах визуального проектирования, как JBuilder. Поэтому между средой визуального проектирования и компонентами Java Swing нет идеального соответствия.

Одна из основных целей данной главы — показать, как преодолеть все сложнос­ти, которые могут встретиться во время использования визуальных средств. Она предназначена для того, чтобы вы уверенно работали с конструктором JBuilder и его возможностями манипулирования Swing-объектами. Если вы освоите несколько приемов и узнаете, каких проблем следует избегать, то вскоре обнаружите, что мо­жете быстро и легко создавать мощные визуальные интерфейсы.

Если конкретно, то в данной главе освещаются следующие темы:

■ Как помещать и размещать компоненты в конструкторе

■ Как с помощью инспектора исследовать компоненты, находящиеся в конст­рукторе.

■ Как конфигурировать расположение компонентов с помощью компоновок Java.

■ Как с помощью конструктора создавать обычные и выпадающие меню.

примечаниеОбсуждение того, как лучше использовать отдельные компоненты, будет прове­дено, в основном, в части III, "Основы JBuilder". Там вы более подробно узнаете о списках выбора, флажках, панелях и других элементах управления. В конце данной главы вы научитесь пользоваться компонентом JTabbedPane.

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

Хоть в это трудно поверить, но существует множество пользователей, не вполне понимающих конструктор. Это один из наиболее мощных инструментов JBuilder, и если вы полностью усвоите его возможности, то это во многом поможет вам.

Теория конструирования интерфейса

Перед тем как начать, я хочу ознакомить вас с одним важным теоретическим по­ложением. Большинство разработчиков, наверное, знакомы с концепцией MVC-ap — хитектуры (model-view-controller — модель-вид-контроллер). Согласно этой теории, необходимо визуальную часть компонента хранить отдельно от данных, которые со­держит этот компонент. Например, в Java проведено четкое различие между кон­тейнером, используемым для хранения строк списка выбора, и средствами визуаль­ного отображения, прорисовывающими этот список на экране. Первая часть — дан­ные — это подсистема Модель архитектуры модель-вид. Вторая часть — компоненты, прорисованные на экране — это подсистема Вид архитектуры модель-вид. Подсисте­ма Контроллер архитектуры модель-вид-контроллер — это код обработки событий, Связывающий воедино подсистемы компонента модель и вид.

Дополнительные сведения о MVC-архитектуре системы Swing вы най — Дете в различных частях данной книги, в том числе в этой главе и частях Ill и VII.

Хотелось бы провести аналогию между корректной разработкой приложения и корректной разработкой компонента. Я уверен, что почти всегда можно отделить код пользовательского интерфейса программы от ее базовой логики. Так же и пользовательский интерфейс списка выбора отделен от содержащихся в нем строк. Я считаю, что в большинстве приложений не стоит смешивать код пользовательско­го интерфейса с кодом, реализующим суть приложения.

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

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

Я считаю, что при создании этого воображаемого приложения у вас должен быть один класс, обычно являющийся потомком JFrame или JPanel, который будет об­рабатывать данные, введенные пользователем. Затем, после ввода всей информации, вы должны создать отдельный класс с единственным назначением — просмотр пос­ледовательности файлов. Возможно, вам понадобится еще и третий класс, для обра­ботки каждого найденного файла.

Каждый класс должен создаваться только для одной цели. Если вы создаете класс, выполняющий две, три, четыре, пять или более отдельных задач, значит, вы выполняете работу небрежно. (Иногда время настолько поджимает, что бывает не до того, но надо же стараться делать все правильно! Если вы спроектируете ваше приложе­ние корректно, то в итоге это сэкономит вам время, причем обычно — во много раз.)

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

Так же, как в компоненте Swing должны быть части Модель и Вид, приложение тоже должно иметь часть ввода данных, обеспечивающее пользовательский интер­фейс, и отдельный класс или классы, обрабатывающие введенные пользователем данные.

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

Надеюсь, что вы правильно восприняли это маленькое теоретическое отступле­ние. Если нет, то мы еще вернемся к более подробному обсуждению этой темы в главе 20, "Компоновка Java".

Я не хочу долго останавливаться на этой теме, однако, дабы полностью прояс­нить мою точку зрения, позвольте мне воспроизвести ее по-другому. JBuilder — это исключительно полезный инструмент. Но нельзя, чтобы он влиял на архитектуру вашего приложения. Вы обнаружите, что JBuilder подталкивает вас к построению всего приложения вокруг одного экземпляра JFrame, на котором помещено не­сколько объектов JButton и JTextField. Если ваша программа не является совер­шенно примитивной, не поддавайтесь на это искушение. Вместо этого пользуйтесь экземпляром JFrame только для ввода пользовательской информации, а все функ­циональные возможности программы разместите в их собственных классах. Ключе­выми аспектами здесь являются “отделяй” и “разделяй и властвуй”. В этом контек­сте важен также термин “корректировка связей”.

Основы конструктора

примечаниеПредварительные замечания закончены, и можно приступать к исследованию самого конструктора. Создайте стандартное приложение, как описано в главе 3, "Создание элементарных приложений и аплетов". Для доступа к конструктору сна­чала с помощью панели проекта выделите Framel или какой-нибудь другой исход­ный Java-файл, имеющий визуальный интерфейс. Например, можно выделить эк­земпляр класса JApplet, JFrame Или JPanel. В Любом стандартном приложении или аплете, построенном JBuilder, находится, по крайней мере, один из этих объек­тов. Для целей нашего обсуждения выделите в своем проекте объект Framel.

N⅛aut*⅛∣⅛*-∣ Если вы попытаетесь выделить какои-либо класс, не имеющий визуаль­ного элемента, наподобие Object, то вы не увидите в конструкторе ничего особо инте­ресного. Помещение такого файла в конструктор не является ошибкой, а иногда именно так и требуется. Например, модули данных, о которых пойдет речь в части VIII, являются невизуальными компонентами, которые можно редактировать в режиме конструирова­ния. Однако в основном переход в этот режим имеет смысл лишь тогда, когда вы работа­ете с экземпляром класса JApplet, JFrame, JPanel или одного из других классов визу­альных компонентов.

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

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

В нашем случае в папке Ul находится объект, разработанный компанией Sun и называемый ContentPane. Оказывается, каждый экземпляр JFrame по умолчанию со­держит панель, которую JBuilder называет ContentPane. Этот элемент JPanel являет­ся контейнером, который будет содержать все элементы управления, которые вы по­местите на Framel. Одной из задач JBuilder является предоставление вам дескрип­тора этого контейнера.

рис. 6,1. в конструкторе выделен простой экземпляр класса jframe. на jframe не помещен ни один элемент, поэтому он выглядит пустым,-jgfc ⅛ju g*⅛rth vjw project run tfl⅛m vteanft ɪboto jfvfrrdow jjvfc ⅛
oas∙¾oβι * * ч
lp* ⅛⅛ 1 s ’ *' "prtrretbburro, * i3bocwrvnfr .∣∙i⅜ frvmel
,natɪɪeo tnn fsnt
iresowitm
,'*t htyflrsuirojectframei
1s -jut
,⅛≈ в contentpane <5 uorderls
i_j menu cjdataaccess -j other
,vtsfc normal
mtt frvm4tfci
,⅛⅛⅞Γ,• ∕p¾⅛r f ⅛1 др t⅞^∣⅜⅛⅞⅝^
⅞. ʌ. jl⅛. j⅛ t `,'' ⅛ ?
,jbttridpf 7 t∙√ document s and setting». ∣*a 4⅛'∙v> r '
примечание

C объектом JPanel Всегда связана его компоновка (layout). Ниже в этой главе вы ознакомитесь с компоновками вообще и с BorlandLayout В частности. Если вы еще не знакомы с компоновками, то, возможно, эта тема покажется вам не совсем инту­итивно понятной. Основная ее идея состоит в следующем: может понадобиться, чтобы Java-приложение отображалось на многих различных платформах. Поэтому необходимо размещать компоненты не на конкретных координатах Х и У, а гибким и масштабируемым образом по отношению друг к другу. Компоновки, подробно рас­сматриваемые в части III, "Основы JBuilder", как раз и позволяют это сделать.

Помещение компонентов на конструктор

Пора, наконец, начать использовать конструктор для того, для чего он предназ­начен. В следующих абзацах вы узнаете, как помещать компоненты на панель кон­структора.

swingiifcel

ʌ 133
text

OataExpress ∣ dbSwing ∣ More dbSv 1 »1

Рис. 6.2. Палитра компонентов, открытая на странице Swing С пиктограммами для
представления
JButton, JRadioButton, JToggleButton, JTextArea И других Swing-компонентов

103

Вдоль верхней части конструктора находится палитра компонентов, состоящая из страниц с пиктограммами, которые представляют различные компоненты. Все компоненты на первой странице палитры компонентов являются частью Swing.

В правом конце палитры компонентов находятся две маленькие кнопочки с изображениями противоположно направленных стрелок Они предназначены для передвижения на дополнительные страницы. (Если разрешение вашего экрана дос­таточно велико, то эти кнопочки могут быть не нужны и поэтому невидимы.) Под ними находится большая черная треугольная стрелка, указывающая вправо. (Если разрешение вашего экрана достаточно велико, или мало число компонентов на странице, то эта стрелка будет отображаться серым цветом и быть неактивной.) Щелкнув на этой стрелке, вы увидите дополнительные пиктограммы компонентов на текущей странице — в данном случае на странице Swing. Аналогичная стрелка слева на палитре компонентов позволяет передвигаться влево на той станице, на ко­торой вы находитесь в данный момент.

По умолчанию палитра компонентов открывается на странице Swing, соответ­ствующей закладке, находящейся рядом со стрелкой выбора (белая стрелка на рис. 6.3). Первый слева компонент на странице Swing — компонент JButton. Щелкните на пиктограмме JButton и переместите курсор в панель конструктора, которая рас­положена под палитрой компонентов, а затем щелкните еще раз На панели конст­руктора появится соответствующая кнопка (см. рис. 6.3).

Теперь посмотрите, что получилось. Например, в панели структуры в папке Ul теперь находится новый элемент с именем jButton1. Это имя JBuilder автоматически присвоил компоненту, который вы поместили на ContentPane. Имя создается из имени компонента и единицы (1) после него. Вы поместили JButton, поэтому ком­поненту присвоено имя JButtoni. Если вы поместите еще одну кнопку JButton, Ее имя будет JButton2 (а не JEineOflHHButton, как мне бы хотелось!).

м , , ; ^s7^l'^ ."^ ^
ftle edit ββareb wew protect run teem wzarte toole window ffeto
,jblrtlonlrnortft
рис. 6.3.
компонент jbutton в конструкторе пользователь-ского интер-фейса

примечаниепримечание

Конечно, разработчики JBuiIder не думали, что jButtonl — замеча­тельное имя для компонента. Они лишь хотели обеспечить уникальность имен нескольких компонентов, помещенных на одной форме. Опять-таки, не позволяйте JBuiIder дикто­вать структуру имен в своем приложении. Именно вы должны полностью контролировать образование имен в своей программе. Все, что предлагает JBuiIder — это алгоритм, обеспечивающий уникальность имен всех компонентов, чтобы полученный код мог ком­пилироваться. Но уникальности имен далеко не достаточно — нужно, чтобы имена были осмысленными.

Компонент jButtonl является дочерним компонентом contentPane. Он нахо­дится сверху панели contentPane, и поэтому отображен на панели структуры так, как показано на рис. 6.3. Когда вы начнете разрабатывать более сложные приложе­ния, порядок, в котором компоненты появляются на панели структуры, будет ста­новиться все более важным.

Обратимся еще раз к рисунку 6.3. Взгляните на закладки над палитрой компо­нентов. Сейчас выделен файл Framel. Java. Нужно всегда помнить, какой файл яв­ляется текущим в редакторе. Для изменения текущего файла можно использовать либо панель проекта, либо закладки над палитрой компонентов.

Теперь посмотрите правее конструктора, и вы увидите инспектор (Inspector). Про этот инструмент более подробно говорится ниже в этой главе, а также в Части IIl "Основы JBuilder". Но и сейчас можно видеть, что он отображает информацию, относящуюся к только что помещенной на Framel кнопке. Инспектор всегда ото­бражает информацию о выделенном в данный момент компоненте. В нашем случае вы можете видеть имя компонента (jButton1) и его ориентацию (на северной стороне BorderLayout), а также другую информацию.

C помощью инспектора можно изменять свойства компонентов. Как уже говори­лось, в реальном приложении следует изменить имя jButtonl на более осмыслен­ное имя, наподобие fileOpenButton, SortButton ИЛИ ЧТО-ТО В ЭТОМ Роде. Ниже В Данной главе вы увидите, как это можно сделать с помощью инспектора. Но если вы хотите, изменение можно провести и в исходном коде.

В самом левом конце палитры компонентов, рядом со словом "Swing", находится белая стрелка, называемая указателем выбора (selection tool). C его помощью можно "разгрузить" курсор, чтобы он не вставлял элементы в конструктор, а выбирал размещенные на нем элементы. В частности, если вы щелкнете в палитре компонентов на пиктограмме JButton, а затем щелкнете на конструкторе, то на нем появится экземп­ляр элемента JButton. Но можно щелкнуть на JButton по ошибке или же передумать после этого. Если нужно "разгрузить" курсор, чтобы он не помещал компоненты на конструкторе, щелкните на указателе выбора.

После щелчка на указателе выбора вы сможете с помощью курсора ‘ выбирать" ком­поненты на визуальной части конструктора. Например, щелкну| на элементе jButton1, вы выберете его. Что он выбран, можно увидеть по тому, что в панели инспектора появятся его свойства. Ниже в этой главе приводится дополнительная информация об указателе Выбора, в разделе о выборе нескольких компонентов.

Просмотр исходного кода, сгенерированного JBuiIder

При работе в конструкторе пользовательского интерфейса JBuilder генерирует Java-код, необходимый для создания компонента, помещенного на Framel. Важно

рис. 6.4.
исходный код, соответствующий визуальным компонентам

Понимать, что JBuilder не рисует компонент на экране, а генерирует код, и на осно­ве этого кода создает экземпляр этого компонента. Это настоящие "живые" компо­ненты, которые вы видите на конструкторе.

Перейдите в режим просмотра исходного кода и посмотрите на окно редактора: вы увидите объявления ContentPane и jButtonl, как показано на рис. 6.4.

В листинге 6.1 приведен полный исходный код Framel, После того как на него был помещен элемент JButton. Несколько следующих абзацев посвящены изуче­нию этого кода, поскольку понимание его структуры исключительно важно. При изучении листинга 6.1 можно видеть, что убраны комментарии, обычно автомати­чески вставляемые JBuilder в код подобного рода. Также убрана закомментирован­ная строка, которую JBuilder обычно вставляет в начало метода jbinit для работы с пиктограммами. Эти удаления сделаны, чтобы не нарушать общее восприятие этой важной части исходного кода.

Листинг 6.1. Простой экземпляр JFrame, созданный в конструкторе пользовательского Интерфейса и содержащий одну кнопку

Import j ava. awt.*;

Import java. awt. event. *;

Import j avax. swing.*;

Public class Framel extends JFrame

{

JPanel ContentPane;

BorderLayout borderLayoutl = new BorderLayout () ;

JButton JButtonl = new JButton () ;

∕∕ Создание Фрейма Public Framel ()

1

BnableEvents(AWTEvent. WINDOW_EVENT_MASK); Try {

Jbɪnit() ;

J

Catch(Exception e)

{

E. printStackTrace();

)

}

∕∕ Инициализация Компонента

Private void jbɪnit() throws Exception

{

ContentPane= (JPanel) this. getContentPane();

JButtonl. setText (" JButtonl’,) ;

ContentPane. SetLayout(borderLayoutl); this. setSize(new Dimension(281, 251)); this. SetTitle("Frame Title");

ContentPane. add(JButtonl, BorderLayout. NORTH);

}

∕∕ Перекрыт, Стало Быть, Можно Выйти При Закрытии Окна Protected void processWindowEvent (WindowEvent e)

{

Super. ProcessWindowEvent(e);

If (e. getID() = WindowEvent-WINDOW-CLOSING)

System.Exit(O);

)

примечаниеКак уже говорилось, в таком сложном языке, как Java, некоторые задачи можно решить различными способами. Поскольку JBuilder генерирует код за вас, его раз­работчикам было необходимо избрать определенный стиль и всячески придержи­ваться его. Наступило время разобраться с некоторыми конкретными элементами этого стиля.

Можно не соглашаться с решениями, которые приняли разработчики JBuiIder в отношении генерации кода. Но лично я считаю, что не стоит с предубеждением относиться к упомянутым решениям. Многие работники, занимающие ключевые позиции в команде разработчиков JBuiIder — достаточно умные люди, к тому же имеющие мно­голетний опыт программирования. Не думайте, что JBuiIder был создан каким-то мелким бюрократом из отдела сбыта JBuiIder. Члены команды JBuiIder не всегда принимают наи­лучшие из возможных решения, однако они редко принимают абсолютно несуразные решения. В общем, это великолепный продукт, и IDE, который вы видите, является кульмина­Цией последовательности хороших решений по многим сложным отдельным вопросам.

Конструктор Framel

Начнем анализировать полученный код. Может показаться, что не стоит обсуж­дать код в главе, посвященной конструктору пользовательского интерфейса. Это да­леко не так. Дабы отчетливо понимать, что выполняет конструктор, необходимо ра­
зобраться в солидном объеме Java-кода. Ведь назначение конструктора и состоит в генерации кода.

Для начала посмотрим на конструктор Framel:

Public FramelO

{

EnableEvents(AWTEvent. WINDOW_EVENT_MASK); Try {

Jblnit() ;

}

Catch(Exception e)

{

E.ρrintStackTrace();

1

Это стандартный код JBuilder, и вы должны легко в нем разбираться. В первой строке вызывается метод enableEvents. Это нужно для того, чтобы ваше приложе­ние надлежащим образом закрывалось. Смысл этого вызова будет объяснен позже, после обсуждения остального кода этого файла.

После вызова enableEvents находится блок try. .catch. Этот код всего лишь вызывает метод ɔbinit и затем перехватывает все исключительные ситуации, кото­рые могут возникнуть в jbinit. Точнее, если в jbinit возникнет какая-то ошибка, то место ее возникновения с помощью вызова printstackTrace будет указано раз­работчику.

Метод Jblnit

Метод jbɪnit — один из краеугольных камней работы в JBuilder. В нем происхо­дит инициализация компонентов.

Этот метод не документирован в языке Java, тем не менее, он является частью со­глашения о кодировании и играет важную роль в JBuilder. JBuilder ожидает, что jbinit присутствует в вашем коде везде, где определяется внешний вид вашего при­ложения. Если вы определите визуальный код где-то или как-то по-другому, то, ско­рее всего, вы не сможете редактировать его с помощью конструктора. Весь код при­дется редактировать вручную.

примечаниеC другой стороны, jbinit можно определить как метод, в который JBuilder по­мещает код, генерируемый при работе в конструкторе. Например, если вы перета­щите на конструктор элемент JButton, JBuilder вставит в jbinit код конфигуриро­вания этой кнопки (но не код создания экземпляра этой кнопки).

Пусть этот абзац не смущает вас. Метод jblnit является абсолютно допустимым Java-кодом, однако это порождение технологии быстрой разработки (Rapid DevelopmentR&D) компании Borland, а не Sun.

В нашей простой программе метод jbinit выглядит так:

// 1Оля Данных Объекта Framel JPanel ContentPane;

BorderLayout borderLayoutl = new BorderLayoutO ;

JButton jButtonl = new JButton() ;

∕∕ … Для Краткости Часть Кода Опущена Private void jblnit() throws Exception {

ContentPane= (JPanel) this. getContentPane () ;

JButtonl. setText("JButtonl");

ContentPane. setLayout(borderLayoutl); this. setSize (new Dimension (281, 251)); this. SetTitle("Frame Title") ;

ContentPane. add(jButtonl, BorderLayout. NORTH);

}

B первой строке тела метода jbinit выбирается компонент JPanel, Встроенный во все компоненты JFrame. Системе JBuilder нужен дескриптор этого компонента, поскольку все кнопки, списки выбора и другие элементы управления, помещаемые на конструктор, попадают в ContentPane.

Во второй строке кода задается текст, или заголовок, кнопки jButtonl:

JButtonlSetTextCjButtonl") ;

Обратите внимание, что вы бы написали вручную именно такой код.

Это очень простая строка, но о ней есть что сказать. Вначале заметьте, что сама кнопка создана выше, при объявлении в качестве члена вашего класса:

JButton JButtonl = New JButton();

Теперь вернемся снова к вызову jButtoni. setτext CjButtonl"). Это значение можно изменить двумя способами:

1. C помощью инспектора, как показано ниже в данной главе. Если вы исполь­зуете инспектор, то вы используете и визуальные средства, изменяющие зна­чения в вашем коде.

2. А можно и самому изменить исходный текст:

JButtonl. SetText CfileOpenButton") ;

примечаниеЕсли вы теперь щелкнете на закладке Design, то увидите, что внешний вид кноп­ки изменился в соответствии с проведенными вами изменениями. Для этого нет не­обходимости задействовать кнопку Compile. JBuilder анализирует введенный вами код и выполняет изменения в конструкторе, соответствующие текущему состоянию буфера, который содержит исходный код.

Если вы не очень-то представляете, о чем идет речь, выполните в JBuiIder следующие шаги:

1. Поместите на JFrame кнопку.

2. Щелкните на закладке Source и измените вызов JButtonl. setTeχt, чтобы его аргу­ментом была не строка " jButtonl", а какая-нибудь другая.

3. Теперь вернитесь в режим конструктора и посмотрите на кнопку. Текст на ней должен Измениться в соответствии с изменениями, проделанными в исходном тексте.

примечаниеИногда, особенно в старых версиях продукта, JBuiIder в режиме конст­руктора не отображал автоматически изменения, проделанные в редакторе. Если вы встретитесь с этим, сохраните все и щелкните на кнопке Compile. Если это не поможет, запустите приложение и посмотрите, все ли верно при выполнении программы.

Если и это не поможет, попробуйте закрыть и снова открыть JBuiIder. Если в вашей систе­ме установлена память не особенно большого размера и JBuiIder работает очень долго, он может не всегда работать корректно. (Увы!) Вспомните, что было сказано о требова­ниях к памяти. Если памяти меньше 256 Мб, то JBuiIder будет работать в напряженном ре­жиме, что может повлечь за собой вышеуказанные проблемы. На моей машине с 448 Мб памяти эта проблема возникает довольно-таки редко.

Остальная часть кода в нашем примере метода jbmit является просто обычным Java-кодом, и поэтому на данном этапе рассматриваться не будет.

Главное сейчас — понять, что здесь размещен код, соответствующий конструкто­ру. Аналогичный код, размещенный в других местах программы, не обязательно бу­дет отображаться в конструкторе. Поэтому если вы хотите перевести обычную Java- программу в JBuilder, часто одной из первых задач будет перенос всего "конструкто — рообразного" кода в метод с именем jbinit, вызываемый из конструктора экземпляра класса JFrame Или JPanei. Код, вызываемый из jbinit, также будет отображаться в конструкторе. Значит, приложение можно "преобразовать" в JBuilder, просто вызвав из метода с названием jbinit ваши методы инициализации компонентов пользовательского интерфейса.

Еще о редактировании кода пользовательского интерфейса вручную

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

Конструктор и редактор тесно связаны друг с другом. Если в редакторе вы впеча­таете код создания экземпляра визуального компонента, то после переключения в режим конструирования этот компонент будет видим.

Чтобы посмотреть, как это работает, переключитесь на просмотр исходного тек­ста и напишите код создания экземпляра JButton. Вверху фрагмента, посвященно­го Framel, Сразу после объявления jButtonl, введите:

JButton MyButton = New JButton () ;

В методе jbinit(), под аналогичными строками, касающимися jButtonl, набе­рите следующие строки:

MyButton. SetText("Моя Кнопка");

ContentPane. add(myButton, BorderLayout. SOUTH);

Теперь перейдите в режим конструирования. Внизу конструктора появится кнопка MyButton.

Следующий листинг поможет вам правильно вставить код для кнопки myButton.

Листинг 6.2. Исходный код Framel после вставки кнопки myButton

Package Inyfirstproject;

Import java. awt.*;

Import java. awt. event.*;

Import javax. swing.*;

Public class Framel extends JFrame

{

JPanel ContentPane;

BorderLayout borderLayoutl = new BorderLayout () ; JButton JButtonl = new JButton ();

JButton myButton = new JButton () ;

∕∕ Создание Фреймов

Public Framel()

<

EnableEvents(AWTEvent. WINDOW_EVENT_MASK);. try {

Jblnit() ;

}

Catch(Exception e)

{

E. printStackTrace() ;

}

)

∕∕ Инициализация Компонентов Private void jbɪnit() throws Exception {

ContentPanes= (JPanel) this. getContentPaneQ;

JButtonl. setText (" JButtonl,,) ; myButton. setText("Моя Кнопка");

ContentPane. SetLayout(borderLayoutl); this. setSize(new Dimension(400, 300)); this. SetTitle("Frame Title");

ContentPane. add(JButtonl, BorderLayout. NORTH);

ContentPane. add(myButton, BorderLayout. SOUTH);

}

∕∕ Перекрыт, Стало Быть, Можно Выйти При Закрытии Окна Protected void ProcessWindowEvent(WindowEvent e)

(

Super. ProcessWindowEvent(e);

If (e. getID() == WindowEvent. WINDOW_CLOSING)

{

System.Exit(O);

}

}

Этот код не сработал бы, если бы в jbinit отсутствовали две последних строки. Например, следующий код прекрасно работает во время выполнения, но не так, как надо, в режиме конструирования:

Public Framel()

{

EnableEvents(AWTEvent. WINDOW_EVENT_MASK);

Try

<

MyButton. setText("Моя Кнопка") ; Jblnit() ;

}

Catch(Exception Е)

{

Е.printStackTrace();

)

}

// Инициализация Компонентов

Private void jblnit() throws Exception

{

ContentPane= (JPanel) this. getContentPane(); JButtonl. setText ("JButtonl’,) ;

ContentPane. setLayout(borderLayoutl); this. setSize (new Dimension(4OOr 300)); this. setTitle("Frame Title");

ContentPane. add(JButtonlr BorderLayout. NORTH); ContentPane. add(myButtonr BorderLayout. SOUTH);

B этом коде я переместил MyButton. Setτext Из JbɪNit В конструктор. C точки зрения языка Java здесь все верно. Это корректный Java-код. JBuilder без проблем скомпилирует этот код, и если вы запустите его, то программа корректно выполнит­ся. Но на этапе конструирования она не будет нормально отображаться. Ошибки не возникнут, но на созданной вами кнопке текст вы не увидите. Тем не менее, следую­щий код будет корректно работать во время конструирования:

// Инициализация Компонентов Private void jbɪnit() throws Exception {

ContentPane = (JPanel) this. getContentPane();

ContentPane. setLayout(borderLayoutl);

SetButtonText();

ContentPane. add(myButton);

This. setSize(new Dimension(400r 300));

This. setTitle("Заголовок Фрейма");

)

Private void SetButtonText()

{

MyButton.SetText("C3M");

}

Здесь вызов MyButton. Setτeχt Не находится внутри jbinit, однако он Вызыва­ется из jbinit, и JBuilder понимает, что вы хотите сделать.

Я считаю, что последний пример с вызовом метода из ɔbinit довольно важен Дело здесь в том, что в программах со сложным интерфейсом метод jbinit может стать очень длинным и сложным. Вы можете, если захотите, разбить эти длинные методы jbinit на несколько блоков, используя продемонстрированный в этой главе прием.

В следующем коде операции, связанные с многостраничными панелями, пере­мещены из jbinit в отдельный метод:

Private void jblnit() throws Exception

{

ContentPane = (JPanel) this. getContentPane(); ContentPane. SetLayout(borderLayoutl);

∕∕ … Для краткости часть кода опущена DoTabbedPane( , ;

This. setSize(new Dimension(400, 300)); This. setTitle("Frame Title");

}

Private void doTabbedPane() {

contentpane.add(jtabbedpanel j tabbedpanel. add (jpanell, ,, jtabbedpanel.add(jpane12, " jtabbedpanel.add(jpanel3, ", BorderLayout. CENTER); JPanell");

JPanel2");

JPanel3");

}

B обсуждаемом здесь примере важно то, что в нем комбинируется некоторый объем визуального программирования с определенным объемом стандартного ре­дактирования. Обычно закладки создаются в конструкторе, а метод наподобие DoTabbedPane Пишется вручную в редакторе JBuilder. Именно так и задумана работа в JBuilder. Вы должны свободно переключаться между текстовыми и визуальными

Средствами.

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

Другие места программы.

Знакомство с ProcessWindowEvent

Как вы помните, в первой строке конструктора Framel Вызывается метод EnableEvents Класса Java. awt. Component. Большинство объектов не получают уведомлений о каком-то специальном виде событий, если только они не регистри­руют для него специальный слушатель (listener, также "блок прослушивания"). Этот метод указывает, что Framei Должен получать сообщения window_event_mask, не­смотря на то, что компонент не зарегистрировал слушателя данного типа. (Слуша­тели и события — тема глав 14 и 15.)

Посмотрите на нижнюю часть рис. 6.1. Вы увидите метод ProcessWindowEvent.

Вот сгенерированная JBuilder версия вызова ProcessWindowEvent, Как она пред­ставлена В Framel. java:

// Переопределено, чтобы можно было выйти при закрытии окна Protected void processWindowEvent(WindowEvent Е)

{

If . getID () = WindowEvent. WINDOW_CLOSING)

{

System. exit(O) ;

}

}

Что этот метод выполняет, я объясню немного позже. А сейчас вам нужно лишь уяснить, что метод ProcesSWindowEvent Никогда не будет вызван, если класс не вызовет сначала метод enabieEvents и не передаст ему параметр AWTEvent. WINDOW_EVENT_MASK.

Вот крайне упрощенная версия метода EnabieEvents, Как она представлена в файле Java JDK С именем Component, java:

Protected final void enableEvents(long eventsToEnable)

{

EventMask = eventsToEnable;

}

После вызова этого метода JBuilder отслеживает, какие события ему необходимо посылать в вашу программу, в переменной EventMask. Он посылает эти события Программе, ИСПОЛЬЗУЯ Виртуальный метод ProcessWindowEvent.

Вот как выглядит иерархия наследования объекта Framel:

Java. Iang. Object I

Ч—J ava. awt. Component I

Ч—java. awt. Container I

4—java. awt. Window I

4—java. awt. Frame I

4—javax. swing. JFrame I

4—Framel

примечаниеКак видите, у Framel Богатая родословная. Все объекты из этой родословной принадлежат JDK Java. Они все реализованы компанией Sun, и все они являются ча­стью любой стандартной виртуальной машины Java Пока что не обязательно пони­мать все объекты этой иерархии, просто знайте, что такая иерархия существует.

В главе 7 вы узнаете, как с помощью JBuiIder просмотреть иерархию, Подобную приведенной здесь.

Если вы исследуете предков Framel, То обнаружите, что сам класс JFrame Содер­жит экземпляр метода ProcessWindowEvent. В ЭТОЙ Версии ProcessWindowEvent Определено некоторое ключевое поведение для этого типа окна.

Protected void ProcessWindowEvent (WindowEvent Е)

super.processwindowevent(е);

{

If (e. getID () = HindowEvent. HIND0W_CL0SING)

{

Switch CdefaultcioseOperation)

{

Case HIDE_ON_CLOSE:

SetVisible(false); break;

Case DISPOSE_ON_CLOSE:

SetVisible(false); dispose () ; break;

Case DO_NOTHING_ON_CLOSE: default: break;

Case EXIT_ON_CLOSE:

System. exit(O); break;

)

>

}

Несложно заметить, что этот метод отвечает на некоторые события, например, делая окно невидимым или, в одном из случаев, закрывая его.

Оказывается, ProcessHindowEvent Вызывается в методе ProcessEvent, Который объявлен В другом предке Framel С именем Hindow. java:

Protected void processEvent(AHTEvent Е)

(

If Instanceof HindowEvent)

{

ProcessHindowEvent((HindowEvent)Е); Return;

}

Super. processEvent(е);

)

Сам метод ProcessEvent Вызывается в классе Component, Являющемся базовым классом любого класса, который может появится на экране. Метод ProcessEvent Не вызывается, если метод EventEnabled Не возвращает True:

Boolean eventEnabled(AHTEvent Е) ( Switch.id) {

Case HindowEvent. HINDOH_OPENED: case HindowEvent. WINDOW_CLOS ING: case HindowEvent. HINDOH_CLOSED: case HindowEvent. HINDOH_ICONIFIED: case HindowEvent. HINDOH_DEICONIFIED: case HindowEvent. HINDOH_ACTIVATED: case HindowEvent. HINDOH_DEACTIVATED:

If ( (eventMask & AHTEvent. HINDOH_EVENT_MASK) != O WindowListener ’ = null) ( return true;

}

Return false;

Default:

Break;

}

Return super. eventEnabled(e) ;

}

Внимательно изучив этот метод, вы должны заметить, что он возвращает True Только в том случае, когда присутствует маска window_event_mask. Это то событие, ожидание которого мы изначально запрашиваем у системы.

Итак, Component, java Не вызовет ProcessEvent, Если не будет вызван EnabieEvents, Который четко определяет, Что должен обрабатываться конкретный вид событий. Поэтому в нашем конструкторе настолько важен вызов метода EnableEvent

EnableEvents(AWTEvent. WINDOW_EVENT_MASK);

Без вызова EnableEvents Никогда не будут вызваны методы ProcessEvent И ProcessWindowEvent. Назначение вызова ProcessWindowEvent Становится совер­шенно очевидным после изучения кода самого метода. Ключевой строкой здесь яв­ляется

System. exit (O);

Эта строка гарантирует, что после закрытия окна программа завершит работу. Если бы не было этой строки, окно бы закрылось, однако программа все равно оста­лась бы в памяти.

примечаниеЯ осознаю, что понимание всего этого требует некоторого умственного напряже­ния, но если вы разберетесь во всем, то будете иметь ясное представление о взаимо­отношениях между ВЫЗОВОМ EnableEvents И методом ProcessWindowEvent, Связан­ным C Framel.

Начинающие программисты могут рассердиться на меня за то, что я вовлек их в исследование столь сложной иерархии объектов. Но более опытные програм­мисты, мало знакомые с Java, скорее сочтут этот анализ полезным. В частности, он показыва­ет, что в Java существует иерархия объектов, очень похожая на то, что присутствует в OWL или VCL. Многие их этих крупных иерархий классов для сложных оконных объектов выглядят, да, впрочем, и являются похожими. Реализованы ли они на Pascal, C++ или Java — все они ведут Себя более или менее похоже. И вот, пожалуйста, еще одна иерархия!

Приемы и технологии визуального программирования

Я обещаю, что в этой главе больше не будет таких нудных разделов, как только что прочитанный вами. В качестве компенсации я ознакомлю вас с двумя простыми описаниями того, как в конструкторе выделить группу компонентов и как удалить тот или иной компонент (или несколько компонентов сразу).

Выбор группы компонентов

Допустим, вам нужно поместить на конструкторе несколько кнопок подряд Пе­рейдите в режим конструирования, нажмите клавишу Shift и, не отпуская, щелкни­те на пиктограмме JButton в палитре компонентов. Теперь дважды щелкните на кон-

Структоре. При каждом щелчке будет появляться элемент JButton. Чтобы прекратить этот процесс, щелкните на стрелке выбора, т. е. на белой стрелке слева вверху палит­ры компонентов.

Удаление компонентов

Компонент можно удалить в режиме редактирования исходного текста. Перей­дите в окно редактирования и удалите такую строку:

JButton myButton = new JButton () ;

Теперь вернитесь в окно конструирования. Теперь MyButton В панели отсутству­ет. Конечно, если вы удаляете в коде MyButton, То следует удалить и все ссылки на нее. Здесь визуальные средства превосходят программирование вручную, поскольку они выполняют за вас всю эту очистку.

примечаниеВ окне конструирования существует много способов удаления компонента. Можно выбрать его в панели структуры и нажать Ctrl+X или щелкнуть правой кноп­кой мыши на его имени в панели структуры и выбрать в контекстном меню пункт Cut, или щелкнуть правой кнопкой на компоненте в конструкторе и выбрать пункт Cut. Также сработает и выбор компонента в конструкторе или в панели структуры с последующим нажатием клавиши Delete. Обратите внимание, что если вы удаляете компоненты в рамках панели структуры, вы можете выбрать несколько компонентов с помощью клавиши Ctrl.

Удаление можно отменить с помощью комбинации клавиш Ctrl+Z. Что касается отмены изменений в визуальном конструкторе, то здесь средства визуального конструирования JBuiIder исключительно мощны. Часто вы можете, нажимая Ctrl+Z, от­менить последствия получасовой работы. Это же касается и редактора, но здесь эффект Не настолько впечатляющий.

Эта великолепная панель структуры

Последний "непримечательный" абзац предыдущего раздела на самом деле очень важен, поскольку он подчеркивает важность использования панели структу­ры. Чаще всего именно с помощью панели структуры проще манипулировать гра­фическими компонентами в JBuilder. В такой среде программирования, как Delphi, удобнее пользоваться конструктором. Но в JBuilder, как вы неоднократно убедитесь, самой важной является как раз панель структуры.

В некотором смысле конструктор — это всего лишь визуальное подтверждение того, что вы делаете в панели структуры. В инструментальных средах наподобие Delphi вы создаете компонент на форме, на которой он должен появиться. До неко­торой степени это верно и в JBuilder. Но по мере увеличения опыта работы с компо­нентами в режиме визуального конструирования вы придете к выводу, что наиболее полезна все-таки панель структуры, а конструктор нужен лишь для того, чтобы вы видели, что конструирование идет так, как надобно.

Часто, если требуется поместить кнопку на экземпляр JFrame, мне удобнее по­местить ее не на сам JFrame, а на список элементов JFrame в панели структуры. В относительно простых проектах эти варианты эквивалентны, и вы можете выбрать
любой из них. Однако в сложных визуальных интерфейсах просто рисовать компо­ненты мышкой на панели конструктора становится все сложнее и сложнее. Мне ка­жется, что в этом случае большую свободу предоставляет панель структуры.

Почему это так? Ответ на этот вопрос находится в главах части III, рассказываю­щих об администраторах компоновки. А коротко можно объяснить так: компонен­ты в JBuilder не имеют конкретных координат х и у, а находятся в некотором отно­шении друг к другу. Панель структуры дает концептуальное представление об этом отношении, причем лучшее, нежели панель содержимого.

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

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

Инспектор

В правой части экрана находится инспектор. C его помощью можно задавать свойства компонентов, а также генерировать для них заготовки обработчиков собы­тий. Поместите компонент в панель и посмотрите на инспектор. По умолчанию в нем отображаются свойства последнего сгенерированного или выбранного компо­нента. Выберите другой компонент, щелкнув на нем или в конструкторе, или в па­нели структуры — по идее, инспектор отобразит свойства выбранного компонента.

По умолчанию инспектор открыт на странице Properties (Свойства). Посмотрите в нижнюю часть панели инспектора, действительно ли в нем выбрана закладка Properties. Свойства, кроме имени, ограничений и ButtonGroup, Перечислены в ал­фавитном порядке.

Давайте в инспекторе изменим некоторые характеристики JButtoni. Выберите элемент jButton1, шелкнув на нем в панели структуры. Теперь щелкните на слове name вверху инспектора — станет выбранным расположенное рядом текстовое поле. Нажмите клавишу Delete для удаления имени jButton1, введите myButton и на­жмите клавишу Enter. Вот вы и переименовали кнопку. Переключитесь в окно ис­ходного текста, и вы увидите следующую строку:

JButton MyButton = New JButton (, ;

примечаниеПерейдите опять в окно конструирования. Для изменения текста на кнопке вы­берите свойство text и повторите этот процесс, введя в поле текста, скажем, Моя кнопка

Текст "Моя кнопка" (два слова) вполне пригоден для заголовка компо­нента. Однако имя компонента должно быть набрано латинскими буквами и без пробе­лов.

Обратимся опять к инспектору. Настройте внешний вид кнопки, изменив ее цвет с помощью свойства Background. Перейдите в инспекторе к свойству background (цвет фона) и в выпадающем списке выберите blue (голубой). Найдите свойство foreground (цвет шрифта) и измените его на cyan (бирюзовый). Затем изме­ните сам шрифт, щелкнув на поле, которое находится справа от свойства font. По­явится кнопка эллипсиса. Щелкнув на ней, вы попадете в диалоговое окно свойств шрифта (Font dialog). Выберите гарнитуру и размер шрифта по своему желанию и щелкните на кнопке OK.

Страница Properties инспектора — это сложное и мощное средство. Но я наде­юсь, что сказанного о ней должно хватить для первого знакомства. В других главах вы прочтете об этом инструменте побольше. В следующем разделе мы рассмотрим страницу Events (События) инспектора.

Создание простого обработчика событий

События — это сложная тема, и о ней пойдет речь в нескольких главах: "Обра­ботка событий" и "Возбуждение событий". А пока я хочу продемонстрировать лишь простой пример того, что можно сделать с помощью страницы Events.

Когда вы связываете с некоторой кнопкой какое-нибудь событие, вы задаете по­ведение этой кнопки при щелчке на ней. Это называется Обработчиком событий {Event Handler), потому что он обрабатывает событие, которое происходит, когда пользователь выполняет щелчок на этой кнопке.

Чтобы добавить обработчик событий для кнопки myButton, внизу панели инс­пектора выберите закладку Events. Щелкните на поле справа от нужного события и нажмите клавишу Enter. JBuilder создаст для данного компонента заготовку кода об­работки этого события и перейдет в режим редактора. Если вам нужно событие ActionPerformed Для некоторого компонента, можно дважды щелкнуть на этом компоненте в конструкторе, и JBuilder создаст заготовку обработчика события. Этот код выглядит следующим образом:

Void JButtonl_ActionPerformed(ActionEvent Е)

(

)

Между фигурными скобками можно внести свой код, который будет определять, что делает кнопка. Например, можно ввести следующий код:

Void JButtonl_ActionPerformed (ActionEvent Е)

{

JOptionPane.ShowMessageDialog(This, "Наша Таня громко плачет, поскольку река-то глубока, а мячик невесть где…");

)

Сейчас можно запустить программу, щелкнуть на кнопке и в отдельном окне увидеть строку не совсем удачной вариации на тему известного детского стихотворе­ния.

Вообще-то при создании обработчика события генерируется больше кода, неже­ли показано здесь. Но для начала хватит и этого, чтобы хоть немного расширить функциональность ваших программ.

119

Использование JTabbedPane

Давайте под конец главы рассмотрим, как применять элемент управления JTabbedPane. Создайте новое элементарное приложение, как было показано в главе 3.

Выделите в панели проекта строку Framel и перейдите в режим конструирова­ния. Выберите в палитре компонентов страницу Swing Containers и поместите в па­нель конструктора элемент JTabbedPane. C этой же страницы палитры компонентов поместите на JTabbedPane Элемент JPanel. Теперь щелкните еще раз на компонен­те JPaneI в палитре компонентов, но на этот раз поместите панель на строку jTabbedPane1 в панели структуры.

Каждая JPanei, Помещенная на JTabbedPane, Создает новую страницу. На дан­ном этапе у вас должна получиться панель JTabbedPane С двумя страницами на ней, как показано на рис. 6.5.

Переключаться между двумя страницами панели JTabbedPane Можно, выбирая объекты JPanel В панели структуры.

Выберите первую страницу. Установите компоновку j Paneil Равной BorderLayout. Поместите на нее элемент JTextArea. Установите его свойство constraints в Center. Найдите текст, который вы хотите отобразить в JTextArea, И скопируйте его в буфер обмена. Выберите свойство text элемента JTextArea И вставьте скопированный текст из буфера в редактор свойств. (Используйте подходя­щие комбинации клавиш, например, Ctrl+V для вставки текста.) Нажмите клавишу Enter, и выбранный вами текст появится на экране, примерно как показано на рис. 6.6.

Перейдите на вторую страницу JTabbedPane И повторите все действия, выпол­ненные с первой страницей, но введите какой-нибудь другой текст. Запустите про­грамму, и вы сможете переключаться со страницы на страницу с помощью закладок.

Можно изменить надписи на закладках страниц, редактируя свойство constraints элементов jPanel1 и jPanel2. Окончательный вид окна программы во время выпол-

wmmrr 7 ∙ c√d<κuntents end 5rttt∏tτ>'mergjc jbpro∣ect<tιnwted35∕ar<√mnttsed9s√f ∣ ∙ ɪ i.fδy0,frt беи gearcb иьа pieiest run team wijaros ⅛ws ⅛ιnu<re. г»ш,rιpf×i,d tɪ а ‘ ¾ в а •о ∙⅛' ⅜ wm jwr
fe j√<⅛⅛- й *
,2 43 jhfi 33.unwβd95,, ssp untltted95.jpx
«project source»
'< ⅛ Λ . -ntιtle<j96
& appllcattonl java
⅛frame1 java untttled9s html
,unttfled95.frame1
is u∪∣
i a qtws
j ∙ fe b contentpane (borderlayj ss borderlayoutt
f? й itabbedpanei 4 ■ s b ∣paneι1
rft <flowlayout∙ *0 --
l j menu
'3 -lj dataaccess -1_) other
,tpanhl jpanefi ® rarn* 
 srtionm* ipywfi i
 al⅛nuιeι>... ml ■■ ∙r.-.i'v
 tom « ɪ
 bac⅛rtxl 
 boʃtɪw .. 
 debuyυ∣ 4teftuβ∙ ‘
■ doubleb ⅛ ... i
 enabled 
 fent w ii thalotf <
 fo∣-jjrounα i b⅛t⅜ i
 ttιρuw⅛tr ,.. .1
 layout «default ∣a>
 masdmu. 
 properties 

,ki ⅛ frarnel i
svrf4 s^<⅛∙rt∣n∙a4^ iibredmbihlrtrtirtwiilertlat * ju
■ ∙-,b1b
,cβarc>Γθ⅝⅜t9n∣a⅛⅜m∙l bct⅜ hwaιy]^
рис. 6.5. панель jtabbedpane с двумя элементами jpanel, образующими на ней страницы

120

Нения представлен на рис. 6.7. Ее исходный текст можно найти в сопровождающих книгу материалах, В файле С именем TabbedPaneExample.

Установка пути класса в IDE

Возможно, вам понадобится добавить к своему проекту библиотеку для расши­рения пути класса. Как это сделать, объясняется в главе 27, в разделе "Установка пути класса: библиотечные файлы JBuilder".

и
fhb edtɪ searth jrtew proferi rtm tegrti v*⅞w<⅛ toote wr
α ∣ia∙ιaв 0« ■ toi£s
j > ∙e∙⅜∙⅜∙>>e „„
w £1 £р unwtodβs ip iinfltiedss ∣px j w ф «project source»
⅛j ⅛ ⅛ untitledss ⅛ , ⅛ applicationl ∣ava .∙ aframeijava i s unfitledgs ntml
,ibuilder 1 c: dutument⅞ and beltings/marule, jbpro(e<t∕untftled7s∕src∕outftted⅛5,Λvβmejt.⅛∣ra,<⅛.j5⅛k½ <x∙,⅛s⅛ra⅛⅛ -j ⅛
∏⅛ sw*i9 ∣5w⅛χj cortatoara {l>fre4ra⅝t cfcsvhng ∣ more cibswtofrf dbswir>q mcκfe⅛t⅝* i» 1
( « ⅛- te- '"~i pxj {^tj q 5≈ ʒ Γj⅛ щ }
,untltled95.framel
_lui
s othls
⅛ q contentpane (borderlayoutj « borderlayoutl
й s jtabbedpanei
ei q jpanelt (borderlayc
i » borderlayout2
'∙ b 
o ∣panel2
_j menu
_j data access
-j other
,-ii

Рис. 6.6. Пример отображения текста на одной странице элемента JTabbedPane

>¾ Frame Title

TrehemeOne

The angels, who are faithful while they view His glory, know not what themselves would do. Were they in our estate! A dimmer light Perhaps would make them err as well as we;

And in the coldness of a darker night, forgetful and lukewarm themselves might be.

Our very rust shall cover us with gold,

Our dust shall sprinkle while their eyes behold The glory springing from a feeble state.

Where mere belief doth, if not conquer fate, Surmount, and pass what it doth antedate.

Рис. 6.7. Программа TabbedPaneExample Во время выполнения

Резюме

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

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

Полное обсуждение сложной природы конструирования интерфейса в JBuilder будет продолжено в части III, "Основы JBuilder". Здесь вы столкнетесь со сложнос­тями, порожденными мощной MVC-архитектурой, которая лежит в основе Swing

Но пока вам вполне хватит знаний о базовых механизмах при работе с конструк­тором. Он является одним из самых мощных средств JBuilder, могущим сэкономить очень много времени. По мере большего ознакомления с конструктором на протя­жении книги вы поймете, что это на самом деле очень гибкий инструмент, разуме­ется, если использовать его умело.

Чарли Калверт

Глава 7

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *