Содержание

Слайд 2

План лекции Компонентный подход в программировании Технология JavaBeans Свойства компонентов JavaBeans

План лекции

Компонентный подход в программировании
Технология JavaBeans
Свойства компонентов JavaBeans
Графические компоненты JavaBeans
События компонентов

JavaBeans
Слайд 3

Объектный подход vs Компонентный подход Объектный подход Программа пишется как объектная

Объектный подход vs Компонентный подход

Объектный подход Программа пишется как объектная модель реальной или

воображаемой системы, объекты и их отношения легко понятны
Компонентный подход Программа собирается из заранее созданных компонентов, каковые могут быть достаточно сложны для понимания
Слайд 4

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

Понятие компонента

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

допускающий взаимодействие с другими компонентами
Особенности компонентов:
Многоразовое использование
Независимость от контекста
Кооперация с другими компонентами
Инкапсуляция
Самостоятельность как единицы программы
Компонент – объект, написанный в соответствии со спецификацией
Слайд 5

Требования к разработке компонентов Полная документация Более строгое тестирование Надежная проверка

Требования к разработке компонентов

Полная документация
Более строгое тестирование
Надежная проверка достоверности входных данных
Возврат

полезных сообщений об ошибках
Разработка с учетом непредусмотренного использования
Слайд 6

Контейнеры и компоненты Контейнер предоставляет контекст, в котором компоненты могут существовать

Контейнеры и компоненты

Контейнер предоставляет контекст, в котором компоненты могут существовать и

действовать совместно
Контейнер тоже может быть компонентом
Это полностью рекурсивно!
Слайд 7

Существующие компонентные модели JavaBeans Enterprise JavaBeans .Net Framework Components ActiveX COM

Существующие компонентные модели

JavaBeans
Enterprise JavaBeans
.Net Framework Components
ActiveX
COM
DCOM
CORBA
VLC & CLX

Слайд 8

JavaBeans Компонентная модель для языка Java Компоненты называются Beans (бины) Компонент

JavaBeans

Компонентная модель для языка Java
Компоненты называются Beans (бины)
Компонент описывается как класс,

удовлетворяющий определенным правилам
Следует различать компонент как класс компонента и компоненты как его экземпляры, использующиеся в программе
Для работы с компонентами используются специальные программные средства, позволяющие «визуально» настраивать компонент и его взаимодействие с другими компонентами (RAD-tools)
Слайд 9

Интроспекция Средства работы с бинами подвергают бины интроспекции Интроспекция – механизм,

Интроспекция

Средства работы с бинами подвергают бины интроспекции
Интроспекция – механизм, основанный на

рефлексии, позволяющий определить характеристики компонента, основываясь на информации, заключенной в именах элементов класса компонента и вспомогательных классах
Слайд 10

Компоненты JavaBeans Компонент имеет свойства, которые представляют собой характеристики компонента и

Компоненты JavaBeans

Компонент имеет свойства, которые представляют собой характеристики компонента и могут

быть изменены в процессе сборки
Компонент использует события для взаимодействия с другими компонентами
Компоненты обладают свойством персистентности: могут сохранять свое состояние в долговременное хранилище и затем восстанавливать его
Методы компонентов являются обычными методами Java и могут использоваться другими компонентами
Слайд 11

Достоинства JavaBeans Компактность Переносимость Поддержка механизмов интроспекции Способность к работе в

Достоинства JavaBeans

Компактность
Переносимость
Поддержка механизмов интроспекции
Способность к работе в графической среде быстрой разработки

приложений (RAD)
Слайд 12

