setpreferredsize java что делает
Инструменты пользователя
Инструменты сайта
Содержание
AWT и Swing
В первой версии языка Java для работы с графикой было только библиотека AWT. Эта библиотека – простой набор классов, таких, как Button(кнопка),TextField (текстовое поле), Label (текстовая метка или иконка) и другие.
Вскоре была создана более совершенная библиотека, которую назвали Swing. Она так же включает в себя кнопки,текстовые поля и другие элементы управления графическими приложениями. Названия компонентов этой библиотеке начинается с буквы J. Например JButton, JTextField и т.д.
Работать в Swing лучше, быстрей и удобней.
Основные элементы Swing
Вот некоторые основные объекты, из которых состоят Swing приложения:
Например, можно создать экземпляр класса JPanel и назначить для него схему размещения. Затем создайте различные графические компоненты и добавьте их на панель. После этого добавьте панель на фрейм, задать его размер и сделать его видимым.
JFrame является главным окном для размещения компонентов и представляет их пользователю.
Панель
Панель JPanel — это элемент управления, представляющий собой прямоугольное пространство, на котором можно размещать другие элементы. Элементы добавляются и удаляются методами, унаследованными от класса Container.
У каждой панели есть менеджер размещения, который определяет стратегию взаимного расположения элементов, добавляемых на панель. Его можно изменить методом setLayout(LayoutManager manager).
Оконные элементы управления
Класс JComponent
Все визуальные компоненты библиотеки Swing унаследованы от класса JComponent. Сам этот класс является абстрактными и непосредственно не используется, но все визуальные компоненты наследуют его методы.
Метка JLabel
В большинстве визуальных библиотек метка — один из самых простейших компонентов. Она представляет собой обычный текст, который выводится в заданном месте окна и используется для вывода вспомогательной текстовой информации: подписи к другим элементам, инструкции и предупреждения для пользователя.
Кнопка JButton
Компоненты JToggleButton, JCheckBox, JRadioButton
Компонент JToggleButton представляет собой кнопку, которая может находиться в двух состояниях: нажатом и отпущенном.
Когда пользователь щелкает мышкой по такой кнопке, она изменяет свое состояние. Именно таким образом ведут себя кнопки форматирования на инструментальной панели текстового редактора. Кнопка [I] не только устанавливает или убирает курсивное начертание в выделенном тексте, но и сигнализирует о его наличии или отсутствии.
От класса JToggleButton унаследован класс JCheckBox — флажок.
Этот класс имеет точно такой же набор конструкторов и методов, т.е. не расширяет функциональность предка. Единственное различие между ними — во внешнем виде: JCheckBox выглядит не как кнопка, а как небольшой квадратик, в котором можно поставить или убрать галочку.
Аналогичным образом ведет себя класс JRadioButton — переключатель или радиокнопка, внешне выглядящая как пустой кружок, когда она не выделена и кружок с точкой в выделенном состоянии.
Для того, чтобы элементы объединить в группу, используется специальный контейнер ButtonGroup Если добавить в один такой контейнер несколько элементов JRadioButton, то выбранным всегда будет только один из них.
Текстовое поле JTextField
Для создания текстового поля чаще всего используются конструкторы:
Поле для ввода пароля JPasswordField
JPasswordField является прямым потомком JTextField, поэтому для него справедливо все сказанное выше. JPasswordField является прямым потомком JTextField, поэтому для него справедливо все сказанное выше.
Область для ввода текста JTextArea
JTextArea также является потомком JTextField и наследует все его методы.
Панель прокрутки JScrollPane
JScrollPane — панель прокрутки. Чаще всего она просто «надевается» на требуемый объект посредством собственного конструктора, принимающего этот объект в качестве параметра. Например, чтобы текстовая область textArea из предыдущего примера обрела полосы прокрутки, необходимо заменить команду
Инструментальная панель JToolBar
В Swing для инструментальных панелей разработан визуальный компонент JToolBar, в котором заложена просто потрясающая функциональность.
Выпадающий список JComboBox
Выпадающий список — весьма распространенный элемент управления. Он содержит множество вариантов, из которых пользователь может выбрать один и только один, либо (если выпадающий список это позволяет) ввести свой собственный.
Ползунок JSlider
Ползунок позволяет пользователю выбрать некоторое число из диапазона доступных значений, наглядно представив этот диапазон.
Панель со вкладками JTabbedPane
Многим программам бывает необходимо разместить в одном окне большое количество элементов управления, некоторые из которых (такие как списки, деревья, текстовые области и т.д.) могут к тому же занимать приличное пространство.
Список JList
Список содержит группу элементов, аналогично выпадающему списку JComboBox, но обладает двумя отличительными особенностями. Во-первых, на экране видны одновременно несколько элементов списка. Во-вторых, пользователь может выбрать в списке не один элемент, а несколько (если установлен соответствующий режим выделения).
Создать список можно с помощью конструктора, работающего на основе массива Object[] или вектора Vector (аналогично JComboBox).
JTable Таблицы
Для отображения табличных данных используется комопнент JTable. JTable внутри себя не содержит данные, а служит только для их отображения.
JFileChooser для выбора файла
При работе с файлами из приложения возникает необходимость рано или поздно использовать диалог для выбора файлов.
JProgressBar полоса загрузки
JMenuBar
Стандартные диалоговые окна
Менеджер размещения
Менеджер последовательного размещения FlowLayout
Менеджер граничного размещения BorderLayout
Менеджер размещения BorderLayout разделяет панель на пять областей: центральную, верхнюю, нижнюю, правую и левую. В каждую из этих областей можно добавить ровно по одному компоненту, причем компонент будет занимать всю отведенную для него область. Компоненты, добавленные в верхнюю и нижнюю области, будут растянуты по ширине. обавленные в правую и левую — по высоте, а компонент, добавленный в центр, будет растянут так, чтобы полностью заполнить оставшееся пространство панели.
При добавлении элемента на панель с менеджером размещения BorderLayout, необходимо дополнительно указывать в методе add(), какая из областей имеется в виду. Для этого служат строки с названиями сторон света: «North», «South», «East», «West» и «Center». Но вместо них рекомендуется использовать константы, определенные в классе BorderLayout: NORTH, SOUTH, EAST, WEST и CENTER (поскольку в строке можно допустить ошибку и не заметить этого, а при попытке написать неправильно имя константы компилятор выдаст предупреждение).
Менеджер табличного размещения GridLayout
GridLayout разбивает панель на ячейки одинаковой ширины и высоты (таким образом окно становится похожим на таблицу). Каждый элемент, добавляемый на панель с таким расположением, целиком занимает одну ячейку. Ячейки заполняются элементами по очереди, начиная с левой верхней.
Этот менеджер, в отличие от рассмотренных ранее, создается конструктором с параметрами (четыре целых числа). Необходимо указать количество столбцов, строк и расстояние между ячейками по горизонтали и по вертикали.
Менеджер блочного размещения BoxLayout и класс Box
Менеджер BoxLayout размещает элементы на панели в строку или в столбец. Обычно для работы с этим менеджером используют вспомогательный класс Box, представляющий собой панель, для которой уже настроено блочное размещение. Создается такая панель не конструктором, а одним из двух статических методов, определенных в классе Box: createHorizontalBox() и createVerticalBox().
Элементы, добавленные на панель с блочным размещением, выстраиваются один за другим. Расстояние между элементами по умолчанию нулевое. Однако вместо компонента можно добавить невидимую «распорку», единственная задача которой — раздвигать соседние элементы, обеспечивая между ними заданное расстояние.
Горизонтальная распорка создается статическим методом createHorizontalStrut(int width), а вертикальная — методом createVerticalStrut(int height). Оба метода определены в классе Box, а целочисленный параметр в каждом из них определяет размер распорки.
Ручное размещение элементов
Если в качестве менеджера размещения панели установить null, элементы не будут расставляться автоматически. Координаты каждого элемента необходимо в этом случае указать явно, при этом они никак не зависят от размеров панели и от координат других элементов. По умолчанию координаты равны нулю (т.е. элемент расположен в левом верхнем углу панели). Размер элемента также необходимо задавать явно (в противном случае его ширина и высота будут равны нулю и элемент отображаться не будет). Координаты элемента можно задать одним из следующих методов:
Работаем с JLabel
JLabel это пожалуй самый простой компонент, который есть в Java Swing. С помощью JLabel можно показать текст с иконкой. Если нужен какой-то компонент, чтобы отобразить какое-то сообщение пользователю или сделать для поля ввода текстовую метку, или показать иконку — используем JLabel. Текст, который показывает JLabel выделять нельзя, только смотреть.
Для создания объекта JLabel, который затем будем располагать в окне, можно воспользоваться конструктором со строковым параметром public JLabel(String text). Строковый параметр — это текст, который будет показываться в JLabel. Кроме того текст, который будет отображаться в JLabel можно установить при помощи метода setText. Единственным параметром метода является строка отображаемого текста String.
JLabel позволяет настраивать шрифт, который будет использоваться для отображения текста. Установка шрифта происходит при помощи метода setFont класса JLabel. Этому методу в качестве параметра передается объект Font. Что мы хотим, когда указываем или создаем шрифт? Первое — это начертание, Verdana или Courier New, или другое. Второе — размер шрифта и третье — жирный будет шрифт или нормальный, или может быть курсив. Поэтому подходящий конструктор для Font это тот, который содержит сразу все три параметра — public Font(String name, int style, int size). Первый параметр, как уже ясно, это имя шрифта. Если параметр не задан, то используется шрифт по умолчанию. Второй параметр задает стиль — жирный, нормальный или курсив. Сюда необходимо передать одну из констант объекта Font — Font.BOLD (жирный), Font.PLAIN (нормальный или плоский) и Font.ITALIC (курсив). Ну и третий параметр — размер шрифта. Объект Font можно создать вот так:
Font font = new Font(«Verdana», Font.PLAIN, 11);
После установки текста и шрифта у JLabel иногда бывает нужно определить выравнивание текста по вертикали и горизонтали. Делается это при помощи двух методов setVerticalAlignment и setHorizontalAlignment соответственно. В качестве параметров для setVerticalAlignment нужно использовать что-то из следующего списка: JLabel.TOP (выравнивать по верхнему краю), JLabel.CENTER (по центру) и JLabel.BOTTOM (выравнивание по нижнему краю). Для метода setHorizontalAlignment параметров больше — JLabel.LEFT (по левому краю), JLabel.CENTER (по центру), JLabel.RIGHT (по правому краю), JLabel.LEADING и JLabel.TRAILING. Интересны последние две константы. Для языков, у которых написание текста идет слева направа JLabel.LEADING — это левый край, а JLabel.TRAILING — правый. Для языков, у которых написание происходит справа налева, JLabel.LEADING — это правый край, а JLabel.TRAILING — левый.
JLabel позволяет отображать иконку вместе с текстом. Для установки иконки используется метод setIcon. Единственный параметр метода — это объект Icon. Когда задана иконка для JLabel, то можно задать расположение текста относительно иконки. Для этого используются методы setVerticalTextPosition и setHorizontalTextPosition. В качестве параметров используются те же константы, что и при выравнивании текста.
Идем дальше. Шрифт мы выбрали. Теперь нужно определить, какого цвета будет текст у нашего JLabel. Делается это при помощи метода setForeground. Сюда нужно передать объект Color. Для создания Color можно воспользоваться разными конструкторами или вместо этого воспользоваться константами, которые определены в объекте Color. Здесь есть черный Color.BLACK, зеленый Color.GREEN, красный Color.RED и другие. Если нужно создать какой-то специфический цвет, то придется воспользоваться конструктором. Для меня, например, самый удобный public Color(int red, int green, int blue). Передаем сюда необходимые составляющие цвета и получаем то, что хотели. Ну а затем устанавливаем цвет у JLabel.
Кроме цвета шрифта можно задать цвет фона JLabel. Делается это с помощью метода setBackground. Интересный момент. По умолчанию, даже если цвет фона установлен, фон у JLabel не отображается. Для того, чтобы JLabel стал показывать фон необходимо вызвать метод setOpaque и передать туда true. Тем самым мы скажем JLabel, что хотим сделать непрозрачным его фон. Цвет фона задается аналогично цвету текста, то есть методу setBackground передается объект Color, который содержит информацию о цвете.
У JLabel, как и у других компонентов, можно устанавливать размеры. Делается это при помощи метода setPreferredSize. Сюда передается объект Dimension с требуемой шириной и высотой.
label.setPreferredSize(new Dimension(100, 100));
Еще одна особенность, про которую нужно обязательно рассказать — это использование HTML в качестве текста. К примеру, в тестовом приложении JLabel используется для того, чтобы показать краткое
описание Google Labs на английском языке.
По традиции тестовое приложение. Здесь я попытался продемонстрировать возможности на практике, о которых говорилось выше. На самой верхней панели можно увидеть результат работы с методами, устанавливающими выравнивание текста JLabel. Для того, чтобы было лучше видно выравнивание, я добавил к каждому JLabel черный border шириной в один пиксель. На средней панели — работа с позиционированием текста JLabel относительно иконки и наконец на самой нижней — использование HTML для отображения в JLabel текста. Внешний вид приложения представлен на рисунке ниже.
Why setting setPreferredSize() on JFrame is bad?
Is setting preferred size of JFrame using setPreferredSize() considered bad?
If it is bad, what is good way to change JFrame window size to dimension I need.
I know laying components in way to reflect final JFrame dimension that I need. But if I use shortcut to change preferred size using call setPreferredSize() just before call to pack() to change final JFrame size is bad? If so why?
For example I have sample form:
This is displayed without setting preferred size.
This is displayed with call: setPreferredSize(new Dimension(500, 300));
I can think setting preferred size as resizing displayed window manually with mouse after it has been displayed. Isn’t it?
2 Answers 2
The main reason it would be considered bad (bad is probably too strong a word, unwise might be better) is the use of unknown (magic) numbers, rather than empirical values.
Every platform (and even similar OS running on different hardware and settings) has it’s own means for rendering content which can change the amount of space that individual components require.
In regards to things like text fields and text-areas, you can make suggestions about the number of columns (and rows for text areas) which can be used to change a frames final size, using setColumns and setRows for example.
So, using the following code.
Now by changing only one line.
I could change the number of rows for the JTextArea and effect the height of the window as well.
The difference is, these values are used in combination with the systems font metrics to calculate the preferred size of the components when the program is run, so it will be different for different systems and platforms.
The main point to layouts is to spend your time focused on the intent and the work flow and not trying to get a pixel perfect solution, because there’s simply no such thing. talk to web developers, they have the same issues, just much worse (multiple browsers on a single system, all rendering differently)
Personally, I think there is nothing wrong with using frame.setPreferredSize() to resize a JFrame window. In fact, I think it is the most appropriate solution for resizing it.
But this is a good time to make a distinction between what some of the most common resizing methods do:
frame.setSize() resizes the window as expected, but only if a component’s parent has no layout manager expressly defined. There is a discussion concerning the use of this method here.
That doesn’t really leave any other methods to use to define the size of a window, which is why I think setting the preferred window size is the best way go about it. I would still make sure to define setMinimumSize() and setMaximumSize() to ensure the components are resized correctly in all cases.
Edit:
Other posts in this thread got me thinking about the use of ‘magic constants’ in setting a components. In web development, for instance, it is generally frowned upon to use pixels, for example, as this changes widely by system. I wanted to see if this was also true with dimensions. In short, my findings concluded it doesn’t.
This was a JFrame with a prefered size of new Dimension(200, 300) taken on my MacBook Pro with Retina Display:
prefered size of new Dimension(200, 300) «>
This was a JFrame with a prefered size of new Dimension(200, 300) taken on my Asus Windows Tablet (non-retina display):
prefered size of new Dimension(200, 300) «>
These windows looked the exact same and, although I couldn’t find this published, the Dimenion is really an already-scaled proportion, taking into consideration the height, width, and resolution of the display to produce a near accurate rendering across all devices. This, I guess you could say, makes sense because it is the Java way.
That being said, here’s some things I think need to watched out for:
Занятие 8
Введение в библиотеку Swing
Библиотека Swing
Современные программы нуждаются в графическом интерфейсе пользователя (GUI). Пользователи отвыкли работать через консоль: они управляют программой и вводят входные данные посредством так называемых элементов управления (в программировании их также называют визуальными компонентами), к которым относятся кнопки, текстовые поля, выпадающие списки и т.д.
Каждый из современных языков программирования предоставляет множество библиотек для работы со стандартным набором элементов управления. Напомним, что под библиотекой в программировании набор готовых классов и интерфейсов, предназначенных для решения определенного круга задач.
В Java есть три библиотеки визуальных компонентов для создания графического интерфейса пользователя. Самая ранняя из них называется AWT. Считается, что при ее проектировании был допущен ряд недочетов, вследствие которых с ней довольно сложно работать. Библиотека Swing разработана на базе AWT и заменяет большинство ее компонентов своими, спроектированными более тщательно и удобно. Третья, самая новая библиотека, называется SWT.
Каждая библиотека предоставляет набор классов для работы с кнопками, списками, окнами, меню и т.д., но эти классы спроектированы по-разному: они имеют различный набор методов с разными параметрами, поэтому «перевести» программу с одной библиотеки на другую (например, с целью увеличения быстродействия) не так-то просто. Это почти как перейти с одного языка программирования на другой: все языки умеют делать одно и то же, но у каждого из них свой синтаксис, своя программная структура и свои многочисленные хитрости.
По этой причине вместо того, чтобы делать обзор всех трех библиотек, мы постараемся получше разобраться в одной из них — библиотеке Swing. Полноценный графический интерфейс может быть разработан с ее помощью.
Окно JFrame
Каждая GUI-программа запускается в окне и по ходу работы может открывать несколько дополнительных окон.
В Swing есть еще несколько классов окон. Например, JWindow — простейшее окно, без рамки и без строки заголовка. Обычно с его помощью делается заставка к программе, которая перед запуском должна выполнить несколько продолжительных действий (например, загрузить информацию из БД).
Чтобы написать простейшую программу, выводящую на экран пустое окно, нам потребуется еще три метода:
setSize(int width, int height) — устанавливает размеры окна. Если не задать размеры, окно будет иметь нулевую высоту независимо от того, что в нем находится и пользователю после запуска придется растягивать окно вручную. Размеры окна включают не только «рабочую» область, но и границы и строку заголовка.
Теперь мы можем написать программу, которая создает окно, выводит его на экран и завершает работу после того, как пользователь закрывает окно.
Обратите внимание, для работы с большинством классов библиотеки Swing понадобится импортировать пакет java.swing. *
Как правило, перед отображением окна, необходимо совершить гораздо больше действий, чем в этой простой программке. Необходимо создать множество элементов управления, настроить их внешний вид, разместить в нужных местах окна. Кроме того, в программе может быть много окон и настраивать их все в методе main() неудобно и неправильно, поскольку нарушает принцип инкапсуляции: держать вместе данные и команды, которые их обрабатывают. Логичнее было бы, чтобы каждое окно занималось своими размерами и содержимым самостоятельно. Поэтому классическая структура программы с окнами выглядит следующим образом:
В файле SimpleWindow.java:
В файле Program.java:
Из примера видно, что окно описывается в отдельном классе, являющемся наследником JFrame и настраивающее свой внешний вид и поведение в конструкторе (первой командой вызывается конструктор суперкласса). Метод main() содержится в другом классе, ответственном за управление ходом программы. Каждый из этих классов очень прост, каждый занимается своим делом, поэтому в них легко разбираться и легко сопровождать (т.е. совершенствовать при необходимости).
Панель содержимого
В примерах этого занятия мы будем использовать только один элемент управления — кнопку (не вдаваясь в подробности ее устройства). Кнопка описывается классом JButton и создается конструктором с параметром типа String — надписью.
Добавим кнопку в панель содержимого нашего окна командами:
JButton newButton = new JButton(); getContentPane().add(newButton);
В результате получим окно с кнопкой. Кнопка занимает всю доступную площадь окна. Такой эффект полезен не во всех программах, поэтому необходимо изучить различные способы расположения элементов на панели.
Класс Container (контейнер)
Элементы, которые содержат другие элементы, называются контейнерами. Все они являются потомками класса Container и наследуют от него ряд полезных методов:
add(Component component) — добавляет в контейнер элемент component ;
remove(Component component) — удаляет из контейнера элемент component ;
removeAll() — удаляет все элементы контейнера;
getComponentCount() — возвращает число элементов контейнера.
Класс JPanel (панель)
Менеджер последовательного размещения FlowLayout
Менеджеры расположения описаны в пакете java.awt. Не забывайте импортировать нужные классы.
Пронаблюдайте за поведением окна, появляющегося после запуска программы. Четыре кнопки в нем расположены как слова в текстовом редакторе (при выравнивании по центру). Эффект будет лучше заметен, если изменять размеры окна во время работы программы.
Проанализируем текст примера. Новый менеджер расположения FlowLayout создается конструктором без параметров. Обратите внимание, в программе не используется промежуточная переменная. То есть вместо двух команд:
FlowLayout newLayout = new FlowLayout(); panel.setLayout(newLayout);
Мы используем одну:
panel.setLayout( new FlowLayout());
Это вполне допустимо в тех случаях, когда в дальнейшем нам не потребуется обращаться к создаваемому объекту (что справедливо для данного примера). Мы создаем менеджер расположения, тут же привязываем его к панели — и все. Теперь панель и менеджер сами найдут друг с другом общий язык.
Кстати, класс JPanel кроме конструктора без параметров, имеет конструктор, в котором в качестве параметра задается менеджер расположения. Поэтому вместо команд
JPanel panel = new JPanel(); panel.setLayout( new FlowLayout());
JPanel panel = new JPanel( new FlowLayout());
Точно также мы добавляем на панель новые кнопки. Мы нигде больше не пытаемся обратиться к этим кнопкам в программе, поэтому заводить под них переменные нет смысла.
Метод setContentPane(JPanel panel) позволяет заменить панель содержимого окна.
Менеджер граничного размещения BorderLayout
Менеджер размещения BorderLayout разделяет панель на пять областей: центральную, верхнюю, нижнюю, правую и левую. В каждую из этих областей можно добавить ровно по одному компоненту, причем компонент будет занимать всю отведенную для него область. Компоненты, добавленные в верхнюю и нижнюю области, будут растянуты по ширине, добавленные в правую и левую — по высоте, а компонент, добавленный в центр, будет растянут так, чтобы полностью заполнить оставшееся пространство панели.
Эффект будет хорошо наблюдаться, если изменять размеры окна.
Данное размещение не случайно используется в панели содержимого по умолчанию. Большинство программ пользуются областями по краям окна, чтобы расположить в них панели инструментов, строку состояния и т.п. А ограничение на один компонент в центральной области абсолютно не существенно, ведь этим компонентом может быть другая панель со множеством элементов и с любым менеджером расположения.
Менеджер табличного размещения GridLayout
GridLayout разбивает панель на ячейки одинаковой ширины и высоты (таким образом окно становится похожим на таблицу). Каждый элемент, добавляемый на панель с таким расположением, целиком занимает одну ячейку. Ячейки заполняются элементами по очереди, начиная с левой верхней.
Этот менеджер, в отличие от рассмотренных ранее, создается конструктором с параметрами (четыре целых числа). Необходимо указать количество столбцов, строк и расстояние между ячейками по горизонтали и по вертикали. Выполните следующий пример и пронаблюдайте эффект.
Менеджер блочного размещения BoxLayout и класс Box
Менеджер BoxLayout размещает элементы на панели в строку или в столбец.
Понять особенности работы этого менеджера лучше на наглядном примере. Мы расположим четыре кнопки вертикально, поставив между двумя центральными «пружину», а между остальными — распорки в 10 пикселов.
Особенности выравнивания элементов
В примере с вертикальной панелью все кнопки оказались выровнены по левому краю. Такое выравнивание по горизонтали принято по умолчанию.
Однако выравнивание работает несколько иначе, чем ожидается. Чтобы это обнаружить, изменим предыдущий пример, выровняв третью кнопку по правому краю. Для этого заменим строку:
box.add( new JButton( «-» ));
JButton rightButton = new JButton( «-» ); rightButton.setAlignmentX(JComponent.RIGHT_ALIGNMENT); box.add(rightButton);
Нам пришлось ввести переменную для обращения к этой кнопке, поскольку теперь нам нужно выполнить с ней не одно, а два действия: установка выравнивания по правому краю и добавление в панель. Прежний прием — одновременное создание кнопки и передача ее в качестве параметра в метод — здесь не сработает.
После запуска программы мы увидим окно, в котором кнопки расположены не так, как, наверное, ожидалось. Мы привыкли, что выравнивание по правому краю прижимает объект к правому краю контейнера, но в данном случае перестроились все элементы, причем кнопка с выравниванием по правому краю оказалась самой левой.
Объяснение просто. При выравнивании по правому краю объект не прижимается к правому краю компонента. Вместо этого он прижимается правым краем к невидимой линии выравнивания. Все остальные компоненты прижимаются к этой линии своим левым краем, поэтому и получается наблюдаемый эффект.
Единственная трудность для начинающего разработчика может оказаться в том, что не всегда легко понять, где именно пройдет эта линия. Ее положение зависит от размеров и выравнивания всех элементов контейнера. Однако легко запомнить простое правило: если все элементы в контейнере выровнены одинаково, мы получим привычное поведение (как это и было в предыдущем примере, когда все компоненты были выровнены влево и линия в результате прижалась к левому краю панели.
Параметр выравнивания на самом деле представляет собой вещественное число в диапазоне от 0 до 1. Он показывает, какая часть компонента окажется слева от линии выравнивания, т.е. в каких пропорциях компонент будет «разрезан». Константы LEFT_ALIGNMENT и TOP_ALIGNMENT на самом деле равны 0, RIGHT_ALIGNMENT и BOTTOM_ALIGNMENT равны 1, а CENTER_ALIGHNMENT — 0.5. Можно подставлять эти числа напрямую (хотя использование констант значительно повышает наглядность!), а можно выбрать любое другое число от 0 до 1 и настроить совершенно произвольное выравнивание.
Попробуйте поэкспериментировать с вертикальной панелью, задавая различное выравнивание для ее элементов, чтобы интуитивно понять логику размещения линии выравнивания. Изменяйте размеры окна во время работы программы, чтобы увидеть как меняется положение этой линии.
Ручное размещение элементов
Координаты элемента можно задать одним из следующих методов:
Размер элемента задается одним из двух методов:
Создадим панель, с которой не будет связано никакого менеджера размещения и вручную разместим на ней две кнопки:
Мы используем одну и ту же переменную button для обращения к обеим кнопкам (причем, второй раз ее описывать не нужно). В самом деле, осуществив все необходимые операции с первой кнопкой и зная, что обращаться к ней нам больше не понадобится, мы используем «освободившуюся» переменную для манипуляций со второй.
Автоматическое определение размеров компонентов
Способ определения координат элементов очевидным образом вытекает из алгоритмов работы каждого менеджера и, таким образом, детально рассмотрен нами выше.
Каждый визуальный компонент имеет три типа размеров: минимально допустимый, максимально допустимый и предпочтительный. Узнать, чему равны эти размеры для данного компонента можно с помощью соответствующих методов:
Менеджер FlowLayout всегда устанавливает предпочтительные размеры элементов. Менеджер BorderLayout устанавливает предпочтительную ширину правого и левого, а также предпочтительную высоту верхнего и нижнего. Остальные размеры подгоняются под доступное пространство панели. Менеджер GridLayout пытается подогнать размеры всех элементов под размер ячеек. Менеджер BoxLayout ориентируется на предпочтительные размеры.
Когда элемент старается занять все доступное ему пространство, он «учитывает» пожелания не делаться меньше своих минимальных или больше максимальных.
Всеми тремя размерами можно управлять с помощью соответствующим методов set:
Чаще всего используется простой прием, когда элементу «не рекомендуется» увеличиваться или уменьшаться относительно своих предпочтительных размеров. Это легко сделать командой:
«Упаковка» окна
Оцените работу этого метода, заменив в каждом из вышеприведенных примеров команду
Заметьте, что когда панель не имеет метода размещения, эта команда не работает (поскольку панель не имеет алгоритма для вычисления своего предпочтительного размера).
Упражнение
Как уже отмечалось, элементом панели может быть другая панель. Создайте панель с тремя кнопками и менеджером размещения FlowLayout и панель с двумя кнопками и менеджером размещения BoxLayout (горизонтальным). Разместите обе панели в главном окне (не изменяя менеджера размещения у панели содержимого): одну в центр, а другую вдоль любой стороны окна.
Рамки
Когда панели служат не просто для размещения элементов в соответствии с алгоритмом некоторого менеджера, а для визуального отделения их друг от друга, они оформляются с помощью рамок.
EmptyBorder — пустая рамка, позволяет создать отступы вокруг панели. Размеры отступов задаются в конструкторе четырьмя целыми числами.
TitledBorder — рамка с заголовком. Простейший конструктор имеет один параметр типа String (текст заголовка). Заголовок может размещаться вдоль любой стороны рамки, иметь различные начертания.
EtchedBorder — рамка с тиснением. Может быть вогнутой или выпуклой.
BevelBorder — объемная рамка (выпуклая или вогнутая). Можно настроить цвета, требуемые для получения объемных эффектов.
SoftBevelBorder — то же самое, что BevelBorder, но позволяет дополнительно скруглить углы.
LineBorder — простая рамка, нарисованная сплошной линией. Можно выбирать цвет и толщину линии, скруглить углы.
MatteBorder — рамка из повторяющегося рисунка.
CompoundBorder — объединяет две рамки, передаваемые в качестве параметров конструктору в одну новую рамку.
Все перечисленные классы описаны в пакете javax.swing.border.
Рассмотрим пример. В этом примере мы создадим шесть панелей с различными рамками и разместим их в виде таблицы. Чтобы не описывать шесть раз процедуру создания новой панели, вынесем ее в отдельный метод:
private JPanel createPanel(Border border, String text)
Метод createPanel() создает панель с кнопкой во весь свой размер. В качестве параметра передается надпись на кнопке и рамка, которую необходимо добавить к панели. Рамка добавляется не напрямую, а путем композиции с пустой рамкой. Этот прием часто используется, чтобы рамка не прилипала к краю панели.
Теперь шесть раз воспользуемся этим методом в конструкторе окна программы.
Класс ImageIcon описывает графическое изображение. Параметр его конструктора — это путь к файлу, из которого изображение может быть загружено. В примере используется относительное имя файла «1.gif». Чтобы объект ImageIcon был успешно создан, файл с таким именем должен быть помещен в папку проекта.