Менеджеры компоновок
При проектировании интерфейса пользователя с использованием языка Java компоненты размещаются в контейнерах. Самым простым примером контейнера может служить окно формы (класс Frame). В общем случае любой класс, наследуемый от класса контейнера java.awt.Container, является контейнером.
В языке Java для «плавающего» размещения компонентов, зависящего от размеров окна и размеров самих компонентов, введены классы компоновок.
Компоновка определяет порядок расположения компонентов на экране. Перед отображением объектов-контейнеров, содержащих другие компоненты, вызывается менеджер компоновки. Он располагает компоненты на экране в соответствующем порядке. Используемый менеджер компоновки указывается вызовом метода setLayout. Если менеджер компоновки не указан явно, то выбирается тот, что используется по умолчанию для данного класса контейнера.
Для того чтобы отключить использование менеджеров компоновки и перейти к явному указанию координат, следует вызвать метод setLayuot(null).
Пакеты java.awt и javax.swing предоставляют следующие классы менеджеров компоновки:
java.awt.FlowLayout — создает последовательное размещение объектов с указанным выравниванием и заданными между этими объектами интервалами.
java.awt.GridLayout — создает табличное размещение объектов с заданным числом строк и столбцов, объекты располагаются последовательно слева направо.
java.awt.GridBagLayout — создает гибкое табличное размещение объектов, позволяя размещать один компонент в нескольких ячейках.
java.awt.BorderLayout — создает размещение объектов по краю контейнера (вверху, внизу, слева, справа и в центре).
java.awt.CardLayout — создает компоновку контейнера, отображая одновременно только один компонент. Как правило, в качестве компонент для данного менеджера компоновки выступают панели.
javax.swing.ScrollPaneLayout — позволяет размещать компоненты на девяти различных областях; является компоновкой по умолчанию для класса ScrollPane.
javax.swing.ViewportLayout — является компоновкой по умолчанию для класса Jviewport.
javax.swing.BoxLayout — является компоновкой по умолчанию для класса Box.
javax.swing.OverlayLayout — позволяет размещать компоненты один над другим.
Для использования конкретного менеджера компоновки следует создать объект данного класса и установить созданную компоновку для данного контейнера, а затем добавить в контейнер другие компоненты.
GridBagLayout gridBagLayout1 = new GridBagLayout();
Button button1 = new Button();
new GridBagConstraints(0, 0, 3, 1, 0.0, 0.0,
new Insets(0, 0, 0, 0),
Метод setLayout следует квалифицировать именем контейнера, для которого устанавливается компоновка. Для класса контейнера, в котором выполняется данный метод, можно использовать ссылку this. В случае предварительного создания объекта «менеджер компоновки», его следует указать как параметр метода setLayout. В противном случае в качестве параметра метода setLayout следует указать оператор создания анонимного объекта «менеджер компоновки».
При использовании панели типа Panel методы объекта «менеджер компоновки» вызываются стандартным образом имя_объекта_менеджер_компоновки.имя_метода.
При использовании панели типа JPanel методы объекта «менеджер компоновки» вызываются с использованием метода getLayout.
Менеджер компоновки BorderLayout разбивает контейнер на пять областей и располагает добавляемые в контейнер объекты по краям (север, юг, запад, восток) и в центре.
Каждая область указывается соответствующей константой: NORTH, SOUTH, EAST, WEST и CENTER. Если в методе add отсутствует строка, указывающая расположение компонента, то по умолчанию используется значение CENTER.
На рисунке приведен внешний вид, реализуемый менеджером компоновки BorderLayout для пяти кнопок, которые расположены в контейнере — апплете.
Следующий код иллюстрирует использование компоновки BorderLayout:
public class MyApplet extends Applet
public static void main(String[] args)
MyApplet myApplet1 = new MyApplet(); >
private void jbInit() throws Exception
add(new Button(«North»), BorderLayout.NORTH);
add(new Button(«South»), BorderLayout.SOUTH);
add(new Button(«East»), BorderLayout.EAST);
add(new Button(«West»), BorderLayout.WEST);
add(new Button(«Center»), BorderLayout.CENTER);
Класс BorderLayout предоставляет ряд методов, включая следующие:
GetHgap — возвращает расстояние в пикселях между компонентами по горизонтали.
SetHgap — устанавливает расстояние в пикселях между компонентами по горизонтали.
GetVgap — возвращает расстояние в пикселях между компонентами по вертикали.
SetVgap — устанавливает расстояние в пикселях между компонентами по вертикали.
Класс CardLayout определяет менеджер компоновки для контейнера, который может содержать несколько страниц («карт») и для которого одновременно может быть видна только одна карта.
Класс CardLayout предоставляет ряд методов, включая следующие:
GetHgap- определяет отступ по горизонтали.
GetVgap — определяет отступ по вертикали.
First — активизирует первую страницу контейнера.
Last — активизирует последнюю страницу контейнера.
Next — активизирует следующую страницу контейнера в циклическом порядке (после последней карты активизируется первая карта).
Previous — активизирует предыдущую страницу контейнера в циклическом порядке.
Show — активизирует компонент указанного контейнера.
// Для контейнера типа JPanel
void jButton1_actionPerformed(ActionEvent e)
// Для контейнера типа Panel
void button1_actionPerformed(ActionEvent e)
Менеджер компоновки FlowLayout размещает добавляемые в контейнер компоненты последовательно слева направо. Компоненты могут быть размещены в нескольких последовательных рядах.
На рисунке приведены два результата применения этой компоновки при изменении размеров контейнера.
Класс FlowLayout предоставляет следующие константы, определяющие выравнивание компонентов:
CENTER — по центру.
LEFT — по левому краю.
RIGHT — по правому краю.
Класс FlowLayout предоставляет ряд методов, включая следующие:
SetAlignment — устанавливает выравнивание компонентов для данной компоновки. Параметр метода может принимать следующие значения: FlowLayout.LEFT, FlowLayout.RIGHT и FlowLayout.CENTER.
GetHgap — определяет расстояние между компонентами по горизонтали.
SetHgap — устанавливает расстояние между компонентами по горизонтали.
GetVgap — определяет расстояние между компонентами по вертикали.
SetVgap- устанавливает расстояние между компонентами по вертикали.
Этот класс позволяет размещать компоненты в контейнере в виде таблицы. В каждой ячейке таблицы может быть размещен только один компонент.
Размер всех ячеек таблицы одинаков. Количество строк и столбцов таблицы определяется или в конструкторе, или вызовом методов setColumns и setRows. При этом, если эти значения не равны нулю, то количество столбцов является величиной вычисляемой и зависит от общего числа компонентов, добавленных на компоновку, и указанного числа строк. И только в том случае, если количество строк задано равным нулю, заданное количество столбцов будет учитываться менеджером компоновки.
На рисунке приведены примеры использования компоновки GridLayout.
Для компоновки GridLayout следует определять или количество строк, или количество столбцов.
Этот класс используется менеджером компоновки GridBagLayout и определяет требования к размещению компонентов.
Компоновка GridBagLayout позволяет размещать компоненты в ячейках таблицы. Но, в отличие от менеджера компоновки GridLayout, ячейки таблицы могут различаться как по ширине, так и по высоте. Размещаемые компоненты могут занимать несколько ячеек.
Область, занимаемая компонентом, называется областью отображения. Ее размеры определяются значениями переменных gridwidth и gridheight (количество ячеек по горизонтали и по вертикали) класса GridBagConstraints.
Отступами (insets) называется расстояние между областью отображения и действительной областью, занимаемой компонентом.
На рисунке приведен пример компоновки, в которой кнопка 3 занимает 9 ячеек, но размер кнопки меньше размера области отображения.
Если область отображения отличается от размера компонента, то для определения требований к размещению используется переменная fill.
Если размер размещаемого компонента меньше размера области отображения, то для указания размещения компонента используется переменная anchor, которая может принимать одно из следующих значений:
Переменная fill класса GridBagConstraint определяет, следует ли изменять размер компонента, и может принимать следующие значения:
GridBagConstraint.NONE — размер компонента не изменять (значение, используемое по умолчанию);
GridBagConstraint.HORIZONTAL — изменить размер по горизонтали, но не изменять его высоту;
GridBagConstraint.VERTICAL — изменить размер по вертикали, но не изменять его ширину;
GridBagConstraint.BOTH — увеличить размеры компонента до размера области отображения.
Переменные gridheight и gridwidthкласса GridBagConstraint определяют число ячеек в столбце или строке соответственно. При этом константа GridBagConstraints.REMAINDER указывает, что компонент будет последним в столбце (строке), а константа GridBagConstraints.RELATIVE указывает, что компонент будет ближайшим к последнему.
Конструктор GridBagConstraints(int gridx, int gridy, int gridwidth, int gridheight, double weightx, double weighty, int anchor, int fill, Insets insets, int ipadx, int ipady) создает объект требований к размещению компонента, используемый менеджером компоновки, со всеми полями, имеющими заданные значения.
Компоненты графического интерфейса пользователя
Java-приложение создается как иерархия вложенных компонентов. Наверху этой иерархии могут находится компоненты классов Frame, JFrame, Applet или JApplet.
Классы панелей используются как контейнеры для размещения других компонентов, в числе которых могут быть и сами панели. Пакет оконного интерфейса java.awt содержит один класс панели — Panel. Для добавления компонентов на панель класса Panel следует выполнить метод add, квалифицировав его именем панели.
Пакет облегченных swing-компонентов предоставляет несколько классов панелей, включая следующие классы:
При использовании менеджеров компоновки с панелями из пакета java.swing для получения ссылки на панель следует использовать метод getLayout.
Пакет javax.swing содержит интерфейс RootPaneContainer, реализуемый классами JApplet, JFrame, JInternalFrame, JWindow и JDialog.
При добавлении компонентов в контейнер, использующий интерфейс RootPaneContainer, метод add надо квалифицировать следующим образом:
Класс JRootPane используется всеми панелями пакета javax.swing. Он позволяет размещать содержимое панели на нескольких уровнях. JRootPane представляет четыре уровня:
ContentPane — используется для отображения компонентов.
MenuBar — необязательный уровень, на котором можно размещать компоненты меню.
LayeredPane — используется для управления contentPane и menuBar.
GlassPane — самый ближайший к пользователю уровень. По умолчанию он невидим. glassPane, как правило, используется для отображения графики или каких-либо всплывающих компонентов. Компоненты этого уровня перекрывают компоненты, расположенные на более «низких» уровнях.
Уровень contentPane должен быть родительским для размещения любого компонента. Для доступа к данному уровню используется метод getContentPane().
Уровень glassPane является самым верхним. Для доступа к данному уровню применяется метод getGlassPane(). Чтобы в приложении можно было использовать уровень glassPane, для него следует вызвать метод setGlassPane().
Компонент JTabbedPane реализует набор страниц, переключаемых по щелчку пользователя на вкладках. Вкладки добавляются методами addTab и insertTab. Вкладки нумеруются, начиная с 0.
Если количество вкладок равно нулю, то индекс текущей вкладки равен -1.
На рисунке показан внешний вид окна, содержащего панель вкладок класса JTabbedPane.
Класс javax.swing.JScrollPane реализует компонент «прокручиваемая область».
Панель JScrollPane состоит из:
области просмотра (viewport) типа JViewport. Для добавления рамки вокруг области просмотра следует использовать метод setViewportBorder, а для добавления рамки вокруг всей прокручиваемой области — метод setBorder.;
вертикальной и горизонтальной области прокрутки типа JScrollBar (необязательная область);
области заголовков строк и области заголовкоd столбцов (необязательная область). Эти области реализуются как объекты типа JViewport, для которых вызваны методы setRowHeaderView и setColumnHeaderView;
четырех угловых областей. По умолчанию угловые области не содерджaт компонентов. Для того чтобы разместить в угловой области компонент, следует использовать метод setCorner.
Чтобы изменить свойство области просмотра, ее следует получить, вызвав метод getViewport. Например, для задания цвета фона нужно записать:
На рисунке показано расположение основных частей прокручиваемой области JScrollPane.
Контейнером для разделяемых панелей служит компонент JSplitPane. Разделяемые плавающие панели имеют одну общую сторону — по вертикали или по горизонтали.
Следующий пример иллюстрирует создание окна, в котором применяются разделяемые панели:
public class Frame1 extends JPanel
JSplitPane jSplitPane1 = new JSplitPane(); // Класс
JScrollPane jScrollPane1 = new JScrollPane();
JScrollPane jScrollPane2 = new JScrollPane();
JTextPane jTextPane1 = new JTextPane();
JTextPane jTextPane2 = new JTextPane();
public static void main(String s[])
JFrame frame = new JFrame(«Панели»);
public void windowClosing(WindowEvent e)
private void jbInit() throws Exception
// Определение ориентации разделяемых панелей
// Размещение левого и правого компонента
// на разделяемой панели
// Отображение кнопок сворачивания и разворачивания
// сторон разделяемой панели
// Задание размера панелей
jScrollPane1.setPreferredSize(new Dimension(300, 60));
jScrollPane2.setPreferredSize(new Dimension(300, 60));
// Добавление разделяемой панели к окну формы
// Добавление компонентов в контейнеры
Кнопки могут располагаться в контейнере как отдельно, так и в группе.
Пакет java.awt содержит следующие классы кнопок и групп:
Button — командная кнопка.
Checkbox — флажок или радиокнопка (переключатель).
CheckboxGroup — группа кнопок.
Пакет облегченных swing-компонентов также предоставляет несколько классов кнопок и групп, включая следующие классы:
ButtonGroup — группа кнопок.
На кнопках из пакета javax.swing помимо метки может также отображаться и пиктограмма.
Класс Button позволяет создавать объекты «командные кнопки». При нажатии на кнопку JVM инициирует событие действия actionPerformed. Наряду с данным семантическим событием, инициируется ряд простых событий, таких как mouseClicked.
Класс Button предоставляет ряд методов, включая следующие:
AddActionListener — регистрирует блок прослушивания для события действия от командной кнопки;
GetActionCommand — возвращает имя команды, инициировавшей событие действия, или метку кнопки, если имя команды равно null (значение по умолчанию);
GetLabel — возвращает метку командной кнопки или null для непомеченной командной кнопки;
SetLabel — изменяет метку командной кнопки.
Класс Checkbox позволяет создавать компоненты кнопки двух типов, называемые флажками и радиокнопками. Такой компонент может иметь два состояния: включено (true) и выключено (false). Каждый щелчок на компоненте изменяет его состояние на обратное.
Несколько переключателей могут быть объединены в группу, используя компонент CheckboxGroup, являющийся контейнером. Такая группа называется группой радиокнопок. Только один компонент группы может одновременно иметь состояние «включен».
Для обработки событий от кнопки используется интерфейс ItemListener. Этот интерфейс определяет всего один обработчик события — метод itemStateChanged (ItemEvent e).
Класс ItemEvent содержит метод getStateChange, позволяющий определить состояние кнопки. Метод может возвращать одно из двух возможных значений:
// Определение состояния кнопки
void itemStateChanged(ItemEvent e)
if (e.getStateChange() == ItemEvent.SELECTED)
Для добавления кнопки в группу для нее следует вызвать метод setCheckboxGroup, указав в качестве параметра объект типа CheckboxGroup.
Следующий листинг иллюстрирует создание флажков и группы радиокнопок:
public class MyApplet extends Applet
Panel panel1 = new Panel();
GridLayout gridLayout1 = new GridLayout();
// Создание новой кнопки:
Checkbox checkbox1 = new Checkbox();
Checkbox checkbox2 = new Checkbox();
GridLayout gridLayout2 = new GridLayout();
Panel panel2 = new Panel();
// Создание группы кнопок:
CheckboxGroup checkboxGroup1 = new CheckboxGroup();
Checkbox checkbox4 = new Checkbox();
Checkbox checkbox5 = new Checkbox();
Checkbox checkbox6 = new Checkbox();
FlowLayout FlowLayout1 = new FlowLayout();
try < jbInit(); >catch(Exception e)
public static void main(String[] args)
MyApplet myApplet1 = new MyApplet(); >
private void jbInit() throws Exception
checkbox2.setState(true); // Состояние флажка —
// Добавление в группу трех кнопок:
checkbox4.setState(true); // Состояние радиокнопки —
// Добавление кнопок в контейнеры — панели
Классы кнопок пакета javax.swing наследуются от класса AbstractButton. Этот класс предоставляет ряд общих методов, включая следующие:
doClick — выполнение щелчка мыши на кнопке программным способом;
getText- возвращает метку кнопки;
setText — устанавливает метку кнопки;
isSelected — определяет состояние кнопки и возвращает true, если переключаемая кнопка находится в состоянии «включена»;
setSelected — устанавливает состояние кнопки;
setMargin — устанавливает отступы между рамкой кнопки и меткой;
setIcon — определяет пиктограмму, используемую по умолчанию. Эта пиктограмма используется для состояния кнопки «нажатая» или «недоступная» в том случае, если для этих состояний не указана иная пиктограмма;
setPressedIcon- определяет пиктограмму для нажатого («pressed») состояния кнопки;
setSelectedIcon — устанавливает пиктограмму для выделенного («selected») состояния кнопки;
setRolloverIcon — устанавливает пиктограмму для нажатого («rollover») состояния кнопки (одновременно могут быть нажаты несколько кнопок);
setDisabledIcon- устанавливает пиктограмму для недоступного состояния кнопки.
ImageIcon ImageIcon1= new
setDisabledSelectedIcon — устанавливает пиктограмму недоступного для выделения состояния кнопки;
setVerticalAlignment — определяет выравнивание по вертикали для пиктограммы и метки, которое может указываться следующими значениями:
SwingConstants.CENTER (по умолчанию);
setHorizontalAlignment — определяет выравнивание по горизонтали для пиктограммы и метки, которое может указываться следующими значениями:
SwingConstants.RIGHT (по умолчанию);
setVerticalTextPosition — определяет позицию текста по вертикали относительно пиктограммы, которая может указываться следующими значениями:
SwingConstants.CENTER (по умолчанию);
setHorizontalTextPosition — определяет позицию текста по горизонтали относительно пиктограммы, которая может указываться следующими значениями:
SwingConstants.RIGHT (по умолчанию);
setActionCommand — задает команду действия для кнопки;
getActionCommand — возвращает строку, которая содержит команду действия, установленную для данной кнопки;
setMnemonic — определяет код символа, используемого как ключ-акселератор (ALT+данный символ).
Для того чтобы определить в методе обработки события itemStateChanged(ItemEvent e), какой кнопкой было инициировано данное событие, следует использовать метод getItemSelectable.
Для того чтобы определить, является ли кнопка, инициировавшая событие, выделенной (находящейся в состоянии «включена» или «нажата»), следует использовать метод getStateChange.
Класс JToggleButton предназначен для создания кнопок, имеющих два состояния — «нажата» и «не нажата». Компонент JToggleButton может находится в зафиксированном нажатом состоянии (быть выделенным).
Этот класс является непосредственным суперклассом для классов JCheckbox и JRadioButton.
Для того чтобы установить состояние кнопки, следует использовать метод setSelected.
Кнопки JToggleButton могут быть объединены в группу. Такую группу следует предварительно создать, используя компонент типа javax.swing.ButtonGroup. Только одна из кнопок группы может одновременно иметь нажатое состояние.
Текстовые компоненты предназначаются для ввода и отображения строк.
Библиотека JDK предоставляет следующие классы текстовых компонентов:
java.awt.TextArea — текстовая область.
java.awt.TextField — текстовое поле, называемое также полем ввода.
javax.swing.JTextField — текстовое поле.
javax.swing.JPasswordField — текстовое поле, предназначаемое для ввода пароля.
javax.swing.JTextArea — текстовая область.
javax.swing.JEditorPane — панель редактора, позволяющая отображать как текстовые, так и графические данные, а также применять различное форматирование текста.
javax.swing.JTextPane — текстовая панель, позволяющая отображать содержимое с использованием различных шрифтов.
Все текстовые компоненты пакета java.awt наследуются от класса TextComponent.
Все текстовые компоненты пакета javax.swing наследуются от класса JTextComponent.
Для отображения текста, который может быть изменен только программным путем, служат компоненты.Label из пакета java.awt и JLabel из пакета javax.swing.
Компонент JLabel также можно использовать и для отображения рисунков.
Большинство названий методов, предоставляемых классами TextComponent и JTextComponent для работы с текстом, совпадают. Так, для того чтобы получить строку, которая содержит весь текст, расположенный в текстовом компоненте, можно использовать метод getText, а для получения позиции ввода — метод getCaretPosition; для определения, можно ли редактировать текст, — метод isEditable, для выделения текста в указанном диапазоне — метод select, а для выделения всего текста — метод selectAll.
При каждом изменении значения текстового компонента, включая ввод каждого символа, происходит событие textValueChanged. При нажатии на клавишу Enter для текстового поля инициируется событие actionPerformed. Но при перемещении фокуса ввода событие actionPerformed не происходит.
Класс TextField позволяет создавать однострочные текстовые поля, используемые для ввода и редактирования одной строки текста. Этот класс предоставляет ряд методов, включая следующие:
AddActionListener — регистрирует блок прослушивания для обработки события действия компонента «текстовое поле».
EchoCharIsSet — возвращает значение true в том случае, если ввод в данное текстовое поле отображается некоторым эхо-символом, скрывающим действительное значение поля.
GetColumns — возвращает размер данного текстового поля (количество символов).
GetEchoChar — возвращает эхо-символ для данного текстового поля.
SetEchoCharacter — устанавливает значение эхо-символа для данного текстового поля. Любой вводимый пользователем символ будет экранирован данным эхо-символом.
SetColumns — устанавливает размер текстового поля в символах.
SetText — определяет новое значение текстового поля.
Хотя компоненты пакета javax.swing и называются облегченными, но они предоставляют значительно большие возможности, чем традиционные текстовые компоненты пакета java.awt.
Управление текстом, отображаемым в текстовом компоненте, определяется интерфейсом Document. Этот интерфейс предназначен для определения методов работы с текстом. Интерфейс Documentреализован классом AbstractDocument.
Текст в компоненте типа JTextComponent представляется ассоциируемой с ним текстовой моделью, определяющей как содержание, так и стиль.
Фактически, текстовый компонент предоставляет доступ к:
модели, реализуемой на основе интерфейса Document и представляющей собой содержание документа;
области просмотра текстового компонента;
набору команд редактирования, предусмотренного для текстового компонента;
таблице ключей акселераторов, связанных с таблицей именованных действий.
Класс DefaultEditorKit и StyledEditorKit описывают набор именованных действий, которые можно использовать для создания на основе текстового компонента редактора текста.
В классе DefaultEditorKit определен набор предоставляемых текстовому компоненту действий, таких как перемещение курсора, выделение или вставка текста.
Например, для создания пункта меню, выполняющего форматирование выделенного диапазона текста, и изменения размера шрифта на 14p, следует записать:
«Имя пункта меню», 14));
Константы класса DefaultEditorKit описывают набор именованных действий, включая следующие:
BackwardAction — перемещение позиции ввода на одну позицию назад.
BeepAction — подача звукового сигнала.
BeginAction — перемещение позиции ввода на начало документа.
BeginParagraphAction — перемещение позиции ввода в начало абзаца.
BeginLineAction — перемещение позиции ввода в начало строки.
BeginWordAction — перемещение позиции ввода на начало текущего слова.
CutAction — вырезание выделенного диапазона текста и помещение его в буфер обмена.
CopyAction — копирование выделенного диапазона текста в буфер обмена.
DeleteNextCharAction — удаление следующего символа.
DownAction- перемещение позиции ввода на один ряд вниз.
DeletePrevCharAction — удаление предыдущего символа.
EndAction — перемещение позиции ввода в конец документа.
EndLineAction — перемещение позиции ввода в конец строки.
EndParagraphAction — перемещение позиции ввода в конец абзаца.
EndWordAction — перемещение позиции ввода на конец текущего слова.
ForwardAction — перемещение позиции ввода на один символ вперед.
InsertBreakAction — вставка в документ символа конца абзаца.
InsertTabAction — вставка символа табуляции.
NextWordAction — перемещение позиции ввода на начало следующего слова.
PageDownAction — перемещение позиции ввода на одну страницу вниз.
PageUpAction — перемещение позиции ввода на одну страницу вверх.
PasteAction — вставка содержимого буфера обмена вместо выделенного диапазона текста или перед текущей позицией ввода.
PreviousWordAction — перемещение позиции ввода на начало предыдущего слова.
ReadOnlyAction — перевод редактора в режим «только чтение».
SelectAllAction — выделение всего документа.
SelectionBackwardAction — расширение области выделения на одну позицию назад (влево).
SelectionBeginAction — расширение области выделения до начала документа.
SelectionBeginLineAction- расширение области выделения до начала текущей строки.
SelectionBeginParagraphAction — расширение области выделения до начала текущего абзаца.
SelectionBeginWordAction — расширение области выделения до начала текущего слова.
SelectionDownAction — расширение области выделения на одну позицию вниз.
SelectionEndAction — расширение области выделения до конца документа.
SelectionEndLineAction — расширение области выделения до конца строки.
SelectionEndParagraphAction- расширение области выделения до конца абзаца.
SelectionEndWordAction — расширение области выделения до конца текущего слова.
SelectionForwardAction — расширение области выделения на один символ вперед (вправо).
SelectionNextWordAction — расширение области выделения до начала следующего слова.
SelectionPreviousWordAction — расширение области выделения до начала предыдущего слова.
SelectionUpAction — расширение области выделения на одну позицию вверх.
SelectLineAction — выделение строки, в которой расположена позиция ввода.
SelectParagraphAction — выделение абзаца, в котором расположена позиция ввода.
SelectWordAction — выделение слова, в котором расположена позиция ввода.
UpAction — перемещение позиции ввода на одну позицию вниз.
WritableAction — перевод редактора в режим редактирования текста.
Для того чтобы добавить в документ строку в отформатированном виде, можно использовать метод insertS класса DefaultStyledDocument. Этот класс является подклассом класса AbstractDocumentи реализует интерфейсы Document и StyledDocument.
Интерфейс StyledDocument определяет методы для работы со стилем документа. Так, для назначения диапазону текста набора атрибутов стиля можно использовать метод setCharacter-Attributes, а для определения используемого стиля или шрифта — методы getStyle и getFont.
Атрибуты стиля определяются интерфейсом AttributeSet. Этот интерфейс реализован классом SimpleAttributeSet.
Для создания набора атрибутов стиля следует создать переменную типа SimpleAttributeSet и установить атрибуты стиля, используя методы класса
SimpleAttributeSet attrSt = new SimpleAttributeSet();
При добавлении строки в текстовый документ вызовом метода insertString класса Default-StyledDocument один из параметров ссылается на набор аттрибутов.
Фактически набор атрибутов стиля накладывается на диапазон текста. Если текстовый компонент содержит текст с различным форматированием, то на каждый отдельный диапазон текста должен быть «наложен» свой набор атрибутов стиля.
Для создания таблицы ключей акселераторов, используемых для текстового компонента, следует:
Создать объект класса Keymap для компонента класса JTextPane.
Keymap keymap = textPane.addKeymap(«MyKeymap»,
Создать объект класса Action и установить для него действие, описанное в классе DefaultEditorKit.
Action action = getActionByName(DefaultEditorKit.downAction);
Создать объект класса KeyStroke и установить для него значение ключа акселератора.
KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_N,
Установить связь между созданным действием и ключем акселератором.
Класс StyleConstants предоставляет набор методов, позволяющих определять или устанавливать значения для атрибутов форматирования.
Набор атрибутов форматирования может быть создан как объект одного из следующих классов:
. SimpleAttributeSet[] attrs = new
// Создание набора атрибутов:
attrs[0] = new SimpleAttributeSet();
// Установка значения атрибута
attrs[1] = new SimpleAttributeSet(attrs[0]);
// Добавление строки в документ с заданным набором
// атрибутов (defaultStyleDocument1 переменная
// класса, наследуемого от DefaultStyleDocument)
Списки позволяют отображать группу элементов в один столбец, предоставляя пользователю возможность выбора элемента.
Библиотека JDK содержит ряд классов списков, включая следующие:
java.awt.Choice — ниспадающий список.
javax.swing.JComboBox — ниспадающий список.
При выделении элемента в списке или в ниспадающем списке (или отмене выделения) инициируется событие itemStateChanged. В метод обработки этого события передается объект типа ItemEvent. Используя свойство SELECTED для объекта типа ItemEvent, можно определить, выделен ли элемент списка. Интерфейс ItemListener описывает метод обработки события itemStateChanged.
При двойном щелчке мышью на элементе списка (или нажатии клавиши Enter при выделенном элементе списка) для компонента типа List, JList или JComboBox инициируется событие actionPerformed. В метод обработки этого события передается объект типа ActionEvent. Интерфейс ActionListener описывает метод обработки события actionPerformed.
Заполнение списков можно выполнять в обработчике события фрейма windowOpened. Добавление элементов в список List и Choice выполняется методом add.
List list1 = new List(4, false); // Создание списка
// с 4 видимыми строками и с запретом множественного выбора
list1.add(«Строка 1»); // Добавление элементов в список
add(list1); // Добавление списка в текущий контейнер
Список JList позволяет выделять один или несколько элементов. Содержание списка представляется моделью ListModel. Доступ к элементам списка реализуется с использованием модели. Для заполнения списка используется метод setListData.
Список JList непосредственно не поддерживает прокрутку списка. Реализовать скроллинг можно двумя способами:
Поместить список в контейнер типа JScrollPane. Например:
JScrollPane scrollPane = new JScrollPane(jList1);
Установить для объекта типа JScrollPane на уровне Viewport (getViewport) в качестве компонента области просмотра (setView) объект типа JList. Например:
JScrollPane scrollPane = new JScrollPane();
String[] data = ; // Массив строк
JList jList1 = new JList(data); // Создание списка,
// содержащего массив строк
// Доступ к элементам списка через модель
// Заполнение списка данными, представляемыми классом Vector
JList jList1 = new JList();
Vector superClasses = new Vector();
Class rootClass = javax.swing.JList.class; // Создание объекта
for(Class cls = rootClass; cls!= null;
jList1.setListData(superClasses); // Заполнение компонента jList1
// списком всех его подклассов
// Добавление элементов в список, хранимый в объекте типа Vector
// Выделение элементов списка:
jList1.setSelectedIndex(1); // Выделение второго элемента списка
jList1.getSelectedValue(); // Возвращает строку, отображаемую
//во втором элементе списка
Воспользуйтесь поиском по сайту:
studopedia.org — Студопедия.Орг — 2014-2023 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.009 с) .
Менеджеры расположения Layout
Менеджер расположения (layout manager) определяет, каким образом на форме будут располагаться компоненты. Независимо от платформы, виртуальной машины, разрешения и размеров экрана менеджер расположения гарантирует, что компоненты будут иметь предпочтительный или близкий к нему размер и располагаться в том порядке, который был указан программистом при создании программы.
На странице представлено описание следующих менеджеров расположения и примеров :
- Полярное расположение BorderLayout
- Последовательное расположение FlowLayout
- Табличное расположение GridLayout
- Менеджер расположения GridBagLayout
- Менеджер расположения CardLayout
- Менеджер расположения BoxLayout
- Менеджер расположения GroupLayout
- Менеджер расположения SpringLayout
- Пример диалогового окна авторизации
- Пример собственного менеджера расположения
Исходные коды примеров различных менеджеров расположения, рассмотренных на странице можно скачать здесь (13.4 Кб).
В Swing менеджер расположения играет еще большую роль, чем обычно. Он позволяет не только сгладить различия между операционными системами, но к тому же дает возможность с легкостью менять внешний вид приложения, не заботясь о том, как при этом изменяются размеры и расположение компонентов.
Поддержка менеджеров расположения встроена в базовый класс контейнеров java.awt.Container. Все компоненты библиотеки Swing унаследованы от базового класса JComponent, который, в свою очередь, унаследован от класса Container. Таким образом, для любого компонента Swing можно установить менеджер расположения или узнать, какой менеджер им используется в данный момент. Для этого предназначены методы setLayout() и getLayout().
Конечно, изменять расположение желательно только в контейнерах, которые предназначены для размещения в них компонентов пользовательского интерфейса, то есть в панелях (JPanel) и окнах (унаследованных от класса Window). Не стоит менять расположение в кнопках или флажках, хотя такая возможность имеется. В стандартной библиотеке Java существует несколько готовых менеджеров расположения, и с их помощью можно реализовать абсолютно любое расположение.
Вызов менджера расположения, revalidate
Контейнер окна вызывает методы менеджера расположения каждый раз при изменении своих размеров или при первом появлении на экране. Кроме этого, можно программно запросить менеджер расположения заново расположить компоненты в контейнере: для этого служит так называемая проверка корректности (валидация) контейнера и содержащихся в нем компонентов. Проверка корректности очень полезна, если интерфейс приложения меняется динамически. Например, если динамически меняются размеры компонентов (во время выполнения программы изменяется текст надписи или количество столбцов таблицы — все это приведет к изменению размеров компонентов). После изменений компонентам может не хватать прежних размеров или наоборот, прежний размер будет для них слишком велик. Для этого и предназначена проверка корректности. Выполнить проверку корректности для любого компонента Swing, будь это контейнер или отдельный компонент, позволяет метод revalidate(), определенный в базовом классе библиотеки JComponent.
Менеджер расположения размещает добавляемые в контейнер компоненты в некотором порядке согласно реализованного в нем алгоритма, и определяет их некоторый размер. При этом он обычно учитывает определенные свойства компонентов :
- Предпочтительный размер. Размер, который идеально подходит компоненту. По умолчанию все размеры компонентов устанавливаются текущим менеджером внешнего вида и поведения (look and feel manager), но можно их изменить. Предпочтительный размер можно изменить с помощью метода setPrefferedSize().
- Минимальный размер. Параметр определения минимального размера компонента. После достижения минимального размера всех компонентов контейнер больше не сможет уменьшить свой размер. Минимальный размер также можно изменить, для этого предназначен метод setMinimumSize().
- Максимальный размер. Параметр определения максимального размера компонента при увеличении размеров контейнера. Например, максимальный размер текстового поля JTextField не ограничен. Чаще всего оно должно сохранять свой предпочтительный размер. Это можно исправить с помощью метода setMaximumSize(), устанавливающего максимальный размер. Большая часть менеджеров расположения игнорирует максимальный размер, работая в основном с предпочтительным и минимальным размерами.
- Выравнивание по осям X и Y. Данные параметры нужны только менеджеру BoxLayout, причем для него они играют важнейшую роль.
- Границы контейнера. Эти параметры контейнера определяют размеры отступов от границ контейнера. Значения границ контейнера позволяет получить метод getInsets(). Иногда менеджеру расположения приходится их учитывать.
Описание бизнес-логики работы менеджера расположения
Логика работы менеджера расположения происходит следующим образом : он ждет прихода сигнала от контейнера окна, требующего расположить в нем компоненты. Этому соответствует вызов метода layoutContainer() интерфейса LayoutManager. В методе layoutContainer() и происходит основная работа по расположению компонентов в контейнере.
Менеджер расположения учитывает различные размеры и свойства компонентов и контейнера, и должен расположить компоненты на определенных позициях в контейнере, вызывая для каждого из них метод setBounds(), позволяющий указать в пикселах в системе координат контейнера прямоугольник, который будет занимать компонент. Для сложных менеджеров расположения с гибким поведением это означает массу работы и сложные вычисления, однако простые алгоритмы расположения компонентов реализовать совсем несложно.
Ниже представлен пример разработки менеджера вертикального расположения компонентов VerticalLayout. Он располагает компоненты вертикально с расстоянием между ними в 5 пикселов и использует для всех компонентов предпочтительный размер.
// Пример разработки менеджера вертикального расположения компонентов import javax.swing.*; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.LayoutManager; // Менеджер вертикального расположения компонентов class VerticalLayout implements LayoutManager < private Dimension size = new Dimension(); // Следующие два метода не используются public void addLayoutComponent (String name, Component comp) <>public void removeLayoutComponent(Component comp) <> // Метод определения минимального размера для контейнера public Dimension minimumLayoutSize(Container c) < return calculateBestSize(c); >// Метод определения предпочтительного размера для контейнера public Dimension preferredLayoutSize(Container c) < return calculateBestSize(c); >// Метод расположения компонентов в контейнере public void layoutContainer(Container container) < // Список компонентов Component list[] = container.getComponents(); int currentY = 5; for (int i = 0; i < list.length; i++) < // Определение предпочтительного размера компонента Dimension pref = list[i].getPreferredSize(); // Размещение компонента на экране list[i].setBounds(5, currentY, pref.width, pref.height); // Учитываем промежуток в 5 пикселов currentY += 5; // Смещаем вертикальную позицию компонента currentY += pref.height; >> // Метод вычисления оптимального размера контейнера private Dimension calculateBestSize(Container c) < // Вычисление длины контейнера Component[] list = c.getComponents(); int maxWidth = 0; for (int i = 0; i < list.length; i++) < int width = list[i].getWidth(); // Поиск компонента с максимальной длиной if ( width >maxWidth ) maxWidth = width; > // Размер контейнера в длину с учетом левого отступа size.width = maxWidth + 5; // Вычисление высоты контейнера int height = 0; for (int i = 0; i < list.length; i++) < height += 5; height += list[i].getHeight(); >size.height = height; return size; > > public class VerticalLayoutTest < public static void main(String[] args) < // Создаем окно JFrame frame = new JFrame("VerticalLayoutTest"); // Определяем размеры frame.setSize(260, 150); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Создаем панель с менеджером вертикального расположения компонентов JPanel contents = new JPanel(new VerticalLayout()); // Добавим кнопки и текстовое поле в панель contents.add(new JButton("Продукты" )); contents.add(new JButton("Галантерея")); contents.add(new JTextField(20)); // Размещаем панель в контейнере frame.setContentPane(contents); // Открываем окно frame.setVisible(true); >>
Менеджер расположения VerticalLayout реализует интерфейс LayoutManager. Самым важным методом является layoutContainer(), который определяет расположения всех компонентов, содержащиеся в контейнере. Алгоритм функционирования менеджера расположения не сложный : размещение компонентов по вертикали, отделяя их друг от друга расстоянием в 5 пикселов; все компоненты имеют предпочтительный размер. Чтобы реализовать алгоритм выполняются следующие шаги :
- Получение массива компонентов — метод контейнера getComponents().
- Организация цикла перебора компонентов.
- Определение предпочтительного размера для каждого из компонентов — метод getPreferredSize().
- Определение позиции компонента на экране методом setBounds().
- Смещение текущей вертикальной координаты Y, увеличением ее значения на высоту очередного компонента с учетом «декоративного» расстояния в 5 пикселов.
Таким образом, менеджер VerticalLayout разместит все компоненты контейнера друг над другом на расстоянии в 5 пикселов. Следует обратить внимание, что компоненты отделены и от левой границы контейнера.
Метод addLayoutComponent() предназначен для добавления компонентов в список менеджера расположения, а метод removeLayoutComponent() для удаления компонентов из списка. addLayoutComponent() позволяет ассоциировать с компонентом строку, которая может быть использована менеджером расположения как рекомендация относительно того, где именно необходимо разместить данный компонент. Наш пример менеджера расположения в отличие от BorderLayout не поддерживает подобных рекомендаций.
Две функции менеджера (предпочтительный preferredLayoutSize() и минимальный minimumLayoutSize()) сообщают размеры контейнера. Для нашего простого менеджера расположения минимальный и предпочтительный размеры контейнера совпадают, их вычисляет метод calculateBestSize(). Для вычисления оптимального размера контейнера в цикле выполняется поиск компонента с самой большой длиной. К найденной длине добавляется 5 пикселов в качестве отступа от левой границы контейнера и получаем оптимальную длину контейнера. Для высоты вычисления чуть сложнее : необходимо сложить высоты всех находящихся в контейнере компонентов, а также прибавлять к ним расстояние в 5 пикселов между всеми компонентами. Полученная сумма и является оптимальной высотой контейнера.
Для тестирования менеджера вертикального расположения в методе main() создаем небольшое окно с рамкой JFrame. Создаем панель с устанавленным менеджером расположения VerticalLayout. В панель добавляется пара кнопок и текстовое поле. Созданную панель размещаем в панели содержимого, после чего окно выводится на экран. На следующем скриншоте представлен интерфейс окна примера использования вертикального менеджера расположения компонентов.
Знание основных принципов работы менеджера расположения позволяет глубже понять технологию размещения компонентов в контейнере при использовании библиотеки Swing.
Полярное расположение BorderLayout
Менеджер BorderLayout специально предназначен для обычных и диалоговых окон. Он позволяет быстро и просто расположить наиболее часто используемые элементы любого окна: панель инструментов, строку состояния и основное содержимое. Для этого BorderLayout разбивает окно на четыре области, а все оставшееся место заполняется компонентом, выполняющим основную функцию приложения — в редакторе это будет текстовое поле, в многооконном приложении — рабочий стол.
Менеджер расположения BorderLayout иммет отличия от остальных. Чтобы добавить с его помощью компонент в методе add() необходимо использовать дополнительный параметр, который определяет область контейнера для размещения компонента. В таблице перечислены допустимые значения этого параметра.
Значение | Строка | Описание |
---|---|---|
BorderLayout.NORTH | North | Компонент располагается вдоль верхней границы окна и растягивается на всю его ширину. Обычно в этом месте размещается панель инструментов. |
BorderLayout.SOUTH | South | Компонент располагается вдоль нижней границы и растягивается на всю ширину окна. Такое положение характерно для строки состояния. |
BorderLayout.WEST | West | Компонент располагается вдоль левой границы окна и растягивается на всю его высоту; при этом учитываются размеры северных и южных компонентов, имеющих приоритет. |
BorderLayout.EAST | East | Компонент располагается вдоль правой границы окна. В остальном его расположение аналогично западному компоненту. |
BorderLayout.CENTER | Center | Компонент помещается в центр окна, занимая максимально возможное пространство. |
Рекомендации : на север помещайте панель инструментов вашего приложения. На юг помещайте строку состояния. Оставляйте западные и восточные зоны окна свободными — только в этом случае панель инструментов можно будет перетаскивать. Для главного окна вашего приложения всегда используйте расположение BorderLayout.
Рассмотрим простой BorderLayout пример. В примере создается окно JFrame, в котором менеджер BorderLayout используется по умолчанию. Во все доступные зоны добавляются компоненты :
// Пример полярного расположения компонентов - BorderLayout import java.awt.*; import javax.swing.*; public class BorderLayoutTest extends JFrame < public BorderLayoutTest() < super("BorderLayoutTest"); setDefaultCloseOperation( EXIT_ON_CLOSE ); setSize(250, 250); // Панель содержимого Container container = getContentPane(); /* * Размещаем в панели компоненты * В качестве параметров можно использовать * строки и константы класса BorderLayout */ container.add(new JButton("Север" ), "North"); container.add(new JButton("Юг" ), "South"); container.add(new JLabel ("Запад" ), BorderLayout.WEST); container.add(new JLabel ("Восток"), BorderLayout.EAST); // При отсутствии 2-го параметра компонент размещается в центре container.add(new JButton("Центр")); // Открываем окно setVisible(true); >public static void main(String[] args) < new BorderLayoutTest(); >>
В примере метод установки менеджера расположения setLayout() не вызывался. В окнах JFrame (также в окнах JWindow и JDialog) расположение BorderLayout применяется автоматически c принимаемой по умолчанию константой Center. При использовании строк в качестве параметров метода add() надо быть внимательным. Со строкой легко сделать трудно обнаруживаемую ошибку, в то время как ошибку при использовании констант сразу же обнаружит компилятор.
Интерфейс примера BorderLayout представлен на следующем скриншоте.
Возможности полярного расположения довольно ограничены. Оно создано специально для окон, но иногда может помочь и в более сложных случаях.
Последовательное расположение FlowLayout
Менеджер последовательного расположение FlowLayout размещает компоненты в контейнере слева направо, сверху вниз. При полном заполнении компонентами строки контейнера FlowLayout переходит на следующую строку вниз. Данное расположение устанавливается по умолчанию в панелях JPanel. Основным свойством FlowLayout является определение предпочтительного размера компонентов. Например, размер метки с текстом JLabel соответствует размеру текста. Рассмотрим простой пример FlowLayout :
// Пример последовательного расположения компонентов - FlowLayout import java.awt.*; import javax.swing.*; public class FlowLayoutTest extends JFrame < public FlowLayoutTest() < super("FlowLayout"); setDefaultCloseOperation( EXIT_ON_CLOSE ); setSize(300, 120); // Панель содержимого Container container = getContentPane(); /* * Определение последовательного расположения * с выравниванием компонентов по центру */ container.setLayout (new FlowLayout(FlowLayout.CENTER)); // добавляем компоненты container.add( new JButton("Школа" )); container.add( new JButton("Институт")); container.add( new JButton("Академия")); // Открываем окно setVisible(true); >public static void main(String[] args) < new FlowLayoutTest(); >>
Конструктор класса FlowLayout имеет три перегруженные версии: без параметров, с параметрами выравнивания компонентов, с параметрами выравнивания компонентов и расстояний между ними. В примере использована вторая версия, устанавливающая последовательное расположение по центру.
На следующем скриншоте показан интерфейс программы для двух разных размеров окна по горизонтали.
На правом скриншоте размер окна не позволил менеджеру FlowLayout разместить компоненты в одной строке, и один компонент сместился в следующую строку.
При последовательном расположении менеджер FlowLayout всегда сохраняет предпочтительный размер компонентов. Если места в контейнере становится мало, то FlowLayout просто прячет «лишние» компоненты, а не уменьшает их размеры.
Также к важным свойствам менеджера расположения FlowLayout следует отнести то, что при вызове метода preferredLayoutSize() или minimumLayoutSize(), позволяющего узнать предпочтительный и минимальный размеры контейнера, в котором этот менеджер действует, метод возвращает размер, соответствующий ситуации расположения всех компонентов в одну строку. Это особенно важно при совмещении последовательного расположения с другими вариантами расположения. Вследствие этого свойства менеджеры других вариантов расположения будут стараться найти достаточно места для размещения компонентов в одну строку.
Поэтому использовать последовательное расположение следует только в контейнере, где достаточно места, или там, где контейнеру некуда будет «прятать» свои компоненты. Пример совмещении последовательного расположения с табличным представлен на этой странице здесь. Тем не менее, этот простотой менеджер расположения FlowLayout очень хорош при организации несложных вариантов расположения.
Табличное расположение GridLayout
Менеджер расположения GridLayout представляет контейнер в виде таблицы с ячейками одинакового размера. Количество строк и столбцов можно указать в конструкторе. Имеется возможность задать произвольное количество либо строк, либо столбцов, но не одновременно. Все ячейки таблицы имеют одинаковый размер, равный размеру самого большого компонента, находящегося в таблице.
Пример табличного расположения компонентов — GridLayout :
// Пример табличного расположения компонентов - GridLayout import java.awt.*; import javax.swing.*; public class GridLayoutTest extends JFrame < public GridLayoutTest() < super("GridLayoutTest"); setSize(320, 320); setLocation(100, 100); setDefaultCloseOperation( EXIT_ON_CLOSE ); // Вспомогательная панель JPanel grid = new JPanel(); /* * Первые два параметра конструктора GridLayout определяют количество * строк и столбцов в таблице. Вторые 2 параметра - расстояние между * ячейками по горизонтали и вертикали */ GridLayout layout = new GridLayout(2, 0, 5, 12); grid.setLayout(layout); // Создаем 8 кнопок for (int i = 0; i < 8; i++) < grid.add(new JButton("Кнопка " + i)); >// Размещаем нашу панель в панели содержимого getContentPane().add(grid); // Устанавливаем оптимальный размер окна pack(); // Открываем окно setVisible(true); > public static void main(String[] args) < new GridLayoutTest(); >>
В примере задается произвольное количество столбцов. Для этого в конструкторе вместо конкретного числа столбцов указывается ноль. Аналогично можно задать и произвольное количество строк в таблице.
Интерфейс работы программы представлен на следующем скриншоте.
Если произвольно увеличить размер окна, то менеджер расположения GridLayout также занимает все место, доступное в данный момент в окне, и пропорционально увеличивает размеры компонентов. Если уменьшить окно, то GridLayout также пропорционально уменьшит размеры компонентов. Основные свойства менеджера табличного расположения :
- Все компоненты имеют одинаковый размер. Доступное пространство контейнера с табличным расположением разбивается на одинаковое количество ячеек, в каждую из которых помещается компонент.
- Все компоненты всегда выводятся на экран вне зависимости от размеров окна.
Чаще всего совмещают панели с различными менеджерами расположения для получения необходимого интерфейса окна. В следующем примере совмещаем менеджер табличного расположения компонентов GridLayout с менеджером последовательного расположения FlowLayout, которое никогда не делает содержащиеся в нем компоненты больше их предпочтительного размера. Для этого создадим элемент пользовательского интерфейса, встречающийся практически в любом диалоговом окне, а именно строку кнопок (кнопки ОК и Отмена). Табличное расположение придаст кнопкам одинаковый размер, а последовательное расположение не даст им «расплыться» и заодно выровняет их по правому краю.
Пример совмещения табличного GridLayout и последовательного FlowLayout расположения компонентов
// Пример использования совмещенного табличного GridLayout и // последовательного FlowLayout расположения компонентов. import java.awt.*; import javax.swing.*; public class ManagerLayoutsTest extends JFrame < public ManagerLayoutsTest() < super("ManagerLayoutsTest"); setSize(320, 240); setLocation(100, 100); setDefaultCloseOperation( EXIT_ON_CLOSE ); // Создание панели с табличным расположением JPanel grid = new JPanel(new GridLayout(1, 2, 5, 0) ); // Добавление кнопок в панель grid.add (new JButton("OK" )); grid.add (new JButton("Отмена")); // Создание панели с последовательным расположением // компонентов и выравниванием по правому краю JPanel flow = new JPanel(new FlowLayout(FlowLayout.RIGHT)); flow.add(grid); // Получение панели содержимого Container container = getContentPane(); // Размещение панели с кнопками внизу справа container.add(flow, BorderLayout.SOUTH); // Открытие окна setVisible(true); >public static void main(String[] args)
В данном примере как бы не изменять размер окна полярное расположение заставит панель с кнопками разместиться вдоль нижней границы окна, а последовательное расположение заставит их прижаться к правому краю. Интерфейс работы программы представлен на следующем скриншоте.
Менеджер расположения GridBagLayout
Менеджер расположения GridBagLayout подобно табличному менеджеру устанавливает компоненты в таблицу. Но он дает возможность определять для компонентов разную ширину и высоту колонок и строк таблицы. Фактически GridBagLayout позволяет получить абсолютно любое расположение компонентов.
Пример менеджера расположения GridBagLayout
// Пример использования менеджера расположения GridBagLayoutTest import java.awt.*; import javax.swing.JButton; import javax.swing.JFrame; public class GridBagLayoutTest < /** * Метод определения интерфейса панели * @param container */ public static void createPanelUI(Container container) < JButton button; container.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); container.setLayout(new GridBagLayout()); GridBagConstraints constraints = new GridBagConstraints(); // По умолчанию натуральная высота, максимальная ширина constraints.fill = GridBagConstraints.HORIZONTAL; constraints.weightx = 0.5; constraints.gridy = 0 ; // нулевая ячейка таблицы по вертикали button = new JButton("Школа"); constraints.gridx = 0; // нулевая ячейка таблицы по горизонтали container.add(button, constraints); button = new JButton("Институт"); constraints.gridx = 1; // первая ячейка таблицы по горизонтали container.add(button, constraints); button = new JButton("Академия"); constraints.gridx = 2; // вторая ячейка таблицы по горизонтали container.add(button, constraints); button = new JButton("Высокая кнопка размером в 2 ячейки"); constraints.ipady = 45; // кнопка высокая constraints.weightx = 0.0; constraints.gridwidth = 2; // размер кнопки в две ячейки constraints.gridx = 0; // нулевая ячейка по горизонтали constraints.gridy = 1; // первая ячейка по вертикали container.add(button, constraints); button = new JButton("Семья"); constraints.ipady = 0; // установить первоначальный размер кнопки constraints.weighty = 1.0; // установить отступ // установить кнопку в конец окна constraints.anchor = GridBagConstraints.PAGE_END; constraints.insets = new Insets(5, 0, 0, 0); // граница ячейки по Y constraints.gridwidth = 2; // размер кнопки в 2 ячейки constraints.gridx = 1; // первая ячейка таблицы по горизонтали constraints.gridy = 2; // вторая ячейка по вертикали container.add(button, constraints); >public static void main(String[] args) < // Создание окна JFrame frame = new JFrame("GridBagLayoutTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Определить панель содержания createPanelUI(frame.getContentPane()); // Показать окно frame.pack(); frame.setVisible(true); >>
При использовании менеджера расположения GridBagLayout необходимо настраивать класс GridBagConstraints для каждого добавляемого компонента. Это существенно усложняет процесс разработки. Поэтому GridBagLayout используется большей частью при автоматизированной разработке интерфейса, при которой мышью указывается расположение компонентов, а система требуемым образом настраивает менеджер GridBagLayout.
Пользовательский интерфейс примера GridBagLayout представлен на следующих скриншотах. На нижнем скриншоте представлен интерфейс для уменьшенного размера окна.
Менеджер расположения CardLayout
Менеджер CardLayout можно использовать для создания так называемых вкладок (tabs), выбирая которые будут избранно открываться разные панели, занимающие одно и то же место в интерфейсе окна. В библиотеке Swing данную задачу можно решить с использованием класса JTabbedPane, организовывающего управление панелями с вкладками.
Пример менеджера расположения CardLayout
// Пример использования менеджера расположения CardLayoutTest import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CardLayoutTest implements ItemListener < private static JPanel cards; final static String BUTTONPANEL = "Панель с кнопками" ; final static String TEXTPANEL = "Панель с текстовым полем"; /** * Метод определения интерфейса панели * @param container - панель содержимого */ public void createPanelUI(Container container) < // Создание компонента с выпадающим списком JComboBoxcombobox = new JComboBox( new String[] ); combobox.setEditable (false); combobox.addItemListener(this ); // Помещаем JComboBox в JPanel для наглядности. JPanel cbPanel = new JPanel(); cbPanel.add(combobox); // Создание "cards". JPanel card1 = new JPanel(); card1.add(new JButton("Продукты")); card1.add(new JButton("Одежда" )); card1.add(new JButton("Обувь" )); JPanel card2 = new JPanel(); card2.add(new JTextField("TextField", 15)); // Создаем панель с менеджером расположения CardLayout cards = new JPanel(new CardLayout()); // Добавляем вкладки cards.add(card1, BUTTONPANEL); cards.add(card2, TEXTPANEL); container.add(cbPanel, BorderLayout.PAGE_START); container.add(cards , BorderLayout.CENTER ); > // Обработчик события public void itemStateChanged(ItemEvent event) < CardLayout layout = (CardLayout)(cards.getLayout()); layout.show(cards, (String)event.getItem()); >public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException < // Создание и настройка окна final JFrame frame = new JFrame("CardLayoutTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); javax.swing.SwingUtilities.invokeLater(new Runnable() < public void run() < (new CardLayoutTest()).createPanelUI(frame.getContentPane()); // Открытие окна frame.pack(); frame.setVisible(true); >>); > >
Пользовательский интерфейс примера менеджера расположения CardLayout представлен на следующих скриншотах. На верхних скриншотах представлен интерфейс окна для разных размеров. На нижнем скриншоте представлен интерфейс окна для вкладки с тестовым полем.
Менеджер расположения BoxLayout
Менеджер расположения BoxLayout позволяет управлять размещением компонентов либо в вертикальном, либо в горизонтальном направлениях и управлять пространством между компонентами, используя вставки. Для размещения компонентов в вертикальной плоскости необходимо конструктору передать константу BoxLayout.Y_AXIS, для размещения в горизонтальной — BoxLayout.X_AXIS.
Пример менеджера расположения BoxLayout
// Пример использования менеджера расположения BoxLayout import java.awt.Component; import java.awt.Container; import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.BoxLayout; public class BoxLayoutTest < /** * Процедура добавления кнопки в контейнер * @param caption заголовок кнопки * @param container контейнер */ private static void addButton(String caption, Container container) < JButton button = new JButton(caption); button.setAlignmentX(Component.CENTER_ALIGNMENT); container.add(button); >/** * Процедура создания интерфейса формы * @param container контейнер */ public static void createUI(Container container) < container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS)); addButton("Хлеб" , container); addButton("Молоко" , container); addButton("Колбасы" , container); addButton("Мясо и птица", container); addButton("Мороженные продукты", container); >public static void main(String[ ] args) < // Создание окна final JFrame frame = new JFrame("BoxLayoutTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Определение интерфейса окна createUI(frame.getContentPane()); javax.swing.SwingUtilities.invokeLater(new Runnable() < public void run() < // Открытие окна frame.pack(); frame.setVisible(true); >>); > >
Пользовательский интерфейс примера менеджера расположения BoxLayout представлен на следующих скриншотах. На верхнем скриншоте представлен интерфейс окна с вертикальным расположением компонентов. На нижнем скриншоте компоненты размещены в горизонтальной плоскости.
Менеджер расположения GroupLayout
Менеджер расположения компонентов GroupLayout появился только в Java 6. Он раскладывает компоненты по группам. Группы имеют горизонтальное и вертикальное направление и могут быть параллельными и последовательными. В последовательной группе у каждого следующего компонента координата вдоль оси на единицу больше (имеется в виду координата в сетке), в параллельной – компоненты имеют одну и ту же координату.
Пример менеджера расположения GroupLayout
// Пример использования менеджера расположения GroupLayout import javax.swing.*; import static javax.swing.GroupLayout.Alignment.*; public class GroupLayoutTest extends JFrame < public GroupLayoutTest() < setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // Список компонентов формы JLabel label = new JLabel("Поиск строки :"); JTextField textField = new JTextField(); JCheckBox cbCaseSensitive = new JCheckBox("Учет регистра"); JCheckBox cbWholeWords = new JCheckBox("Целое слово" ); JCheckBox cbBackward = new JCheckBox("Поиск назад" ); JButton btnFind = new JButton("Найти" ); JButton btnCancel = new JButton("Отменить"); cbCaseSensitive.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); cbWholeWords .setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); cbBackward .setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); // Определение менеджера расположения GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); // Создание горизонтальной группы layout.setHorizontalGroup(layout.createSequentialGroup() .addComponent(label) .addGroup(layout.createParallelGroup(LEADING) .addComponent(textField) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(LEADING) .addComponent(cbCaseSensitive) .addComponent(cbBackward)) .addGroup(layout.createParallelGroup(LEADING) .addComponent(cbWholeWords)))) .addGroup(layout.createParallelGroup(LEADING) .addComponent(btnFind) .addComponent(btnCancel)) ); layout.linkSize(SwingConstants.HORIZONTAL, btnFind, btnCancel); // Создание вертикальной группы layout.setVerticalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(BASELINE) .addComponent(label) .addComponent(textField) .addComponent(btnFind)) .addGroup(layout.createParallelGroup(LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(BASELINE) .addComponent(cbCaseSensitive) .addComponent(cbWholeWords)) .addGroup(layout.createParallelGroup(BASELINE) .addComponent(cbBackward))) .addComponent(btnCancel)) ); setTitle("Поиск"); pack(); >public static void main(String args[]) < java.awt.EventQueue.invokeLater(new Runnable() < public void run() < JFrame.setDefaultLookAndFeelDecorated(true); new GroupLayoutTest().setVisible(true); >>); > >
Интерфейс окна примера менеджера расположения GroupLayout представлен на следующем скриншоте.
Менеджер расположения SpringLayout
Несмотря на универсальность менеджера расположения SpringLayout, действие его весьма специфично и не похоже на действие ни одного из уже рассмотренных выше менеджеров расположения.
С каждым компонентом ассоциируется особый информационный объект SpringLayout, который позволяет задать расстояние (в пикселах) между парой границ различных компонентов. Границ у компонента четыре — это его северная, восточная, западная и южная стороны. Можно задавать расстояние и между границами одного и того же компонента: к примеру, задав расстояние между северной и южной сторонами одного компонента, вы укажете его высоту. По умолчанию все компоненты имеют предпочтительный размер, однако SpringLayout учитывает и два остальных размера, не делая компоненты меньше минимального и больше максимального размеров.
На первом этапе работы менеджера SpringLayout все компоненты находятся в начале координат контейнера и имеют предпочтительный размер. Чтобы разместить их по нужным позициям, обычно проводят следующие действия: первый компонент отделяют некоторым расстоянием от границы контейнера, второй отделяют от первого расстоянием между нужными границами, далее размещают третий компонент и т.д.
Пример менеджера расположения SpringLayout
// Пример использования менеджера расположения SpringLayout import java.awt.Component; import java.awt.Container; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; import javax.swing.SpringLayout; public class SpringLayoutTest < public static void main(String args[]) < JFrame frame = new JFrame("SpringLayoutTest"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container contentPane = frame.getContentPane(); SpringLayout layout = new SpringLayout(); contentPane.setLayout(layout); Component label = new JLabel("Метка"); Component field = new JTextField(15); contentPane.add(label); contentPane.add(field); layout.putConstraint(SpringLayout.WEST , label, 10, SpringLayout.WEST , contentPane); layout.putConstraint(SpringLayout.NORTH, label, 25, SpringLayout.NORTH, contentPane); layout.putConstraint(SpringLayout.NORTH, field, 25, SpringLayout.NORTH, contentPane); layout.putConstraint(SpringLayout.WEST , field, 20, SpringLayout.EAST , label ); frame.setSize(300, 110); frame.setVisible(true); >>
Интерфейс окна примера менеджера расположения SpringLayout представлен на следующем скриншоте.
Интерфейс диалогового окна авторизации
Интерфейс примера диалогового окна авторизации LoginDialog представлен на следующем скриншоте.
Исходный код примера LoginDialog в виду его большого размера не приводится. Но его можно скачать вместе с остальными примерами.
Какой менеджер компоновок позволяет разместить компоненты в таблице с ячейками равного размера
ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ JAVA
А. А. ЕВДОКИМОВ, Н. В. МАЙСТРЕНКО
Введение Лабораторная работа №1 Лабораторная работа №2 Лабораторная работа №3 Лабораторная работа №4 Лабораторная работа №5 Лабораторная работа №6 Тест Список литературы Сведения о пособии
Язык программирования высокого уровня Java относится к объектно-ориентированным языкам. На него оказали влияние такие языки программирования как C++ и Smaltalk. Популярность язык Java получил благодаря идеям, которые реализовали его разработчики и заключающимся в возможностях кроссплатформенного исполнения программ, встроенных механизмов для работы в компьютерных сетях и создания многопоточных приложений, а также полной поддержки всех концепций объектно-ориентированной парадигмы программирования.
Реализация кроссплатформенности заключается в формировании из исходного кода программы специального байт-кода, который может выполняться только виртуальной машиной Java (Java Virtual Machine, JVM), установленной на конкретной платформе. Таким образом, приложения Java, представленные файлами на байт-коде (*.class), могут исполняться на любом оборудовании и любой операционной системой, в которой есть среда исполнения JVM. Виртуальная машина Java в данной схеме служит в качестве интерпретатора. В современных JVM реализована JIT-компиляция, которая увеличивает производительность приложений за счет динамической компиляции часто исполняемых фрагментов байт-кода в машинный код.
Поддержка сетевых технологий также способствовало развитию Java. Первые версии языка давали возможность писать апплеты – клиентские приложения, которые выполнялись в интернет-браузерах. Для серверов язык Java используется напрямую через CGI (Common Gateway Interface), в виде сервлетов – приложений Java, выполняющихся в отдельной среде (контейнере сервлетов), и сценариев JSP (Java Server Pages). Java поддерживает также работу с большинством современных СУБД через унифицированный доступ с помощью стандартов JDBC (Java Database Connectivity) и SQLJ.
В Java реализована встроенная поддержка построения многопоточных программ. Во время выполнения приложений JVM использует автоматическое управление памятью, что значительно упрощает разработку программ. В языке присутствует набор стандартных контейнеров, реализованный в Java Collections Framework. Java реализует поддержку функционального программирования с помощью лямбда-выражений (функциональных интерфейсов) и замыканий, а также предлагает широкий набор классов для работы с потоками ввода/вывода.
В настоящее время Java активно используется для разработки мобильных приложений, выполняющихся в операционной системе Android, что продолжает способствовать популярности языка. Android-приложения на Java выполняются виртуальными машинами Dalvik и ART. Несмотря на особенности разработки мобильных приложений (работа на автономных системах, ресурсозависимость и т.д.), программисты могут использовать все возможности языка Java.
« Назад Вперед »
ЛАБОРАТОРНАЯ РАБОТА №1
Создание приложения Java на основе класса JFrame
Цель работы: Освоить основные элементы проектирования оконных приложений Java. Изучить особенности создания и запуска оконных приложений. Ознакомиться с архитектурой класса JFrame.
Методические указания к выполнению лабораторной работы
Разработка приложений с графическим пользовательским интерфейсом (Graphical User Interface, GUI) в Java построена на использовании библиотеки классов Swing (javax.swing), являющейся альтернативой и основанной на базовой подсистеме GUI Abstract Window Toolkit (AWT).
Классы Swing были разработаны с целью снять некоторые ограничения AWT, связанные с зависимостью внешнего вида (а в некоторых случаях и поведения) визуальных компонентов от платформы, на которой запускается приложение. Базовый набор элементов управления, окон и диалогов AWT использовал на каждой платформе нативный («родной») набор ресурсов. Это приводило к разному внешнему виду одного и того же приложения на разных платформах, фиксированному внешнему виду каждого конкретного компонента, невозможности управлять дополнительными характеристиками отображения, такими как прозрачность и форма. Такое поведение AWT не поддерживало основную идею разработчиков Java, заключенную в тезисе «write once, run everywhere». Компоненты AWT также называют тяжеловесными компонентами, так как они используют «родные» ресурсы кода платформы. За некоторыми исключениями, компоненты Swing являются облегченными (легковесными), так как написаны целиком на Java. Внешний вид каждого компонента определяется классами Swing, а не базовой операционной системой. Таким образом, каждый компонент будет выглядеть и функционировать одинаково на всех платформах.
Кроме того Swing поддерживает принцип подключаемого внешнего вида, когда тот отделен от поведения компонента. Преимуществом данного подхода является легкость изменения способа визуализации каждого компонента без затрагивания логики его работы. Такой подход также позволяет заранее определить целые наборы различных способов визуализации, которые задают разные стили GUI. Преимуществами подключаемого внешнего вида является возможность создать специальные стили для конкретных платформ, стили, одинаковые для всех платформ, а также динамически изменять стиль компонентов приложения во время его работы.
В основе графического пользовательского интерфейса с использованием классов Swing находятся два набора ключевых элементов: компоненты и контейнеры. Компонент представляет собой отдельный визуальный элемент управления, например, текстовое поле или кнопка. Контейнер в свою очередь является особым типом компонента и предназначен для объединения и содержания других компонентов. Более того, для отображения компонента необходимым условием является его нахождения внутри конкретного контейнера. В любом приложении Java, построенном на классах Swing, есть как минимум один контейнер. Так как контейнеры также являются и компонентами, то любой контейнер может содержать другие контейнеры. И для построения сложных приложений определяется иерархия вместимости, в которой выделяются контейнеры верхнего уровня.
В Swing определены два типа контейнеров: контейнеры верхнего уровня и облегченные контейнеры.
К контейнерам верхнего уровня относятся JFrame, JApplet, JWindow и JDialog. Эти классы контейнеров не являются производными от класса JComponent. Базовыми для них классами являются AWT-классы Component и Container, поэтому контейнеры верхнего уровня являются тяжеловесными компонентами (единственные в библиотеке Swing). Контейнеры верхнего уровня также называют окнами, которые являются основой пользовательского интерфейса любой операционной системы. Окна визуально разделяют выполняемые в среде приложения. Так как контейнеры верхнего уровня являются тяжеловесными, их внешний вид будет зависеть от конкретной операционной системы. Контейнер верхнего уровня не может находиться ни в каком другом контейнере. Каждая иерархия вместимости для любого приложения с GUI должна начинаться с контейнера верхнего уровня.
Родителем всех окон Swing является окно без рамки и без элементов управления JWindow. Класс JWindow определяет базовые возможности оконных приложений, например, закрытие или перемещение. Окно JFrame наследует свойства класса JWindow и является самым часто используемым контейнером верхнего уровня. У JFrame в отличие от JWindow есть рамка, которая позволяет изменять размер окна, заголовок с названием приложения (может быть пустым), кнопки управления для закрытия и свертывания окна. В окне JFrame также есть возможность использовать системное меню, позволяющее выполнять стандартные действия над окном и приложением.
Например, простое оконное приложение Java на основе класса JFrame с компонентом JButton:
import javax.swing.*; public class SimpleJFrame extends JFrame < private javax.swing.JButton jButton1; public SimpleJFrame() < initComponents(); >private void initComponents() < jButton1 = new JButton(); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jButton1.setText("This is Button"); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(68, 68, 68) .addComponent(jButton1) .addContainerGap(58, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(45, 45, 45) .addComponent(jButton1) .addContainerGap(46, Short.MAX_VALUE)) ); pack(); >public static void main(String args[]) < java.awt.EventQueue.invokeLater(new Runnable() < public void run() < new SimpleJFrame().setVisible(true); >>); > >
Вторым типом контейнеров в Swing являются облегченные контейнеры. Они являются производными от JComponent. Примером легковесного контейнера является JPanel. Облегченные контейнеры часто используют для объединения компонентов в группы по структурному или функциональному признаку, упрощая управление таких компонентов.
Каждый контейнер верхнего уровня включает в себя набор панелей (pane). Панель JRootPane представляет собой легковесный контейнер, который находится вверху иерархии вместимости панелей и предназначен для управления остальными панелями. JRootPane может управлять также линейкой меню приложения. Панели, которые содержатся в корневой панели, называются «стеклянной» панелью (glass pane), панелью содержимого (content pane) и многослойной панелью (layered pane).
Многослойная панель является экземпляром JLayeredPane. Многослойная панель предназначена для управления глубиной расположения компонентов. Значение, соответствующее этой глубине, определяет, какой компонент перекрывает собой другой компонент. Многослойная панель содержит панель содержимого и линейку меню приложения. Панель содержимого предназначена для размещения визуальных компонентов приложения и по умолчанию является непрозрачным экземпляром JPanel. Любой компонент, который добавляется в контейнер верхнего уровня, попадает в панель содержимого. «Стеклянная» панель находится над всеми остальными панелями и по умолчанию является прозрачным экземпляром JPanel. Она может перехватывать и управлять событиями мыши или рисовать поверх любого другого компонента.
Каким образом в панели содержимого будут располагаться компоненты, определяет менеджер расположения или компоновщик (layout manager). Независимо от операционной системы, версии виртуальной машины Java, разрешения и размеров экрана менеджер расположения гарантирует, что компоненты будут иметь предпочтительный или близкий к нему размер и располагаться в том порядке, который был указан разработчиком при создании программы.
Поддержка компоновщиков определена в базовом классе контейнеров java.awt.Container. Все Swing-компоненты являются производными классами от класса JComponent, для которого базовым является класс Container. Таким образом, для любого компонента Swing можно определить, какой менеджер размещения используется им в данный момент или установить нужный менеджер. Для этого используются методы getLayout() и setLayout().
Основными менеджерами расположения являются BorderLayout, FlowLayout, GridLayout, BoxLayout, CardLayout и GroupLayout.
BorderLayout – менеджер для полярного расположения. Предназначен для обычных и диалоговых окон. Данный компоновщик позволяет просто и быстро разместить наиболее часто используемые элементы любого окна: панель инструментов, строку состояния и основное содержимое. Для этого BorderLayout разбивает окно на четыре области, а все оставшееся место заполняется компонентом, выполняющим основную функцию приложения. Чтобы добавить с помощью менеджера расположения BorderLayout компонент, в его методе add() необходимо использовать дополнительный параметр, который определяет область контейнера для размещения компонента. Значениями этого параметра могут быть:
- BorderLayout.NORTH – в этом случае компонент располагается вдоль верхней границы окна и растягивается на всю его ширину. Обычно в этом месте размещается панель инструментов;
- BorderLayout.SOUTH – компонент располагается вдоль нижней границы и растягивается на всю ширину окна. Такое положение характерно для строки состояния;
- BorderLayout.WEST – компонент располагается вдоль левой границы окна и растягивается на всю его высоту. При этом учитываются размеры северных и южных компонентов, имеющих приоритет;
- BorderLayout.EAST – компонент располагается вдоль правой границы окна;
- BorderLayout.CENTER – компонент помещается в центр окна, занимая максимально возможное пространство.
FlowLayout – менеджер для последовательного расположения. Он размещает компоненты в контейнере слева направо, сверху вниз. При полном заполнении компонентами строки контейнера FlowLayout переходит на следующую строку вниз. Данное расположение устанавливается по умолчанию в панелях JPanel. Основным свойством FlowLayout является определение предпочтительного размера компонентов.
GridLayout – менеджер для табличного расположения. Он представляет контейнер в виде таблицы с ячейками одинакового размера. Количество строк и столбцов можно указать в конструкторе. Имеется возможность задать произвольное количество либо строк, либо столбцов, но не одновременно. Все ячейки таблицы имеют одинаковый размер, равный размеру самого большого компонента, находящегося в таблице.
Менеджер расположения BoxLayout позволяет управлять размещением компонентов либо в вертикальном, либо в горизонтальном направлениях и управлять пространством между компонентами, используя вставки. Для размещения компонентов в вертикальной плоскости необходимо конструктору передать константу BoxLayout.Y_AXIS, для размещения в горизонтальной – BoxLayout.X_AXIS.
Менеджер расположения CardLayout можно использовать для создания вкладок (tabs), выбирая которые будут избранно открываться разные панели, занимающие одно и то же место в интерфейсе окна. В библиотеке Swing данную задачу можно решить с использованием класса JTabbedPane, организовывающего управление панелями с вкладками.
Менеджер расположения компонентов GroupLayout раскладывает компоненты по группам. Группы имеют горизонтальное и вертикальное направление и могут быть параллельными и последовательными. В последовательной группе у каждого следующего компонента координата вдоль оси на единицу больше (имеется в виду координата в сетке), в параллельной – компоненты имеют одну и ту же координату.
1. Какие проблемы ограничений базовой библиотеки AWT были решены в библиотеке Swing?
2. В чем заключается принцип подключаемого внешнего вида?
3. Для чего предназначены контейнеры библиотеки Swing?
4. Перечислите контейнеры верхнего уровня библиотеки Swing.
5. Что инкапсулирует класс JFrame?
6. Для чего используются легковесные контейнеры библиотеки Swing?
7. Перечислите базовый набор панелей приложения, указывая их назначение.
8. Для чего используется менеджеры расположения?
9. Как управляет расположением компонентов BorderLayout?
10. Как управляет расположением компонентов FlowLayout?
Видео для подготовки
Тег video не поддерживается вашим браузером. Скачайте видео.
Исходные коды проекта из видео:
« Назад Вперед »
ЛАБОРАТОРНАЯ РАБОТА №2
Решение простых вычислительных задач на Java. Компоненты пользовательского интерфейса Swing. Формирование и компоновка GUI. Делегирование обработки событий
Цель работы: Изучить основные компоненты набора классов Swing. Исследовать возможности среды разработки по формированию и компоновке графического интерфейса пользователя. Изучить принцип делегирования обработки событий, наборы обработчиков для компонентов пользовательского интерфейса.
Методические указания к выполнению лабораторной работы
В общем случае компоненты из библиотеки Swing происходят от класса JComponent, который предлагает функциональные возможности, общие для всех компонентов. Например, JComponent поддерживает подключаемый внешний вид. JComponent наследует AWT-классы Container и Component, следовательно, основан на компоненте AWT и совместим с ним. Все компоненты Swing представлены классами, определенными в пакете javax.swing и начинаются с буквы «J».
Основными классами элементов управления Swing являются JLabel, JButton, JToggleButton, JCheckBox, JRadioButton, JComboBox, JList, JTextField, JPasswordField, JFormattedTextField, JTextArea, JScrollBar, JSlider, JProgressBar, JSpinner, JSeparator, JEditorPane, JTextPane и JTree.
JLabel – используется для вывода статического текста (метки). Возможен вывод текста с изображением (иконкой) и применение html-разметки для форматированного вывода.
JButton – используется для взаимодействия с пользователем, представляет собой кнопку (прямоугольник с текстом и/или изображением). Обычно для кнопки регистрируется слушатель события действия (нажатие кнопки).
JToggleButton – представляет собой кнопку, которая может находиться и в обычном состоянии, и в нажатом. Состояние кнопки при этом фиксируется. Когда пользователь взаимодействует с такой кнопкой, она изменяет свое состояние на противоположное. Управление внешним видом компонента осуществляется так же, как и у JButton.
JCheckBox – представляет собой элемент для выбора (флажок). Класс JCheckBox является производным от JToggleButton, отличается от последнего только внешним видом: квадрат, в который можно поставить или убрать галочку. Функциональность наследуется от JToggleButton. JCheckBox обычно используется в меню настроек для множественного выбора из группы элементов.
JRadioButton – представляет собой элемент для выбора (переключатель). Класс JRadioButton также является наследником класса JToggleButton. Внешний вид элемента: круг, в который можно поставить или убрать точку. Однако в группе элементов JRadioButton он ведет себя как переключатель. Если пользователь выбирает конкретный элемент («устанавливает точку»), то с ранее выбранного элемента выбор снимается («убирается точка»). JRadioButton также используется в меню настроек, но для выбора одного элемента из группы элементов.
JComboBox – используется для выбора одного элемента из нескольких вариантов, представляет собой раскрывающийся список, который в нормальном состоянии отображает только один выбранный элемент. Остальные элементы появляются в специальном всплывающем окне при раскрытии списка. JComboBox допускает редактирование текущего элемента, то есть пользователь может не только выбрать определенный элемент, но и ввести свое собственное значение. Список JComboBox обладает возможностью поиска элементов с клавиатуры, что значительно упрощает работу с большими наборами.
JList – используется для отображения группы элементов (списка). В отличие от компонента JComboBox отображает одновременно сразу несколько элементов списка (весь список или его часть), кроме того пользователь может выбрать в списке также несколько элементов (если установлен соответствующий режим выделения).
JTextField – используется для ввода и редактирования однострочного текста. Для обработки текстовых данных, введенных пользователем, обычно используют слушатель события действия, который получает событие после нажатия пользователем клавиши Enter.
JPasswordField – представляет собой однострочный текстовый редактор. Работа с компонентом производится аналогично, как и с JTextField. Единственным отличием данного компонента от JTextField является то, что весь введенный в него текст заменяется специальными символами (звездочками или другими заданными символами). Обычно используется для ввода паролей.
JFormattedTextField – используется для форматированного ввода данных и представляет собой однострочный текстовый редактор. Используя средства форматирования данного компонента, можно установить текстовые поля для ввода дат, индексов, телефонов, адресов сайтов, электронной почты и т.д., то есть данных, для которых есть общепринятый формат. Такой компонент может облегчить работу разработчика по валидации полученных от пользователя исходных данных.
JTextArea – представляет собой многострочный текстовый редактор. Класс JTextArea является производным от JTextField и наследует все его методы, дополняя их методами для управления вводом нескольких строк. При вводе пользователь разделяет строки обычным способом, нажимая клавишу Enter на клавиатуре. Если текст формируется динамически в программе, то для разделения строк используется специальный управляющий символ «\n». JTextArea обычно помещается в панель (контейнер) с полосами прокрутки JScrollPane.
JScrollBar – представляет собой отдельную полосу прокрутки (ползунок, область его движения и управляющие движением ползунка кнопки). Используется дополнительно для некоторых компонентов, если нет возможности использовать JScrollPane.
JSlider – представляет собой элемент для изменения значения в заданном диапазоне. Внешний вид компонента: шкала значений заданного диапазона (числа, изображения «засечек» или другие пиктограммы) и ползунок. Для управления ползунком используется перетаскивание мышью или клик на шкале ползунка. Для работы ползунка используется информация о минимальном значении, максимальном значении, текущем значении и внутреннем диапазоне.
JProgressBar – представляет собой индикатор процесса (например, некоторого вычисления), который позволяет наглядно отображать его выполнение. Пользователь может оценить время исполнения некоторого процесса, прогнозировать его завершение и т.д. Внешний вид компонента: непрерывно меняющаяся (заполняющаяся) полоса со значением (в процентах), насколько выполнен процесс. В отличие от JSlider индикатор процесса JProgressBar использует лишь три значения: минимальное и максимальное значения задаются перед выполнением процесса, а текущее значение должно обновляться по мере выполнения процесса.
JSpinner – представляет собой счетчик, который позволяет изменять текущее значение путем нажатия на соответствующие кнопки (увеличения и уменьшения значения). Внешне компонент похож на список JComboBox с одним выбранным элементом списка, но нажатие не раскрывает список, а изменяет значение в области отображения. Данное свойство счетчика позволяет использовать неограниченное количество элементов. Для счетчика JSpinner можно узнать его текущее, предыдущее и следующее значения, а также сменить текущее значение новым. Для обработки события изменения значения счетчика используется слушатель ChangeListener.
JSeparator – представляет собой вертикальную или горизонтальную черту (разделитель). Используется для графического разделения различных по структуре или функциям областей программы (например, пунктов меню).
JEditorPane – представляет собой многострочный текстовый редактор с возможностью обработки и отображения форматированного текста. JEditorPane используется обычно для отображения текста в двух широко распространенных форматах: HTML и RTF, но потенциально может использоваться для отображения текста любого формата, с любыми элементами и любым оформлением.
JTextPane – представляет собой многострочный текстовый редактор. Класс JTextPane является производным от класса JEditorPane. Обладая всеми возможностями своего базового класса, JTextPane добавляет к нему стилевую разметку текста. Компонент JTextPane используется в приложениях, где необходим многофункциональный текстовый редактор, который позволяет установить шрифт и его размер, цвет символов, выравнивание текста и т.п., использовать различные стили для выделения заголовков, основного текста, сносок и элементов текста.
JTree – используется для графического отображения данных, связанных иерархической структурой. Для представления дерева данных используется списочная диаграмма с отображением дочерних узлов на заданном отступе от родительского элемента, связанных графически линиями. JTree используется обычно для представления части файловой системы, используемой приложением для своей работы.
Подход к обработке событий в Java основан на модели делегирования событий, определяющей стандартные и согласованные механизмы для гене-рации и обработки событий. При этом логика обработки события отделяется от логики пользовательского интерфейса, генерирующего эти события. Каждый элемент пользовательского интерфейса может «делегировать» обработку события отдельному фрагменту кода.
Концепция модели делегирования событий включает совместную работу трех объектов: источника, слушателя и события (рис.1).
Источник генерирует событие и посылает его одному или более слушателей. Слушатель ожидает до тех пор, пока не получит событие. Как только событие получено, слушатель обрабатывает его и возвращает управление.
Рис. 1. Модель делегирования событий
Под событием в данной модели понимается объект, инкапсулирующий изменение состояния источника. Событие генерируется в результате взаимодействия пользователя с элементом в графическом интерфейсе (например, клик на экранной кнопке, ввод символа с клавиатуры, выбор элемента в списке или клик кнопкой мыши).
Под источником в данной модели понимается объект, генерирующий событие. Генерация события происходит при изменении внутреннего состояния объекта. Источники могут генерировать более одного типа событий. Для обработки событий источник должен регистрировать слушателей. Каждый тип события имеет собственный метод регистрации. Общая форма регистрации слушателя:
public void add Type Listener( Type Listener el );
Где Type – это имя объекта события, el – ссылка на слушателя события. Например, addKeyListener() – регистрация слушателя событий клавиатуры, addMouseMotionListener() – регистрация слушателя движения мыши. Когда событие сгенерировано, все зарегистрированные слушатели получают копию объекта события. Это называется групповой рассылкой события.
Источник также может отменить регистрацию слушателя для определенного типа событий. Общая форма отмены регистрации слушателя:
public void remove Type Listener( Type Listener el );
Под слушателем понимается объект, уведомляемый о возникновении события и выполняющий определенный набор действий (обработку события). Слушатель должен быть зарегистрирован одним или более источниками событий, чтобы получать уведомления о событиях определенного рода. А также должен реализовать методы для получения и обработки данных событий.
Основные классы событий: MouseEvent, который генерируется при перетаскивании, перемещении, щелчках, нажатии и отпускании кнопок мыши, а также возникает, когда курсор мыши входит на компонент либо покидает его; KeyEvent, который генерируется при получении ввода с клавиатуры; ActionEvent, который генерируется при нажатии кнопки, двойном щелчке на элементе списка либо выборе пункта меню; ItemEvent, который генерируется при щелчке на флажке или элементе списка, при выборе элемента списка, отметке или снятии отметки пункта меню; MouseWheelEvent, который генерируется при прокрутке колесика мыши; TextEvent, который генерируется при изменении значения текстовой области или текстового поля; FocusEvent, который генерируется, когда компонент получает или теряет фокус клавиатурного ввода; WindowEvent, который генерируется при активизации либо закрытии окна, а также при деактивизации, свертывании, развертывании или выходе из него; ComponentEvent, который генерируется при сокрытии компонента, его перемещении, изменении его размера либо включении видимости; ContainerEvent, который генерируется при добавлении или исключении компонента из контейнера.
Основные интерфейсами слушателей являются MouseListener, KeyListener, ActionListener, ItemListener, MouseMotionListener, MouseWheelListener, TextListener, FocusListener, WindowFocusListener, WindowListener, ComponentListener и ContainerListener.
MouseListener содержит метод для обработки клика мыши (нажатия и отпускания кнопки мыши в одной и той же точке) mouseClicked(), метод для обработки события перехода мыши в область отображения компонента mouseEntered(), метод для обработки события перехода мыши из области отображения компонента mouseExited(), метод для обработки нажатия кнопки мыши mousePressed() и метод для обработки отпускания кнопки мыши mouseReleased(). Каждый метод этого слушателя принимает событие MouseEvent.
KeyListener содержит метод для обработки нажатия клавиши клавиатуры keyPressed(), метод для обработки отпускания клавиши клавиатуры keyReleased() и метод для обработки печати (ввода) символа (только для печатных символов) keyTyped(). Каждый метод данного слушателя принимает событие KeyEvent.
ActionListener содержит один метод для обработки события действия actionPerformed(), который принимает событие ActionEvent.
ItemListener содержит один метод для обработки события изменения состояния элемента itemStateChanged(), который принимает событие ItemEvent.
MouseMotionListener содержит метод для обработки перемещения курсора мыши mouseMoved() и метод для обработки перетаскивания курсора мыши mouseDragged(). Каждый метод этого слушателя принимает событие MouseEvent.
MouseWheelListener содержит один метод для обработки события прокрутки колесика мыши mouseWheelMoved(), который принимает событие MouseWheelEvent.
TextListener содержит один метод для обработки события изменения содержимого текстового поля или текстовой области textChanged(), который принимает событие ТехtEvent.
FocusListener содержит метод для обработки события получения компонентом фокуса клавиатурного ввода focusGained() и метод для обработки события потери компонентом фокуса клавиатурного ввода focusLost(). Каждый метод данного слушателя принимает событие FocusEvent.
WindowFocusListener содержит метод для обработки события получения окном фокуса ввода windowGainedFocus() и метод для обработки события потери окном фокуса ввода windowLostFocus(). Каждый метод данного слушателя принимает событие WindowEvent.
WindowListener содержит метод для обработки события активизации окна windowActivated(), метод для обработки события закрытия окна windowClosed(), метод для обработки события деактивизации окна windowDeactivated(), метод для обработки события разворачивания окна windowDeiconified(), метод для обработки события сворачивания окна в пиктограмму на панели задач операционной системы windowlconified(), метод для обработки события открытия окна windowOpened(). Каждый метод данного слушателя также принимает событие WindowEvent.
ComponentListener содержит метод для обработки события изменения размера компонента componentResized(), метод для обработки события перемещения компонента componentMoved(), метод для обработки события отображения компонента componentShown() и метод для обработки события сокрытия компонента componentHidden(). Каждый метод этого слушателя принимает событие ComponentEvent.
ContainerListener содержит метод для обработки события добавления компонента к контейнеру componentAdded() и метод для обработки события удаления компонента из контейнера componentRemoved(). Каждый метод данного слушателя принимает событие ContainerEvent.
Использование модели делегирования событий заключается в реализации соответствующего интерфейса в слушателе и его последующей регистрации источником как получателя уведомлений о событии. Так как источник может генерировать несколько типов событий, он может зарегистрировать отдельно для каждого собственного слушателя. К тому же слушатель может подписаться на получение нескольких типов событий и должен реализовать все интерфейсы, необходимые для получения этих событий.
1. Для чего предназначены компоненты библиотеки Swing?
2. Перечислите и опишите компоненты библиотеки Swing для управления текстовым вводом.
3. Укажите назначение и опишите компоненты библиотеки Swing JButton, JToggleButton и его наследников.
4. Перечислите и опишите компоненты библиотеки Swing для работы со списками элементов.
5. Укажите назначение и опишите компоненты библиотеки Swing JSlider, JProgressBar и JSpinner.
6. Опишите модель делегирования события Java, приведите схему, опишите назначение и роль объектов.
7. Как осуществляется регистрация слушателя события?
8. Перечислите основные классы событий Java.
9. Перечислите основные интерфейсы слушателей Java и их методы?
10. Перечислите этапы использования модели делегирования событий.
Видео для подготовки
Тег video не поддерживается вашим браузером. Скачайте видео.
Исходные коды проекта из видео:
« Назад Вперед »
ЛАБОРАТОРНАЯ РАБОТА №3
Работа с массивами данных. Компонент JTable
Цель работы: Изучить концепцию Model-View-Controller (MVC) на примере компонента пользовательского интерфейса JTable. Изучить свойства и методы компонента JTable. Исследовать возможности компонента JTable для работы с массивами данных.
Методические указания к выполнению лабораторной работы
В общем случае визуальный компонент определяется тремя отдельными аспектами: как компонент выглядит во время его визуализации на экране, как компонент взаимодействует с пользователем и информацией о состоянии компонента (текущем значении его свойств).
Независимо от того, какая архитектура используется для реализации компонента, она должна неявно включать эти три аспекта. Главной архитектурой в разработке компонентов с графическим интерфейсом остается архитектура «модель-представление-контроллер» (Model-View-Controller – MVC).
Успех архитектуры MVC объясняется тем, что каждый элемент дизайна соответствует некоторому аспекту компонента. Исходя из терминологии MVC, модель соответствует информации о состоянии, связанной с компонентом. Например, в случае флажка его модель содержит поле, которое показывает, отмечен ли флажок. Представление определяет, как компонент отображается на экране, включая любые аспекты представления, зависящие от текущего состояния модели. Контроллер определяет, как компонент будет реагировать на действия пользователя. Например, когда пользователь щелкает на флажке, контроллер реагирует изменением модели, чтобы отразить выбор пользователя (отметка флажка или снятие отметки). Это впоследствии приводит к обновлению представления. Разделяя компонент на модель, представление и контроллер, можно изменять конкретную реализацию любого из этих аспектов, не затрагивая остальные. Например, различные реализации представлений могут визуализировать один и тот же компонент разными способами, однако это не будет влиять на модель или контроллер.
Swing использует модифицированную версию MVC, которая объединяет представление и контроллер в один логический объект, называемый делегатом пользовательского интерфейса. В связи с этим подход, применяемый в Swing, называется или архитектурой «модель-делегат» (Model-Delegate), или архитектурой «разделяемая модель» (Separable Model).
Подключаемый внешний вид в Swing возможен благодаря архитектуре «модель-делегат». Поскольку представление и контроллер отделены от модели, внешний вид можно изменять, не влияя на способ использования компонента внутри программы. Для поддержания архитектуры «модель-делегат» большинство компонентов Swing содержат два объекта. Один из них представляет модель, а другой – делегата пользовательского интерфейса.
Компонент JTable позволяет отображать двухмерную информацию в виде таблицы (строк и столбцов), настраивать и сортировать данные, выводить их в любом подходящем виде, управлять заголовками таблицы и ее выделенными элементами.
JTable использует три модели, поставляющие ей данные и сохраняющие изменения при изменении этих данных. Первая и самая важная модель реализует интерфейс TableModel и хранит данные ячеек таблицы и дополнительную служебную информацию об этих ячейках. Вторая модель реализует интерфейс TableColumnModel и управляет столбцами таблицы. TableColumnModel позволяет добавлять, перемещать и находить столбцы, узнавать об изменениях в их расположении, с ее помощью можно изменить расстояние между столбцами и находящимися в них ячейками. Третья модель таблицы SelectionModel используется для выделения списка. Она управляет выделением строк таблицы и не затрагивает столбцы. Модель TableColumnModel имеет собственную модель выделения списка ListSelectionModel. Помимо моделей таблица JTable предоставляет еще несколько удобных механизмов выделения строк, столбцов и ячеек.
В модели данных таблицы можно хранить не только простые элементы, но и объекты. Для отображения в ячейке таблицы одного из атрибутов объекта используются специальные отображающие объекты, наследующие свойства DefaultTableCellRenderer. Отображающие объекты позволяет настраивать стиль и формат представления значения ячейки.
При работе с таблицами необязательно использовать модели. JTable включает конструкторы, в которые можно передать массивы или коллекции с информацией о ячейках таблицы и при необходимости о названиях ее столбцов. Для простых программ и незатейливых таблиц такой подход удобнее. Значение любой ячейки таблицы в этом случае можно получить с использованием метода getValueAt(), а изменить значение ячейки можно методом setValueAt().
Таблица JTable реализует интерфейс Scrollable и ее можно добавлять в панель прокрутки JScrollPane. При прокрутке полностью появляются следующий столбец или следующая строка таблицы. Заголовок таблицы, реализованный классом JTableHeader, будет виден только при помещении таблицы в панель прокрутки, поскольку таблица размещает компонент JTableHeader в виде заголовка панели прокрутки.
Модель данных таблицы TableModel позволяет подробно описать каждую ячейку таблицы JTable. Определенные в модели методы позволяют получить значение произвольной ячейки и изменить его, узнать о возможности редактирования ячейки, получить информацию о столбцах (количество, наименование, тип) и строках. Модель DefaultTableModel хранит переданные ей данные в двух векторах: в одном из векторов хранятся такие же векторы c данными строк, а во втором векторе хранятся названия столбцов таблицы. К недостаткам DefaultTableModel относят низкую производительность.
Модель столбцов таблицы TableColumnModel позволяет настраивать столбцы таблицы JTable: устанавливать размеры столбцов, менять их местами, настраивать объекты для отображения в столбце и для редактирования ячеек столбца, управлять заголовком столбца и т.д.
Таблица JTable отображает в интерфейсе порядок столбцов согласно параметрам, определенным в TableColumnModel. Каждый столбец таблицы представлен объектом TableColumn, c помощью которого указываются: размеры столбца (предпочтительный, максимальный и минимальный), индекс столбца, объекты для отображения и редактирования данных, хранящихся в столбце.
В JTable для хранения информации о столбцах по умолчанию используется стандартная модель DefaultTableColumnModel. Модель столбцов таб-лицы хранит список TableColumn и при смене какого-либо свойства столбца или его расположения оповещает об этом событии слушателей TableColumnModelListener.
Ячейки таблицы можно выделять разными способами: строками, столбцами, интервалами, единичными ячейками и т.д. Эту задачу решают модели выделения SelectionModel, которые хранят выделенные строки и столбцы таблицы. Следует отметить, что и для столбцов, и для строк таблицы имеются собственные модели выделения, представленные интерфейсом ListSelectionModel. Таким образом, таблица имеет две модели выделения. Первая модель хранится непосредственно в JTable и отвечает за выделение строк таблицы. Вторая модель отвечает за выделение столбцов таблицы и хранится в модели столбцов таблицы TableColumnModel.
По умолчанию в таблице и для строк, и для столбцов используется стандартная реализация интерфейса ListSelectionModel – класс DefaultListSelectionModel.
Например, приложение Java с JTable:
import javax.swing.*; import java.awt.event.*; public class TableMonth9 extends JFrame < private String holidays9[]; private JScrollPane jScrollPane1; private JScrollPane jScrollPane2; private JTable jTable1; private JTextPane jTextPane1; public TableMonth9() < initComponents(); holidays9 = new String[30]; holidays9[10] = "1 сентября.\nДень знаний.\n"; . holidays9[12] = "13 сентября.\nДень программиста.\n"; . >private void initComponents() < jScrollPane1 = new JScrollPane(); jTable1 = new JTable(); jScrollPane2 = new JScrollPane(); jTextPane1 = new JTextPane(); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE ); jTable1.setFont(new java.awt.Font("Consolas", 1, 24)); jTable1.setModel(new javax.swing.table.DefaultTableModel( new Object [][] < < null, null, null, null, null, new Integer(1), new Integer(2) >, < new Integer(3), new Integer(4), newInteger(5), new Integer(6), new Integer(7), new Integer(8), new Integer(9) >, < new Integer(10), new Integer(11), new Integer(12), new Integer(13), new Integer(14), new Integer(15), new Integer(16) >, < new Integer(17), new Integer(18), new Integer(19), new Integer(20), new Integer(21), new Integer(22), new Integer(23) >, < new Integer(24), new Integer(25), new Integer(26), new Integer(27), new Integer(28), new Integer(29), new Integer(30) >>, new String [] < "ПН", "ВТ", "СР", "ЧТ", "ПТ", "СБ", "ВС" >) < Class[] types = new Class [] < java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class, java.lang.Integer.class >; boolean[] canEdit = new boolean [] < false, false, false, false, false, true, false >; public Class getColumnClass(int columnIndex) < return types [columnIndex]; >public boolean isCellEditable(int rowIndex, int columnIndex) < return canEdit [columnIndex]; >>); jTable1.setIntercellSpacing(new java.awt.Dimension(2, 2)); jTable1.setOpaque(false); jTable1.setRowHeight(30); jTable1.setRowSelectionAllowed(false); jTable1.addMouseListener(new MouseAdapter() < public void mouseClicked(MouseEvent evt) < jTable1MouseClicked(evt); >>); jScrollPane1.setViewportView(jTable1); jScrollPane2.setViewportView(jTextPane1); . pack(); > private void jTable1MouseClicked(MouseEvent evt) < int i = jTable1.getSelectedRow(); int j = jTable1.getSelectedColumn(); Integer day = (Integer) jTable1.getValueAt(i, j); jTextPane1.setText(holidays9[day-1]); >public static void main(String args[]) < java.awt.EventQueue.invokeLater(() ->< new TableMonth9().setVisible(true); >); > >
1. Какими аспектами определяется компонент с графическим интерфейсом?
2. Из каких элементов состоит архитектура MVC?
3. Для чего предназначен контроллер в MVC?
4. Какие модифицированные версии MVC используются в библиотеке компонентов Swing.
5. Что инкапсулирует класс JTable?
6. Какая модель компонента JTable отвечает за управление данными в ячейках таблицы?
7. Какая модель компонента JTable управляет столбцами таблицы?
8. Какая модель компонента JTable отвечает за выделение элементов таблицы?
9. Где хранит данные модель DefaultTableModel?
10. Какие методы используются для получения доступа к ячейке таблицы?
Видео для подготовки
Тег video не поддерживается вашим браузером. Скачайте видео.
Исходные коды проекта из видео:
« Назад Вперед »
ЛАБОРАТОРНАЯ РАБОТА №4
Многопоточное программирование в Java. Синхронизация потоков в Java. Мониторы
Цель работы: Изучить особенности многопоточного программирования, методы и средства работы с потоками в Java. Исследовать средства синхронизации потоков в Java.
Методические указания к выполнению лабораторной работы
Процесс это совокупность кода и данных, разделяющих общее виртуальное адресное пространство. Чаще всего одна программа состоит из одного процесса.
При запуске программы операционная система создает процесс, загружая в его адресное пространство код и данные программы, а затем запускает главный поток созданного процесса. Один поток – это одна единица исполнения кода. Каждый поток последовательно выполняет инструкции процесса, которому он принадлежит, параллельно с другими потоками этого процесса. Операционная система (ОС) переключается между потоками, поочередно давая выполняться каждому потоку (псевдо-параллелизм). Перед переключением ОС запоминает состояние (контекст) каждого потока. В контекст потока входят такие параметры, как стек, набор значений регистров процессора, адрес исполняемой команды.
Каждый процесс имеет хотя бы один выполняющийся поток. Тот поток, с которого начинается выполнение программы, называется главным. В Java выполнение главного потока начинается с метода main().
Многопоточная система в Java построена на основе класса Thread и интерфейса Runnable. Класс Thread инкапсулирует поток исполнения. Чтобы создать новый поток, следует расширить класс Thread или реализовать интерфейс Runnable.
Поток можно создать из объекта любого класса, реализующего интерфейс Runnable. Для реализации интерфейса Runnable в классе должен быть объявлен единственный метод run(). В теле метода run() определяется код, который будет выполняться в отдельном потоке. После создания класса, реализующего интерфейс Runnable, в этом классе следует получить экземпляр класса Thread. Класс Thread содержит ряд конструкторов, использующих Runnable. Например: Thread(Runnable объект_потока), Thread(Runnable объект_потока, String имя_потока).
Поток можно создать также из любого класса наследованием класса Thread и переопределением его метода run(). Для создания потока из производного класса, можно воспользоваться, например, следующими конструкторами базового класса – Thread() или Thread(String имя_потока).
Запуск созданного потока осуществляется вызовом метода start(). Для управления потоком класс Thread также содержит методы: getName() для получения имени потока, setName() для задания имени потока, getPriority() для получения приоритета потока, setPriority() для задания приоритета потока, join() для ожидания завершения исполнения потока, isAlive() для определения состояния потока (выполняется ли данный поток), sleep() для приостановления выполнения потока на заданное время в миллисекундах.
Во время работы многопоточного приложения возможна ситуация, когда два или более потока имеют доступ к одному совместно используемому ресурсу. В таком случае работу потоков необходимо организовать таким способом, чтобы ресурс в один момент времени использовался только одним потоком. Синхронизация обеспечивает такую работу потоков.
В основе механизма синхронизации Java лежит понятие монитора. Монитор – это объект, используемый для взаимоисключающей блокировки потоков. Только один поток может в одно и то же время владеть монитором. Поток входит в монитор, когда запрашивает блокировку. Все остальные потоки, пытающиеся войти в заблокированный монитор, будут приостановлены до тех пор, пока первый поток не выйдет из монитора, то есть будут ожидать монитор.
Синхронизировать код можно двумя способами с использованием ключевого слова synchronized.
Первый способ основан на использовании синхронизированных методов. Метод, объявленный с модификатором synchronized, становится монитором. Когда поток оказывается в синхронизированном методе, все другие потоки, пытающиеся вызвать его для того же самого экземпляра, вынуждены ожидать.
Второй способ использует «синхронизированные» объекты. Для синхронизации доступа к методам объектов, не предназначенных для многопоточного доступа (не синхронизированных), применяют оператор synchronized:
Например, приложение для параллельного построения графиков функций с заданным шагом в одной области отображения (общий ресурс):
import java.awt.Color; import java.awt.Graphics; import javax.swing.*; class GraphP implements Runnable < private Graphics g; private Color cl; private String nameFunc; private int yP; GraphP(Graphics g, String f, Color cl) < yP = 0; this.g = g; nameFunc = f; this.cl = cl; new Thread(this).start(); >public void run() < for(int i = 0; i < 792; i++) < try < Thread.sleep(40+(new java.util.Random(42)).nextInt(5)); >catch (InterruptedException ex) <> yP = (nameFunc.equals("SIN"))?yPointSin(i):yPointCos(i); drawPoint(i, yP, cl); > > private void drawPoint(int x, int y, Color col) < synchronized(g) < g.setColor(col); g.fillOval(x, y, 4, 4); >> private int yPointSin(int x) < return 200+(int)Math.round(200*Math.sin(x*0.02)); >private int yPointCos(int x) < return 200+(int)Math.round(200*Math.cos(x*0.02)); >> public class GraphThreadUI extends JFrame < private java.awt.Canvas canvas1; public GraphThreadUI() < initComponents(); >private void initComponents() < canvas1 = new java.awt.Canvas(); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); canvas1.setBackground(new java.awt.Color(0, 0, 0)); canvas1.addKeyListener(new java.awt.event.KeyAdapter() < public void keyPressed(java.awt.event.KeyEvent evt) < canvas1KeyPressed(evt); >>); … pack(); > private void canvas1KeyPressed(java.awt.event.KeyEvent evt) < int key = evt.getKeyCode(); int x, y; if(key == evt.VK_SPACE) < Graphics g = canvas1.getGraphics(); g.setColor(Color.WHITE); GraphP gt1 = new GraphP(g,"SIN",new Color(124,124,124)); GraphP gt2 = new GraphP(g,"COS",Color.RED); >> public static void main(String args[]) < … java.awt.EventQueue.invokeLater(new Runnable() < public void run() < new GraphThreadUI().setVisible(true); >>); > >
1. Объясните понятия процесса и потока.
2. Что включает в себя контекст потока?
3. На чем построена многопоточная система Java?
4. Какими способами можно создать поток в Java?
5. Какие конструкторы используются при создании объекта Thread?
6. Какие методы содержит класс Thread для управления потоком?
7. Какие проблемы могут возникнуть при использовании потоками программы общих ресурсов?
8. Объясните понятие монитора?
9. Как используется ключевое слово synchronized?
10. Приведите пример синхронизации по объекту.
Видео для подготовки
Тег video не поддерживается вашим браузером. Скачайте видео.
Исходные коды проекта из видео:
« Назад Вперед »
ЛАБОРАТОРНАЯ РАБОТА №5
Сетевое программирование в Java. Работа с классами Socket и ServerSocket
Цель работы: Изучить особенности сетевого программирования Java, методы и средства работы с клиентскими и серверными сокетами в Java.
Методические указания к выполнению лабораторной работы
В основе работы в сети, поддерживаемой в Java, находится понятие сокета, инкапсулирующего конечную точку в сети. Сокет позволяет отдельному компьютеру (серверу) одновременно предоставлять доступ к сервисам множеству других компьютеров в сети (клиентов). Это достигается благодаря использованию порта. Сервер «прослушивает» порт до тех пор, пока клиент не соединится с ним. Для управления соединениями со многими клиентами сервер должен быть многопоточным.
Связь между сокетами устанавливается и поддерживается стеком протоколов TCP(UDP)/IP. Протокол TCP резервирует первые 1024 порта для отдельных прикладных протоколов. Например, некоторые служебные порты:
- порт 21 – для файлового протокола FTP;
- порт 23 – для протокола Telnet;
- порт 25 – для протокола электронной почты SMTP;
- порт 43 – для службы whois;
- порт 80 – для протокола гипертекста HTTP.
Для инкапсуляции IP-адреса (как числового его представления, так и соответствующего ему доменного имени) используется класс InetAddress. Этот класс может оперировать адресами как по протоколу IPv4, так и по протоколу IPv6. В классе InetAddress отсутствуют доступные конструкторы. Чтобы создать объект, следует использовать один из доступных в нем фабричных методов. Фабричный метод – статический метод, возвращающий экземпляр класса.
Фабричные методы класса InetAddress: getLocalHost(), который получает адрес локального хоста; getByName(), который получает адрес по имени хоста, указанного параметром; getAllByName(), который получает все адреса конкретного хоста, указанного параметром. Данные фабричные методы могут вызвать исключение UnknownHostException.
Основные методы класса InetAddress: getAddress(), который использу-ется для получения IP-адреса в виде массива байт; getHostAddress(), который используется для получения IP-адреса хоста в строковом виде; getHostName(), который используется для получения доменного имени хоста.
В Java поддерживаются две разновидности сокетов по протоколу TCP/IP: класс ServerSocket для инкапсуляции сервера, класс Socket для инкапсуляции клиента. Класс ServerSocket ожидает подключения клиентов для выполнения заданных действий (обрабатывает запросы). Класс Socket служит для подключения к серверным сокетам и инициирования обмена данными по сетевому протоколу.
Конструкторы класса Socket: Socket(String hostName, int port), Socket(InetAddress address, int port). Могут вызывать исключения UnknownHostException и IOException.
Методы для получения информации о сокете: getInetAddress(), используемый для получения связанного с сокетом адреса; getPort(), используемый для получения связанного с сокетом порта.
Для доступа к потокам ввода/вывода, связанным с сокетом, используют следующие методы: getInputStream() для получения потока байтового ввода InputStream и getOutputStream() для получения потока байтового вывода OutputStream. Данные методы могут вызвать исключение IOException. Объекты InputStream и OutputStream можно использовать для организации форматированного ввода/вывода – создания объектов DataInputStream и DataOutputStream, передавая их конструкторам байтовые потоки ввода/вывода.
Методы класса DataOutputStream: writeDouble() – для записи в поток данных типа double, writeBoolean() – для записи в поток данных типа boolean, writeInt() – для записи в поток данных типа int, writeUTF() – для записи в поток данных типа String.
Методы DataInputStream: readDouble() – для чтения из потока данных типа double, readBoolean() – для чтения из потока данных типа boolean, readInt() – для чтения из потока данных типа int, readUTF() – для чтения из потока данных типа String.
Класс ServerSocket применяется для создания серверов, которые принимают запросы от клиентских программ, устанавливающих соединение с ними через открытые порты. Конструкторы класса ServerSocket с указанием порта port и максимального количества подключаемых клиентов max:
ServerSocket(int port) throws IOException;
ServerSocket(int port, int max) throws IOException;
Метод accept() класса ServerSocket реализует блокирующий вызов, чтобы ожидать от клиента начала соединения. После соединения метод возвращает объект типа Socket, который используется для взаимодействия с клиентом.
Например, приложение, реализующее клиентский сокет для отправки текстового сообщения на сервер и получения ответного сообщения:
import java.net.*; import java.io.*; import java.awt.event.*; public class ClientFrame extends javax.swing.JFrame < Socket client; ChatSocket cs; String lastMessage = ""; . //элементы GUI public ClientFrame() < initComponents(); >class ChatSocket implements Runnable < DataInputStream in; DataOutputStream out; boolean work; String name; ChatSocket(InputStream is, OutputStream os, String name) < in = new DataInputStream(is); out = new DataOutputStream(os); work = true; this.name = name; Thread t = new Thread(this); t.start(); >private synchronized void add(String s) < jTextArea1.append(s + "\n"); >public void stopListen() < work = false; >public void sendToServer(String s) < try < s = name + ": " + s; lastMessage = s; add(s); out.writeUTF(s); out.flush(); >catch(IOException e)<>; > public void run() < try < String line = null; while(work) < line = in.readUTF(); if(line.compareTo(lastMessage) != 0) add(line); >> catch(IOException e)<>; > > private void initComponents() < . // формирование GUI приложения >private void jButton1ActionPerformed(ActionEvent evt) < try < String s = jFormattedTextField1.getText(); InetAddress ia = InetAddress.getByName(s); s = jFormattedTextField2.getText(); int port = Integer.parseInt(s); client = new Socket(ia, port); String name = jTextField2.getText(); jTextArea1.append("Подключение установлено.\n"); InputStream in = client.getInputStream(); OutputStream out = client.getOutputStream(); cs = new ChatSocket(in, out, name); >catch(IOException e)<>; > private void jTextField1ActionPerformed(ActionEvent evt) < cs.sendToServer(jTextField1.getText()); jTextField1.setText(""); >public static void main(String args[]) < . java.awt.EventQueue.invokeLater(new Runnable() < public void run() < new ClientFrame().setVisible(true); >>); > >
1. Объясните понятие сокета.
2. Какой стек протоколов используется для связи между сокетами?
3. Приведите примеры служебных портов.
4. Что инкапсулирует класс InetAddress?
5. Какие разновидности сокетов поддерживается в Java?
6. Какие конструкторы используются для создания объектов Socket?
7. Какие методы используются для доступа к потокам ввода/вывода, связанным с сокетом?
8. Какие объекты потоков используются для организации форматированного ввода/вывода?
9. Какие конструкторы используются для создания объектов Server-Socket?
10. Какой метод используется для ожидания подключения клиентов в классе ServerSocket?
Видео для подготовки
Тег video не поддерживается вашим браузером. Скачайте видео.
Исходные коды проекта из видео:
« Назад Вперед »
ЛАБОРАТОРНАЯ РАБОТА №6
Коллекции Java. Объектная декомпозиция предметной области
Цель работы: Применить объектную декомпозицию к выбранной предметной области. Изучить возможности использования в разработке Java Collections Framework.
Методические указания к выполнению лабораторной работы
В данной работе необходимо разработать приложение для выбранной предметной области с использованием JCF (Java Collections Framework). Для этого рекомендуется выполнить следующие действия:
- определить предметную (проблемную) область;
- осуществить объектную декомпозицию – разделить предметную область на объекты (реальные и/или абстрактные);
- определить характеристики объектов, возможные действия над ними;
- определить связи (и их типы) между объектами, возможные взаимодействия объектов;
- представить объекты в виде классов (абстрактных типов данных);
- предусмотреть использование нескольких коллекций Java;
- использовать композицию и наследование при формировании связей между объектами;
- реализовать полиморфизм (полиморфное поведение методов).
В качестве предметной области можно выбрать: прикладные задачи (проектирование СППР (системы поддержки принятия решений), вычислительные задачи, любые приложения с GUI и т.д.), задачи моделирования (моделирование управления объектами некой системы, моделирование взаимоотношений и взаимодействий элементов некой системы, моделирование управления и отображений оборота документации некой системы, моделирование технологического оборудования и технологических процессов и т.д.).
Большинство задач не предполагает ограниченное число объектов с фиксированным временем жизни. Для управления неограниченным количеством объектов (созданием, хранением, удалением) Java содержит набор классов контейнеров (в библиотеке java.util), например, List, Set, Queue, Map. Эти типы объектов также называются классами коллекций. Классы коллекций способны автоматически изменяться в размерах.
Использование контейнеров предполагает использование обобщений (дженериков или обобщенных типов), обеспечивающих контроль за типами объектов коллекций. Без обобщенных типов компилятор может игнорировать помещение в контейнер объектов разных типов. Использование обобщенных типов предотвращает помещение неверного типа объекта в контейнер на стадии компиляции.
Например, чтобы определить ArrayList для хранения объектов String, следует использовать запись ArrayList. В угловые скобки заключаются параметры-типы (их может быть несколько), определяющие типы, которые могут храниться в данном экземпляре контейнера.
Коллекции Java рассматривает вопрос хранения объектов как совокупность двух концепций, выраженных основными интерфейсами библиотеки: Коллекция (Collection) и Карта (Map).
Коллекция – последовательность отдельных элементов, формируемая по некоторым правилам. Интерфейс List (список) хранит элементы в определенной последовательности. В интерфейсе Set (множество) нельзя хранить повторяющиеся элементы. Интерфейс Queue (очередь) выдает элементы в порядке, определяемом дисциплиной очереди (обычно совпадающем с порядком вставки). Очереди часто используются для надежного перемещения объектов из одной области программы в другую.
Карта – набор пар объектов «ключ-значение» с возможностью выборки значения по ключу. Если контейнер ArrayList позволяет получить объект по числу, то карта позволяет получить объект по другому объекту. Также для контейнеров Map используют термин ассоциативный массив (объекты ассоциируются с другими объектами) и словарь (по аналогии поиска определения (объекта-значения) по слову (объекту-ключу)).
Интерфейс Collection обобщает концепцию последовательности – способа хранения группы объектов. Однако использовать восходящее преобразование к базовым интерфейсам необходимо с учетом того, что интерфейсы и классы обладают дополнительной функциональностью. Например, LinkedList содержит методы, отсутствующие в интерфейсе List, а TreeMap содержит методы, не входящие в интерфейс Map. Или, например, метод add() для интерфейса Collection добавляет в контейнер только те элементы, которые в нем отсутствовали (функциональность Set).
Для добавления групп элементов в Collection используются методы классов Arrays и Collections. Метод Arrays.asList() получает массив или список элементов переменной длины, который преобразуется в объект List. Метод Collections.addAll() получает объект Collection и либо массив, либо список элементов переменной длины, который добавляется в Collection.
Контейнер List гарантирует хранение списка элементов в определенной последовательности. Интерфейс List добавляет в Collection методы вставки и удаления элементов в середине списка. Существует две разновидности List: ArrayList и LinkedList.
Базовый контейнер ArrayList обладает отличной скоростью произвольного доступа к элементам, но относительно медленными операциями вставки и удаления элементов в середине. Связанный список LinkedList обладает оптимальным последовательным доступом и низкозатратными операциями вставки и удаления в середине списка, но относительно медленными операциями произвольного доступа. В LinkedList добавлены методы, которые позволяют использовать его как стек, очередь или дек (двустороннюю очередь).
Например, приложение, демонстрирующее возможности работы со списками ArrayList:
import java.util.*; public class ListFeatures < public static void main(String[] args) < Listl = new ArrayList(); Collections.addAll(l, "массив", "карта", "список", "очередь", "карта", "стек"); System.out.println("1: " + l); String a = new String("множество"); l.add(a); System.out.println("2: " + l); System.out.println("3: " + l.contains(a)); l.remove(a); String b = l.get(2); System.out.println("4: " + b + " " + l.indexOf(b)); String c = new String("дек"); System.out.println("5: " + l.indexOf(c)); System.out.println("6: " + l.remove(c)); System.out.println("7: " + l); String d = new String("очередь"); System.out.println("8: " + l.indexOf(d)); System.out.println("9: " + l.remove(d)); System.out.println("10: " + l); System.out.println("11: " + l.remove(b)); System.out.println("12: " + l); l.add(3, new String("множество")); System.out.println("13: " + l); List addl = new ArrayList(Arrays.asList("очередь", "список", "дек")); l.addAll(addl); System.out.println("14: " + l); List subl = l.subList(3, 7); System.out.println("Подсписок: " + subl); System.out.println("15: " + l.containsAll(subl)); Collections.sort(subl); System.out.println("Подсписок после сортировки: " + subl); System.out.println("16: " + l.containsAll(subl)); Collections.shuffle(subl, new Random(42)); System.out.println("Подсписок после перемешивания: " + subl); System.out.println("17: " + l.containsAll(subl)); List copyl = new ArrayList(l); subl = Arrays.asList(l.get(1), l.get(5)); System.out.println("Подсписок: " + subl); copyl.retainAll(subl); System.out.println("18: " + copyl); copyl = new ArrayList(l); copyl.remove(2); System.out.println("19: " + copyl); copyl.removeAll(subl); System.out.println("20: " + copyl); copyl.set(1, new String("карта")); System.out.println("21: " + copyl); copyl.addAll(2, subl); System.out.println("22: " + copyl); System.out.println("23: " + l.isEmpty()); l.clear(); System.out.println("24: " + l); System.out.println("25: " + l.isEmpty()); l.addAll(copyl.subList(0, 5)); System.out.println("26: " + l); Object[] o = l.toArray(); System.out.println("27: " + o[3]); String[] sa = l.toArray(new String[0]); System.out.println("28: " + sa[3].toUpperCase()); > >
Set представляет собой разновидность Collection, реализуя поведение, отличное от поведения List. Контейнер Set сохраняет не более одного экземпляра каждого объекта-значения, то есть предотвращает появление дубликатов. Разновидности Set:
- HashSet – использует для размещения элементов хеширование (увеличивается скорость доступа);
- LinkedHashSet – также использует хеширование для повышения скорости поиска, но элементы «сохраняются» в связанном списке в порядке вставки;
- TreeSet – хранит элементы отсортированными в специальной структуре данных – «красно-черном дереве».
Самая частая операция, выполняемая с множествами, является проверка присутствия значений методом contains().
Главной функциональностью контейнера Map является возможность отображения одних объектов на другие объекты. Объект Map чаще других используется для создания сложных вложенных контейнеров. Разработчик в таком случае получает возможность быстро организовать любую нетривиальную структуру данных.
Часто необходим код для работы с контейнером, не зависящий от его конкретного типа. Для решения данной проблемы используется концепция итератора (iterator). Итераторы унифицируют доступ к контейнерам.
Итератор – объект, обеспечивающий перемещение по последовательности объектов с выбором каждого объекта этой последовательности. Итератор является легковесным объектом: его создание не занимает много ресурсов.
Интерфейс Iterator поддерживает перемещение только в одном направлении. Операции, доступные итератору:
- запрос у Collection итератора посредством метода iterator(). Этот итератор готов вернуть первый элемент последовательности;
- получение следующего элемента последовательности вызовом метода next();
- проверка наличия следующего объекта в последовательности методом hasNext();
- удаление из последовательности элемента, возвращенного итератором последним, методом remove().
Интерфейс ListIterator является двусторонним, но работает только с классами List.
1. В чем заключается объектная декомпозиция предметной области задачи?
2. Для чего используются коллекции Java?
3. Укажите особенности интерфейсов Collection и Map.
4. Как добавить группу элементов в коллекцию типа Collection?
5. Какие разновидности коллекций List есть в JCF?
6. Какие разновидности коллекций Set есть в JCF?
7. Для чего используются коллекции типа Map?
8. Что используют для унифицированного доступа к контейнерам?
9. Какие операции доступны итератору типа Iterator?
10. Укажите, что будет выведено при выполнении заданного фрагмента программы работы с коллекциями ArrayList, приведенной выше? Объясните, для чего используются методы в данном фрагменте?
Библиотека классов JDK. Основы построения интерфейса пользователя на языке Java. Компоновки и элементы управления
Этот класс позволяет размещать компоненты в контейнере в виде таблицы. В каждой ячейке таблицы может быть размещен только один компонент.
Размер всех ячеек таблицы одинаков. Количество строк и столбцов таблицы определяется или в конструкторе, или вызовом методов setColumns и setRows . При этом, если эти значения не равны нулю, то количество столбцов является величиной вычисляемой и зависит от общего числа компонентов, добавленных на компоновку, и указанного числа строк. И только в том случае, если количество строк задано равным нулю, заданное количество столбцов будет учитываться менеджером компоновки.
На рис. 27.3 приведены примеры использования компоновки GridLayout .
Рис. 27.3. Пример компоновки GridLayout
Для компоновки GridLayout следует определять или количество строк, или количество столбцов.
this.setLayout(gridLayout1); gridLayout1.setRows(3);
Класс GridBagLayout
Этот класс используется менеджером компоновки GridBagLayout и определяет требования к размещению компонентов.
Компоновка GridBagLayout позволяет размещать компоненты в ячейках таблицы. Но, в отличие от менеджера компоновки GridLayout , ячейки таблицы могут различаться как по ширине, так и по высоте. Размещаемые компоненты могут занимать несколько ячеек.
Область, занимаемая компонентом, называется областью отображения. Ее размеры определяются значениями переменных gridwidth и gridheight (количество ячеек по горизонтали и по вертикали) класса GridBagConstraints .
Отступами ( insets ) называется расстояние между областью отображения и действительной областью, занимаемой компонентом.
На рис. 27.4 приведен пример компоновки, в которой кнопка 3 занимает 9 ячеек, но размер кнопки меньше размера области отображения.
Рис. 27.4. Отступы, устанавливаемые объектом GridBagConstraints
Если область отображения отличается от размера компонента, то для определения требований к размещению используется переменная fill.
Если размер размещаемого компонента меньше размера области отображения, то для указания размещения компонента используется переменная anchor , которая может принимать одно из следующих значений:
- GridBagConstraints.CENTER
- GridBagConstraints.NORTH
- GridBagConstraints.NORTHEAST
- GridBagConstraints. EAST
- GridBagConstraints.SOUTHEAST
- GridBagConstraints.SOUTH
- GridBagConstraints.SOUTHWEST
- GridBagConstraints.WEST
- GridBagConstraints.NORTHWEST .
Переменная fill класса GridBagConstraint определяет, следует ли изменять размер компонента, и может принимать следующие значения:
- GridBagConstraint.NONE — размер компонента не изменять (значение, используемое по умолчанию);
- GridBagConstraint.HORIZONTAL — изменить размер по горизонтали, но не изменять его высоту;
- GridBagConstraint.VERTICAL — изменить размер по вертикали, но не изменять его ширину;
- GridBagConstraint.BOTH — увеличить размеры компонента до размера области отображения.
Переменные gridheight и gridwidth класса GridBagConstraint определяют число ячеек в столбце или строке соответственно. При этом константа GridBagConstraints. REMAINDER указывает, что компонент будет последним в столбце (строке), а константа GridBagConstraints.RELATIVE указывает, что компонент будет ближайшим к последнему.
Конструктор GridBagConstraints(int gridx, int gridy, int gridwidth, int gridheight, double weightx, double weighty, int anchor, int fill, Insets insets , int ipadx, int ipady) создает объект требований к размещению компонента, используемый менеджером компоновки, со всеми полями, имеющими заданные значения.