Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теория экзамен.doc
Скачиваний:
25
Добавлен:
29.05.2015
Размер:
516.61 Кб
Скачать

25. Событийная модель Java

Модель обработки событий Java 1.0

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

Каждый компонент может обрабатывать события, заместив определенные методы, вызываемые используемой по умолчанию реализацией метода handleEvents класса Component. Этот метод вызывается с объектом классаEvent, описывающего все возможные типы событий. Наиболее часто используемые события, например, те, что связаны с мышью и клавиатурой, диспетчеризируются другим методам класса Component.

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

  • mouseEnter вызывается в том случае, когда мышь входит в компонент.

  • mouseExit вызывается при выходе мыши из области компонента.

  • mouseMove вызывается при перемещении мыши в области компонента.

  • mouseDown вызывается при нажатии кнопки мыши.

  • mouseDrag вызывается при перемещении мыши с нажатой кнопкой.

  • mouseUp вызывается при отпускании кнопки мыши.

Аналогично, keyDown и keyUp вызываются при каждом нажатии и отпускании клавиши. Событие передается методу вместе с кодом нажатой клавиши. Событие можно проверить, чтобы посмотреть, нажаты ли в данный момент какие либо клавиши-модификаторы, для этой цели можно также пользоваться методами shiftDown, controlDown и metaDown. В классе Event определены десятки констант, позволяющих использовать символические имена, например, PGUP и HOME.

Наконец, для работы со специальными событиями, например, с обратными вызовами (callback) из компонентов Button, Scrollbar и Menu, вам придется замещать метод action. Этот метод вызывается с исходным событием и со вторым параметром, который представляет собой компонент пользовательского интерфейса, создавший это событие. Вы должны проверить этот объект, разобраться, какой из компонентов послал вам событие, после чего передать управление соответствующему данному компоненту обработчику. Для того, чтобы перед приведением типа проверить, принадлежит ли объект к определенному классу, например, к классу Button, вы можете использовать оператор instanceof.

А вот и пример на обработку событий. Мы добавили объект Label к примеру с игрой в “пятнашки”, а также заместили метод action для того, чтобы обрабатывать события, возникающие при нажатии кнопок. Точно такой же механизм можно использовать для управления вводом через любой из подклассов Component.

26. Чтобы обработать событие от компонента ему (компоненту) надо указать объект который будет этим заниматься. Например, для обработки управляющего (action) события это выглядит следующим образом:

AnyComponent.addActionListener(ObWhoMustHandleEvents);

Одному компоненту можно назначить, таким образом, несколько обработчиков событий. Каким же свойством должен объект, который сможет обработать событие (в нашем примере ObWhoMustHandleEvent)? Все очень просто - он должен имплементировать интерфейс ActionListener. В интерфейсе всего один метод: actionPerformed(ActionEvent e), который и нужно реализовать вашему объекту - обработчику события. Этот метод выполнится при возникновении события.

По аналогичной схеме обрабатываются и другие события. Например, чтоб обработать события от мыши, указываем функцией addMouseListener(ObWhoMustHandleEvents)объект, который будет их обрабатывать, этот объект должен имплементировать интерфейс MouseListener. Здесь нужно реализировать уже 5 функцийmousePressed(MouseEvent e)mouseReleased(MouseEvent e)mouseEntered(MouseEvent e)mouseExited(MouseEvent e) и mouseClicked(MouseEvent e). И так далее. Вот функции которыми обладают все компоненты для регистрации обработчиков событий:

  • addComponentListener - регистрирует обработчика таких событий как перемещение коппонента, изменение его размеров и т.д.

  • addFocusListener - регистрирует обработчика событий получения и потери компонентом фокуса

  • addKeyListener - регистрирует обработчика событий клавиатуры (когда компонент имеет фокус)

  • addMouseListener - регистрирует обработчика таких событий мыши как вход и виход мыши в область компонента, нажатие кнопки мыши, отпускание кнопки и клик мышью по компоненту

  • addMouseMotionListener - регистрирует обработчика событий простого движения мыши над компонентом и движения с нажатой кнопкой (drag)

