Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методичка Java-технологии.doc
Скачиваний:
12
Добавлен:
01.05.2019
Размер:
793.09 Кб
Скачать

Контрольні питання.

  • Що таке процес?

  • Що таке потік?

  • Якими способами можна створити клас, екземплярами якого будуть потоки?

Завдання.

  1. Написати додаток, у якому використаються потоки. Використати завдання класу потоку як спадкоємця Thread. Клас потоку повинен забезпечувати в методі run порядковий несинхронізований вивід у консольне вікно чисел від 1 до 100 порціями по 10 чисел у рядку, розділених пробілами, причому перед кожною такою порцією повинна стояти напис “Thread 1:” для першого потоку, “Thread 2:” для другого, і т.д. Для виводу рядка задати в класі метод print10. У додатку по натисканні на першу кнопку повинні створюватися два або більше потоки, а при натисканні на другу вони повинні стартувати.

  2. Удосконалити додаток, забезпечивши синхронізацію за рахунок оголошення виклику print10 у методі run синхронізованим.

  3. Створити копію класу потоку, що відрізняється від первісної тем, що виводяться числа від 101 до 200, клас заданий як реалізуючий інтерфейс Runnable, а метод print10 заданий як синхронізований. Додати в додаток створення й старт потоків - екземплярів даного класу.

Лабораторна робота № 6.

Тема: Основні компоненти Java. Модель обробки подій. Слухачі подій.

Ціль: Одержання практичних навичок у роботі з основними

компонентами Swing та у використанні оброблювачів подій.

Короткі теоретичні відомості.

У моделі подій Swing компоненти можуть ініціювати (“збуджувати”) події. Кожен тип події представляється різними класами. Коли подія збуджується подія, вона приймається одним або декількома “слухачами”, які реагують на цю подію. Таким чином, джерело подій і місце, де подія обробляється, можуть бути розділені. Тому що ви звичайно використаєте компоненти Swing, як вони є, то необхідно писати код, що викликається в тому випадку, коли компонентів приймає подію, це гарний приклад поділу інтерфейсу й реалізації.

Кожен слухач події - це об'єкт класу, що реалізує певний тип інтерфейсу слухача. Як програміст, усе, що ви робите - це створюєте об'єкт слухача й реєструєте його в компоненті, що збуджує подія. Ця реєстрація виконується викликом методу addXXXListener( ) для компонента, що збуджує подію, у якому “XXX” представляє тип слухача події. Ви можете легко довідатися, який тип події може бути оброблений, переглянувши імена методів “addListener”, і якщо ви спробуєте слухати невірні події, ви виявите помилку часу компіляції. Тому, вся ваша событийная логіка переходить у клас слухача. Коли ви створюєте клас-слухач, головне обмеження в тім, що він повинен реалізовувати підходящий інтерфейс.

Усе компоненти Swing включають методи addXXXListener( ) і removeXXXListener( ), так що підходящий тип слухача може бути доданий і вилучений для кожного компонента. Ви заметете, що “XXX” у кожному випадку також представляє аргумент методу, наприклад: addMyListener(MyListener m). Наведена нижче таблиця 19 включає основні асоційовані події, слухачі й методи, поряд з основними компонентами, які підтримують ці певні події, забезпечуючи методи addXXXListener( ) і removeXXXListener( ). Ви повинні мати на увазі, що модель подій розроблена для розширення, так що ви можете нарахувати інші події й типи слухачів, що не потрапили в цю таблицю.

Таблиця 19.

Подія, інтерфейс слухача й методи додавання, видалення

Компоненти, що підтримують ця подія

ActionEvent ActionListener addActionListener( ) removeActionListener( )

JButton, JList, JTextField, JMenuItem й успадковані від них, включаючи JCheckBoxMenuItem, JMenu й JpopupMenu.

AdjustmentEvent AdjustmentListener addAdjustmentListener( ) removeAdjustmentListener( )

JScrollbar і все, що ви створюєте, реалізуючи Adjustable interface.

ComponentEvent ComponentListener addComponentListener( ) removeComponentListener( )

*Component й успадковані від нього, включаючи JButton, JCanvas, JCheckBox, JComboBox, Container, JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog, JFrame, JLabel, JList, JScrollbar, JTextArea й JTextField.

