Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
vidpovidi_OOP.doc
Скачиваний:
21
Добавлен:
23.02.2016
Размер:
281.6 Кб
Скачать

26. Механізм зворотного виклику. Інтерфейс ActionListener.

Механізм зворотнього виклику (callback) використовується при створенні графічного інтерфейсу користувача. Зворотній виклик означає, що програміст задає дії, які мають виконуватись за умови виконання деякої події, пов’язаної з натисканням на клавішу або на кнопку миші, наведення курсору та інші дії користувача. Кожна операційна система, що підтримує графічний інтерфейс, НЕПЕРЕРВНО відслідковує такі події і повідомляє про них програму, що виконується. В програмі указується як слід реагувати на ту чи іншу дію користувача.

В мові Java обробці підлягають події, які передбачені бібліотекою AWT. Кожний об’єкт можна визначити як обробник події („слухач події”, event listener). Інформація про події передається за допомогою об’єкту типу подія (ActionEvent).

Механізм обробки події бібліотеки AWT полягає в наступному:

 обробник події (слухач події) є екземпляр класу, що реалізує спеціальний інтерфейс;

 джерело події – це об’єкт, який може реєструвати обробників подій і надсилати їм об’єкти подій;

 коли відбувається подія, джерело події надсилає об’єкти події усім зареєстрованим обробникам;

 обробники використовують інформацію, що надійшла разом з об’єктом подія, для того, щоб вирішити, як реагувати на подію.

Для реєстрації обробника використовується синтаксис типу:

buttоn.addActionListener(listener);

buttоn - об’єкт, який є джерело події,

Action – подія,

listener – обробник події.

Оскільки слухачі подій мають різні методи для обробки подій, то для їх реалізації якнайкраще підходить механізм інтерфейсів. Дійсно, в інтерфейсі потрібно тільки указати, що мають виконуватись якісь дій, але які конкретно – указується в об’єкті, що підтримує даний інтерфейс.

Отже, ВСІ слухачі подій реалізуються на основі механізму інтерфейсів. Всі слухачі є нащадками інтерфейсу EventListener, який не має жодного метода (!). Це означає, що всі слухачі.

Розглянемо більш детально найпростіший інтерфейс-слухач ActionListener:

public interface ActionListener

{

void actionPerformed (ActionEvent event);

}

1. Об’єкт-джерело реєструє усіх обробників події за допомогою методу addActionListener(listener).

2. Об’єкт-обробник події (listener) створюється як такий, що підтримує інтерфейс ActionListener.

3. Об’єкт-слухач мітить метод actionPerformed (ActionEvent event), який описує дії, що виконуються при здійсненні події.

Об’єкт-джерело в момент здійснення події (натискання на кнопку. наприклад) створює об’єкт класу ActionEvent і передає його методу actionPerformed (ActionEvent event). Обробників події можна створити не один, а кілька. Тоді об’єкт-джерело передасть об’єкт класу ActionEvent в усі методи actionPerformed усіх зареєстрованих обробників.

Приклад:

public static void main(String[] args)

{

JButton SeizeButton = new JButton("Seize");

ActionListener listener = new SeizeListener();

SeizeButton.addActionListener(listener);

}

class SeizeListener implements ActionListener

//слухатель натискання на кнопку

{

public void actionPerformed(ActionEvent e)

{

smo.seize();

}

}

27.Внутрішні класи.28.Локальні внутрішні класи.

Внутрішній клас – це клас, опис якого міститься всередині іншого (зовнішнього) класу.

Внутрішній клас має доступ до УСІХ полів зовнішнього класу, у тому числі закритих.

Внутрішній клас можна скрити від інших класів.

Безіменний, або анонімний, внутрішній клас зручний для визначення зворотного виклику під час виконання програми.

Внутрішні класи дозволяють значно скоротити код програми. Але користуватись ними потрібно обережно.

Внутрішні класи, що визначені всередині метода, називають локальними внутрішніми класами. Область видимості локального внутрішнього класу обмежена блоком { …}, в якому він використовується. Однією з переваг локального класу є те, що він має доступ не тільки до полів зовнішнього класу, але й до параметрів методу, в я кому він використовується. Методи локального внутрішнього класу можуть використовувати тільки змінні, що об’явлені в методі як термінальні ( final ). Термінальні змінній присвоюється значення тільки один раз. Після цього змінити її значення неможливо. Єдине своє значення термінальна змінна може отримати як під час опису, так і після нього. Термінальна змінна, яка не отримала свого значення під час опису називається порожньою термінальною змінною.