Кроме того, разные компоненты могут иметь свои специфические события и соответственно имеют функции для назначения обработчиков этих событий. Например, для событий окон, таких как открытие, закрытие активизация окна и т.д., окна регистрируют обработчика событий (который имплементирует интерфейс WindowListener) функцией addWindowListener(ObWhoMustHandleEvents)

28

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

Простейший пример контейнера - класс Frame (форма), объекты которого отображаются на экране как стандартные окна с рамкой.

Форма представляет собой основу оконного графического интерфейса – это прямоугольное окно, которое пользователь может перемещать, растягивать, сворачивать/разворачивать и т.д. Форма содержит внутри себя различные элементы управления – панели, кнопки, текстовые поля, списки, таблицы т.д.. В Java форма представлена классом JFrame пакета javax.swing.

Для того чтобы скрыть (инкапсулировать) описание внутреннего содержимого формы, обычно для каждой формы создается новый класс – наследник JFrame. Элементы управления, содержащиеся на форме, объявляются в виде private-свойств класса формы, значения свойств формы и элементов управления задаются в конструкторе формы. В момент создания и отображения формы (например в main()), требуется лишь создать экземпляр класса формы и отобразить его на экране.

Основные методы формы:

  1. void setDefaultCloseOperation(EXIT_ON_CLOSE) – при закрытии формы приложение завершает свою работу;

  2. void setSize(int width, int height) – установить размер формы;

  3. void setTitle(String s) – установить заголовок формы;

  4. void setVisible(boolean b) – отобразить/скрыть форму;

  5. JPanel getContentPane() – получить ссылку на панель содержимого и т.д.

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

При разработке дизайна формы, обычно сначала определяют логическую структуру (иерархию) панелей, разбивая таким образом интерфейс программы на отдельные логические элементы. Базовой панелью (панелью верхнего уровня) формы, является «панель содержимого» (content pane) которая покрывает всю поверхность формы, за исключением заголовка. Панель содержимого всегда присутствует на форме и создается по умолчанию. В Java получить ссылку на панель содержимого можно с помощью метода getContentPane() формы.

В Java панель представлена классом JPanel пакета javax.swing. Класс JPanel как и большинство элементов управления (кнопки, списки, флажки и т.д.) является наследником класса JComponent, в котором содержится большая часть свойств и методов элементов управления

Размещение

Размещение (Layout), или «менеджер компоновки» определяет способ расстановки элементов управления на панели. Задавая панели различные способы размещения, можно выстроить элементы управления в горизонтальный или вертикальный ряд, разместить их «построчно», заставить элементы управления прижиматься к краям панели, накладываться друг на друга слоями и т.д.

Для того чтобы установить в панели новый способ размещения, нужно создать новый объект-размещение и назначить его панели с помощью метода setLayout().

Рассмотрим основные виды размещения:

FlowLayout заставляет элементы управления, размещенные на панели выстраиваться в горизонтальные ряды, при этом элементы управления размещаются последовательно, слева направо и переносятся по строкам, подобно словам в тексте:

BorderLayout заставляет элементы управления, размещенные на панели, полностью занять определенную область. При изменении размеров панели, элементы управления тоже изменяют свои размеры.

При данном типе размещения на панель можно добавить до пяти элементов управления. При добавлении, указывается константа – область в которой размещается добавляемый элемент управления. Константы содержатся в классе BorderLayout и соответствуют показанным на рисунке областям:

BGroup 86orderLayout.CENTER

BorderLayout.WEST

BorderLayout.EAST

BorderLayout.NORTH

BorderLayout.SOUTH

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

