Язык Java содержит 2 библиотеки классов, предназначенных для разработки приложений, реализующих графический интерфейс пользователя (GUI – graphics user interface):
- библиотека AWT (Abstract Window Toolkit – набор абстракций для работы с окнами) поставляется в составе JDK в пакете java.awt
- библиотека JFC (Java Foundation Classes) более известная как Swing поставляется в составе JDK в пакете javax.swing.
В первых версиях языка (Java 1.0, 1.1) программистам была доступна только библиотека AWT, JFC пакет был включен в версию Java 2. Он расширяет функциональность обычных компонентов (меток, кнопок, переключателей, списков и т.п.) и добавляет новые: панели со вкладками, панели с прокруткой, деревья и таблицы и др.
Важно отметить, что в отличие от AWT-компонентов Swing-компоненты не реализованы специфическим для платформы кодом. Вместо этого они написаны полностью на Java, поэтому являются платформно - независимыми. Такие элементы принято называть облегченными (lightweight).
Хотя Java 2 продолжает поддерживать пакет AWT, но по приведенным выше причинам Sun настоятельно рекомендует использовать Swing. Для облегчения работы программистов названия Swing элементов начинаются с буквы J в отличие от названий в AWT (например, Button в AWT и JButton в Swing).
Часть иерархии классов библиотек AWT и Swing представлена на рис.
Основные классы библиотек AWT и Swing
Основное понятие, заложенное в графические библиотеки – компонент графической системы. Компонент – отдельный, полностью определенный элемент, который можно использовать в GUI независимо от других элементов. Например, это поле ввода, кнопка, строка меню, полоса прокрутки, «радиопереключатель» и т.п. Само окно приложения – тоже его компонент.
В Java компонентом считается объект класса Component или одного из классов, расширяющих Component. В классе Component определены общие методы работы с любым компонентом GUI. Этот класс – вершина иерархии графических библиотек, поэтому его необходимо рассмотреть подробнее.
Класс Component
Класс Component является абстрактным и не может использоваться сам по себе, применяются только унаследованные от него подклассы. В этом классе определены методы, отвечающие за управление событиями, позиционирование и изменение размеров окна, перерисовку окна и т.п.
Компонент всегда занимает прямоугольную область окна со сторонами, параллельными сторонам экрана. В компоненте есть система координат. Ее начало – точка с координатами (0,0) – находится в левом верхнем углу компонента. Оси направлены так, как показано на рис.
Ox
Oy
Высоту и ширину компонента можно узнать с помощью метода
Dimension getSize()
Этот метод возвращает объект класса Dimension, в полях width и height, которого хранятся ширина и высота компонента. Ту же задачу можно решить с помощью методов
int getWidth()
int getHeight()
класса Component. Разница заключается в том, что в объекте класса Dimension переменные width и height хранятся в виде чисел типа double, а методы класса Component возвращают числа типа int.
Чтобы установить положение и размеры компонента можно воспользоваться методом
setBounds(int x, int y, int width, int height)
Доступность компонента и его видимость на экране определяется с помощью методов
isEnabled()
isVisible()
Управлять этими параметрами можно с помощью методов
setEnabled(boolean b)
setVisible(boolean b)
Класс Container
Каждый компонент перед выводом на экран должен быть помещен в контейнер – специальный объект, отвечающий за размещение компонентов на экране. Контейнер может содержать набор компонентов, которые добавляются к нему с помощью метода
Component add(Component comp)
и другие контейнеры. В языке Java контейнер – объект класса Container или всякого его расширения. Класс Container сам является невидимым компонентом, он расширяет класс Component. Все классы окон унаследованы от класса Container.
Класс окна - JFrame
Контейнер JFrame - это готовое окно со строкой заголовка, в которую помещены кнопки контекстного меню, сворачивания/разворачивания окна, закрытия приложения. Окно типа Frame имеет рамку, которая позволяет перемещать его и изменять его размеры с помощью мыши.
Конструкторы класса JFrame:
JFrame()
JFrame(String title)
Первый конструктор создает окно с пустой строкой заголовка. Второй – окно со строкой заголовка, задаваемой параметром title. Заголовок окна можно создать и позже – методом
setTitle(String title)
Созданное окно типа Frame вначале является невидимым. Чтобы сделать его видимым, следует вызвать метод
setVisible(Boolean state)
класса Component, рассмотренный выше.
Окно типа JFrame после создания автоматически регистрируется в оконном менеджере
Графический контекст
При создании компонента автоматически формируется его графический контекст (graphics context). Контекст содержит текущий и альтернативный цвет рисования и цвет фона, текущий шрифт для вывода текста, систему координат. Управляет контекстом класс Graphics. Т.к. графический контекст сильно зависит от конкретной графической платформы, этот класс является абстрактным. Получить ссылку на созданный графический контекст можно с помощью метода
Graphics getGraphics()
После получения ссылки на графический контекст, можно пользоваться методами класса Graphics для работы с графикой и текстом. Основные методы класса Graphics представлены в таблице
Таблица
Метод | Описание |
drawLine(int x1,int y1, int x2, int y2) | Вычерчивает текущим цветом отрезок прямой между точками (x1,y1) и (x2,y2) |
drawRect(int x, int y, int width, int height) | Чертит прямоугольник со сторонами, параллельными краям экрана, задаваемый координатами верхнего угла (x,y), шириной width и высотой height |
drawOval(int x, int y, int width, int height) | Чертит овал, вписанный в прямоугольник, заданный аргументами метода (если width = height – окружность) |
drawArc(int x, int y, int width, int height, int startAngle, int arc) | Чертит дугу овала, вписанного в прямоугольник, заданный первыми четырьмя аргументами. Дуга имеет величину arc градусов и отсчитывается от угла startAngle. Угол отсчитывается в градусах от оси Ox. Положительный угол отсчитывается против часовой стрелки, отрицательный – по часовой стрелке. |
drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) | Чертит прямоугольник с закругленными краями. Закругления вычерчиваются четвертинками овалов, вписанных в прямоугольники шириной arcWidth и высотой arcHeight, построенные в углах основного прямоугольника. |
drawPolygon(int xPoints[], int yPoints[], int nPoints) | Чертит замкнутую ломаную с вершинами в точках (xPoints[i], yPoints[i]) и числом вершин nPoints |
drawString(String s, int x, int y) | Выводит строку s. Вывод начинается с позиции (x,y). |
Класс Color
Цвет в Java – объект класса Color. В классе Color конструкторы:
Color(int r, int g, int b)
Создается цвет, получающийся смешением красной (r), зеленой (g) и синей (b) составляющих (модель RGB). Значение интенсивности каждой составляющей меняется от 0 до 255.
Если нет необходимости тщательно подбирать цвета, можно воспользоваться одной из статических констант типа Color, имеющихся в классе Color. Таких констант 13: black, blue, cyan, darkGray, gray, green, lightGray, magenta, orange, pink, red, white, yellow.
Класс Polygon
Этот класс предназначен для работы с многоугольниками. Объекты данного класса можно создать двумя конструкторами:
Polygon()
Создается пустой объект.
Polygon(int xPoints[], int yPoints[], int nPoints)
Создается многоугольник с вершинами (xPoints[i], yPoints[i]). Число вершин – nPoints.
Данный класс содержит методы, позволяющие легко проверить, лежит ли в многоугольнике заданная точка, отрезок или целый прямоугольник. Основные методы класса Polygon собраны в таблице.
Метод | Описание |
boolean contains(double x, double y) | Проверяет, лежит ли точка (x,y) внутри многоугольника |
boolean contains(double x, double y, double w, double h) | Проверяет, лежит ли прямоугольник, заданный аргументами метода внутри многоугольника |
boolean contains(int x, int y) | Проверяет, лежит ли точка (x,y) внутри многоугольника |
boolean contains(Point p) | Проверяет, лежит ли точка (x,y) внутри многоугольника |
boolean intersects(double x, double y, double w, double h) | Проверяет, пересекается ли прямоугольник, заданный аргументами метода с многоугольником |
В следующем примере строится квадрат. Выбирается случайная точка, выводятся ее координаты и проверяется ее принадлежность квадрату.
Пример:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
class Rect
{public static void main(String args[])
{int xPoints[] = new int[4];
int yPoints[] = new int[4];
int x,y;
JFrame f = new JFrame();
f.setBounds(10,10,500,200);
f.setVisible(true);
Graphics g = f.getGraphics();
g.setColor(new Color (0,0,255));
Random r = new Random();
xPoints[0]=20;yPoints[0]=70;
xPoints[1]=280;yPoints[1]=70;
xPoints[2]=280;yPoints[2]=150;
xPoints[3]=20;yPoints[3]=150;
x = r.nextInt (500);
y = r.nextInt (200);
Polygon p = new Polygon(xPoints,yPoints,4);
g.drawPolygon (p);
g.setColor(new Color (255,0,0));
if (p.contains (x,y)==true)
g.drawString ("Точка " + x + " " + y +
" попадает в прямоугольник", 20,50);
else
g.drawString ("Точка " + x + " " + y +
" не попадает в прямоугольник", 20,50);
f.addWindowListener (new WindowAdapter()
{public void windowClosing(WindowEvent ev)
{System.exit (0); } }); }}
Вывод этой программы:
Элементы управления
Библиотеки AWT и Swing поддерживает следующие основные элементы управления:
• Текстовые метки
• Кнопки
• Флажки
• «Радиопереключатели»
• Списки
• Поля со списком
• Текстовые поля
• Текстовые области
• Панели прокрутки
• Панели с вкладками
• Деревья
• Таблицы
Все элементы управления реализованы как объекты специальных классов, являющихся подклассами класса Component. Как уже говорилось ранее, каждый компонент (в том числе элемент управления) должен быть включен в некоторый контейнер (подкласс класса Container). В библиотеке AWT таким контейнером является само окно. Для добавления элемента управления к окну необходимо использовать одну из форм метода add(), определенного в классе Container. Самая простая форма выглядит следующим образом:
Component add(Component obj)
Здесь obj – экземпляр элемента управления, который добавляется к окну. Метод возвращает ссылку на объект, который передается параметром obj. Сразу после добавления элемент будет выводиться на экран автоматически, когда отображается его «родительское» окно.
Удаление элемента управления из окна производится методом
void remove (Component obj).
Вызывая метод removeAll() можно удалить сразу все присоединенные к окну элементы управления.
Управлять положением элемента управления относительно окна, в котором он размещен, можно с помощью методов setBounds() и getBounds(). Формат этих методов:
void setBounds(int x, int y, int width, int height)
void setBounds(Rectangle r)
Rectangle getBounds()
В компоненте хранятся координаты его левого верхнего угла в системе координат «родительского» окна. Узнать их можно с помощью метода:
Point getLocation()
а изменить с помощью методов:
void setLocation(int x, int y)
void setLocation(Point p)
Все элементы управления, за исключением текстовых меток, могут взаимодействовать с пользователем, генерируя некоторые события, которые в программе можно идентифицировать и обрабатывать. Модель обработки событий, реализованная в языке Java, будет рассматриваться ниже.
В библиотеке Swing компоненты перед выводом на экран должны быть помещены не в окно, а внутрь специального контейнера, который называется панель содержания (content pane). Этот контейнер не нужно создавать, его можно получить для окна подобно графическому контексту:
JFrame f = new JFrame("Test");
Container cp = f.getContentPane();
После этого все операции добавления/удаления компонентов выполняются для панели содержания, а не для самого окна.
Графические изображения
В библиотеке Swing графические изображения инкапсулированы классом ImageIcon, реализующим интерфейс Icon.
Конструктор класса ImageIcon:
ImageIcon(String filename)
Основные методы класса ImageIcon:
int getIconHeight()
int getIconWidth()
void paintIcon(Component comp, Graphics g, int x, int y)
Текстовые метки
Самый простой для использования компонент графического интерфейса – текстовая метка (label). Текстовые метки – это объекты класса JLabel, содержащие одну строку статического текста и/или графическое изображение. Среди всех элементов графического интерфейса только метки являются пассивными, т.е. не поддерживают никакого взаимодействия с пользователем во время выполнения.
Конструкторы класса JLabel:
JLabel (String str)
JLabel (Icon id_icon)
JLabel (String str, Icon id_icon, int align)
создает метку, содержащую строку str и/или графическое изображение id_icon. Выравнивание строки определяется параметром align. Значением align должна быть одна из трех констант, определенных в классе JLabel:
JLabel.LEFT - выравнивание по левому краю
JLabel.RIGHT - выравнивание по правому краю
JLabel.CENTER - выравнивание по центру
Текст в метке можно устанавливать или изменять с помощью метода
void setText(String str)
Текущую метку можно получить, используя метод
String getText()
Управлять выравниванием текста можно с помощью методов
void setAlignment(int align)
int getAlignment()
Графическое изображение в метке можно устанавливать или изменять методами:
void setIcon(Icon id_icon)
Текущее графическое изображение можно получить, используя метод
Icon getIcon()
Управляющие кнопки
Управляющая кнопка – это объект класса JButton. Кнопка может содержать текстовую строку (надпись на кнопке) и/или графическое изображение. Она генерирует события в ответ на щелчок мышью.
Основные конструкторы класса JButton:
JButton(String str)
JButton(Icon id_icon)
Методы, позволяющие управлять видом кнопки:
String getLabel()
void setLabel(String str)
Icon getLabel()
void setIcon(Icon id_icon)
Флажки – переключатели
Флажки-переключатели являются объектами класса JCheckBox. Самая общая форма конструктора:
JCheckBox (String str, Icon id_icon, boolean state)
Управление состоянием флажка из программы осуществляется с помощью методов:
boolean getSelected()
void setSelected(boolean state)
Группы кнопок («радиопереключатели»)
«Радиопереключатели» в библиотеке Swing реализованы как объекты класса JRadioButton. Самая общая форма конструктора:
JRadioButton (String str, Icon id_icon, boolean state)
«Радиопереключатели» должны быть объединены в группу, в пределах которой будет обеспечиваться уникальность выбора элемента. Чтобы создать группу создается экземпляр объекта специального класса ButtonGroup. Далее все созданные радиопереключатели добавляются в созданную группу (что не отменяет необходимости их добавления к панели содержания).
Пример:
JFrame f = new JFrame();
Container cp = f.getContentPane();
JRadioButton jrb1 = new JRadioButton("a",false);
JRadioButton jrb2 = new JRadioButton("b",false);
JRadioButton jrb3 = new JRadioButton("c",true);
ButtonGroup bg = new ButtonGroup();
bg.add(jrb1);
bg.add(jrb2);
bg.add(jrb3);
cp.add(jrb1);
cp.add(jrb2);
cp.add(jrb3);
Раскрывающиеся списки
Раскрывающийся список – компонент класса JComboBox. Создать раскрывающийся список можно с помощью одного из конструкторов:
JComboBox()
JComboBox(Vector v[])
JComboBox(Object obj[])
Далее в список можно добавлять новые пункты с помощью методов:
addItem(Object item)
Новые строки будут добавляться к списку в том порядке в котором выполнялись вызовы метода addItem().
Вставить строку в список в определенную позицию (index) можно методом:
insertItemAt(Object anObject, int index)
Удаление строк из списка:
void removeItem(String text)
void removeItemAt(int index)
void RemoveAllItems()
Для определения текущего выбранного элемента можно использовать методы
String getSelectedItem()
int getSelectedIndex()
Первый метод возвращает строку с именем элемента, а второй – номер выбранной строки. Строки в списке нумеруются от 0. По умолчанию выбранным считается нулевая строка.
Чтобы получить текущее количество элементов в списке используется метод:
int getItemCount()
Зная номер строки в списке можно получить ее имя с помощью метода:
String getItemAt(int index)
Можно произвести выбор пункта в списке из программы с помощью методов:
void setSelectedIndex (int index)
void setSelectedItem (Object obj)
По умолчанию раскрывающийся список является не редактируемым. Чтобы сделать его редактируемым, необходимо использовать метод:
void setEditable (boolean state)
Списки
Списки – объекты класса JList. В них допускается множественный выбор.
Стандартный объект класса JList – неизменяемый список, поэтому его необходимо заполнять данными в момент создания.
Конструкторы:
JList(Vector v[])
JList(Object obj[])
Кроме того объекты типа JList не поддерживают автоматическую прокрутку. Поэтому для того, чтобы элементы в списке могли прокручиваться, список необходимо поместить в специальный объект JScrollPane, а уже этот объект добавить в контейнер.
Пример:
JFrame f = new JFrame();
Container cp = f.getContentPane();
f.setBounds(100,100,300,300);
String s[] = {"1","2","3","4","5","6","7","8","9","10"};
JList jl = new JList(s);
jl.setBounds(10,10,30,30);
JScrollPane p = new JScrollPane(jl);
cp.add(p);
f.setVisible(true);
Для определения выбранного элемента (элементов) используются методы:
Object getSelectedValue()
Object[] getSelectedValues()
int getSelectedIndex()
int[] getSelectedIndices()
Текстовые поля
Однострочная область ввода текста (текстовое поле) – объект класса JTextField. Текстовые поля дают возможность вводить строки, редактировать их с помощью клавиш-стрелок, Backspace, Delete, пользоваться буфером обмена.
Конструкторы:
JTextFiled()
JTextFiled(int numChars)
JTextFiled(String str)
JTextFiled(String str, int numChars)
Первая форма создает пустое текстовое поле. Вторая текстовое поле шириной numChars символов. Третья – инициализирует текстовое поле строкой str. Четвертая – инициализирует текстовое поле и задает его ширину.
Основные методы класса JTextField:
String getText()
Возвращает строку, содержащуюся в поле ввода.
void setText(String str)
Устанавливает в поле ввода текст str.
String getSelectedText()
Пользователь может выделять часть текста в текстовом поле с помощью клавиатуры или мыши. Метод getSelectedText() возвращает выделенную часть текста.
void select(int start, int end)
Этот метод позволяет программно выделить часть текста в поле ввода начиная с позиции start до позиции end.
Следующие два метода управляют доступностью текстового поля для редактирования.
boolean isEditable()
void setEditable(boolean canEdit)
В обоих методах true означает доступность текста для изменения.
Если необходимо, чтобы пользователь мог вводить текст без его отображения в текстовом поле (например, пароли), то нужно воспользоваться методом
void setEchoChar(char ch)
ch – символ, который будет отображаться вместо фактически вводимого.
Текстовые области
Текстовая область (многострочное поле ввода) – объект класса JTextArea. Нажатие клавиши Enter переводит курсор в начало следующей строки. В текстовой области могут быть установлены линейки прокрутки.
Конструкторы:
JTextArea()
JTextArea(int numLines, int numChars)
JTextArea(String str)
JTextArea(String str, int numLines, int numChars)
numLines определяет высоту текстовой области в строках, numChars определяет ширину текстовой области в символах, str – начальный текст.
Объект JTextArea поддерживает все методы, описанные выше для класса JTextField. В дополнение к ним поддерживаются методы:
void append (String str)
Строка str добавляется к концу текущего текста
void insert (String str, int index)
Строка str вставляется в позицию, указанную в параметре index.
void replaceRange(String str, int start, int end)
Заменяет символы от start до end-1 строкой str.
Для обеспечения горизонтальной и вертикальной прокрутки компоненты JTextField и JTextArea должны быть помещены в контейнер JScrollPane.
JTable – отображение данные в виде таблицы
Очень часто возникает необходимость в приложениях показать данные в виде таблицы с определенным количеством строк и столбцов. В Java Swing для отображения табличных данных используется комопнент JTable. JTable внутри себя не содержит данные, а служит только для их отображения.
Рассмотрим простой пример создания и использования таблицы. Для этого мы создадим таблицу, заполним её тестовыми данными и разместим на панели прокрутки. Размещение таблицы на панели прокрутки – это обычная практика, потому что это удобно и красиво.
Существует несколько способов того, как сказать JTable, какие данные и столбцы следует отображать. Рассмотрим самый простой способ. Для начала определим, какие столбцы мы хотим показывать в таблице. Для примера взяты столбцы проводника Windows – Name (Имя файла или папки), Last modified (Дата последней модификации), Type (Тип) и Size (Размер). Собираем столбцы в массив строк вот так:
String[] columnNames = {"Name", "Last modified", "Type", "Size"}; |
Далее необходимо определить данные, которые мы хотим отображать в таблице. Делается это тоже при помощи массива строк вот так:
String[][] data = { {"addins", "02.11.2006 19:15", "Folder", ""}, {"AppPatch", "03.10.2006 14:10", "Folder", ""}, {"assembly", "02.11.2006 14:20", "Folder", ""}, {"Boot", "13.10.2007 10:46", "Folder", ""}, {"Branding", "13.10.2007 12:10", "Folder", ""}, {"Cursors", "23.09.2006 16:34", "Folder", ""}, {"Debug", "07.12.2006 17:45", "Folder", ""}, {"Fonts", "03.10.2006 14:08", "Folder", ""}, {"Help", "08.11.2006 18:23", "Folder", ""}, {"explorer.exe", "18.10.2006 14:13", "File", "2,93MB"}, {"helppane.exe", "22.08.2006 11:39", "File", "4,58MB"}, {"twunk.exe", "19.08.2007 10:37", "File", "1,08MB"}, {"nsreg.exe", "07.08.2007 11:14", "File", "2,10MB"}, {"avisp.exe", "17.12.2007 16:58", "File", "12,67MB"}}; |
Далее необходимо создать собственно сам JTable и передать ему массив столбцов и массив с данными для показа.
JTable table = new JTable(data, columnNames); |
Потом создаем JScrollPane, на котором размещаем таблицу и добавляем панель на JFrame. Внешний вид получившегося приложения можно увидеть на рисунке ниже.
Исходный код приложения представлен ниже.
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class TestFrame extends JFrame {
public static void createGUI() {
JFrame frame = new JFrame("Test frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] columnNames = {"Name","Last modified","Type", "Size" };
String[][] data = {
{"addins", "02.11.2006 19:15", "Folder", ""},
{"AppPatch", "03.10.2006 14:10", "Folder", ""},
{"assembly", "02.11.2006 14:20", "Folder", ""},
{"Boot", "13.10.2007 10:46", "Folder", ""},
{"Branding", "13.10.2007 12:10", "Folder", ""},
{"Cursors", "23.09.2006 16:34", "Folder", ""},
{"Debug", "07.12.2006 17:45", "Folder", ""},
{"Fonts", "03.10.2006 14:08", "Folder", ""},
{"Help", "08.11.2006 18:23", "Folder", ""},
{"explorer.exe", "18.10.2006 14:13", "File", "2,93MB"},
{"helppane.exe", "22.08.2006 11:39", "File", "4,58MB"},
{"twunk.exe", "19.08.2007 10:37", "File", "1,08MB"},
{"nsreg.exe", "07.08.2007 11:14", "File", "2,10MB"},
{"avisp.exe", "17.12.2007 16:58", "File", "12,67MB"},
};
JTable table = new JTable(data, columnNames);
JScrollPane scrollPane = new JScrollPane(table);
frame.getContentPane().add(scrollPane);
frame.setPreferredSize(new Dimension(450, 200));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true); }
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame.setDefaultLookAndFeelDecorated(true);
createGUI(); } }); }}
Обработка событий в Swing
Графический интерфейс пользователя включает в себя не только расположение в окне необходимых элементов управления, но и назначение реакции на пользовательские события. Большая честь действий в оконных программах выполняется в ответ на выбор пользователем команд меню, нажатие кнопок, а иногда даже просто в ответ на ввод нового символа в текстовое поле.
Таким образом, при разработке программы необходимо:
· Выявить события, в ответ на которые потребуется реакция программы.
· Написать код, реализующий эту реакцию (так называемый обработчик событий).
· Связать обработчик события с соответствующим событием.
Первый пункт зависит от логики работы приложения и находится всецело на усмотрении программиста. Обработчик события — это, как правило, обычный метод и ничего особенного в его написании нет.
Шаблон проектирования «наблюдатель» (listener)
В библиотеке Swing для привязки обработчика события к вызывающему его компоненту используется шаблон проектирования «наблюдатель».
Шаблоны проектирования — это стандартные приемы объектно-ориентированного программирования, позволяющие оптимальным образом справиться с нетривиальными, но часто возникающими в программировании ситуациями. Шаблон проектирования описывает классы, которые необходимо ввести для разрешения такой ситуации и взаимодействие между классами.
Шаблон проектирования «наблюдатель» применяется, когда один объект должен оповещать другие о произошедших с ним изменениях или внешних воздействиях. Такой объект называется наблюдаемым, а объекты, которые следует оповестить — наблюдателями.
Для того, чтобы подобное взаимодействие было возможным, объект-наблюдатель должен иметь метод (или несколько методов) с заранее определенными именем и параметрами. Когда с наблюдаемым объектом произойдет ожидаемое событие, он вызовет соответствующий метод у своего наблюдателя. В этом методе и будет запрограммирована реакция на событие.
Для того, чтобы наблюдаемый объект мог вызвать метод наблюдателя, он должен знать о том, что такой наблюдатель существует. Поэтому у наблюдаемого предварительно должен быть вызван специальный метод, регистрирующий его наблюдателя.
Заметим, что в данной схеме один наблюдатель может быть зарегистрирован у нескольких объектов (т.е. одинаково реагировать на изменения в каждом из них), а у одного объекта может быть несколько наблюдателей (т.е. при возникновении события выполняется несколько независимых методов-обработчиков). Это весьма увеличивает гибкость программирования.