Администраторы компоновки

Э

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

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

В продуктах наподобие Delphi или Visual Basic компоненты обычно размещают­ся на форме в конкретных координатах х и у. Но в Java компоненты располагаются друг относительно друга. Различные администраторы компоновки как раз и помо­гают выбрать природу взаимного расположения компонентов.

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

Существует много администраторов компоновки, и все они работают, определяя общие правила размещения и размер компонентов. В нескольких программах, при­веденных ранее в качестве примеров, главная панель программы имела компоновку BocderLayout. Вы, очевидно, заметили, что при размещении компонентов в пане­ли они располагались по некоторому правилу. А именно, они размещались на севе­ре, юге, востоке, западе и в центре панели (North, South, East, West и Center). Это правило было продиктовано администратором компоновки, который является объектом, определяющим правило отображения компонентов.

Не все администраторы компоновки так же легки для понимания, как BorderLayout. Некоторые из них, например, GridBagLayout, Очень сложны. Дру­гие, наподобие GridLayout, Относительно просты, если вы знаете некоторые про­стые приемы работы с ними. Есть и многие другие, с различными уровнями слож­

Ности.

Теория компоновки

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

Немного теории контейнеров

Компоновки существуют внутри контейнеров. Контейнер — это не только тех­нический термин Java, но и название конкретного класса.

Контейнер {Container} — это класс языка Java, который может содержать другие компоненты. Примерами контейнеров являются классы JPanel, JTrame и JApplet.

Если у вас редакция SE или Enterprise, перейдите в начало типового класса Framel Стандартного приложения JBuilder. Щелкните правой кнопкой мыши на слове JFrame в описании класса и в появившемся контекстном меню выберите пункт Find References. Вы увидите много различной информации о классе JFrame, В том числе и список предков JFrame. В редакции Personal список предков можно по­лучить, подведя курсор к слову JFrame и нажав клавишу Fl. В появившемся Javadoc — файле вы увидите следующую иерархию:

Java.IangObject I

ЧJ ava. awt. Cootponent I

ЧJava. awt. Container I

Ч—j ava. awt. Window I

4—j ava. awt. Frame I

4—javax. swing. JFrame

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

Компонент — ^to визуально отображаемый класс, который взаимодействует с пользователем.

Контейнер — это компонент, который может содержать другие компоненты.

Контейнер имеет два очень важных метода: Add И SetLayout.

Метод add контейнеров предназначен для добавления в контейнер компонен­тов. Метод SetLayout Служит для задания компоновки контейнера:

ContentPane = (JPanel) This.GetContentPane(, ;

ContentPane. setLayout CgridLayoutl);

ContentPane. add(jButtonl, null);

Взаимосвязь между компонентами, контейнерами и компоновками очень четко определена и интуитивно понятна. Это и есть признак хорошей разработки.

GridBagLayout против остальных

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

GridBagLayout принадлежит к элитному набору Java-компонентов, ко­торый хоть и не запрещен, но многими неуемными критиками считается "не рекоменду­емым". Другими известными членами этого клуба являются классы Applet и JApplet — Аргументы против GridBagLayout сводятся к тому, что от него больше мороки, чем пользы. Хотя мне тоже иногда приходится повозиться с этим классом, я считаю, что все — таки с ним можно справиться. Поэтому я буду рассматривать его как компонент первого класса.

GridBagLayout часто можно заменить комбинацией нескольких других компо­новок. Например, ВЫ можете сочетать GridLauout ИЛИ BorderLayout C ОДНОЙ ИЛИ двумя другими компоновками, вроде BoxLayout, и получить относительно гибкий интерфейс.

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

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

Компоновка — это просто класс

Администратор компоновки является обычным Java-классом. Каждый класс реа­лизует некоторые правила компоновки. Правило может состоять в размещении компонента слева, вверху, справа, внизу или в середине контейнера. Или же вы мо­жете разместить несколько компонентов как бы на сетке, вроде шахматной доски. А, возможно, вы захотите, чтобы компоненты располагались на контейнере сверху вниз или горизонтально слева направо. Каждая из этих схем называется Политикой (Policy), а Администраторы компоновки (Layout Managers) — это просто классы, реали­зующие эти политики. Например, BorderLayout реализует первую описанную в данном параграфе политику, вторую реализует GridLayout, а третью — BoxLayout.

Поскольку компоновка является обычным классом, т в язык можно добавлять но­вые администраторы компоновки. В нескольких случаях компания Borland так и сдела­ла. Некоторые ИЗ ЭТИХ классов очень полезны, например, VerticalFlowLayout.

Еще один класс Borland, XYLayout, Очень похож на форму Delphi или Visual Basic. Но он не всегда хорошо ведет себя в межплатформенных приложениях. По­этому он не очень полезен, если не считать имитации компоновки для контейнера. Я считаю, что лучше избегать использования XYLayout, Если вы не знаете точно, за­чем он вам нужен. Вместо этого прочитайте данную главу и попробуйте разобрать­ся, как это делается в стиле Java. К администраторам компоновки нужно привык­нуть, но когда вы поймете, как они устроены, то, я думаю, что вы сочтете их весьма полезным средством.

Использование классов Borland в вашей программе

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

В некоторых случаях Sun даже не обеспечивает bean-оболочек для таких ключе­вых классов компоновок, как BoxLayout. Не имея bean-оболочки класса, трудно или вовсе невозможно использовать этот класс в качестве визуального компонента, ко­торый можно перетащить с палитры компонентов и которым можно легко манипу­лировать с помощью визуальных средств Borland. В общем, без bean-оболочки класс невозможно применять в инструменте визуального проектирования, таком как JBuilder. Вместо этого приходится переключаться в режим текстового редактирова­ния JBuilder и вручную вводить требуемый код. Из-за этого теряются многие пре­имущества JBuilder, и приходится работать примерно так же, как и в простом тек­стовом редакторе вроде Блокнота или Kate.

К счастью, Borland достойно вышла из этой ситуации, предложив несколько сво­их администраторов компоновки. Например, существует bean-оболочка для BoxLayout, Называемая BoxLayout2. В предыдущем разделе был упомянут другой Полезный администратор КОМПОНОВКИ Borland: VerticalFlowLayout.

примечаниеЭти классы, разработанные Borland, находятся в каталоге Redist, Поставляемом вместе с инсталляцией JBuilder. В этом каталоге компания Borland собрала файлы, предназначенные для распространения вместе с вашими приложениями. Вы може­те распространять их любым способом, если вы не включаете их исходные файлы. Например, вы можете включить все файлы Borland в их "родном" JAR-файле JBCL. Jar. Или же можно включить в программу отдельные файлы классов: либо как есть, либо с помощью Archive Builder. Утилита Archive Builder описывается в главе 28, "Инсталляция аплетов, приложений и исполняемых файлов Java".

Прочтите нижеследующее официальное сообщение и не используйте данную книгу как официальное руководство. Чтобы узнать больше о легальных аспек­тах использования кода Borland в своих программах, прочитайте файл license. htxnl, на­ходящийся в корневом каталоге JBuiIder, а также внимательно изучите следующий файл из подкаталога redist каталога, содержащего JBuiIder:

2. Распространение файлов JBCL

В рамках лицензии, входящей в состав данного продукта, распространяемые файлы библиотеки JavaBean-компонентов определяется как файл jbcl. jar в каталоге ∕jbuilder6∕redist и/или отдельные файлы из этого архива.

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

A) В виде отдельных файлов классов

B) В виде всего файла jbcl. jar

C) В виде файла класса, включенного в ваш архивный файл, например, с помощью Archive Builder.

Я считаю, что использовать классы Borland в программах просто и легко. Если у вас еще остались вопросы, ответы на них можно найти на форуме Forums.Borland.Com И на конференции BorɪAnd.Public.Jbuilder,Jbcl.

Здесь заканчивается теоретическая часть данной главы. А теперь можно присту­пать к изучению конкретных классов компоновок.

BorderLayout

Конечно, все зависит от ЛИЧНЫХ Вкусов, НО Я считаю, ЧТО BorderLayout Луч­ший администратор компоновки по умолчанию. Он легок в использовании и поня­тен, а также достаточно гибок, чтобы создавать довольно логичные компоновки для тестовых приложений. Всякий раз, когда я начинаю размещать компоненты на кон­тейнере, и слабо предполагаю, что из этого получится, я начинаю с указания кон­тейнеру использовать BorderLayout.

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

Администратор BorderLayout Делит визуальный компонент на пять зон, как по­казано на рис. 12.1. Вы можете создать одну зону в центре (Center) и выровнять ос­тальные вдоль четырех краев. Эти края называются North, South, East и West (Север, Юг, Восток и Запад). На рис. 12.1 JButto∏3 Находится в зоне North, JButtonl В зоне West и т. д.

BorderLayout Является компоновкой по умолчанию для ContentPane Элемента JPanel, На котором вы размещаете компоненты при работе с потомками JFrame. Чтобы почувствовать, как работает эта компоновка, запустите новое элементарное приложение и перейдите в режим конструирования для Framel.

Добавьте на Framel Пять элементов JButton. Первый компонент, размещаемый на панели, будет расположен в верхней части конструктора пользовательского ин­терфейса. После добавления всех кнопок они будут иллюстрировать размер и пра­вило размещения администратора BorderLayout При его работе в JBuilder. На рис. 12.1 показан конструктор пользовательского интерфейса с пятью кнопками в ком­поновке BorderLayout.

CT JBuiIdcr Fι∕Γ∣ocumcnfe find SetIingsJcharheZjhρroject∕unlitled1 ZsrcZurditJedVfwme? java