BoxLayout позволяет вам управлять вам размещением компонент либо вертикально, либо горизонтально, и управлять пространством между компонентами. Конструктор для BoxLayout немного отличается от других менеджеров компоновки — вы обеспечиваете Container, который будет управляться BoxLayout, в качестве первого аргумента, и направление компоновки в качестве второго аргумента. Для упрощения дела, есть специальный контейнер, называемый Box, который использует BoxLayout, как свой родной менеджер.

Элементы управления

Большинство элементов управления (кнопки, текстовые поля, метки, списки, панели, панели прокрутки, таблицы и т.д.) являются наследниками класса JComponent пакета javax.swing. В классе JComponent определены основные свойства и методы, присущие большей части элементов управления:

Некоторые из методов JComponent:

  • setPreferredSize(Dimension d) – установка размера элемента управления. Dimension – объект представляющий пару чисел width (ширина) и height (высота);

  • setBackground(Color c) – установка цвета фона. Color можно установить из набора констант, например Color.RED;

  • setForeground(Color c) – установка цвета содержимого;

  • setEnabled(Boolean b) – установка активности элемента управления;

  • setVisible(Boolean b) – установка видимости элемента управления и т.д.

Метка (JLabel)

Элемент управления Метка используется для отображения текста на форме.

Метод setText(String s) используется для задания текста метки.

Список (JList)

Список предназначен для отображения набора однородных элементов (например, строк) и предоставления пользователю возможности выбора элементов списка.

Для добавления элементов списка существует несколько методов. Один из наиболее полезных – метод setListData(Object o[]). Для использования этого метода нужно в классе, объекты которого передаются в список, переопределить метод String toString(), определив тем самым строку, которая будт служить текстовым представлением объектов данного класса. Метод setListData(Object o[]) требует в качестве параметра массив объектов, передает его в список, вызывает у каждого объекта метод toString() и формирует для каждого объекта строку списка.

Панель прокрутки (JScrollPane)

Используется в качестве контейнера для элементов управления для которых необходимо обеспечение прокрутки. Например, если создается список (JList), и, предположительно, содержимое списка может быть достаточно большим, т.е. выйти за пределы заданной области, то список помещается в панель прокрутки.

Для того, чтобы добавить элемент управления в панель прокрутки нужно вызвать метод getViewport(), который возвращает ссылку на внутреннюю панель панели прокрутки, и затем вызвать метод add(Component c).

Панель закладок (JTabbedPane)

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

В Java панель закладок представлена классом JTabbedPane пакета javax.swing.

Для добавления компонента-закладки на панель закладок используется метод add(Component c, Object o), в который помимо компонента-закладки можно указать объект (обычно строковый), который будет отображен в закладке

Пример:

tabbedPane1.add(panel1, “Панель 1”).

Текстовое поле (JTextField)

Текстовое поле – прямоугольное окно, предназначенное для отображения, ввода и редактирования текста.

В Java текстовое поле представлено классом JTextField пакета javax.swing. Класс JTextField является наследником класса JComponent, в котором содержится большая часть свойств и методов элементов управления.

Обработка событий

При работе пользователя с интерфейсом приложения возникает ряд событий – перемещение мыши по экрану, нажатие кнопок клавиатуры (например, ввод текста в текстовое поле), открытие/закрытие/перемещение формы, выбор элементов списка, нажатие кнопок и т.д.

Каждое возникающее событие может быть обработано, т.е. в программе указан набор операций (процедура), которые будут выполняться при возникновении данного события.

Событие с одной стороны относится к определенному элементу управления, с другой стороны у каждого элемента управления имеется множество событий, которые могут быть обработаны. Программист сам решает какие события у каких элементов управления обрабатывать, а какие нет. Например, если на форме размещены две кнопки button1 и button2, то мы можем у кнопки button1 запрограммировать (обработать) событие «нажатие на кнопку», а у кнопки button2 запрограммировать событие «перемещение мыши поверх кнопки». Это не значит, что, например, у кнопки button2 не происходит событие «нажатие на кнопку» когда пользователь щелкает на нее, но так как оно не обработано, то никаких специальных действий при этом выполняться не будет.

