Transcript Паттерны проектирования
Slide 1
Паттерны проектирования
Slide 2
Что такое паттерны?
Идея!
Slide 3
Постановка задачи
Компания выпустила игру SimDuck – успешный имитатор утиного пруда, в
котором плавают и крякают утки разных видов.
Slide 4
Теперь утки будут летать!
Для этого необходимо в суперкласс Duck добавить метод fly()
Slide 5
Побочные эффекты
В программе имитаторе начали летать все утки! Даже резиновые!
Локальное изменение кода привело к нелокальному побочному эффекту!
Slide 6
Вариант разрешения ситуации
Можно переопределить метод fly() в
классе RubberDuck() и оставить тело
метода пустым.
Но что произойдет, если в программу
добавятся другие виды уток?
Например, деревянные уткиприманки, которые ни летают, ни
крякают?
Slide 7
Тест
Какие из перечисленных недостатков относятся к
применению наследования для класса Duck?
1. Дублирование кода в подклассах
2. Трудности с изменением поведения на стадии
выполнения
3. Уток нельзя научить танцевать
4. Трудности с получением информации обо всех
аспектах поведения уток
5. Утки не могут летать и крякать одновременно
6. Изменения могут оказать непредвиденное влияние
на другие классы
Slide 8
Еще один вариант разрешения ситуации
Если спецификация программы будет меняться и
будут добавляться новые классы, то придется
искать и изменять методы fly() и quack() ВЕЧНО!
Более простой (чем пустое переопределение
методов) способ заставить только некоторых уток
летать и крякать – использовать интерфейсы!
При этом методы fly() и quack() необходимо
исключить из родительского суперкласса Duck.
Только те утки, которые должны летать и крякать,
реализуют соответствующий интерфейс.
Slide 9
Использование интерфейса
Slide 10
Использование интерфейса.
Недостатки
Наследование не является оптимальным в данном
случае.
Применение интерфейса частично решает проблему
(летают только те утки, которые реализуют интерфейс),
но создает новую – невозможность повторного
использования кода, т.к. интерфейсы не имеют
реализации.
Если утки должны летать по-разному, то применение
интерфейса в таком виде невозможно.
Единственная постоянная вещь в вашей программе –
изменения! Иначе приложение будет не востребовано!
Slide 11
Первый принцип проектирования
Выделите аспекты приложения, которые могут изменяться, и
отделите их от тех, которые всегда остаются постоянными!
Другая формулировка этого принципа:”Выделите переменные
составляющие и инкапсулируйте их, чтобы позднее их
можно было изменять или расширять без воздействия на
постоянные составляющие!”
Если не считать проблем с fly() и quack() класс Duck работает
хорошо.
fly() и quack() – изменяющиеся части класса Duck в зависимости от
подкласса.
Чтобы отделить эти переменные аспекты поведения от класса,
необходимо вынести их за пределы класса и создать новый набор
классов для представления этих аспектов.
Slide 12
Выделение аспектов
Slide 13
Второй принцип проектирования
Необходимо сохранить максимальную гибкость, иметь возможность
при создании объекта инициализировать его конкретным типом
поведения и менять тип поведения во время работы программы!
Для этого необходимо программировать на уровне
интерфейса, а не реализации!
Для представления каждого аспекта поведения FlyBehavior или
QuackBehavior будет использоваться интерфейс, а каждая
реализация аспекта поведения будет представлена реализацией
этого интерфейса (классами поведения).
Ранее поведение реализовывалось либо в классе Duck, либо в его
подклассах, т.е. зависело от реализации.
В новом варианте архитектуры подклассы Duck используют
поведение, представленное интерфейсами.
Slide 14
Почему интерфейс?
Интерфейс в данном случае означает супертип. Главной целью
применения полиморфизма посредством программирования на
уровне супертипа является отсутствие жесткой привязки к
конкретному объекту во время выполнения.
Программирование на уровне реализации
Dod d=new Dog();
d.bark();
Программирование на уровне супертипа
Animal an=new Dog();
An.getSound();
Slide 15
Реализация поведения уток
Slide 16
Преимущества использования подхода с
классами поведения
Возможно использовать поведение и в других
классах, потому что это поведение не скрывается в
классах Duck.
Можно добавлять новые аспекты поведения без
изменения существующих классов поведения и без
последствий для классов Duck.
Что необходимо сделать в новой архитектуре, что
бы утки могли летать на реактивной тяге?
Slide 17
Интеграция поведения с классом Duck
1.
2.
Сначала в класс Duck включаются две переменные
flyBehavior и quackBehavior с типом интерфейса поведения.
Каждый объект на стадии выполнения присваивает этим
переменным полиморфные значения.
Методы fly() и quack() удаляются из класса Duck и
заменяются аналогичными методами performFly() и
performQuack().
Slide 18
Интеграция поведения с классом Duck
Вместо того, что бы выполнять действие самостоятельно,
объект Duck поручает эту работу объекту, на который
ссылается quachBehavior.
В этой части кода совершенно не интересно, что это за
объект. Лишь бы он умел выполнять quack().
Slide 19
Инициализация поведения
Slide 20
Тестирование кода. №1
Slide 21
Тестирование кода №2
Slide 22
Тестирование кода №3
Slide 23
Запуск кода
Slide 24
Общий вид. Третий принцип
Отдавайте предпочтение композиции перед наследованием!
Slide 25
Задание
Slide 26
Решение
Slide 27
Исключительные ситуации в
Java и обработка событий
Slide 28
Обработка ошибок
Назначение механизма обработки
исключительных ситуаций – передача
данных из того места кода, где возник сбой,
обработчику ошибок, который может
справиться с ними.
При возникновении ошибок программа
должна сделать одно из двух:
вернуться в безопасное состояние и позволить
пользователю выполнить другие команды;
дать пользователю возможность сохранить
результаты своей работы и аккуратно
завершить программу.
Slide 29
Наиболее “популярные” виды
ошибок
Ошибки ввода (неправильный адрес
сайта)
Сбои оборудования (принтер отключен,
сайт недоступен)
Физические ограничения (переполнен
диск, исчерпана память)
Ошибки программирования (неверная
работа методов)
При возникновении ошибки возбуждается
объект, инкапсулирующий информацию об
ошибке.
Slide 30
Иерархия наследования
исключительных ситуаций
Throwable
Error
…
Exception
IOException
Runtime
Exception
…
Error – внутренние ошибки, связанные с исчерпанием ресурсов.
Возбудить объект подобного типа программист не может!
Exception – основная иерархия ошибок, которой следует уделять
внимание.
Slide 31
Иерархия Exception
Исключительные ситуации RuntimeException возникают
вследствие ошибок программирования. Все другие
исключительные ситуации – стечение обстоятельств.
RuntimeException
другие
Правило:
Неверное
приведениеситуация
типов RuntimeException, то это Ваша
есливозникла
исключительная
вина!
Выход за допустимые пределы массива
Попытка
обратиться
к объекту
ссылке null –
Все ошибки,
производные
от класса
Error по
и RuntimeError,
неконтролируемые,
все
остальные
– контролируемые.
Обрыв файла
Попытка соединиться с неправильным URL
Попытка обнаружить несуществующий объект класса Class
Slide 32
Объявление исключительных
ситуаций, возбуждаемых методом
Идея – метод предсказывает, какие ошибки могут возникнуть.
class MyAnimation{
public Image loadImage(String s) throws IOException,
MalformedURLException{
…
}
}
Неконтролируемые исключительные ситуации от классов
Error и RuntimeException объявлять не нужно. Пример
class MyAnimation{
void drawImage(int i) throws ArrayIndexOutOfBoundsException{
…
}
}
Slide 33
Возбуждение исключительных
ситуаций
Пример. Метод ReadData считывает из файла размером 1024
символа, однако чтение прервалось после 733 символа.
String ReadData (BufferReader in)
throws EOFException{
…
while(…)
{ if (ch == 1) //обнаружен конец файла
{ if (n < len )
EOFException e=new EOFException();
throw e;
}
…
} return s;
}
Если существует подходящий
класс исключений:
• Найти подходящий класс
исключений.
2. Создать объект этого
класса.
3. Возбудить его.
Slide 34
Создание классов
исключительных ситуаций
Если в программе возникает ситуация, не предусмотренная
ни одним из существующих классов исключения, достаточно
создать свой собственный класс от Exception или его
потомков (IOException).
class FileFormatException extend IOException{
public FileFormatException (){} //конструктор по умолчанию
Что(String
дальше?
public FileFormatException
g){ //”подробный” конструктор
super(g);}
}
…
String ReadData (BufferReader in) throws FileFormatException{
while(…)
{ if (ch == 1) //обнаружен конец файла
{ if (n < len ) throw new FileFormatException();}
…}
return s; }
Slide 35
Перехват исключительных
ситуаций (try/catch)
public void read (BufferReader reader){ Если оператор в секции try
try{
вызвал исключение, то
boolean done=false;
программа пропускает
while(!done)
оставшиеся операторы и
{ String line=reader.readLine();
переходит в секцию catch.
if (line == null) // конец файла
done = true;
Стандартный метод
else
readLine() может возбуждать
{Обработка строки line;} }
исключение IOException.
}
Если в секции catch нет
catch (IOException exception){
обработчика для такого
exception.printStackTrace();}
исключения, то метод
}
останавливает работу.
Slide 36
Распространение
исключительных ситуаций
Если в методе readLine() возникла ошибка, то можно
переложить обработку на вызывающий метод. Для этого
достаточно указать, что метод readLine() может возбуждать
исключительную ситуацию IOException.
public void read (BufferReader reader) throws IOException{
boolean done=false;
while(!done)
{ String line=reader.readLine();
if (line == null) // конец файла
done = true;
else
{Обработка строки line;} }
}
Slide 37
Перехват нескольких исключений
try {…}
catch (MalformedURLException e1){
…}
catch (UnknownHostException e2){
…}
catch (IOException e3){
…}
Объекты (e1, e2, e3)
исключительных
ситуаций могут
содержать информацию
о ней - e3.getMessage();
Тип объекта можно
определить
e3.getClass().getName()
.
Slide 38
Повторное возбуждение
исключительной ситуации
Иногда нужно перехватить исключение, сделать некоторые
действия и отправить исключение на дальнейшую обработку
в вызывающий метод:
Graphics g = image.getGraphics();
try{ код, который может вызвать исключение;}
catch(MalformedURLException e){
g.dispose();
throw e;}
Обработка исключения и передача нового:
Graphics g = image.getGraphics();
try{ код, который может вызвать исключение;}
catch(MalformedURLException e){
g.dispose();
throw new Exception(“My new exception”);}
Slide 39
Раздел finally
Graphics g = image.getGraphics();
try{ код, который может вызвать исключение;}
catch(IOException e){}
finally{
g.dispose();}
Graphics g = image.getGraphics();
try{ код, который может вызвать исключение;}
finally{
g.dispose();}
Slide 40
Обработка событий
Slide 41
Модель событий
Любой графический компонент может инициировать событие.
Каждое отдельное событие представлено определенным
классом. Когда событие инициируется, оно принимается
одним или несколькими слушателями Listener, которые его
обрабатывают. Таким образом, источник события и место его
обработки могут быть разнесены.
Слушатель каждого события – объект класса, реализующий
определенный вид интерфейса, характерного для всех
слушателей этого события. Необходимо создать объектслушатель и зарегистрировать его в компоненте, который
порождает событие. Слушатель – объект, заинтересованный
в получении события.
Slide 42
Модель событий
В объекте, который порождает событие, содержится список
слушателей, заинтересованных в получении уведомления,
что событие произошло. Источник оповещает слушателя
путем вызова спецметода и передачи события EventObject.
Регистрация события происходит с помощью метода
addXXXListener, принадлежащего компоненту, вызвавшему
событие, где XXX – тип обрабатываемого события
Метод getSource() класса event возвращает объект,
вызвавший событие
Удаление слушателя производится методом
removeXXXListener
Slide 43
Slide 44
Модель событий
В интерфейсе слушателя может определятся несколько
методов, например для MouseEvent. Если какой-либо класс
реализовывает интерфейс, то он обязан реализовать все
его методы. Это не удобно, если нас интересует всего один
из нескольких. Для этого для каждого интерфейса
слушателя, содержащего несколько методов, определен
простой класс адаптер, в котором эти методы пустые. Если
необходимо, то их можно переопределять.
Public class windowclosing extends WindowAdapter{
public void windowClosing(WindowEvent e){
………..}
}
Slide 45
Slide 46
Пример
public class Button2 extends JApplet {
private JButton b1 = new JButton("Button 1");
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String name = ((JButton)e.getSource()).getText();
txt.setText(name); }
}
private ButtonListener blistener = new ButtonListener();
public void init() {
b1.addActionListener(blistener);
......}
}
Slide 47
Пример
Можно не описывать как в предыдущем примере класс,
реализующий интерфейс, а затем создавать его экземпляр.
Следующий пример реализует те же действия, но более
коротким путем.
private ActionListener bl = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String name = ((JButton)e.getSource()).getText();
txt.setText(name);
}
Slide 48
Некоторые важные интерфейсы
MouseMotionListener и MouseMotionEvent:
mouseMoved()
mouseDragged()
MouseListener и MouseEvent:
mousePressed()
mouseReleased()
mouseClicked()
Методы события getX() и getY() возвращают координаты
Slide 49
Некоторые важные интерфейсы
KeyListener и KeyEvent:
keyTyped()
keyPressed()
keyReleased()
Метод события KeyEvent getKeyChar() возвращает символ
Slide 50
Благодарю за внимание!
Паттерны проектирования
Slide 2
Что такое паттерны?
Идея!
Slide 3
Постановка задачи
Компания выпустила игру SimDuck – успешный имитатор утиного пруда, в
котором плавают и крякают утки разных видов.
Slide 4
Теперь утки будут летать!
Для этого необходимо в суперкласс Duck добавить метод fly()
Slide 5
Побочные эффекты
В программе имитаторе начали летать все утки! Даже резиновые!
Локальное изменение кода привело к нелокальному побочному эффекту!
Slide 6
Вариант разрешения ситуации
Можно переопределить метод fly() в
классе RubberDuck() и оставить тело
метода пустым.
Но что произойдет, если в программу
добавятся другие виды уток?
Например, деревянные уткиприманки, которые ни летают, ни
крякают?
Slide 7
Тест
Какие из перечисленных недостатков относятся к
применению наследования для класса Duck?
1. Дублирование кода в подклассах
2. Трудности с изменением поведения на стадии
выполнения
3. Уток нельзя научить танцевать
4. Трудности с получением информации обо всех
аспектах поведения уток
5. Утки не могут летать и крякать одновременно
6. Изменения могут оказать непредвиденное влияние
на другие классы
Slide 8
Еще один вариант разрешения ситуации
Если спецификация программы будет меняться и
будут добавляться новые классы, то придется
искать и изменять методы fly() и quack() ВЕЧНО!
Более простой (чем пустое переопределение
методов) способ заставить только некоторых уток
летать и крякать – использовать интерфейсы!
При этом методы fly() и quack() необходимо
исключить из родительского суперкласса Duck.
Только те утки, которые должны летать и крякать,
реализуют соответствующий интерфейс.
Slide 9
Использование интерфейса
Slide 10
Использование интерфейса.
Недостатки
Наследование не является оптимальным в данном
случае.
Применение интерфейса частично решает проблему
(летают только те утки, которые реализуют интерфейс),
но создает новую – невозможность повторного
использования кода, т.к. интерфейсы не имеют
реализации.
Если утки должны летать по-разному, то применение
интерфейса в таком виде невозможно.
Единственная постоянная вещь в вашей программе –
изменения! Иначе приложение будет не востребовано!
Slide 11
Первый принцип проектирования
Выделите аспекты приложения, которые могут изменяться, и
отделите их от тех, которые всегда остаются постоянными!
Другая формулировка этого принципа:”Выделите переменные
составляющие и инкапсулируйте их, чтобы позднее их
можно было изменять или расширять без воздействия на
постоянные составляющие!”
Если не считать проблем с fly() и quack() класс Duck работает
хорошо.
fly() и quack() – изменяющиеся части класса Duck в зависимости от
подкласса.
Чтобы отделить эти переменные аспекты поведения от класса,
необходимо вынести их за пределы класса и создать новый набор
классов для представления этих аспектов.
Slide 12
Выделение аспектов
Slide 13
Второй принцип проектирования
Необходимо сохранить максимальную гибкость, иметь возможность
при создании объекта инициализировать его конкретным типом
поведения и менять тип поведения во время работы программы!
Для этого необходимо программировать на уровне
интерфейса, а не реализации!
Для представления каждого аспекта поведения FlyBehavior или
QuackBehavior будет использоваться интерфейс, а каждая
реализация аспекта поведения будет представлена реализацией
этого интерфейса (классами поведения).
Ранее поведение реализовывалось либо в классе Duck, либо в его
подклассах, т.е. зависело от реализации.
В новом варианте архитектуры подклассы Duck используют
поведение, представленное интерфейсами.
Slide 14
Почему интерфейс?
Интерфейс в данном случае означает супертип. Главной целью
применения полиморфизма посредством программирования на
уровне супертипа является отсутствие жесткой привязки к
конкретному объекту во время выполнения.
Программирование на уровне реализации
Dod d=new Dog();
d.bark();
Программирование на уровне супертипа
Animal an=new Dog();
An.getSound();
Slide 15
Реализация поведения уток
Slide 16
Преимущества использования подхода с
классами поведения
Возможно использовать поведение и в других
классах, потому что это поведение не скрывается в
классах Duck.
Можно добавлять новые аспекты поведения без
изменения существующих классов поведения и без
последствий для классов Duck.
Что необходимо сделать в новой архитектуре, что
бы утки могли летать на реактивной тяге?
Slide 17
Интеграция поведения с классом Duck
1.
2.
Сначала в класс Duck включаются две переменные
flyBehavior и quackBehavior с типом интерфейса поведения.
Каждый объект на стадии выполнения присваивает этим
переменным полиморфные значения.
Методы fly() и quack() удаляются из класса Duck и
заменяются аналогичными методами performFly() и
performQuack().
Slide 18
Интеграция поведения с классом Duck
Вместо того, что бы выполнять действие самостоятельно,
объект Duck поручает эту работу объекту, на который
ссылается quachBehavior.
В этой части кода совершенно не интересно, что это за
объект. Лишь бы он умел выполнять quack().
Slide 19
Инициализация поведения
Slide 20
Тестирование кода. №1
Slide 21
Тестирование кода №2
Slide 22
Тестирование кода №3
Slide 23
Запуск кода
Slide 24
Общий вид. Третий принцип
Отдавайте предпочтение композиции перед наследованием!
Slide 25
Задание
Slide 26
Решение
Slide 27
Исключительные ситуации в
Java и обработка событий
Slide 28
Обработка ошибок
Назначение механизма обработки
исключительных ситуаций – передача
данных из того места кода, где возник сбой,
обработчику ошибок, который может
справиться с ними.
При возникновении ошибок программа
должна сделать одно из двух:
вернуться в безопасное состояние и позволить
пользователю выполнить другие команды;
дать пользователю возможность сохранить
результаты своей работы и аккуратно
завершить программу.
Slide 29
Наиболее “популярные” виды
ошибок
Ошибки ввода (неправильный адрес
сайта)
Сбои оборудования (принтер отключен,
сайт недоступен)
Физические ограничения (переполнен
диск, исчерпана память)
Ошибки программирования (неверная
работа методов)
При возникновении ошибки возбуждается
объект, инкапсулирующий информацию об
ошибке.
Slide 30
Иерархия наследования
исключительных ситуаций
Throwable
Error
…
Exception
IOException
Runtime
Exception
…
Error – внутренние ошибки, связанные с исчерпанием ресурсов.
Возбудить объект подобного типа программист не может!
Exception – основная иерархия ошибок, которой следует уделять
внимание.
Slide 31
Иерархия Exception
Исключительные ситуации RuntimeException возникают
вследствие ошибок программирования. Все другие
исключительные ситуации – стечение обстоятельств.
RuntimeException
другие
Правило:
Неверное
приведениеситуация
типов RuntimeException, то это Ваша
есливозникла
исключительная
вина!
Выход за допустимые пределы массива
Попытка
обратиться
к объекту
ссылке null –
Все ошибки,
производные
от класса
Error по
и RuntimeError,
неконтролируемые,
все
остальные
– контролируемые.
Обрыв файла
Попытка соединиться с неправильным URL
Попытка обнаружить несуществующий объект класса Class
Slide 32
Объявление исключительных
ситуаций, возбуждаемых методом
Идея – метод предсказывает, какие ошибки могут возникнуть.
class MyAnimation{
public Image loadImage(String s) throws IOException,
MalformedURLException{
…
}
}
Неконтролируемые исключительные ситуации от классов
Error и RuntimeException объявлять не нужно. Пример
class MyAnimation{
void drawImage(int i) throws ArrayIndexOutOfBoundsException{
…
}
}
Slide 33
Возбуждение исключительных
ситуаций
Пример. Метод ReadData считывает из файла размером 1024
символа, однако чтение прервалось после 733 символа.
String ReadData (BufferReader in)
throws EOFException{
…
while(…)
{ if (ch == 1) //обнаружен конец файла
{ if (n < len )
EOFException e=new EOFException();
throw e;
}
…
} return s;
}
Если существует подходящий
класс исключений:
• Найти подходящий класс
исключений.
2. Создать объект этого
класса.
3. Возбудить его.
Slide 34
Создание классов
исключительных ситуаций
Если в программе возникает ситуация, не предусмотренная
ни одним из существующих классов исключения, достаточно
создать свой собственный класс от Exception или его
потомков (IOException).
class FileFormatException extend IOException{
public FileFormatException (){} //конструктор по умолчанию
Что(String
дальше?
public FileFormatException
g){ //”подробный” конструктор
super(g);}
}
…
String ReadData (BufferReader in) throws FileFormatException{
while(…)
{ if (ch == 1) //обнаружен конец файла
{ if (n < len ) throw new FileFormatException();}
…}
return s; }
Slide 35
Перехват исключительных
ситуаций (try/catch)
public void read (BufferReader reader){ Если оператор в секции try
try{
вызвал исключение, то
boolean done=false;
программа пропускает
while(!done)
оставшиеся операторы и
{ String line=reader.readLine();
переходит в секцию catch.
if (line == null) // конец файла
done = true;
Стандартный метод
else
readLine() может возбуждать
{Обработка строки line;} }
исключение IOException.
}
Если в секции catch нет
catch (IOException exception){
обработчика для такого
exception.printStackTrace();}
исключения, то метод
}
останавливает работу.
Slide 36
Распространение
исключительных ситуаций
Если в методе readLine() возникла ошибка, то можно
переложить обработку на вызывающий метод. Для этого
достаточно указать, что метод readLine() может возбуждать
исключительную ситуацию IOException.
public void read (BufferReader reader) throws IOException{
boolean done=false;
while(!done)
{ String line=reader.readLine();
if (line == null) // конец файла
done = true;
else
{Обработка строки line;} }
}
Slide 37
Перехват нескольких исключений
try {…}
catch (MalformedURLException e1){
…}
catch (UnknownHostException e2){
…}
catch (IOException e3){
…}
Объекты (e1, e2, e3)
исключительных
ситуаций могут
содержать информацию
о ней - e3.getMessage();
Тип объекта можно
определить
e3.getClass().getName()
.
Slide 38
Повторное возбуждение
исключительной ситуации
Иногда нужно перехватить исключение, сделать некоторые
действия и отправить исключение на дальнейшую обработку
в вызывающий метод:
Graphics g = image.getGraphics();
try{ код, который может вызвать исключение;}
catch(MalformedURLException e){
g.dispose();
throw e;}
Обработка исключения и передача нового:
Graphics g = image.getGraphics();
try{ код, который может вызвать исключение;}
catch(MalformedURLException e){
g.dispose();
throw new Exception(“My new exception”);}
Slide 39
Раздел finally
Graphics g = image.getGraphics();
try{ код, который может вызвать исключение;}
catch(IOException e){}
finally{
g.dispose();}
Graphics g = image.getGraphics();
try{ код, который может вызвать исключение;}
finally{
g.dispose();}
Slide 40
Обработка событий
Slide 41
Модель событий
Любой графический компонент может инициировать событие.
Каждое отдельное событие представлено определенным
классом. Когда событие инициируется, оно принимается
одним или несколькими слушателями Listener, которые его
обрабатывают. Таким образом, источник события и место его
обработки могут быть разнесены.
Слушатель каждого события – объект класса, реализующий
определенный вид интерфейса, характерного для всех
слушателей этого события. Необходимо создать объектслушатель и зарегистрировать его в компоненте, который
порождает событие. Слушатель – объект, заинтересованный
в получении события.
Slide 42
Модель событий
В объекте, который порождает событие, содержится список
слушателей, заинтересованных в получении уведомления,
что событие произошло. Источник оповещает слушателя
путем вызова спецметода и передачи события EventObject.
Регистрация события происходит с помощью метода
addXXXListener, принадлежащего компоненту, вызвавшему
событие, где XXX – тип обрабатываемого события
Метод getSource() класса event возвращает объект,
вызвавший событие
Удаление слушателя производится методом
removeXXXListener
Slide 43
Slide 44
Модель событий
В интерфейсе слушателя может определятся несколько
методов, например для MouseEvent. Если какой-либо класс
реализовывает интерфейс, то он обязан реализовать все
его методы. Это не удобно, если нас интересует всего один
из нескольких. Для этого для каждого интерфейса
слушателя, содержащего несколько методов, определен
простой класс адаптер, в котором эти методы пустые. Если
необходимо, то их можно переопределять.
Public class windowclosing extends WindowAdapter{
public void windowClosing(WindowEvent e){
………..}
}
Slide 45
Slide 46
Пример
public class Button2 extends JApplet {
private JButton b1 = new JButton("Button 1");
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String name = ((JButton)e.getSource()).getText();
txt.setText(name); }
}
private ButtonListener blistener = new ButtonListener();
public void init() {
b1.addActionListener(blistener);
......}
}
Slide 47
Пример
Можно не описывать как в предыдущем примере класс,
реализующий интерфейс, а затем создавать его экземпляр.
Следующий пример реализует те же действия, но более
коротким путем.
private ActionListener bl = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String name = ((JButton)e.getSource()).getText();
txt.setText(name);
}
Slide 48
Некоторые важные интерфейсы
MouseMotionListener и MouseMotionEvent:
mouseMoved()
mouseDragged()
MouseListener и MouseEvent:
mousePressed()
mouseReleased()
mouseClicked()
Методы события getX() и getY() возвращают координаты
Slide 49
Некоторые важные интерфейсы
KeyListener и KeyEvent:
keyTyped()
keyPressed()
keyReleased()
Метод события KeyEvent getKeyChar() возвращает символ
Slide 50
Благодарю за внимание!