Ручное размещение элементов
Если в качестве менеджера размещения панели установить null, элементы не будут расставляться автоматически. Координаты каждого элемента необходимо в этом случае указать явно, при этом они никак не зависят от размеров панели и от координат других элементов. По умолчанию координаты равны нулю (т.е. элемент расположен в левом верхнем углу панели). Размер элемента также необходимо задавать явно (в противном случае его ширина и высота будут равны нулю и элемент отображаться не будет).
Координаты элемента можно задать одним из следующих методов:
setLocation(int x, int y),
setLocation(Point point)
Эти методы работают аналогично, устанавливая левый верхний угол элемента в точку с заданными координатами. Разница в способе задания точки. Можно представить точку двумя целыми числами, а можно объектом класса Point. Класс Point по сути представляет собой ту же пару чисел, его конструктор имеет вид Point(int x, int y). Получить доступ к отдельной координате можно методами getX() и getY().
Можно задаться вопросом: зачем использовать класс Point, если можно просто передать пару чисел? Но дело в том, что многие полезные методы возвращают результат – координаты некоторой точки – в виде объекта этого класса. Например, метод getLocation(), возвращающий координаты элемента. Предположим, нам нужно поместить элемент b в точности в то место, которое занимает элемент a. Этого легко добиться одной строкой:
b.setLocation(a.getLocation());
Размер элемента задается одним из двух методов:
setSize(int width, int height),
setSize(Dimension size)
Эти методы работают одинаково – разница, как и в прошлый раз, в способе передачи параметра. Класс Dimension, аналогично классу Point, просто хранит два числа, имеет конструктор с двумя параметрами: Dimension(int width, int height) и позволяет получить доступ к своим составляющим – ширине и высоте – с помощью простых методовgetWidth() и getHeigth(). Для того, чтобы получить текущий размер элемента, можно воспользоваться методомgetSize(), возвращающего объект класса Dimension. Элемент b можно сделать точно такого же размера, как элемент a, выполнив команду:
b.setSize(a.getSize());
Создадим панель, с которой не будет связано никакого менеджера размещения и вручную разместим на ней две кнопки:
SimpleWindow(){
super("Пробное окно");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(null);
JButton button = new JButton("Кнопка");
button.setSize(80, 30);
button.setLocation(20,20);
panel.add(button);
button = new JButton("Кнопка с длинной надписью");
button.setSize(120, 40);
button.setLocation(70,50);
panel.add(button);
setContentPane(panel);
setSize(250, 150);
}
Мы используем одну и ту же переменную button для обращения к обеим кнопкам (причем, второй раз ее описывать не нужно). В самом деле, осуществив все необходимые операции с первой кнопкой и зная, что обращаться к ней нам больше не понадобится, мы используем «освободившуюся» переменную для манипуляций со второй.
Автоматическое определение размеров компонентов
Если у панели есть любой менеджер размещения, она игнорирует явно заданные размеры и координаты всех своих элементов. В этом легко убедиться, заменив в предыдущем примере команду panel.setLayout(null) на panel.setLayout(new FlowLayout()). Менеджер размещения сам определяет координаты и размеры всех элементов.
Способ определения координат элементов очевидным образом вытекает из алгоритмов работы каждого менеджера и, таким образом, детально рассмотрен нами выше.
Мы также отмечали, что в некоторых случаях компоненты стараются заполнить все доступное им пространство. Например, всю центральную область в случае менеджера BorderLayout или всю ячейку в менеджере GridLayout. А в панели с менеджером FlowLayout, напротив, элементы никогда не пытаются выйти за определенные границы. Рассмотрим, что это за границы.
Каждый визуальный компонент имеет три типа размеров: минимально допустимый, максимально допустимый и предпочтительный. Узнать, чему равны эти размеры для данного компонента можно с помощью соответствующих методов:
getMinimumSize(),
getPreferredSize(),
getMaximumSize().
Методы возвращают результат типа Dimension. Они запрограммированы в соответствующем классе. Например, у кнопки минимальный размер – нулевой, максимальный размер не ограничен, а предпочтительный зависит от надписи на кнопке (вычисляется как размер текста надписи плюс размеры полей).
Менеджер FlowLayout всегда устанавливает предпочтительные размеры элементов. Менеджер BorderLayoutустанавливает предпочтительную ширину правого и левого, а также предпочтительную высоту верхнего и нижнего. Остальные размеры подгоняются под доступное пространство панели. Менеджер GridLayout пытается подогнать размеры всех элементов под размер ячеек. Менеджер BoxLayout ориентируется на предпочтительные размеры.
Когда элемент старается занять все доступное ему пространство, он «учитывает» пожелания не делаться меньше своих минимальных или больше максимальных.
Всеми тремя размерами можно управлять с помощью соответствующим методов set:
setMinimumSize(Dimension size),
setPreferredSize(Dimension size),
setMaximumSize(Dimension size).
Чаще всего используется простой прием, когда элементу «не рекомендуется» увеличиваться или уменьшаться относительно своих предпочтительных размеров. Это легко сделать командой:
element.setMinimumSize(element.getPreferredSize());
«Упаковка» окна
В рассмотренных выше примерах мы явно задавали размер окна методом setSize(). Но когда используется какой-либо менеджер расположения, расставляющий элементы и изменяющий их размеры по собственным правилам, трудно сказать заранее, какие размеры окна будут самыми подходящими.
Безусловно, наиболее подходящим будет вариант, при котором все элементы окна имеют предпочтительные размеры или близкие к ним.
Если вместо явного указания размеров окна, вызвать метод pack(), они будут подобраны оптимальным образом с учетом предпочтений всех элементов, размещенных в этом окне.
Оцените работу этого метода, заменив в каждом из вышеприведенных примеров команду
setSize(250, 100);
на команду
pack();
Заметьте, что когда панель не имеет метода размещения, эта команда не работает (поскольку панель не имеет алгоритма для вычисления своего предпочтительного размера).
Рамки
Когда панели служат не просто для размещения элементов в соответствии с алгоритмом некоторого менеджера, а для визуального отделения их друг от друга, они оформляются с помощью рамок.
Рамка панели устанавливается методом setBorder(Border border). Параметром метода выступает рамка – объект класса Border. Это абстрактный класс, поэтому для создания рамки используются его наследники:
EmptyBorder – пустая рамка, позволяет создать отступы вокруг панели. Размеры отступов задаются в конструкторе четырьмя целыми числами.
TitledBorder – рамка с заголовком. Простейший конструктор имеет один параметр типа String (текст заголовка). Заголовок может размещаться вдоль любой стороны рамки, иметь различные начертания.
EtchedBorder – рамка с тиснением. Может быть вогнутой или выпуклой.
BevelBorder – объемная рамка (выпуклая или вогнутая). Можно настроить цвета, требуемые для получения объемных эффектов.
SoftBevelBorder – то же самое, что BevelBorder, но позволяет дополнительно скруглить углы.
LineBorder – простая рамка, нарисованная сплошной линией. Можно выбирать цвет и толщину линии, скруглить углы.
MatteBorder – рамка из повторяющегося рисунка.
CompoundBorder – объединяет две рамки, передаваемые в качестве параметров конструктору в одну новую рамку.
Все перечисленные классы описаны в пакете javax.swing.border.
Рассмотрим пример. В этом примере мы создадим шесть панелей с различными рамками и разместим их в виде таблицы. Чтобы не описывать шесть раз процедуру создания новой панели, вынесем ее в отдельный метод:
private JPanel createPanel(Border border, String text) {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(new JButton(text));
panel.setBorder(new CompoundBorder(new EmptyBorder(12,12,12,12), border));
return panel;
}
Метод createPanel() создает панель с кнопкой во весь свой размер. В качестве параметра передается надпись на кнопке и рамка, которую необходимо добавить к панели. Рамка добавляется не напрямую, а путем композиции с пустой рамкой. Этот прием часто используется, чтобы рамка не прилипала к краю панели.
Теперь шесть раз воспользуемся этим методом в конструкторе окна программы.
SimpleWindow(){
super("Пробное окно");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2,3,5,10));
panel.add(createPanel(new TitledBorder("Рамка с заголовком"), "TitledBorder"));
panel.add(createPanel(new EtchedBorder(), "EtchedBorder"));
panel.add(createPanel(new BevelBorder(BevelBorder.LOWERED), "BevelBorder"));
panel.add(createPanel(new SoftBevelBorder(BevelBorder.RAISED), "SoftBevelBorder"));
panel.add(createPanel(new LineBorder(Color.ORANGE, 4), "LineBorder"));
panel.add(createPanel(new MatteBorder(new ImageIcon("1.gif")), "MatteBorder"));
setContentPane(panel);
pack();
}
Этот пример показывает, с помощью каких конструкторов создаются различные рамки и как они выглядят. В нем использованы два новых класса: Color и ImageIcon.
Класс Color предназначен для работы с цветом. В нем есть несколько констант, описывающих наиболее распространенные цвета. В частности, к таковым относится Color.ORANGE.
Класс ImageIcon описывает графическое изображение. Параметр его конструктора – это путь к файлу, из которого изображение может быть загружено. В примере используется относительное имя файла «1.gif». Чтобы объект ImageIcon был успешно создан, файл с таким именем должен быть помещен в папку проекта.
Дата добавления: 2017-01-26; просмотров: 1334;