МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах
РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ" ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах Гендерна антидискримінаційна експертиза може зробити нас моральними рабами ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів
Контакти
Тлумачний словник Авто Автоматизація Архітектура Астрономія Аудит Біологія Будівництво Бухгалтерія Винахідництво Виробництво Військова справа Генетика Географія Геологія Господарство Держава Дім Екологія Економетрика Економіка Електроніка Журналістика та ЗМІ Зв'язок Іноземні мови Інформатика Історія Комп'ютери Креслення Кулінарія Культура Лексикологія Література Логіка Маркетинг Математика Машинобудування Медицина Менеджмент Метали і Зварювання Механіка Мистецтво Музика Населення Освіта Охорона безпеки життя Охорона Праці Педагогіка Політика Право Програмування Промисловість Психологія Радіо Регилия Соціологія Спорт Стандартизація Технології Торгівля Туризм Фізика Фізіологія Філософія Фінанси Хімія Юриспунденкция |
|
|||||||
Слухачі подійПодієва модель в JFC Тепер розглянемо безпосередньо подієву модель Java. По-перше, треба відмітити, що вона повністю реалізована засобами стандартної бібліотеки Java ( JFC - Java Foundation Classes). По-друге, слід сказати, що подієва модель, у свою чергу, використовується в інших програмних парадигмах JFC як засіб реалізації або складова частина. До них відносяться MVC -архітектура (від Model - View - Controller), Java Beans і інші поняття. Отже знати основи подієвої моделі Java дуже важливо. Ми не розглядатимемо її повністю, в усіх аспектах, а лише з точки зору реального використання. Внутрішня реалізація подієвої моделі і ряд нюансів залишаться нерозглянутими. Базові класи, на яких заснована подієва модель, знаходяться в пакеті java.util . Власне об'єкт-подія (event state object) це - об'єкт класу, породженого від класу EventObject . Як вказувалося, цей об'єкт є носієм параметрів події, що сталася. Розглянемо документацію по EventObject . З неї можна зробити висновок, що мінімальний набір параметрів події - це об'єкт джерело події, яке може бути отримане методом public Object getSource() класу EventObject . Оскільки EventObject є базовим класом для усіх інших класів-подій, то цей метод присутній в усіх цих класах. Другий вивід, який можна зробити з документації, це само наявність об'єкту - джерела події. Тобто будь-яка подія в JFC завжди породжується деяким об'єктом, якогось класу. Отже, ми маємо дві дійові особи - об'єкт-джерело і об'єкт-подія . Третьою діючою особою є "слухач" (лісенер, listener ). Із слухачами подій ми вже зустрічалися в прикладах. Зараз розберемо це поняття детальніше. Слухачем може бути об'єкт будь-якого класу, що задовольняє певному інтерфейсу - інтерфейсу-слухачеві. Усі інтерфейси-слухачі породжені від базового інтерфейсу EventListener . Якщо ми подивимося документацію по цьому інтерфейсу, то побачимо, що він не має ніяких методів. Це означає, що усі слухачі мають різні методи для прослуховування подій. Усі інтерфейси-слухачі (за рідкісним виключенням) мають імена XXXListener . Тут під XXX мається на увазі деяке ім'я події. Наприклад, ActionListener або AWTEventListener, і так далі Об'єкти - джерела подій мають бути об'єктами класу, який має методи для реєстрації слухача addXXXListener і відключення слухача removeXXXListener . Відповідно, кожен конкретний клас - джерело подій дозволяє підключати до об'єкту-джерела тільки слухачі певних типів, для яких в класі є методи підключення addXXXListener . Робота моделі подій заснована на тому, що при настанні якої-небудь події об'єкт-джерело викликає певні методи інтерфейсу XXXListener для усіх об'єктів-слухачів, що реєструються. Слухачі представлені в JFC у вигляді інтерфейсів, а не класів тому, що по сенсу вони самі по собі нічого не повинні робити. Вони надають нам можливість написати програмний код, який виконуватиметься при настанні якої-небудь події. Розглянемо для прикладу простий інтерфейс-слухач ActionListener з пакету java.awt.event . Він містить єдиний метод public void actionPerformed(ActionEvent e)Цей метод викликається, коли виконана деяка дія. Що це за дію і коли воно відбувається, самим цим інтерфейсом не визначено. Але у ряді класів є методи addActionListener, які дозволяють зареєструвати слухача типу ActionListener для прослуховування тих або інших подій. Що це за події із змістовної точки зору (тобто в яких випадках вони відбуваються) - це описано в класі, що має метод addActionListener . По розглянутих прикладах ми знаємо, що для об'єкту класу JButton можна зареєструвати слухача типу ActionListener . Звернемося до документації по класу JButton . У документації ми побачимо, що в самому класі JButton метод addActionListener не визначений, але в його базовому класі AbstractButton такий метод є. На жаль, в документації по цьому методу не описано, коли викликається метод actionPerformed інтерфейсу ActionListener і можна лише здогадатися, що саме при натисненні цієї кнопки. Документація лише посилає нас до відповідного керівництва How to Use Buttons, Check Boxes, and Radio Buttons . Згадаємо розглянуті раніше приклади. Так в програмі Dialog4.java присутній такий фрагмент. btn.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ lbl.setText("Натиснута кнопка"); }});У цьому фрагменті використаний апарат анонімних класів для скорочення об'єму коду. Реалізуємо цей фрагмент в іншому еквівалентному виді, розписавши детально кожен етап. // 1. Клас ButtonListener1 реалізує інтерфейс ActionListenerclass ButtonListener1 implements ActionListener { public void actionPerformed(ActionEvent e){ lbl.setText("Натиснута кнопка"); }}// 2. Створюємо об'єкт слухач класу ButtonListener1ActionListener listener = new ButtonListener1();// 3. Для об'єкту - джерела подій (btn) реєструємо слухача (listener)btn.addActionListener(listener);У такому варіанті наочніше видно, що відбуватиметься. При натисненні на кнопку об'єкт btn згенерує подію ActionEvent, тобто фактично він створить об'єкт класу ActionEvent і викличе метод actionPerformed з цим об'єктом як параметр для усіх слухачів, що реєструються. Таким чином, в потрібний момент буде викликаний метод actionPerformed, який ми запрограмували в класі ButtonListener1 . В нашому прикладі цей метод ніяк не використовує інформацію з об'єкту події (параметр e ). В даному випадку вона не потрібна. Усе, що треба, нам вже відомо - сталося натиснення на кнопку btn . Уявимо собі іншу ситуацію. Нехай у нас в програмі декілька кнопок. В цьому випадку у нас є вибір з двох варіантів реалізації реакції на натиснення кнопок. Перший полягає в створенні для кожної кнопки окремого класу, окремого об'єкту цього класу і реалізації в кожному з методів actionPerformed необхідних дій. Тоді, як і в прикладі, нам не буде потрібно інформацію з параметра методу actionPerformed . Другий варіант полягає в створенні одного класу-слухача, одного об'єкту-слухача і в програмуванні усіх дій у рамках одного методу actionPerformed . Ось тут нам обов'язково буде потрібно параметр цього методу, оскільки тільки з його допомогою ми зможемо дізнатися, яка саме кнопка була натиснута. Приведемо в шаблонному виді реалізацію цього варіанту JButton btn1, btn2, btn3;...ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e){ JButton btn = (JButton) e.getSource(); if ( btn == btn1 ){ тут дії з натиснення на кнопку btn1 } else if ( btn == btn2 ){ тут дії з натиснення на кнопку btn2 } else if ( btn == btn3 ){ тут дії з натиснення на кнопку btn3 } }} btn1.addActionListener(listener);btn2.addActionListener(listener);btn3.addActionListener(listener);Обидва варіанти є прийнятними і в кожній конкретній ситуації можна вибрати один з них. · Відмітимо, що, коли б не апарат анонімних класів, який дає можливість записати реалізацію слухачів в компактній формі, то другий варіант був би прийнятнішим. · Цей приклад демонструє ще одну особливість слухачів. Ми не лише можемо до одного об'єкту - джерелу подій підключити ряд слухачів, але і одного слухача підключити до декількох об'єктів - джерел подій. Інтерфейс ActionListener дуже простий, він містить всього один метод. Але існують і складніші інтерфейси слухачів, наприклад, WindowListener, з яким ми теж вже зустрічалися в прикладах. Звернемося знову до документації. Інтерфейс WindowListener має такі методи. public void windowOpened(WindowEvent e)Викликається при відкритті вікна (коли воно стає видимим вперше). public void windowClosed(WindowEvent e)Викликається при закритті вікна. public void windowActivated(WindowEvent e)Викликається при активізації вікна. public void windowDeactivated(WindowEvent e)Викликається при деактивизации вікна. public void windowClosing(WindowEvent e)Викликається при спробі закрити вікно. public void windowIconified(WindowEvent e)Викликається при згортанні вікна в іконку на панелі. public void windowDeiconified(WindowEvent e)Викликається при розгортанні вікна з іконки в нормальний стан. Як бачимо тут досить багато методів. Вони викликаються в певних ситуаціях в деякій послідовності. Так, наприклад, при згортанні вікна в іконку буде викликаний спочатку метод windowDeactivated, потім windowIconified . Зазвичай для інтерфейсів-слухачів, що мають більш за один метод, створюються допоміжні класи-адаптери. У цих класах усе, або більшість методів цього інтерфейсу реалізовані і зазвичай нічого не виконують. Це зроблено з практичних міркувань. Якщо створювати клас, що задовольняє, скажімо, інтерфейсу WindowListener, то в нім треба реалізувати усі методи цього інтерфейсу. В той час, як найчастіше нас цікавить один або декілька методів цього інтерфейсу. Тут на допомогу приходять класи-адаптери. Свій клас можна успадкувати від класу-адаптера і перевизначити в нім потрібні методи. Саме так ми і робили в прикладах для організації завершення застосування при закритті головного вікна. WindowListener wndCloser = new WindowAdapter() { public void windowClosing(WindowEvent e){ System.exit(0); } }; addWindowListener(wndCloser);Тут для побудови анонімного класу використаний не інтерфейс WindowListener, як ми робили при роботі з ActionListener, а клас-адаптер WindowAdapter . В нім усі методи інтерфейсу WindowListener реалізовані, і ми можемо перевизначити тільки один метод, що цікавить нас, - windowClosing . Читайте також:
|
||||||||
|