Якщо в програмі створюється один об’єкт внутрішнього класу, то класу можна не присвоювати ім’я. Такий клас називають безіменним або анонімним. Анонімні класи широко використовуються при організації інтерфейсу користувача. Так, в наведеному вище прикладі змінна слухача listener класу SeizeListener використовується тільки один раз (як і сам клас), тому можна створювати змінну цього класу під час реєестрації слухача за допомогою анонімного класу:

Приклад:

SeizeButton.addActionListener(

new ActionListener()

/*створюється новий об’єкт анонімного класу, що реалізує інтерфейс ActionListener()*/

{

public void actionPerformed(ActionEvent e)

{

smo.seize();

text.append(" SEIZE, STATE = "+smo.getState()+"\n");

//throw new UnsupportedOperationException("Not supported yet.");

}

}

В загальному випадку синтаксис анонімного класу наступний:

new ім’яСупертипу (параметри, що використовуються для створення об’єкта)

{

поля та методи внутрішнього класу

}

У випадку з класом SeizeListener супертипом є інтерфейс ActionListener, тому використовується new ActionListener(). Супертипом може бути і клас, тоді анонімний внутрішній клас наслідує супертип.

(!)Якщо вслід за дужками, в яких містяться параметри об’єкта, указана відкрита фігурна дужка, це означає визначення анонімного внутрішнього класу.

Приклад:

package smallsmo;

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

public class ButtonFrame extends JFrame

{private JTextArea text;

private JScrollPane scroll;

private JPanel panel;

public ButtonFrame() //конструктор вікна

{

setTitle("Model SMO");

setSize(300,300);

this.setLocation(100,200);

panel = new JPanel(); //створення панелі

JButton SeizeButton = new JButton("Seize");

JButton ReleizeButton = new JButton("Releize");

JButton ResultsButton = new JButton("Results");

text = new JTextArea();

device D = new device();

queue Q = new queue();

final smo_simple smo = new smo_simple(D,Q);

SeizeButton.addActionListener(

new ActionListener() //слухатель натискання на кнопку

{

public void actionPerformed(ActionEvent e)

{

smo.seize();

text.append(" SEIZE, STATE = "+smo.getState()+"\n");

//throw new UnsupportedOperationException("Not supported yet.");

}

}

);

ReleizeButton.addActionListener(

new ActionListener() //слухатель натискання на кнопку

{

public void actionPerformed(ActionEvent e)

{

if(smo.getDevice().getState()==0)

JOptionPane.showMessageDialog(null, "Неможливо зайняти пристрій");

else

{

smo.releize();

text.append(" RELEIZE, STATE = "+smo.getState()+"\n");

}

}

}

);

ResultsButton.addActionListener

(

new ActionListener() //слухатель натискання на кнопку

{

public void actionPerformed(ActionEvent e)

{

text.setText("\n Результати моделювання: \n\n\n") ;

text.append(" кількість необслугованих вимог =

"+smo.getNumNeobsl()+"\n");

text.append(" кількість обслугованих вимог =

"+smo.getNumObsl()+"\n");

text.append(" максимальна кількість у черзі =

"+smo.getQueue().getMaxLength()+"\n");

}

}

);

panel.add(SeizeButton);

panel.add(ReleizeButton);

panel.add(ResultsButton);

panel.add(text);

add(panel,BorderLayout.NORTH);

scroll = new JScrollPane(text);

add(scroll,BorderLayout.CENTER);

}

}

package smallsmo;

import javax.swing.JFrame;

public class Main {

public static void main(String[] args) {

ButtonFrame f = new ButtonFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setVisible(true);

}

}

Внутрішній клас може бути об’явлений як статичний. В цьому випадку ім’я класу має вигляд

ім’я зовнішнього класу. ім’я внутрішнього класу

Приклад

public class FoundMin

{

public static void main(String[] args)

{

double[] massiv = new double[20];

for(int j=0;j<20;j++)

massiv[j] = 100*Math.random();

FoundPair.Pair p = FoundPair.min();

System.out.println(p.getMin());

}

}

class FoundPair

{

public static class Pair

{

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]