В Java для реализации механизма обработки событий применен специальный прием программирования, называемый «Слушатель». Суть этого метода в том, что каждому элементу управления может быть назначен специальный объект-слушатель, который прослушивает этот элемент управления на предмет возникновения события, и при его возникновении вызывает метод, определенный внутри объекта-слушателя. Этот метод и содержит операции, определяемые программистом и выполняемые при возникновении данного события.

Для каждого типа события (например «Нажатие на кнопку клавиатуры», «Выбор элемента списка» и т.д.) существует определенный интерфейс (interface), в котором содержатся объявления одного или нескольких методов, вызываемых при возникновении события. Класс-слушатель, предназначенный для обработки событий определенного типа должен реализовать соответствующий интерфейс и определить (реализовать) методы, объявленные в этом интерфейсе.

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

Создание класса слушателя, реализующего соответствующий интерфейс

Реализация в классе слушателя одного или нескольких методов, объявленных в интерфейсе и выполняемых в случае возникновения события.

Создание объекта-слушателя

Назначение объекта-слушателя прослушиваемому объекту (т.е. объекту, у которого необходимо обработать событие). Например:

class MyListener implements ListSelectionListener {

public void valueChanged(ListSelectionEvent e) {

/* последовательность действий, выполняемые в случае возникновения события */

}

}

Создаем объект-слушатель (в конструкторе формы):

MyListener m = new MyListener();

Назначаем объект-слушатель списку list1 с помощью метода списка (JList) addListSelectionListener(ListSelectionListener l):

list1.addListSelectionListener(ml);

Обращение к элементам списка (JList)

Элементы списка представляют собой коллекцию объектов. Для того чтобы получить выбранный пользователем объект - элемент списка используется метод Object getSelectedValue(). В случае, если в списке ничего не выбрано, метод возвращает null.

Динамическое определение типа объекта

Часто при обращении к объекту с помощью ссылки базового типа требуется определить точный тип (дочерний класс), которому принадлежит объект, однако нам требуется определить точный тип для объекта, на который ссылается объект.

Для решения подобных задач в JAVA используется механизм RTTI (run-time type identification – динамическое определение типа). Для определения точного типа объекта можно использовать логический оператор instanceof, который проверяет объект на принадлежность указанному классу и возвращает true, если объект принадлежит этому классу, и false если нет. Синтаксис оператора instanceof:

<ссылка на объект> instanceof <Класс>

Кнопки (JButton)

Кнопки используются для выполнения, подтверждения, отмены определенных действий. В JAVA кнопка объявляется с помощью класса JButton пакета javax.swing. Класс JButton является наследником класса JComponent, в котором содержится большая часть свойств и методов элементов управления

Обработка события «нажатие на кнопку»:

Для обработки нажатия на кнопку необходимо создать представителя класса, реализующего интерфейс ActionListener. Интерфейс ActionListener заставляет переопределить метод void actionPerformed(ActionEvent e). Этот метод выполняется при нажатии на кнопку.

Добавление слушателя нажатия кнопки выполняется с помощью метода кнопки (JButton) addActionListener(ActionListener a).

Стандартные диалоги (JOptionPane)

Диалог – окно, предназначенное для отображения определенной информации, подтверждения/отмены определенного действия, ввода данных и т.д.

В JAVA имеется набор стандартных диалогов, заключенных в классе JOptionPane. Диалоги разных типов создаются путем вызова статических методов класса JOptionPane, например:

  • void JOptionPane.showMessageDialog(…) – диалог, содержащий сообщение;

  • String JOptionPane.showInputDialog(…) – диалог, требующий ввод каких либо данных, возвращает строку, введенную пользователем;

  • int JOptionPane.showConfirmDialog(…) – диалог, требующий подтверждение/отмену какого-либо действия, возвращает целочисленную константу, соответствующую кнопке, нажатой пользователем (например, JOptionPane.YES_OPTION, JOptionPane.NO_OPTION,

JOptionPane.OK_OPTION, JOptionPane.CANCEL_OPTION).