Требования к компоненту JavaBeans Способность к инстанцированию нового экземпляра (бин –

Требования к компоненту JavaBeans

Способность к инстанцированию нового экземпляра (бин – не

интерфейс, не абстрактный класс)
Наличие конструктора по умолчанию (конструктора без параметров)
Возможность сериализации
Следование соглашениям об именах и способах проектирования
Использование модели делегирования обработки событий
Слайд 13

Удивительное рядом Нет общего супер-класса для бинов API пакета java.beans предоставляет

Удивительное рядом

Нет общего супер-класса для бинов
API пакета java.beans предоставляет только классы

поддержки функционирования компонентов JavaBeans
Нет никакого специализированного языка описания интерфейсов
Слайд 14

Свойства Виды свойств по способу доступа Допускающие запись Допускающие чтение Виды

Свойства

Виды свойств по способу доступа
Допускающие запись
Допускающие чтение
Виды свойств по сложности
Простые
Индексированные
Связанные
Контролируемые

Слайд 15

Простые свойства Доступны пользователю как пара методов доступа (setter/getter) Любой из

Простые свойства

Доступны пользователю как пара методов доступа (setter/getter)
Любой из этих методов

может отсутствовать, определяя таким образом доступность свойства для чтения/записи (read-only/write-only)
Соглашения именования:
Общий вид
public ТипСвойства getИмяСвойства()
public void setИмяСвойства(ТипСвойства значение)
Логические свойства
public boolean isИмяСвойства()
public void setИмяСвойства(boolean значение)
Слайд 16

Бин с простым свойством package beans; public class MyBean implements java.io.Serializable

Бин с простым свойством

package beans;
public class MyBean implements java.io.Serializable {
private String

message;
public MyBean() {
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Слайд 17

Работа с простыми свойствами

Работа с простыми свойствами

Слайд 18

Индексированные свойства Определяют доступ к массиву свойств с возможностью доступа по

Индексированные свойства

Определяют доступ к массиву свойств с возможностью доступа по номеру
Соглашения

именования:
public ТипСвойства[] getИмяСвойства()
public void setИмяСвойства (ТипСвойства[] значения)
public ТипСвойства getИмяСвойства (int индекс)
public void setИмяСвойства (int индекс, ТипСвойства значение)
Слайд 19

Бин с индексированным свойством public class MyBean implements java.io.Serializable { private

Бин с индексированным свойством

public class MyBean implements java.io.Serializable {
private String[]

lines = new String[5];
public String[] getLines() {
return lines;
}
public void setLines(String[] lines) {
this.lines = lines;
}
public String getLines(int index) {
return lines[index];
}
public void setLines(int index, String line) {
this.lines[index] = line;
}
}
Слайд 20

Работа с индексированными свойствами

Работа с индексированными свойствами

Слайд 21

Связанные свойства Поддерживают механизм оповещения об изменениях значений свойств Обработчики реализуют

Связанные свойства

Поддерживают механизм оповещения об изменениях значений свойств
Обработчики реализуют интерфейс PropertyChangeListener

и принимают объекты PropertyChangeEvent, содержащие имя свойства и его старое и новое значения
Используется вспомогательный класс PropertyChangeSupport
Слайд 22

Бин со связанным свойством public class MyBean implements PropertyChangeListener, Serializable {

Бин со связанным свойством

public class MyBean implements PropertyChangeListener, Serializable {
private

String message;
private String[] lines = new String[5];
private final PropertyChangeSupport pcs =
new PropertyChangeSupport(this);
public MyBean() {
pcs.addPropertyChangeListener(this);
}
public void addPropertyChangeListener(
PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(
PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
...
Слайд 23

Бин со связанным свойством ... public void setMessage(String message) { String

Бин со связанным свойством

...
public void setMessage(String message) {
String

old = this.message;
this.message = message;
pcs.firePropertyChange("message", old, message);
}
...
public void setLines(int index, String line) {
String old = this.lines[index];
this.lines[index] = line;
pcs.fireIndexedPropertyChange("lines", index, old, lines);
}
...
public void propertyChange(PropertyChangeEvent evt) {
//some property change logic
}
...
Слайд 24

Работа со связанными свойствами

Работа со связанными свойствами

Слайд 25

Контролируемые свойства Похожи на связанные свойства, но перед присвоением нового значения

Контролируемые свойства

Похожи на связанные свойства, но перед присвоением нового значения свойства

оно должно быть проверено обработчиками
Любой обработчик в праве запретить изменение, в этом случае значение свойства останется прежним
Обработчики реализуют интерфейс VetoableChangeListener и принимают объекты PropertyChangeEvent, содержащие имя свойства и его старое и новое значения
Используется вспомогательный класс VetoableChangeSupport
Слайд 26

Бин с контролируемым свойством public class MyBean implements java.io.Serializable { private

Бин с контролируемым свойством

public class MyBean implements java.io.Serializable {
private String

message;
private final VetoableChangeSupport vcs =
new VetoableChangeSupport(this);
public MyBean() {
vcs.addVetoableChangeListener(new VetoChangeListener());
}
public void addVetoableChangeListener(
VetoableChangeListener lnr) {
vcs.addVetoableChangeListener(lnr);
}
public void removeVetoableChangeListener(
VetoableChangeListener lnr){
vcs.removeVetoableChangeListener(lnr);
}
...
Слайд 27

Бин с контролируемым свойством ... public void setMessage(String message) { String

Бин с контролируемым свойством

...
public void setMessage(String message) {
String

old = this.message;
try {
vcs.fireVetoableChange("message", old, message);
this.message = message;
...
} catch (PropertyVetoException e) {
this.message = old;
}
}
...
}
Слайд 28

VetoChangeListener public class VetoChangeListener implements VetoableChangeListener { public void vetoableChange(PropertyChangeEvent evt)

VetoChangeListener

public class VetoChangeListener implements VetoableChangeListener {
public void vetoableChange(PropertyChangeEvent evt)
throws PropertyVetoException

{
String eventName = evt.getPropertyName();
if (eventName.equalsIgnoreCase("message")) {
String message = (String) evt.getNewValue();
if (message.toLowerCase().contains("hello")) {
throw new PropertyVetoException("Veto!!", evt);
}
System.out.println("Message applied = " + message);
}
}
}
Слайд 29

Графические компоненты Если компоненты содержит средства визуализации, то его суперкласом должен

Графические компоненты

Если компоненты содержит средства визуализации, то его суперкласом должен быть:
java.awt.Component если

создается компонент на базе AWT
javax.swing.JComponent если создается компонент на базе Swing
Хотя и компоненты AWT, и компоненты Swing являются компонентами JavaBeans, не рекомендуется смешивать их в одном контейнере
Слайд 30

Графический бин public class MyBean extends JComponent implements java.io.Serializable { private

Графический бин

public class MyBean extends JComponent
implements java.io.Serializable {
private String message

= "!!!";
...
protected void paintComponent(Graphics g) {
g.setColor(getForeground());
int height = g.getFontMetrics().getHeight();
if (message != null) {
g.drawString(message, 0, height);
}
}
...
Слайд 31

Графический бин ... public void setMessage(String message) { String old =

Графический бин

...
public void setMessage(String message) {
String old =

this.message;
try {
vcs.fireVetoableChange("message", old, message);
this.message = message;
pcs.firePropertyChange("message", old, message);
repaint();
} catch (PropertyVetoException e) {
this.message = old;
}
}
...
}
Слайд 32

Работа с графическим бином

Работа с графическим бином

Слайд 33

Модель делегирования обработки событий Событие – объект, описывающий изменение состояния источника

Модель делегирования обработки событий

Событие – объект, описывающий изменение состояния источника
Источник –

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

Модель делегирования обработки событий Слушатели должны зарегистрироваться у источника – события

Модель делегирования обработки событий

Слушатели должны зарегистрироваться у источника – события посылаются

только зарегистрировавшимся слушателям
Логика кода, обрабатывающего события, отделена от логики интерфейса, генерирующего события
Это реализация паттерна проектирования Observer
Слайд 35

Слушатели и источники Один источник может генерировать несколько типов событий Один

Слушатели и источники

Один источник может генерировать несколько типов событий
Один слушатель может

быть слушателем нескольких видов событий
Один слушатель может получать события одного вида от нескольких источников
Слушатель может быть источником для других слушателей и для самого себя
Источник может быть слушателем других источников и самого себя
Слайд 36

События JavaBeans Класс слушателя должен наследовать от базового типа слушателя для

События JavaBeans

Класс слушателя должен наследовать от базового типа слушателя для вида

событий EventListenerType
Чтобы слушатель события мог быть зарегистрирован, компонент должен предоставлять метод public void addEventListenerType(EventListenerType a)
Чтобы слушатель события мог отказаться от регистрации, компонент должен предоставлять метод public void removeEventListenerType(EventListenerType a)
Если компонент позволяет регистрировать одновременно ограниченное количество обработчиков события, то метод добавления слушателя должен объявлять исключение java.util.TooManyListenersException
Работа с событиями также может вестись на уровне средства разработки
Слайд 37

Работа с событиями

Работа с событиями

Слайд 38

Работа с событиями

Работа с событиями

Слайд 39

Работа с событиями

Работа с событиями

Слайд 40

Работа с событиями

Работа с событиями

Слайд 41

Результат работы приложения

Результат работы приложения

Слайд 42

Персистентнось Способность объекта существовать во времени, переживая породивший его процесс Для

Персистентнось

Способность объекта существовать во времени, переживая породивший его процесс
Для JavaBeans реализуется

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

Упаковка в Jar Класс компонента, вспомогательные классы, файлы помещаются в jar-архив

Упаковка в Jar

Класс компонента, вспомогательные классы, файлы помещаются в jar-архив
В файле

манифеста при этом указывается дополнительная информация:

Name: beans/MyBean.class
Java-Bean: True

Слайд 44

Добавление библиотек в палитру

Добавление библиотек в палитру

Слайд 45

Вложенные типы © Составление, Будаев Д.С., Гаврилов А.В., 2013 Лекция 9.2 УНЦ «Инфоком» Самара 2013

Вложенные типы

© Составление, Будаев Д.С., Гаврилов А.В., 2013

Лекция 9.2

УНЦ «Инфоком»
Самара
2013

Слайд 46

План лекции Понятие вложенного типа Вложенные классы и интерфейсы Внутренние классы

План лекции
Понятие вложенного типа
Вложенные классы и интерфейсы
Внутренние классы

Слайд 47

Синтаксически корректный код class MyFirstClass { public static void main(String[] args)

Синтаксически корректный код

class MyFirstClass {
public static void main(String[] args) {

// ...
}
class MySecondClass {
private int a, b;
public MySecondClass(int a, int b) {
this.a = a;
this.b = b;
}
//...
}
}
Слайд 48

Вложенные типы Считаются частью внешнего типа, со всеми вытекающими правами Позволяют

Вложенные типы

Считаются частью внешнего типа, со всеми вытекающими правами
Позволяют представить тип

в виде логически связанных структурных групп и контекстов
Простой и эффективный инструмент объединения семантики соотносимых объектов
Слайд 49

Статические вложенные классы Простейшая форма вложенного класса Может использоваться любыми классами,

Статические вложенные классы

Простейшая форма вложенного класса
Может использоваться любыми классами, обладающими соответствующими

правами доступа
Классы, вложенные в интерфейсы, статичны по определению

class ClassA {
int a = 10;
protected static class ClassB {
int b = 15;
}
}
public class Test {
public static void main(String[] args) {
ClassA.ClassB t = new ClassA.ClassB();
System.out.println(t.b);
}
}

Слайд 50

Вложенные интерфейсы Всегда статичны (модификатор static по умолчанию) Доступ определяется доступом

Вложенные интерфейсы

Всегда статичны (модификатор static по умолчанию)
Доступ определяется доступом внешнего класса

или интерфейса и модификаторами доступа

class ClassA {
public interface InterfaceB {
//...
}
//...
public InterfaceB get() {
//...
}
}
public class Test {
public static void main(String[] args) {
ClassA.InterfaceB t = (new ClassA()).get();
}
}

Слайд 51

Нестатические вложенные классы Называются внутренними классами Тип находится в контексте объекта

Нестатические вложенные классы

Называются внутренними классами
Тип находится в контексте объекта
Объект внутреннего класса

всегда ассоциируется с т.н. внешним объектом
Элементы внутреннего класса имеют доступ к полям и методам внешнего объекта
Это позволяет создавать семейства сильно связанных объектов
Слайд 52

Пример внутреннего класса class ClassA { private int a = 10;

Пример внутреннего класса

class ClassA {
private int a = 10;
protected

class ClassB {
private int b = 15;
public int getA() { return a; }
public int getB() { return b; }
}
public ClassB getB() { return new ClassB(); }
public void setB(int b, ClassB obj) { obj.b = b; }
}
public class Test {
public static void main(String[] args) {
ClassA objA = new ClassA();
ClassA.ClassB objB = objA.getB();
objA.setB(20, objB);
System.out.println(objB.getA() + " " + objB.getB());
}
}
Слайд 53

И ещё один пример class ClassA implements Serializable { private ClassB[]

И ещё один пример

class ClassA implements Serializable {
private ClassB[] arr =

new ClassB[10];
{
for(int i = 0; i < 10; i++) {
arr[i] = new ClassB();
arr[i].a = i + 65;
}
}
public Interface getB(int index) { return arr[index]; }
private class ClassB implements Interface {
private int a;
public int getA() { return a; }
}
}
interface Interface extends Serializable { int getA(); }
Слайд 54

И его результат… public class Test { public static void main(String[]

И его результат…

public class Test {
public static void main(String[] args)

throws Exception {
ClassA objA = new ClassA();
Interface objB = objA.getB(5);
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("test.bin"));
out.writeObject(objB);
out.close();
}
}

¬н ♣sr ♪ClassA$ClassBиeТнwјЛ☻ ☻I ☺aL ♠this$0t ◘LClassA;xp Fsr ♠ClassAhќЯѓэЄрЈ ☻ ☺[♥arrt ►[LClassA$ClassB;xpur ►[LClassA$ClassB;єВ2 ♂т|­Ў ☻ xp sq ~ Aq ~ ♣sq ~ Bq ~ ♣sq ~ Cq ~ ♣sq ~ Dq ~ ♣sq ~ Eq ~ ♣q ~ ☻sq ~ Gq ~ ♣sq ~ Hq ~ ♣sq ~ Iq ~ ♣sq ~ Jq ~ ♣

Слайд 55

Локальные классы Описываются в теле блока Экземпляры имеют доступ к полям

Локальные классы

Описываются в теле блока
Экземпляры имеют доступ к полям и методам

внешнего объекта
Экземпляры имеют доступ к локальным переменным, снабженным модификатором final

public class ClassA {
public Iterator iterator() {
class Iter implements Iterator {
...
}
...
return new Iter();
}
...
}

Слайд 56

Локальные классы class A { protected char a = 'a'; }

Локальные классы

class A { protected char a = 'a'; }
class B

{ protected char b = 'b'; }
public class C extends A {
private char c = 'c';
public static char d = 'd';
public void createLocalObject(final char e)
{
final char f = 'f';
class Local extends B
{
char g = 'g';
public void printVars()
{
System.out.println(g + "," + f + "," + e); // local
System.out.println(d + "," + c); // outer
System.out.println(b + "," + a); // inherited
}
}
new Local().printVars();
}
}
Слайд 57

Анонимные классы Описываются непосредственно в выражении new и служат его частью

Анонимные классы

Описываются непосредственно в выражении new и служат его частью
Тип, указанный

после new является базовым для объявляемого анонимного класса
Могут расширять один класс или реализовывать один интерфейс
Явно писать implements или extends нельзя
Не могут иметь конструкторов
Слайд 58

Пример анонимного класса import java.awt.*; import javax.swing.*; public class MyApplet extends

Пример анонимного класса

import java.awt.*;
import javax.swing.*;
public class MyApplet extends JApplet {
...

public void init() {
JButton btn = new JButton("?");
getContentPane().add(btn);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
((JButton)e.getSource()).setText("!");
}
});
}
}
Слайд 59

Спасибо за внимание!

Спасибо за внимание!