В java немає таких пойнять як “запис” у pascal, або “структура” в C, тут використовується найбільш широке, зручніше та узагальнююче пойняття –клас.
Для найкращого розуміння роботи та взаємодії класів, розглянемо графічну схему зв’язку класів – UML-діаграму класів (рис. 1.3.1).
Рис. 1.3.1 UML-діаграма класів програми.
Головним класом програми є клас MainFrame, який догружатиме у процесі роботи усі інші класи. Розглянемо його роботу, починаючи з методу main.
Розглянемо головний робочий цикл програми, головний поток.
Конструкція JFrame frame = getMainFrame(); використовується для запобігання запуску на данному ПК ще одної аналогічної програми, що зашкодить її нормальній роботі.
При наступному визові
frame = getMainFrame();
frame.show();
Ще одно вікно не відкриється. Ми будемо працювати з тим же самим вікном.
Такий шаблон у програмуванні носить назву Singletone, тобто завжди у пам’яті ПК зберігається лише один екземпляр класу, що реалізує цей шаблон, повторне звернення до нього поверне той самий екземпляр.
|
|
завантажується конструктор класу;
завантажується необхідний драйвер для роботи з портами вводу/виводу com.sun.comm.Win32Driver.
відбувається перевірка наявності на ПК портів вводу/виводу, серед списку необхідних відбувається пошук необхідного нам lpt-порта, якщо такого в системі не знайдено, програма видає помилку та припиняє свою роботу;
утворюються два потоки на читання/запис у lpt-порт. У даному випадку потоками можна вважати специфічні вказівники на області пам’яті (регістри), яки відповідають зміст даних у lpt-порті;
проводиться ініціалізація утилітарних класів, що відповідають за прийом та передачу даних Receiver та Transmitter, при цьому слід зауавжити, що клас Receiver запускається у окремому потоку, що забезпечує безперервний опит стану lpt-порта;
задаються розміри вхідних та вихідних програмних буферів для запису/зчитування даних;
установлюється програма-володар порта, яка займає порт на весь час роботи з ним;
відбувається графічна ініціалізація програми;
Початкова ініціалізація на цьому закінчується. Після цього відбувається робота користувача з графічними елементами програми (кнопками, пунктами меню і т.п.).
а) Користувач натискає кнопку „Список активних модулей”. Визивається функція readModulesFromFile(). При цьому відбувається наступний порядок дій:
- очищується модель списку модулей;
- завантажується з файту Modules.properties список активних модулей, який користувач задав перед початком функціонування програми. Слід зазначити, що список модулей можна змінювати й під час роботи програми, слід тільки натиснути указану кнопку;
- заповнюється модель списку модулей.
|
|
б) Користувач нажимає кнопку „опитати модуль”, задавши попередньо значення номеру опитуємого модуля. Викликається метод askModule(Integer moduleNumber). При цьому відбувається наступний порядок дій:
утворюється новий екземпляр класу Module, йому передається вказаний номер модуля;
номер модуля конвертується у бітову послідовність;
за допомогою одиничного екземпляра класа Transmitter, метод sendBytes відбувається відправка бітової послідовності на порт, при цьому передані дані потрапляють у поток, що був проініційований раніше, який відповідає за передачу даних на порт;
після цього встановлюється пограмна затримка (що за умовчанням дорівнює 10 мілісекундам та може бути змінена користувачем під час роботи програми);
опрошується вхідний буфер порта, якщо значення не змінилося – викликається помилка „даний модуль не дає відповіді” у цьому випадку модуль може бути опитаний повторно. Якщо вхідний буфер не дорівнює константі довжини вхідного буфера, викликається помилка „помилка при отримані відповіді”, якщо помилок немає – робимо аналіз прийнятого пакету;
у вказаного об’єкта-модуля утворюється ініціюється поле weatherData, при цьому робиться перевірка переданого та прийнятого номерів модуля, якщо номери не співпадають, генерується помилка: „неспівпадіння номерів модуля”, робити аналіз прийнятих даних немає сенсу;
робиться перекодування прийнятої бітової послідовності у цілі числа та перевірка контрольної суми, якщо прийнята та щойно прорахована контрольні суми не співпадають – генерується помилка „помилка контрольної суми”;
за алгоритмами, що описані у методах класу WeatherData робиться перерахунок прийнятої перекодованої інформації з бітової послідовності у реальні показники;
на інформаційній панелі відображується отриманий результат.
в) Користувач натискає кнопку „опитати всі модулі”. Викликається метод askAllModules(). При цьому відбувається наступний порядок дій:
- циклічно опитується кожний модуль, за алгоритмом, наведаним у пункті “б”;
- якщо при опиті модуля виникають певні помилки – накопичуються у буфер, модуль набуває признак „недійсний”;
- відображується інформація про всі модулі з признаком „дійсний”;
- відображується інформація про помилки, що виникли під час опиту усіх модулей з указаням номеру модуля та тексту помилки.