Каждый из методов имеет несколько реализаций с различным набором параметров. Минимальный обязательный набор параметров практически для каждого типа диалога (2 параметра):

  • Component parentComponent – родительский компонент диалога (это может быть, например, кнопка, по которой вызывается диалог, форма относительно которой отображается диалог, панель и т.д.);

  • Object message – сообщение, отображаемое внутри диалога (например, «Сохранить изменения?» – для Confirm-диалога, «Введите название» – для Input-диалога).

Меню (JMenuBar, JMenu, JMenuItem)

Основное меню представляет собой иерархично организованный набор пунктов выбора, размещаемый в верхней части формы. В JAVA меню организуется с помощью классов JMenuBar, JMenu, JMenuItem:

  • JМenuBar – определяет область (панель) меню, служит контейнером для элементов, составляющих меню. Т.е. на форму сначала помещается панель меню (JМenuBar), а затем в нее помещаются элементы (JMenu, JMenuItem).

  • JMenu – представляет пункт меню, включающий себя другие пункты. Т.е. если элемент меню содержит подпункты, то он объявляется как JMenu. Класс JMenu наследуется от JMenuItem.

  • JMenuItem – представляет элементарный (листовой) пункт меню, т.е. пункт нижнего уровня, не включающий в себя другие подпункты.

Методы, необходимые для работы с меню:

При создании пункта меню (JMenu, JMenuItem) в конструкторе можно указать текст, размещенный в данном пункте, например: JMenu mnuFile = new JMenu(“Файл”);

Включение пунктов меню друг в друга осуществляется с помощью метода add(…)

Назначение меню форме осуществляется с помощью метода формы JFrame.setJMenuBar(JMenuBar menuBar).

Обработка событий меню

Обработка нажатия (выбора) пункта меню осуществляется аналогично обработке нажатия на кнопку (JButton): класс слушателя реализует интерфейс ActionListener, добавление объекта слушателя осуществляется с помощью метода addActionListener(ActionListener l) классов JMenu, JMenuItem.

Диалоги (JDialog)

Создание собственных диалогов похоже на создание собственных форм: создается новый класс – наследник JDialog, в заголовке объявляются элементы управления, в конструкторе задаются их свойства и т.д.

Одно из отличий диалогов JDialog от формы (JFrame) – это наличие свойства модальности. Модальность можно задать с помощью метода JDialog.setModal(boolean b)

Стандартный диалог сохранения/открытия файлов (JFileChooser)

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

В Java диалоги открытия/сохранения файлов представлены классом JFileChooser. Для того чтобы отобразить диалог на экране, необходимо создать объект указанного класса, при этом в конструкторе можно указать строку – путь к папке, которая будет отображаться по умолчанию при отображении диалога. Например, можно указать “c:\” для отображения корня диска С или “.” для отображения текущей папки (рабочей директории программы).

Далее для отображения диалога нужно вызвать один из двух методов объекта класса JFileChooser с указанием родительского компонента:

  • Int jFileChooser.showOpenDialog (Component parentComponent) – отображение диалога для открытия файла;

  • int jFileChooser.showSaveDialog (Component parentComponent) – отображение диалога для сохранения файла.

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

  • JFileChooser.APPROVE_OPTION – пользователь нажал «Open» или «Save» (в зависимости от типа диалога);

  • JFileChooser.CANCEL_OPTION – пользователь нажал «Cancel»/

После этого можно получить путь/имя выбранного в диалоге файла:

File jFileChooser.getSelectedFile () – возвращает объект типа File, соответствующий папке/файлу, выбранному в диалоге. Соответственно, String jFileChooser.getSelectedFile().getPath() – возвращает строку (String), содержащую полный путь + имя выбранного файла.