ContainerEvent ContainerListener addContainerListener( ) removeContainerListener( )

Container й успадковані від нього, включаючи JPanel, JApplet, JScrollPane, Window, JDialog, JFileDialog й JFrame.

FocusEvent FocusListener addFocusListener( ) removeFocusListener( )

Component й успадковані.

KeyEvent KeyListener addKeyListener( ) removeKeyListener( )

Component й успадковані.

MouseEvent (для кличів і переміщень) MouseListener addMouseListener( ) removeMouseListener( )

Component й успадковані.

MouseEvent (для кличів і переміщень) MouseMotionListener addMouseMotionListener( ) removeMouseMotionListener( )

Component й успадковані.

WindowEvent WindowListener addWindowListener( ) removeWindowListener( )

Window й успадковані від нього, включаючи JDialog, JFileDialog й JFrame.

ItemEvent ItemListener addItemListener( ) removeItemListener( )

JCheckBox, JCheckBoxMenuItem, JComboBox, JList і все, що реалізує ItemSelectable interface.

TextEvent TextListener addTextListener( ) removeTextListener( )

Усе, що успадковано від JTextComponent, включаючи JTextArea й JTextField.

Як тільки ви довідаєтеся, які події підтримує певний компонент, вам не потрібно буде шукати нічого, щоб відреагувати на цю подію. Ви просто:

  1. Берете ім'я класу події й видаляєте слово “Event”. До залишку додаєте слово “Listener”. Це інтерфейс слухача, що ви повинні реалізувати у вашому внутрішньому класі.

  2. Реалізуєте вищезгаданий інтерфейс і пишіть методи для подій, що ви хочете відслідковувати. Наприклад, ви можете стежити за рухом миші, тоді ви пишіть код методу mouseMoved( ) з інтерфейсу MouseMotionListener.

  3. Створюєте об'єкт класу слухача. Реєструєте його у вашому компоненті за допомогою методу, зробленого додаванням “add” до імені вашого слухача. Наприклад: addMouseMotionListener( ).

Деякі з інтерфейсів слухача представлені в таблиці 20:

Таблиця 20.

Інтерфейс слухача w/ adapter

Методи інтерфейсу

ActionListener

actionPerformed(ActionEvent)

AdjustmentListener

adjustmentValueChanged( AdjustmentEvent)

ComponentListener ComponentAdapter

componentHidden(ComponentEvent) componentShown(ComponentEvent) componentMoved(ComponentEvent) componentResized(ComponentEvent)

ContainerListener ContainerAdapter

componentAdded(ContainerEvent) componentRemoved(ContainerEvent)

FocusListener FocusAdapter

focusGained(FocusEvent) focusLost(FocusEvent)

KeyListener KeyAdapter

keyPressed(KeyEvent) keyReleased(KeyEvent) keyTyped(KeyEvent)

MouseListener MouseAdapter

mouseClicked(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent)

MouseMotionListener MouseMotionAdapter

mouseDragged(MouseEvent) mouseMoved(MouseEvent)

WindowListener WindowAdapter

windowOpened(WindowEvent) windowClosing(WindowEvent) windowClosed(WindowEvent) windowActivated(WindowEvent) windowDeactivated(WindowEvent) windowIconified(WindowEvent) windowDeiconified(WindowEvent)

ItemListener

itemStateChanged(ItemEvent)

У наведеній вище таблиці ви можете бачити, що деякі інтерфейси слухачів мають тільки один метод. Вони дуже прості для реалізації, тому що ви реалізуєте його, тільки коли напишіть цей певний метод. Однак інтерфейси слухачів, що мають кілька методів, менш приємні у використанні. Наприклад, те, що ви повинні завжди робити при створенні додатка, це забезпечення WindowListener для JFrame, так що коли ви одержуєте подію windowClosing( ), ви могли б викликати System.exit( ) для виходу з додатка. Але тому що WindowListener - це інтерфейс, ви повинні реалізувати всі інші методи, навіть якщо вони нічого не роблять. Це явний недолік.

Для рішення проблеми деякі (але не все) з інтерфейсів слухачів, які мають більше одного методу, забезпечуються адаптерами, імена яких ви можете бачити в наведеній вище таблиці. Кожен адаптер забезпечує за замовчуванням порожні методи для кожного методу інтерфейсу. Тому все, що вам потрібно зробити - це успадковувати від адаптера й перекрити тільки ті методи, які потрібно змінити. Наприклад, типовий WindowListener, що ви будете використати, виглядає так:

class MyWindowListener extends WindowAdapter {

public void windowClosing(WindowEvent e) {

System.exit(0);

}

}

Основне призначення адаптерів складається в полегшенні створення слухаючих класів.

Щоб переконається, що ці події дійсно збуджуються, і як експеримент, варто створити апплет, що відслідковує додаткове поводження JButton (а не тільки стежить за його натисканням). Цей приклад також показує вам, як успадковувати ваш власний об'єкт кнопки, тому що вона буде використатися як мішень для всіх подій, що цікавлять нас. Щоб зробити це, ви просто успадковуєте від JButton.

Клас MyButton - це внутрішній клас TrackEvent, так що MyButton може одержати доступ у батьківське вікно й управляти його текстовими полями, що необхідно для запису інформації статусу в поля батька. Звичайно це обмежена ситуація, тому що myButton може використатися тільки в з'єднанні з TrackEvent. Код такого роду іноді називається “глибоко зв'язаний”:

// Показ виникаючих подій.

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import com.bruceeckel.swing.*;

public class TrackEvent extends JApplet {

HashMap h = new HashMap();

String[] event = {

"focusGained", "focusLost", "keyPressed",

"keyReleased", "keyTyped", "mouseClicked",

"mouseEntered", "mouseExited","mousePressed",

"mouseReleased", "mouseDragged", "mouseMoved"

};

MyButton

b1 = new MyButton(Color.blue, "test1"),

b2 = new MyButton(Color.red, "test2");

class MyButton extends JButton {

void report(String field, String msg) {

((JTextField)h.get(field)).setText(msg);

}

FocusListener fl = new FocusListener() {

public void focusGained(FocusEvent e) {

report("focusGained", e.paramString());

}

public void focusLost(FocusEvent e) {

report("focusLost", e.paramString());

}

};

KeyListener kl = new KeyListener() {

public void keyPressed(KeyEvent e) {

report("keyPressed", e.paramString());

}

public void keyReleased(KeyEvent e) {

report("keyReleased", e.paramString());

}

public void keyTyped(KeyEvent e) {

report("keyTyped", e.paramString());

}

};

MouseListener ml = new MouseListener() {

public void mouseClicked(MouseEvent e) {

report("mouseClicked", e.paramString());

}

public void mouseEntered(MouseEvent e) {

report("mouseEntered", e.paramString());

}

public void mouseExited(MouseEvent e) {

report("mouseExited", e.paramString());

}

public void mousePressed(MouseEvent e) {

report("mousePressed", e.paramString());

}

public void mouseReleased(MouseEvent e) {

report("mouseReleased", e.paramString());

}

};

MouseMotionListener mml =

new MouseMotionListener() {

public void mouseDragged(MouseEvent e) {

report("mouseDragged", e.paramString());

}

public void mouseMoved(MouseEvent e) {

report("mouseMoved", e.paramString());

}

};

public MyButton(Color color, String label) {

super(label);

setBackground(color);

addFocusListener(fl);

addKeyListener(kl);

addMouseListener(ml);

addMouseMotionListener(mml);

}

}

public void init() {

Container c = getContentPane();

c.setLayout(new GridLayout(event.length+1,2));

for(int i = 0; i < event.length; i++) {

JTextField t = new JTextField();

t.setEditable(false);

c.add(new JLabel(event[i], JLabel.RIGHT));

c.add(t);

h.put(event[i], t);

}

c.add(b1);

c.add(b2);

}

public static void main(String[] args) {

Console.run(new TrackEvent(), 700, 500);

}

}

У конструкторі MyButton установлюється кольори викликом SetBackground( ). Всі слухачі встановлюються простим викликом методу.

Клас TrackEvent містить HashMap для зберігання рядків, що представляють тип події, і поля JTextField, які містять інформацію про події. Коли викликається report( ) він дає ім'я події й рядок параметрів події. Далі використається HashMaph із зовнішнього класу для пошуку реального JTextField, асоційованого із цим ім'ям події, і відбувається приміщення рядка параметрів у це поле.

Тепер, коли ви розумієте модель подій, ви готові подивитися як використати компоненти Swing.