file fdll search view project run
d £ β-∙⅛ h β<'i*>
⅛ untitledl .frame2 j∙∙di8
& cjnns
& f contentpane (sorderlayouq ɪ tŋf borderlayout1
;• ‰ (buttonl « ∣button2 “ )button3
` i=∙ (button4 зй jbuttons
-d menu -d dataaccess d other
team wizards tools window help,⅛ » & ∙m ‰ ь `
a fumel Λframe2 ∣
swing f swing containers dataexpress cbswing f morecbswsig ∣ aswingmc-jxxj
⅞g { t∞j im b- •— ⊂□ ∣*wt∣ pf ∣ ]^∣ ∈□ cds
,(buttons,source' design (bean (uml∣ рос] hlstoryl-
рис. 12.1. borderlayout делит экран на пять зон под названиями north, south, east, westu center. на данном рисунке каждая из кнопок занима-ет одну из зон
{button3 
jbuttoni !button4 ibutttdl 

, 
пита ∣panel2 
constrainti south 
scttonmap 
slignmenlx 0^5 
sliflnmenty 05 
background □ ^236,23- 
bo⅛er 
sebugora jdefautfem 
ooubiebuf true 
bnabled true 
ibnt 'd∣a∣pjf,o. 
fereground ■ black 
 
properties events]
ibuttons: south
примечание
при размещении компонентов на borderlayout могут возникнуть не
которые трудности.

Если почему-то компоненты не расположены так, как вам нужно, попробуйте ус­тановить их СВОЙСТВО Constraints В North, South, East, West Или Center, В зависи­мости от того, что вам требуется.

Если вы помещаете на контейнер компоненты, которые сами являются контей­нерами, то можно промахнуться и разместить один компонент на другой, а не на ле­жащую в основе панель, как требуется. Например, если вы помещаете на JFrame пять компонентов JPanei, Легко сделать какой-либо из них потомком другого, а не JFrame. Чтобы эта проблема не возникала, попытайтесь работать не на панели со­держимого, а на панели структуры. Просто перетащите JPanel На то место панели структуры, где она должна быть. Для меня это более понятный способ работы не только с BorderLayout, Но и со многими другими компоновками.

Компоненты JButton Также являются потомками класса Container. Но в среде JBuilder по умолчанию они не ведут себя как контейнеры. Поэтому вы обычно мо­жете помещать их не на панель структуры, а на панель содержимого. (Вообще-то вы можете вручную поместить одну кнопку на другую, но вряд ли вы придумаете, зачем нужна такая непонятная для потенциальных пользователей конструкция! К счас­тью, по умолчанию JBuilder не позволяет проделывать подобные фокусы на панели содержимого.)

Обратите внимание, что на рис. 12.1 на панели структуры выделена строка Frame2. Единственным дочерним элементом Frame2 Является ContentPane. Все кнопки, а также объект BorderLayout, Являются дочерними по отношению к ContentPane. Знакомство с тем, как компоненты отображаются на панели структу­ры. является одним из наиболее важных умений, которыми необходимо овладеть, есги вы > отите уверенно работать с JBuilder.

Посмотрим на код, сгенерированный для Frame2. Исходный текст для этого по­томка JFrane Показан в листинге 12.1.

Листинг 12.1. Исходный код объекта JFrame с пятью расположенными на нем кнопками

Package untitledl;

Import java. awt.*;

Import java. awt. event.*;

Import javax. swing.*;

Public class Frame2 extends JFrame

{

JPanel contentPane;

BorderLayout borderLayoutl = new BorderLayoutO ; JButton j Buttonl = new JButton () ;

JButton jButton2 = new JButton();

JButton jButton3 = new JButton () ;

JButton jButton4 = new JButton () ;

JButton jButton5 = new JButton() ;

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

Public Frame2 ()

{

EnableEvents(AWTEvent. WINDOW_EVENT_MASK); try {

Jblnit() ;

}

Catch(Exception e)

{

E. printStackTrace();

1
∕∕ инициализация компонентов
private void jbɪnit() throws exception {
1

ContentPane = (JPanel) this. getContentPane () ;

ContentPane. SetLayout(borderLayoutl);

This. setSize(new Dimension(291, 227)) ;

This. setTitle("Frame Title”) ;

JButtonl. setText (,, jButtonl,’) ;

JButton2. setText (*, jButton2 n) ;

JButton3. setText (,, jButton3») ;

JButton4.setText("jButton4");

JButton5. setText (n jButton5,,) ;

ContentPane. add(j Buttonl, BorderLayout. WEST);

ContentPane. add(jButton2, BorderLayout. EAST);

ContentPane. add(jButton3, BorderLayout. NORTH);

ContentPane. add(jButton4, BorderLayout. CENTER);

ContentPane. add(jButton5, BorderLayout-SOUTH);

}

∕∕ Перекрыт, чтобы можно было выйти при закрытии окна Protected void procesSWindowEvent (WindowEvent e)

{

Super. ProcessWindowEvent(e);

If (e. getID() = WindowEvent-WlNDoWjCLOSING)

{

System. exit(O);

)

)

227

Посмотрим на данные для объекта Frame2:

Public class Frame2 extends JFrame

{

JPanel contentPane;

BorderLayout borderLayoutl = new BorderLayoutO ;

JButton j Buttonl = new JButton () ;

JButton jButton2 = new JButton () ;

JButton jButton3 = new JButton () ;

JButton jButton4 = new JButton();

JButton jButton5 = new JButton();

Здесь находятся все дочерние компоненты объекта Frame2. На самом деле ком­поновка и кнопки содержатся в ContentPane. Это трудно увидеть в данном фраг­менте кода, но гораздо легче в методе Jbɪnit И на панели структуры (см. рис. 12.1):

west); east); north); center); south);

помните, что сама contentpane принадлежит frame2. поэтому эти кнопки в конце концов принадлежат и самому фрейму.
взгляните на код jbinit и посмотрите на простые java-операторы, сгенерированные jbuilder при размещении компонентов на frame2. примерно такой же код написал бы и любой грамотный программист на java, создавая интерфейс, показанный на рис. 12.1. это единственный осмысленный способ создать такого рода потомка jframe.
,det3ugθraphις «default* doub∣ebu*rered true enabled true,font
конечно, если вы захотите изменить компоновку frame2, вы можете вручную ис-править исходный код. но все же обычно легче провести такие изменения в режиме конструирования. в частности, в режиме конструирова
ния вы можете сразу же видеть, дают ли изменения, проводимые вами, нужный эффект.
например, с помощью установки в инспекторе свой-ства constraints можно выбрать расположение компонента, как показано на рис. 12.2. в компоновке borderlayout вы можете выбрать расположение north,
south, east, west или center. например, изменив свойство constraints элемента jbuttonl на north, вы можете разместить его вдоль верхнего края панели.
,gridlayout,foreground
intjutverifier
,⅛lacκ,layout borderlayout,администратор компоновки gridlayout позволяет создать набор строк и колонок одинакового размера, расположенных наподобие шахматной доски. простейшая компоновка gridlayout может иметь вид прямоугольника, поделенного на две равные половины — по-,idaximumbefc
minimums'ee
nextfoςusabje..
,-⅜ я
2p7483w.2u

ContentPane. setLayout(borderLayoutl); ContentPane. add(jButtonl, BorderLayout contentPane. add(jButton2, BorderLayout contentPane. add(jButton3, BorderLayout, contentPane. add(jButton4, BorderLayout contentPane. add(jButton5, BorderLayout,

Добно тому, как делится сеткой стол для игры в настольный теннис. Более сложная компоновка GridLayout Может быть похожа на шахматную доску.

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

Создайте в JBuilder элементарное приложение и установите компоновку Framei В GridLayout. Поместите на Framel Пять-шесть кнопок. После запуска полученной программы она будет выглядеть примерно как показано на рис. 12.3.

{⅛ frame Title

■ ■

KiFraiite Title

■ ■

* 1

I

Рис. 12.3. GridLayout С одной строкой и шестью колонками

Рис. 12.4. GridLayout С двумя строками и тремя колонками

____________ I

Name

GridLayout1 ∣

Columns

3

Hgap

O Z

Rows

2 j

Vgap

O

propertiesjeventsВ режиме конструирования выберите gridLayout1, щелкнув на соответствующей строке в панели струк­туры. Измените значение в поле Rows (строки) с 1 на 2, а поле columns (колонки) — на 3. Теперь Framel Будет выглядеть как показано на рис. 12.4.

В панели инспектора, показанной на рис. 12.5, видны простые управляющие элементы для измене­ния значений, применяемых В GridLayout.

рис. 12.5. инспектор, отображающий поля класса gridlayoutВ листинге 12.2 приведен исходный текст про­граммы, соответствующей рис. 12.4.

Листинг 12.2. Исходный текст простой программы,

Использующей GridLayout. Набор кнопок выстроен в две строки и три колонки

Package untitledl;

Import java. awt.*;

Import java. awt. event.*;

Import javax. swing.*;

Import j ava. applet. AppletContext; public cla □ Framel extends JFrame 1

JPanel contentPane;

JButton jButtonl = new JButton () ;

JButton jButton3 = new JButton () ;

JButton jButton4 = new JButton();

JButton jButton6 = new JButton();

JButton jButton2 = new JButton () ;

JButton jButton5 = new JButton () ;

GridLayout gridLayoutl = new GridLayoutO ;

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

Public Framel ()

{

EnableEvents(AWTEvent. WINDOW_EVENT_MASK); try {

Jblnit();

}

Catch(Exception e)

(

E. printStackTrace();

}

}

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

Private void jMnit() throws Exception

{

ContentPane ≈ (JPanel) this. getContentPane();

ContentPane. SetLayout(gridLayoutl); gridLayoutl. setCoIumns(3) ; gridLayoutl. setRows(2); this. setSize (new Dimension (400, 300)) ; this. SetTitle("Frame Title") ; jButtonl. setText("jButtonl"); jButton3.setText("jButton3"); jButton4.setText("jButton4"); jButton6.setText("jButton6"); jButton2.setText("jButton2"); jButton5.setText("jButton5");

ContentPane. add(jButtonl, null);

ContentPane. add(jButton5, null);

ContentPane add(jButton2, null);

ContentPane. add(jButton4, null); contentPane. add(jButton6, null);

ContentPane. add(jButton3, null);

}

∕ ∕ Перекрыт, Чтобы можно было выйти при закрытии окна Protected void ProcessWindowEvent (WindowEvent e)

{

Super. ProcessWindowEvent(e);

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

{

System. exit(O);

}

вот τr τ код, который создает и настраивает экземпляр gridlayout:

GridLayout gridLayoutl = new GridLayoutO;

ContentPane. setLayout(gridLayoutl); GridLayoutl. setColumns(3); GridLayoutl. setRows(2);

примечаниеКак видите, это очень простая в использовании компоновка, даже если писать соответствующий код вручную. Hy а с помощью визуальных средств JBuilder приме­нять ее еще проще. Что более важно, при проведении изменений в конструкторе вы можете сразу же визуально контролировать, что делает ваш код.

Возможно, вы заметили, что я снова и снова показываю вам по сути одну и ту же программу, но каждый раз с новой компоновкой. Это позволяет вам уви­деть, как выглядит потомок JFrame с пятью или шестью кнопками на нем, но с различны­ми компоновками. Если вы откроете JBuiIder и несколько раз переключитесь туда-сюда между различными компоновками, то вы гораздо быстрее поймете, что они делают. Ре­комендуется также’ запустить эти программы и несколько раз изменить размеры Framel, чтобы увидеть, как ведут себя различные компоновки

FIowLayout

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

При работе в JBuiIder с компоновкой FlowLayout на JPanel вы мо­жете столкнуться со странной аномалией. А именно, может оказаться так, что вы не смо­жете воспользоваться инспектором для просмотра свойств класса FlowLayout, исполь­зуемого для JPanel по умолчанию. Эта проблема решается изменением в инспекторе Свойства Layout с <FlowLayout> на что-нибудь вроде AowLayoutI.

Вот более подробное объяснение этой проблемы: когда вы создаете объект JPanei, свойство layout в инспекторе будет содержать текст,,<default layout>" (‘^ком­поновка по умолчанию=*"), а в панели структуры появятся слова "<FlowLayout>". Если вы щелкнете в панели структуры на ‘,<FlowLayout>", в инспекторе не отобразится ничего. Это не есть хорошо. Чтобы поправить ситуацию, разверните в инспекторе список возможных значений свойства layout объекта JPanel и выберите в нем FIowLayout. Теперь в инспекторе свойство layout будет равно FIowLayout, а в панели структуры будет присутствовать строка FIowLayoutI. При выборе FIowLayoutI в пане­ли структуры вы увидите свойства этого объекта в инспекторе. В следующем разделе мы еще вернемся к этому вопросу.

Компоненты, помещаемые на FiowLayout, Принимают свои естественные раз­меры. Например, если вы размещаете на ней набор кнопок, то кнопка с самой длинной надписью будет самой широкой, а остальные будут поменьше. FiowLayout Не приводит автоматически все компоненты к одному размеру.

231

«default layout* i⅛
xfla7out
vertjcaifiowlayout
boxlayout2
overtaylayout2
borderlayout
itiaxlmwnsjze muiimurnsmb n«tfocysabiecum opaqueproperties ∣ ewritslрис. 12.6. выбор в инспекторе компоновки flowlayoutЧтобы воспользоваться компоновкой FlowLayout, Нужно просто разместить на наследнике JFrame Эк­земпляр JPanel. Или же, если хотите, можно устано­вить СВОЙСТВО Layout элемента Framel Вместо BorderLayout В FlowLayout.

Для примера создайте новое приложение и выде­лите в нем компонент Framel. При этом в панели структуры должна быть выделена ContentPane. В пане­ли инспектора щелкните на свойстве layout и выбери­те в раскрывшемся списке строку FIowLayout, как по­казано на рис. 12.6. Поместите на Framel пять кно­пок JButton.

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

Выберите в панели структуры flowLayout1, щелкнув на этой строке. На панели инспектора будут отобра­жены свойства объекта FiowLayout. Теперь с помощью инспектора можно изменить выравнивание по умолчанию на левое или правое, а также настроить горизонталь­ные и вертикальные промежутки.

Изменяя свойства FiowLayout, Можно получить интерфейсы различного вида, например, панель кнопок. В программе на рис. 12.9 используется выравнивание влево, горизонтальный промежуток 20 и вертикальный промежуток 30.

JBuilrirr 7 — G√’src. *rcjava ZaIIunHtIediZMyrIratProjert ∕*re∕myth∙MjB∙βjecг, Tremei java

File Edit Search VIeW Protect gun Tegm Wfcsrds Tools V⅛nα∏w Надр ʌ.

Q <s ’¾ u β `* ⅛ « ^i «I ≠ “9Й ⅛* "%!∙≈⅛’IS »

⅛⅛<e

J& 0 ⅜⅜⅝⅛

5P MyFlrstProjectjpM, ffi∙Φ «Project Source*

I ft’4> myflrstproject

-l⅜.>∣i∣⅝⅝¾m^ '^m "× ʌ: ._j-. is ,<-f- ∣4⅛
к <& framet j
(× swing ibvmn9cortainerei damewwtsi ifcswinei morexbswingi ubswlngmnmtj wernatbnt cbi
{ cb*~,∙∣i ий» ζ⅛f∙*r^∖ pf] Γ^'' i r÷□ <zh }
jblrttonl ] jbtiftonβ j jbutton/

itiyflrstprojectframei
i⅛ ~jui
,i contentpane« }5 aowlayou 15 )button1 i⅛ jθutton6 ⅛s ∣button7 j55 (button8
■ 1⅛ ,button9 Γ5s jθutton2 г» )button3 js⅛ jbuttor∣4 f⅛ jbuttons
,<i,icontt ttpane (fimwlayolrt),jffafrfttrtte,,pconertieslfvefltsi jβuttona i jβutton⅛ i jsuttora f jbuttaiu
 ,"""v—1~—∙∣ ∙∙∙••••••••■•••■• ∙∙ ` ∙∣ ∣v,'. l
contentpane u>ntenlpane j
mte ел
de⅛uttctos⅛..
enabled true i
font
foreground ?
lcofltmajje
jtoemiaar h⅛⅞∑j
: .∙l
locate
res⅛able
state ⅛⅛wit*ysfi
true - j
jbuttai⅛5 i
oestδfl i bean ooc

∙∙∙4⅛ FrameLjava i •& MyFirstProject java

Рис. 12.7. FlowLayout В панели конструктора пользовательского интерфейса JBuilder

рис. 12.8. задание свойств объекта flowlayout htlf,jsuljyft j ∣bu8on⅜ i ibuhnti/ j,
ibuiiens } ffiu⅛onfl∣ i , , ⅝⅛⅝o∣
* г , »
,⅜utoπ3 i jbuttnm j ∣8uttκ⅛ i
г m.* кrviv •*,flte- g® gββrcħ mβw project run fejro w⅛mte toete wtedow hete
*'-"l ■ .-г-’'-—-∙^u⅞⅞γlις,∙--⅞7*^ι„gyl⅞s
,d s6∙l¾a 9 *<i' 4∙ «♦ ] <►
%irf<(a 5l*-
s myftrstprojectjpx s be∙ ш «project source*
j »=• ⅛⅜ myfirstproject 1 ' ■ <⅛ frameljava
<⅜ myfirstprojeci java
,? tnynrstprojectframei
⅛ c*u∣
,1 contentpane (flι ⅜∙
8? зв2я535п
⅛⅛ jbuttonl ⅛ j6utton6 ⅛ jbuttonz ⅛⅜? jbutton8 .⅛s jbuttons й jbutton2 ⅛' jbutton3 ⅛⅛ jbutton4 ** sw jbuttons
,. i dl х|,xfisffirtteiftji .χ s<
" uw⅛, an(tehm }e⅝te(⅛e<*, ⅛sτ*^ tetew44∣to⅛fc i hemetβ⅛jlii
' ⅛½⅛rt⅛⅛-→>-t-i '-ξ;- ет ->∙i
,и»,spurttej p⅜e⅝n ijbtetejteimti <⅝⅛j ⅜⅜⅛rt⅝Γ
рис. 12.9. измененное расположения кнопок с помощью инспектора

рис. 12.10. простая компоновка с боль-шой областью отображения и двумя кнопками в нижней левой части экрана

Простое диалоговое окно на основе FIowLayout

Теперь, когда уже понятно, как работает FlowLayout, Можно посмотреть, как с его помощью создать простой интерфейс для реального приложения. Пример программы FlowLayoutButtons, Которую мы сейчас со­здадим, показан на рис. 12.10 и входит в со­став сопровождающих книгу материалов. В данной главе эта программа будет создана несколько раз, каждый раз с несколько дру­гой схемой компоновки.

Сначала создайте элементарное прило­жение. На Framel поместите два экземпля­ра JPaneI: один в центре, а другой вдоль юж­ной стороны. На той панели, которая нахо­дится на южной стороне, поместите две кнопки. C помощью инспектора измените свойство background (цвет фона) элемента jPanel1 на LightGray (светло-серый).

Полученный интерфейс должен быть похож на показанный на рис. 12.10. Несо­ответствие только в том, что кнопки расположены в центре второй панели, а не сле­ва. Чтобы поправить положение, необходимо выполнить два шага:

1. Явно установите компоновку jPanel2 (на которой расположены кнопки) рав­ной FIowLayout. По умолчанию эта компоновка и равна FIowLayout, но это просто переменная, объявленная в начале файла FiowLayout. java, А не ре­альный экземпляр FiowLayout. Поэтому в инспекторе она отображается не­корректно. Чтобы исправить ситуацию с инспектором, необходимо явно уста­новить свойство layout панели с кнопками на FIowLayout. После этого свойство layout будет равно чему-то вроде AowLayoutI, а не <FlowLayout>.

2. Установите свойство alignment (выравнивание) компоновки FIowLayout в LEFT (слева).

Теперь все выглядит так, как на рис. 12.10. Это, наверно, самый простой и понят­ный способ получить окно такого вида. Исходный текст этой программы можно найти в листинге 12.3.

Листинг 12.3. Исходный текст для Framel из программы FlowLayoutButtons

Package fIowlayoutbuttons;

Iɪrport j ava. awt. * ;

Import java. awt. event.*;

Inport javax. swing.*;

Public class Framel extends JFrame

{

JPanel ContentPane;

BorderLayout borderLayoutl = new BorderLayout();

JPanel jPanell = new JPanel() ;

JPanel jPanel2 = new JPanel();

JButton jButtonl = new JButton();

JButton jButton2 = new JButton();

FlowLayout fIowLayoutl ≈ new FlowLayout();

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

{

EnableEvents(AWTEvent. WINDOW_EVENT_MASK); try 1

Jbɪnit() ;

}

Catch(Exception e)

1

E. printStackTrace();

1

1

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

ContentPane = (JPanel) this. getContentPane() ;

ContentPane. setLayout(borderLayoutl); this. setSize(new Dimension(400, 300)); this. setTitle("Frame Title"); jPanell. SetBackground(Color. IightGray); jButtonl. setText("jButtonl"); jButton2.setText("jButton2"); jPanel2.setLayout(fIowLayoutl); fIowLayoutl. SetAlignment(FlowLayout. LEFT);

ContentPane. add(j Panell, BorderLayout. CENTER);

ContentPane. add(jPanel2, BorderLayout. SOUTH); jPanel2.add(jButtonl, null);

JPanel2.add(jButton2, null);

}

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

{

Super. processWindowEvent(е);

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

{

System. exit(О) ;

)

Обратите внимание, что в исходном тексте две панели размещены на COntentPane компонента Framel, на которой находится И FlowLayout:

ContentPane = (JPanel) this. getContentPane();

ContentPane. SetLayout (IaorderLayoutl) ;

ContentPane. add(j Panel1, BorderLayout. CENTER);

ContentPane. add(jPanel2, BorderLayout. SOUTH);

Панели расположены в центре (center) и вдоль южной стороны (south).

На jPanei2 находится FiowLayout С выравниванием влево и две кнопки:

JPanel2.SetLayout(fIowLayoutl); FIowLayoutl. SetAlignment(FlowLayout. LEFT); JPane12.add(jButtonl, null);

JPanel2.add(jButton2, null);

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

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

Простое диалоговое окно на основе VerticalFIowLayout

Система, описанная в предыдущем разделе, отлично работает, если необходимо разместить кнопки вдоль нижней стороны контейнера. А если мы захотим, чтобы они были слева? В этом случае проще всего воспользоваться классом VerticalFiowLayout Компании Borland. Этот администратор компоновки доступен в редакциях SE и Enterprise.

примечаниеЕсли вы используете VerticalFlowLayout, BoxLayout2 или любой другой класс из JBCL, то вам потребуется включить в проект библиотеку JBCL. Если вы добавляете эти компоновки Borland с помощью инспектора JBuiIder, то классы JBCL до­бавляются в проект автоматически. Но если вы создаете код как-то по-другому, могут возникнуть проблемы. Например, если вы вставляете или вручную набираете код, ис­пользующий JBCL, непосредственно в редакторе, то вам нужно вручную добавить в про­ект библиотеку JBCL. Для этого выберите пункт меню Project ∣ Project Properties и пе­рейдите на страницу Required Libraries. Щелкните на кнопке Add, выберите в раскрыв­Шемся списке библиотеку JBCL и щелкните на кнопке OK.

На рис. 12.11 вы видите окно про­граммы FIowLayoutRight, которая также входит в состав сопровождающих книгу материалов. Это тот вид, который нам надо получить. Исходный код этой про­граммы приведен в листинге 12.4.

Листинг 12.4. Исходный код для Framel из программы FIowLayoutRight. Программа основана на использовании класса VerticaIFIowLayout Из библиотеки JBCL

Package fIowlayoutright;

Import java. awt.*;

Import java. awt. event.*;

Import javax. swing.*;

Import com. borland. jbcl. layout.*; public class Framel extends JFrame {

рис. 12.11. простая программа с кнопками, расположенными справаJPanel ContentPane;

BorderLayout borderLayoutl = new BorderLayoutO;

JPanel jPanell = new JPanel();

JPanel jPanel2 = new JPanel ();

VerticalFlowLayout VerticalFlowLayoutl = new VerticalFlowLayoutO; JButton jButtonl ≈ new JButton();

JButton jButton2 = new JButton();

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

Public Framel()

{

OnableEvents(AWTEvent. WINDOW_EVENT_MASK); try {

Jbɪnit () ;

}

Catch(Exception e)

{

E. printStackTrace();

1

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

Private void jbɪnit() throws Exception

{

ContentPane ≈ (JPanel) this. getContentPane(); ContentPane. setLayout(borderLayoutl); this. setSize(new Dimension(400, 300)); this. setTitle("Frame Title"); jPanell. SetBackground(Color. IightGray); jPane12.setLayout(VerticalFlowLayoutl); jButtonl. setText("jButtonl"); jButton2.setText("jButton2");

ContentPane. add(jPanell, BorderLayout-CENTER); ContentPane. add(jPanel2, BorderLayout. EAST); jPanel2.add(jButton2, null);

JPanel2.add(jButtonl, null);

)

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

{

Super. ProcessWindowEvent(е);

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

{

System. exit(О) ;

)

Создание этой программы не отличается от создания предыдущей. Создайте но­вое приложение и разместите на Framel две панели JPaneI. Первую панель размес­тите в центре (CENTER), а вторую — вдоль восточной стороны (EAST). Вы сделаете это с помощью визуальных средств, а полученный код будет выглядеть так:

contentpane contentpane contentpane. contentpane= (JPanel) this. getContentPane(); .SetLayouttborderLayoutl); Add(j Panell, BorderLayout. CENTER) add(j Panel2, BorderLayout. EAST);

C помощью инспектора установите компоновку правой панели в VerticaIFIowLayout. Щелкните в панели структуры на строке VerticaIFIowLayout, и в ин­спекторе установите выравнивание компонента VerticalFIowLayoutI в TOP (сверху), которое предлагается по умолчанию

Теперь остается лишь поместить на JPaneI, использующую VerticaIFIowLayout, две кнопки JButton. (Опять-таки, возможно, вы сочтете более удобным сделать это, пе­ретащив эти компоненты на слово jPanel2 в панели структуры. Иногда работа с панелью содержимого доставляет множество хлопот. Или, может быть, лучше сказать, что па­нель структуры является идеальным средством при создании сложного контейнера.)

Классы Box и их компоновки

В нескольких следующих разделах вы познакомитесь с классами Box, BoxLayout И BoxLayout2. Я сначала расскажу о классе Box, Поскольку его, возможно, проще всех использовать в JBuilder.

рис. 12.12. окно с кнопками, правильно расположенными в своем контейнереИспользование контейнера Box

Данная глава посвящена политикам компоновки, но я считаю, что зачастую вместо класса компоновки лучше восполь­зоваться классом-контейнером под назва­нием Box. Этот компонент можно найти на странице Swing Containers палитры компо­нентов.

На самом деле Box является довольно многогранным классом и может выполнять множество разных функций, не показанных здесь Я не собираюсь подробно разбирать его, поскольку эта книга о JBuilder, а не о JDK. Но все же я покажу несколько способов применения этого класса.

Сначала создадим первый вариант приложения, показанный на рис. 12.12. Вы можете найти эту программу в сопровождающих материалах, в каталоге BoxLayout02.

Сначала создадим новое приложение. Перетащите с палитры компонентов в конструктор пользовательского интерфейса горизонтальный объект Box. Установите его ориентацию в SOUTH (юг). Теперь поместите на панель структуры элемент JPaneI, и ориентируйте его в CENTER (центр). Измените его цвет на dark gray (тем­но-серый) или какой-либо другой, чтобы он отличался от других компонентов. Эк­земпляр JPanei Должен быть элементом, родственным boxl, а не дочерним ему.

рис. 12.13. окно, в котором кнопки прижаты друг к другу в левой части содержащего их контейнера boxC помощью панели структуры помести­те на компонент Box две кнопки. Эти кноп­ки должны быть дочерними компонентами компонента Box. Теперь Framel должен выглядеть так, как показано на рис. 12.13.

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

12.12, где вокруг них есть небольшое про­странство.

Самый простой способ получить про­странство вокруг кнопок — снова восполь­зоваться классом Box. Но на этот раз он бу­дет размещен вручную, а не с помощью ви­зуального конструктора. Окончательный код приведен в листинге 12-5. Взгляните на него, а потом мы обсудим его подробнее.

Листинг 12.5. Компонент-контейнер Box Может с успехом заменить класс BoxLayoutZ

Package boxlayout02,

Import j ava. awt.*;

Import java. awt. event.*;

Imμort javax. swing.*;

∕**

* <p>Title: <∕p>

* <p>Description: <∕p>

* <p>Copyright: Copyright (С) 2002 by Charlie Calvert<∕p>

* <p>Company: Elvenware<∕p>

* θauthor Charlie Calvert

* (Aversion 1.0 */

Public class Framel extends JFrame

<

JPanel ContentPane;

BorderLayout borderLayoutl = new BorderLayoutO; JPanel jPanell ≈ new JPanel();

Box boxl;

JButton jButtonl = new JButton();

JButton jButton2 = new JButton();

Component boxHorzSpace01;

Compofient boxHorzSpace02;

Component boxVertSpace;

11 Создание Фрейма Public Freunel()

{

EnableEvents(AWTEvent. WINDOW_EVENT_MASK); try {

JblnitO;

}

Catch(Exception e)

{

E. printStackTrace();

»

}

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

ContentPane = (JPanel) this. getContentPane();

Boxl = Box-CreateHorizontalBoxO ;

BoxHorzSpace01 = Box-CreateHorizontalStrut(IO);

BoxHorzSpace02 = Box-CreateHorizontalStrut(IO);

BoxVertSpace = Box. CreateVerticalStrut(40);

ContentPane. setLayout(borderLayoutl);

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

This. SetTitle("Box Class Exanple");

JPanell. SetBackground(Color. gray);

JButtonl. SetText("jButtonl");

JButton2.setText("jButton2",;

ContentPane. add(jPanell, BorderLayout. CENTER); ContentPane. add(boxl, BorderLayout. SOUTH); boxl. add(boxHorzSpace01);

Boxl. add(jButtonl, null); boxl. add(boxHorzSpaceO2); boxl. add(jButton2, null); boxl. add(boxVertSpace);

}

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

{

Super. ProcessWindowEvent(е);

If (e. getID() == WindowEvent-WINDOWeCLOSING)

System. exit(О) ;

}

Основной код здесь приведен в начале раздела данных:

Component boxHorzSpace01;

Component boxHorzSpace02;

Component boxVertSpace;

Эти три экземпляра класса Component Будут использованы для обеспечения про­межутков между кнопками. Разумное применение этих промежутков изменит вне­шний вид приложения с показанного на рис. 12.13 на показанный на рис. 12.12.

Создаются эти компоненты следующим образом:

BoxHorzSpaceOl = Box-CreateHorizontalStrut(IO); BoxHorzSpace02 = Box-CreateHorizontalStrut(IO); BoxVertSpace = Box. CreateVerticalStrut(40);

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

Горизонтальные распорки обеспечивают промежутки между левыми и правыми сторонами кнопок, а вертикальная распорка сделает контейнер Box достаточно вы­соким, чтобы кнопки разместились в нем с комфортом:

Boxl. add(boxHorZSpaceOl); Boxl. add(jButtonl, null); Boxl. add(boxHorzSpaceO2); boxl. add(jButton2, null); boxl. add(boxVertSpace);

Обратите внимание, что порядок, в котором эти экземпляры класса Component Добавляются на форму, очень важен Элемент BoχHorzSpace01 Обеспечивает проме­жуток между левым краем компонента Box и левым краем первой кнопки, а элемент BoxHorzSpace02 Разделяет КНОПКИ JButton01 И JButton02.

Ясно, ЧТО ТОГО Же эффекта проще ДОСТИЧЬ С ПОМОЩЬЮ Класса FlowLayout. Но в некоторых случаях распорки класса Box Могут довольно легко решить сложные зада­чи размещения компонентов. Здесь я лишь привел простой пример применения этого класса.

BoxLayout2

Наверно, простейшей из всех компоновок является BoxLayout, Доступная в JSuilder редакций SE и Enterprise. Этот класс обеспечивает две возможности

1. Компоненты можно упорядочивать по оси х.

2. Или компоненты можно упорядочивать по оси у.

Хоть этот класс и прост, но компания Sun не создала к нему bean-оболочку. По­этому, если вы хотите применять класс BoxLayout В визуальном конструкторе, то не­обходимо использовать класс BoχLayout2, Разработанный Borland.

BoχLayout2 Представляет собой bean-компонент Java компании Borland, являю­щийся оболочкой для класса BoxLayout И поставляемый вместе с JDK. Дело здесь в том, что Sun не выпустила BoxLayout В виде bean-оболочки, поэтому данную работу пришлось взять на себя компании Borland. Это еще один пример несовпадения, когда одна компания создает API, а другая — среду разработки.

BoxLayout2 Это очень маленький класс, и включение его в программу является тривиальной процедурой. Он входит в библиотеку JBCL, являющуюся JAR-файлом, поставляемым с некоторыми версиями JBuilder. В некоторых выпусках JBuilder дос­тупен и ее исходный код.

Совсем не обязательно включать в проект весь файл jbcl.Jar, Если нужен лишь один маленький класс. Вместо этого можно просто поместить класс BoχLayout2 В Каталог с исходными файлами и компилировать его прямо в своей программе. Мож­но поступить и по-другому: создать программу с помощью BoχLayout2, А затем пе­ред сдачей в эксплуатацию заменить экземпляры BoxLayout2 На BoxLayout, Как по­казано в комментариях листинга 12.6. Еще один вариант — самостоятельное созда­ние "чистой" оболочки класса. Эта очень простая задача сводится к созданию оболочек для методов класса BoxLayout С помощью своих собственных методов. Если вы никогда не писали раньше bean-компоненты, обратитесь к части VII.

BoxLayout Очень хорошо использовать, когда надо создать простое диалоговое окно, выглядящее так, как во всех стандартных Windows-приложениях. Пример применения класса BoxLayout Приведен в следующем разделе.

примечание
в исходном файле для boχlayout2 компании borland включен шутли

Вый комментарии:

/**

* Класс-оболочка Bean Для Javax. swing. BoxLayout

* (Sun — компания, которая изобрела Java bean)

*/

Трудно быть уверенным, но я считаю, что здесь присутствует оттенок сарказма: автор не понимает, почему именно Sun (из всех компаний) не создала bean-оболоч­ку для этого класса!

Использование класса Box вместе с BoxLayout2

Пример применения класса BoχLayout2 Очень похож на предыдущий пример. На самом деле это в основном тот же код, но использующий в качестве контейнера класс BoxLayout2, А не Box.

примечаниеЕсли вы не можете достичь желаемого результата с помощью одной из простых компоновок в сочетании с классом Box, тогда часто единственным выходом остается применение GridBagLayout. Поскольку GridBagLayout многими считается Очень сложным, то технологии применения класса Box стоит уделить особое внимание.

рис. 12.14. программа renumfile, которая входит в состав сопровождающих книгу материалов, является примером использования класса boxlayout2Предположим, что на JPanei Находятся две кнопки, а сама JPanei Расположена на ЮЖНОЙ Стороне BorderLayout. ЕСЛИ разме­стить обе кнопки на BoxLayout Выровнен­ными по оси х, то кнопки прижмутся к ле­вой стороне и друг к другу без промежутков, как показано на рис. 12.13. C помощью класса Box Можно разъединить эти компо­ненты, чтобы они имели более привлека­тельный вид, как показано на рис. 12.14.

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

Код, приведенный в листинге 12.6, яв­ляется примером выполнения этой задачи.

Как уже говорилось ранее в этой главе, если вы работаете с BoχLayout2 С помощью инспектора JBuilder, то классы JBCL автоматически будут включены в проект. В дру­гих случаях необходимо явно добавить в проект этот класс с помощью пункта меню Project I Project Properties.

Листинг 12.6. Правильное размещение кнопок на форме с помощью класса Box. Обратите Внимание на комментарии, позволяющие переключаться между BoxLayout2 И BoxLayout

Package renumfile;

Import j ava. awt.*;

Import java. awt. event.*;

Import javax. swing.*;

Import com. borland. jbcl. layout. BoxLayout2;

Import javax. swing. border.*;

Public class Framel extends JFrame

1

JPanel ContentPane;

BorderLayout borderLayoutl = new BorderLayoutO;

JPanel jPanell = new JPanel();

JButton jButtonl = new JButton();

JButton jButton2 = new JButton() ;

JPanel jPane12 = new JPanel();

JPanel jPanel3 = new JPanel() ;

JPanel jPanel4 = new JPanel() ;

GridLayout gridLayoutl = new GridLayoutO;

BoxLayout2 boxLayout = new BoxLayout2();

//BoxLayout boxLayout;

Component boxl;

Component box2;

Component box3;

// создание фрейма
public framel()
enableevents(awtevent.window_event_mask); try {
jblnit() ;
}
catch(exception e)
{
e.printstacktrace() ;
}
}
∕∕ инициализация компонентов
private void jbɪnit() throws exception {
ContentPane = (JPanel) this. getContentPane(); boxl = Box-CreateHorizontalStrut(IO); box2 = Box-CreateHorizontalStrut(IO); box3 = Box-CreateVerticalStrut(Ie);

ContentPane. setLayout(borderLayoutl); this. setSize(new Dimension(400, 300)); this. SetTitle("Frame Title"); jButtonl. SetAlignmentY((float) 0.1);

JButtonl. SetHorizontalAlignment(SwingConstants. LEFT); jButtonl. setText("JButtonl"); jButton2.SetAlignmentY((float) 0.1) ;

JButton2.SetHorizontalAlignment(SwingConstants. LEFT); jButton2.setText("jButton2"); jPanel2.setLayout(gridLayoutl);

JPanel3.SetBackground(SystemColor. inactiveCaption); jPanel4.SetBackground(Color. magenta);

Z∕boxLayout = new BoxLayout(jPanell, BoxLayout. X_AXIS); JPanell. setLayout(boxLayout);

JPanell. SetMinimumSize(new Dimension(188, 27) );

JPanell. SetPreferredSize(new Dimension (188, 40)) ; ContentPane. add(J Panell, BorderLayout. SOUTH);

J Panell. add(boxl, null);

JPanell. add(JButtonl, null);

JPanell. add(box2, null);

JPanell. add(JButton2, null);

JPanell. add(box3, null);

ContentPane. add(j Panel2, BorderLayout. CENTER); jPane12.add(JPanel3, null);

JPanel2.add(JPanel4, null);

}

∕∕ Перекрыт, чтобы можно было выйти при закрытии окна Protected void proceSsWindowEvent(WindowEvent e)

{

Super. processWindowEvent(e);

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

{

System. exit(O);

}

)

Программа, приведенная в листинге 12.6, начинает работу с размещения на Framel Простой КОМПОНОВКИ BorderLayout:

ContentPane = (JPanel) this. getContentPane();

ContentPane. SetLayout(borderLayoutl);

Вверху этой компоновки помещаются две панели: JPanell И JPanel2. Одна ори­ентирована в центре, а другая — вдоль южной стороны. У той, которая расположена в центре, установлена компоновка GridLayout, И на ней размещены две дополни­тельных панели JPanei3 И jPanel4, Как показано на рис. 12.14. Я раскрасил эти па­нели в разные цвета, чтобы их было легче отличить друг от друга. На JPanell Уста­новлена компоновка BoxLayout И размещены две кнопки:

ContentPane. add(j Panell, BorderLayout. SOUTH); JPanell. add(jButtonl, null); jPanell. add(jButton2, null);

ContentPane. add(jPanel2, BorderLayout-CENTER); jPanel2.add(jPanel3, null); JPanel2.add(jPanel4, null);

Это похоже на то, что было сделано на рис. 12.13. Все здесь как надо, только кнопки прижаты к левому краю. Чтобы исправить это, перейдите в режим редакти­рования исходного текста и добавьте код, использующий класс Box для создания двух компонентов-распорок. Вставьте эти компоненты в нужное место между кноп­ками на jPaneli:

Component boxl;

Component box2;

Component ЬохЗ;

11Здесь для ясности пропущена часть хода Boxl = Box-CreateHorizontalStrut(IO); Box2 = Box. CreateHorizontalStrut(10);

ЬохЗ = Box. createVerticalStrut(16);

// … Здесь для ясности пропущена часть хода ContentPane. add(jPanel1, BorderLayout. SOUTH); jPane11.add(boxl, null);

JPanell. add(jButtonl, null); jPanell. add(box2, null); JPanell.Add(jButton2, null); jPanell. add(ЬохЗ, null);

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

Размещение кнопок справа в диалоговом окне с помощью BoxLayout

Разместить с помощью BoxLayout Кнопки справа, как показано на рис. 12.15, не очень-то и просто. Но изучение способов сделать это поможет понять различные комбинации инструментов, которые можно применять для выполнения разных за­дач. Для достижения показанных здесь эффектов я предлагаю снова воспользовать­ся VerticaiFlowLayout. Я показываю вам этот код лишь для того, чтобы вы почув­ствовали, что можно сделать с помощью классов BoxLayouT2 и Box. Иногда компо-

{⅜⅛box layoirt righlрис. 12.15. программа boxlayoutright, входящая в состав сопровождающих книгу материаловНовка VecticalFlowLayout Бесполез­на в решении вашей проблемы, и тог­да может помочь код, подобный при­веденному здесь.

Создайте элементарное приложе­ние с двумя панелями JPanel: Одна в центре, а другая вдоль восточной сто­роны. Для восточной панели укажите компоновку BoxLayout2 и поместите на нее две кнопки. Выберите в панели структуры bo×Layout21 и затем с помо­щью инспектора установите ее ось в у — axis (ось у).

Тут же всплывает наша обычная проблема: кнопки прижаты вверх, и вокруг них нет промежутков. К данному моменту вставка вертикального промежутка между двумя кнопками уже достаточно изучена. Не­обходимо просто переключиться в режим редактирования исходного текста и ввести код, где с помощью Box. CreateVerticaistrut Создаются и вставляются в нужное ме­сто два компонента:

SpaceHeight = Box. CreateVerticalStrut(5);

JPanel2.add(SpaceHeight);

JPanel2.add(jButtonl, null);

SpaceHeight2 = Box. CreateVertiealStrut(5);

JPanel2.add(SpaceHeight2);

JPanel2.add(jButton2, null);

B листинге 12.6 видно, что компоненты SpaceHeightH spaceHeight2 объявлены раньше, в начале программы. Если хотите, можно создавать распорки и помещать их на панель с помощью одного оператора:

JPanel2.add(Box. createVerticalStrut(5));

примечаниеЭто полностью корректный κo,π, но конструктор пользовательского интерфейса JBuilder не позволяет выбирать компоненты, созданные подобным образом. Для вас это может оказаться несущественным, но, возможно, лучше поступать так, как я. За­тем, после перехода в режим конструирования, вы можете выбирать созданные вами распорки и оценивать, насколько точно они реализуют ваши планы.

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

Теперь уже почти все готово, но нужно еще создать рамку слева и справа от кно­пок. Проще всего это сделать с помощью класса Box Но вместо этого выберите па-

рис. 12.16. настройка размеров рамки с помощью jbuilder

Нель и щелкните на кнопке эллипсиса справа от свойства Border (рамка). Появится диалоговое окно, показанное на рис. 12.16. В этом окне установите Border Туре (тип рамки) в Empty (пусто) и отступы Left (слева) и Right (справа) в 5. После этого окно программы примет вид, показанный на рис. 12.15.

Листинг 12.7. Программа BoxLayoutRight из сопровождающих материалов, которая

JPanel jPanel2 = new JPanel();

BoxLayout2 boxLayout21 = new BoxLayout2();

JButton jButtonl = new JButton();

JButton jButton2 = new JButton();

Component SpaceHeight, SpaceHeight2;

∕∕ Создание фрейма public Fxamel()

{

EnableEvents(AWTEvent. WINDOW_EVENT_MASK); try {

Jblnit() ;

}

Catch(Exception e)

{

E. printStackTrace() ;

}

)

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

Private void jblnit() throws Exception

{

ContentPane = (JPanel) this. getContentPane(); border1 = BorderFactory. CreateEmptyBorder(0,5,0,5); ContentPane. setLayout(borderLayoutl);

This. setSize(new Dimension(400, 300)); this. setTitle("Box Layout Right"); jPanel2.setLayout(boxLayout21); jButtonl. SetText CjButtonl"); boxLayout21.setAxis(BoxLayout. Y_AXIS); jButton2. setText (" jButton2,,) ; jPanell. SetBackground(Color. IightGray); jPanel2.setBorder(borderl);

ContentPane. add(jPanell, BorderLayout. CENTER); ContentPane. add(jPanel2, BorderLayout. EAST); SpaceHeight = Box. CreateVerticalStrut(5); jPanel2.add(spaceHeight);

JPanel2.add(jButtonl, null);

SpaceHeight2 = Box. CreateVerticalStrut(5);

J Panel2.add(spaceHeight2);

J Panel2.add(jButton2, null);

)

∕∕ Перекрыт, чтобы можно было выйти при закрытии окна Protected void proceSsWindowEvent(WindowEvent e)

{

Super. ProcessWindowEvent(e);

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

<

System. exit(O) ;

}

)

Border borderl;

Резюме

В данной главе вы ознакомились с администраторами компоновки. Вы увидели взаимосвязь между классами компоновок и контейнерами, содержащими их. Вы увидели простые компоновки, такие как BorderLayout и GridLayout, а также по­знакомились с более сложными технологиями, наподобие сочетания классов BoχLayout2 и Box. Что еще более важно, вы узнали, что наиболее удачные компо­новки оказываются комбинацией нескольких различных компоновок.

В следующей главе будет идти речь о компоновках GridBagLayout, Null и XYLayout, и CardLayout, и на этом обсуждение компоновок будет завершено. Но, в конце концов, единственный способ по-настоящему разобраться в компоновках — это увидеть множество различных приложений и аплетов в действии и разобраться, как они устроены. В этой книге содержится много примеров таких программ, и я надеюсь, что, дочитав эту книгу до конца, вы многое почерпнете из них.

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

марджи и чарли калверт

Глава 13

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

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