Pracadyplomowainżynierska TomaszRozbicki › docstore › download › WUT307571 ›...

79
Politechnika Warszawska Wydzial Elektroniki i Technik Informacyjnych Instytut Informatyki Rok akademicki 2012/2013 Praca dyplomowa inżynierska Tomasz Rozbicki Edytor schematów elektrycznych wykorzystujący interfejs dotykowy dla urządzeń typu tablet z systemem Android Opiekun pracy: dr inż. Zbigniew Jaworski Ocena .................................. ......................................... Podpis Przewodniczącego Komisji Egzaminu Dyplomowego

Transcript of Pracadyplomowainżynierska TomaszRozbicki › docstore › download › WUT307571 ›...

  • Politechnika WarszawskaWydział Elektroniki i Technik Informacyjnych

    Instytut Informatyki

    Rok akademicki 2012/2013

    Praca dyplomowa inżynierska

    Tomasz Rozbicki

    Edytor schematów elektrycznychwykorzystujący interfejs dotykowy

    dla urządzeń typu tablet z systemem Android

    Opiekun pracy:dr inż. Zbigniew Jaworski

    Ocena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Podpis Przewodniczącego

    Komisji Egzaminu Dyplomowego

  • Specjalność: Informatyka –Inżynieria systemów informatycznych

    Data urodzenia: 9 sierpnia 1990 r.

    Data rozpoczęcia studiów: 21 lutego 2010 r.

    Życiorys

    Urodziłem się 9 sierpnia 1990 r. w Pułtusku. Edukację rozpocząłem w Szkole Podsta-wowej nr 3 w Pułtusku. Następnie uczęszczałem do Gimnazjum nr 1 oraz Liceum Ogólno-kształcącego im. Piotra Skargi w Pułtusku (klasa o profilu matematyczno-fizycznym). Wroku 2009 uzyskałemwykształcenie średnie oraz zdałem egzaminmaturalny, z matematykąoraz fizyką na poziomie rozszerzonym. W lutym 2010 roku rozpocząłem studia dzienne naWydziale Elektroniki i Technik Informacyjnych Politechniki Warszawskiej, kierunek infor-matyka. Obecnie pracuję na stanowisku młodszego programisty w firmie Samsung PolandR&D Center.

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .podpis studenta

    Egzamin dyplomowy

    Złożył egzamin dyplomowy w dn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

    Z wynikiem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

    Ogólny wynik studiów . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

    Dodatkowe wnioski i uwagi Komisji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

  • Streszczenie

    Tytuł: Edytor schematów elektrycznych wykorzystujący interfejs dotykowy dla urządzeń typu tabletz systemem Android.

    Praca inżynierska prezentuje budowę prostego edytora schematów elektrycznych na platformę An-droid. Aplikacja została zaprojektowana z myślą o urządzeniach mobilnych typu tablet, które wyróż-niają się dużą powierzchnią ekranu. Edytor umożliwia także synchronizację utworzonych schematówze zdalnym serwerem. Praca podejmuje problematykę implementacji edytora schematów, wykorzystu-jącego jedynie interfejs dotykowy, a zapewniającego podobne funkcje co aplikacje dostępne na kompu-tery osobiste.

    Abstract

    Title: Electrical schematic editor for tablet devices running Android OS.

    This thesis describes process of building simple electrical schematic editor for Android platform.The application is designed primarily for tablet devices which are equipped with large screens. It is alsopossible to synchronize the created schematics with remote server using the editor. The thesis addressessubject of implementation a schematic editor, which uses only the touch interface, but provides similarfunctionality to the editors available for personal computers.

  • Spis treści

    1. Wstęp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1. Dostępne edytory schematów elektrycznych . . . . . . . . . . . . . . . . . . . . . . . . 1

    1.1.1. Schematic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1.2. WeSpice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.1.3. EagleViewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    1.2. Cel pracy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42. Platforma Android . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

    2.1. Wybór platformy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.2. Segmentacja urządzeń . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.3. Wymagana wersja systemu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.4. Ograniczenie pamięci RAM dla aplikacji . . . . . . . . . . . . . . . . . . . . . . . . . . 9

    3. Struktura programu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.1. Edytor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.2. Pakiet wspólny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.3. Serwer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.4. Klient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.5. Biblioteki zewnętrzne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

    3.5.1. Bugsense . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.5.2. Guava . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.5.3. SimpleXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

    4. Edytor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154.1. Architektura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154.2. Model danych . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    4.2.1. Klasa Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.2.2. Komórka edytora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204.2.3. Model komponentu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274.2.4. Komendy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.2.5. Asocjacja informacji elementów elektrycznych . . . . . . . . . . . . . . . . . . . 314.2.6. Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

    4.3. Interfejs użytkownika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.3.1. Funkcje edytora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344.3.2. Tryb edytora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.3.3. Budowa widoku edytora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424.3.4. Widok komponentu elektrycznego . . . . . . . . . . . . . . . . . . . . . . . . . 454.3.5. Gesty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494.3.6. Preferencje debugowania . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544.3.7. Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

    4.4. Kontroler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564.4.1. Mapowanie punktu dotyku na indeks komórki . . . . . . . . . . . . . . . . . . 564.4.2. Sprawdzanie dozwolonej pozycje komponentu . . . . . . . . . . . . . . . . . . 574.4.3. Walidacja schematu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574.4.4. Wczytywanie schematu z pliku XML . . . . . . . . . . . . . . . . . . . . . . . . 584.4.5. Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

  • Spis treści ii

    4.5. Synchronizacja z serwerem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594.5.1. Aktywność synchronizacji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604.5.2. Komunikacja z serwerem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604.5.3. Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

    5. Serwer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645.1. Architektura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645.2. Konfiguracja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665.3. Argumenty terminala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

    6. Podsumowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69A. Konfiguracja środowiska . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

    A.1. IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70A.2. Java JDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71A.3. Budowanie projektu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71A.4. Użyteczne skrypty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

    A.4.1. cat_scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72A.4.2. diff_scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73A.4.3. ls_schemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73A.4.4. pull_scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73A.4.5. push_scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74A.4.6. rm_schemes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

  • 1. Wstęp

    Rynek aplikacji mobilnych na platformę Android liczy ponad 850 tys. pozycji, dostęp-nychwoficjalnym sklepieGoogle Play1. Producenci telefonów także posiadająwłasne sklepynp. Samsung Apps2, zatem ich liczba może być znacznie większa. Jedne z najpopularniej-szych kategorii aplikacji to: gry, rozrywka, muzyka, media oraz dostęp do sieci społeczno-ściowych. Wszystko to możemy zainstalować, często bez żadnych opłat, na smartfonie lubtablecie. Istnieją także produkty komercyjne, nastawione na zysk ze sprzedaży, lub darmowew momencie zakupu lecz wymagające płatności za dodatkowe funkcjonalności czy bonusy.

    Wobecnych czasach urządzeniamobilewyposażone sąwkilkurdzenioweprocesory orazpamięci RAM, której rozmiar sięga nawet kilku gigabajtów. Dzięki temu, producenci progra-mów komputerowych skłonni są wdrażać na platformymobilne produkty, które dotychczasdostępne były tylko na komputery osobiste. W przypadku profesjonalnych narzędzi bywa,że w znacznym stopniu ograniczone zostają funkcjonalności np. program nie udostępniamożliwości edycji zdjęcia, mimo iż wwersji komputerowej jest to możliwe. W kategorii edy-tora schematów elektrycznych, nie jest dostępny żaden zaawansowanyprodukt dla urządzeńz systemem Android.

    1.1. Dostępne edytory schematów elektrycznych

    Poniżej przedstawione są trzywybrane aplikacje dostępnewGoogle Play. Dwie pierwszeto edytory schematów elektryczych, trzecia umożliwia jedynie podgląd schematów utwo-rzonych za pomocą programu EAGLE3. Żaden z edytorów nie jest zgodny z już istniejącymiformatami zapisu schematów. Nie jest zatem możliwy import już istniejących schematów.Cowięcej wszystkie te produkty są oprogramowaniem komercyjnym, za które należy zapła-cić. Dostępne są jednak ich darmowe wersje z mocno ograniczonymi możliwościami, któreposłużyły do sporządzenia opisów programów. i

    1.1.1. Schematic

    Program posiada główny ekran edytora z możliwością 6-krotnego powiększenia siatki.Na górze ekranu znajduje się menu, z którego możemy dodać nowe obiekty, zapisaćlub wczytać schemat czy zarządzać ustawieniami edytora. Pozostałe funkcjonalnościrealizowane są poprzez długie przytrzymanie palca na obiekcie czy jednokrotne lub dwu-krotne stuknięcie (ang. tap) na nim. Regulacja powiększenia siatki edytora wykorzystujegest "uszczypnięcia"(ang. pinch-to-zoom). Wymagane jest, aby urządzenie posiadałowielodotykowy ekran (ang. multi-touch), gdyż gest formowany jest za pomocą dwóchpalców.

    1 Google Play – https://play.google.com/store2 Samsung Apps – http://apps.samsung.com/3 EAGLE – http://pl.wikipedia.org/wiki/Eagle_(program_komputerowy)

    https://play.google.com/storehttp://apps.samsung.com/http://pl.wikipedia.org/wiki/Eagle_(program_komputerowy)

  • 1.1. Dostępne edytory schematów elektrycznych 2

    Rysunek 1.1. Zrzut ekranu edytora Schematic.

    Adres: http://play.google.com/store/apps/details?id=ru.ustimov.schematicCena aplikacji: 11,05 zł

    1.1.2. WeSpice

    Poza tworzeniem schematów elektrycznych, WeSpice pozwala także na ich symulacjęza pomocą wbudowanego programu SPICE. Interfejs użytkownika jest podobny jak wprogramie Schematic. U góry ekranu znajduje się pasek narzędzi pozwalający na wybórpomiędzy tworzeniem schematu, jego symulacją oraz podglądem jej wyników. W wersjidemo nie jest możliwe dodawanie żadnych elementów elektronicznych, za to możemywstawiać punkty połączeniowe oraz linie je łączące. WeSpice także wykorzystuje gestyjednokrotnego i dwukrotnego stuknięcia do implementacji funkcjonalności np. modyfikacjiparametrów linii połączeniowej. Zamiast gestu długiego przytrzymania obiektu, zastoso-wano dodatkowe menu pojawiające się nad paskiem narzędzi, gdy element jest zaznaczony.Regulacja powiększenia edytora (maksymalnie około 15-krotnego) wykorzystuje gestpinch-to-zoom. Wygląd WeSpice przedstawiony jest na rysunku 1.2.

    Adres: https://play.google.com/store/apps/details?id=eu.lindentree.wespicedemoCena aplikacji: 61,13 zł

    1.1.3. EagleViewer

    Program umożliwia jedynie podgląd schematów elektrycznych i projektów płytek dru-kowanych, w odpowiednich formatach. Ich utworzenie jest możliwe za pomocą pro-gramu EAGLE. Regulacja siatki wykorzystuje gest pinch-to-zoom, ograniczony do około20-krotnego powiększenia. Wygląd programu EagleViewer przedstawiony jest na rysunku1.3.

    Adres: https://play.google.com/store/apps/details?id=de.elfsoft.eagleviewerCena aplikacji: 4,06 zł

    http://play.google.com/store/apps/details?id=ru.ustimov.schematichttps://play.google.com/store/apps/details?id=eu.lindentree.wespicedemohttps://play.google.com/store/apps/details?id=de.elfsoft.eagleviewer

  • 1.1. Dostępne edytory schematów elektrycznych 3

    Rysunek 1.2. Zrzut ekranu edytora WeSpice.

    Rysunek 1.3. Zrzut ekranu programu EagleViewer.

  • 1.2. Cel pracy 4

    1.2. Cel pracy

    Celempracy inżynierskiej jest stworzenie edytora schematów elektrycznych na platformęAndroid. Motywacją do budowy własnego rozwiązania jest brak darmowych narzędzi tegotypu. Obecnie dostępne narzędzia nie spełniają wszystkich potrzeb użytkowników jak np.łatwawymiana utworzonych schematów z komputeremosobistym. Następujące funkcjonal-ności są obligatoryjne, aby zapewnić kompletny zestaw narzędzi pozwalający na wygodnetworzenie schematów elektrycznych:

    — powiększanie i zmniejszanie widoku edytora,— wybór typu elementu elektrycznego,— dodawanie i usuwanie elementów,— zmiana położenia, rotacja i kopiowanie elementów,— łączenie elementów za pomocą linii połączeniowych,— ustawianie parametrów technicznych elementów,— zapisywanie i wczytywanie schematów,— możliwość cofnięcia i ponowienia ostatniej akcji.

    Dodatkowo edytor ma umożliwiać synchronizację zapisanych schematów ze zdalnymserwerem (w dwie strony tzn. pobranie schematu ze zdalnego serwera oraz wysłanie sche-matu z urządzenia mobilnego na serwer). Wynika z tego potrzeba stworzenia programuserwera i odpowiedniego protokołu komunikacji. W efekcie możliwa będzie pracowa nadschematem z wielu urządzeń mobilnych, przy wykorzystaniu tego samego serwera do ichsynchronizacji.

    Eksport oraz import w uniwersalnym formacie XML, ma pozwolić na edycję parame-trów elementów oraz ich rozmieszczenia na schemacie (nawet po stronie serwera), bez ko-nieczności uruchamiania aplikacji. W przyszłości istnieje takżemożliwość transformacji mo-deli XML do formatuwymaganego przez programywykonujące symulacje schematów elek-trycznych np. SPICE4.

    Kolejnym planowanym elementem jest nawigator, pokazujący aktualnie wyświetlanyfragment schematu oraz pozwalający w szybki sposób nawigować po nim. Lista dodat-kowych funkcjonalności, których nie posiada żadnen z dostępnych obecnie edytorów jestnastępująca:

    — połączenia elementów przez nazwę,— synchronizacja schematów elektrycznych ze zdalnym serwerem,— usuwanie schematów na zdalnym serwerze,— nawigator edytora.

    Edytor wyposażony będzie w podobny interfejs użytkownika co aplikacje Schematic iWeSpice. Menu z wyborem aktualej akcji oraz gesty takie jak dwukrotne stuknięcie czypinch-to-zoom są powszechnie stosowane w przeróżych aplikacjach. Użytkownicy tabletówsą przyzwyczajeni do ich używania na codzień. Przekłada się to na przyspieszenie edycjischematu, a także większą intuicyjność obsługi edytora. Wzorcem profesjonalnego rozwią-zania jest program EAGLE w wersji komputerowej.

    Aplikacja przeznaczona ma być głównie dla urządzeń typu tablet. Ze względu na dużyrozmiar ekranu, są to jedyne urządzenia które pozwalają na wygodną pracę z edytorem.Możliwe jednak będzie uruchomienie aplikacji na dowolnym urządzeniu z odpowiedniąwersją systemuAndroid. Może to zostać wykorzystane np. tylkow celu podglądu schematulub synchronizacji schematów z serwerem.

    4 SPICE – http://bwrcs.eecs.berkeley.edu/Classes/IcBook/SPICE/

    http://bwrcs.eecs.berkeley.edu/Classes/IcBook/SPICE/

  • 2. Platforma Android

    System operacyjny Android, tworzony początkowo przez firmę Android Inc., następnieprzejęty w 2005 roku przez Google Inc. jest obecnie najbardziej rozpowszechnionym sys-temem dla urządzeń mobilnych. Platforma oparta jest na jądrze systemu Linux i posiadaotwarty kod źródłowy. Projekt systemu nosi nazwę Android Open Source Project i jest zarzą-dzany przez konsorcjum firm pod nazwą Open Handset Alliance (Google, HTC, Motorola,Samsung, Sony oraz inne). Są to firmy zajmujące się produkcją sprzętu, oprogramowaniem,telekomunikacją oraz wspólnie rozwijające otwarte standardy dla urządzeń mobilnych.

    Pierwsza wersja systemu ukazała się w 2008 roku i konkurowała z takimi produktamijak Symbian, RIM,WindowsMobile czy iOS. Stały wzrost popularności zapewnił systemowiAndroid miano lidera rynku już po dwóch latach. Od tamtej pory ukazało się wiele nowychwersji systemu (obecnie najnowsza 4.2.2 Jelly Bean). Według najnowszych danych udostęp-nionych przez Google, codziennie rejestrowanych jest 1.35 miliona urządzeń, zaś całkowitaliczba już zarejestrowanych wynosi 750 milionów.

    Rysunek 2.1. Globalna sprzedaż smartfonów IV kw. 2012 w tys. sztuk.(źródło: http://en.wikipedia.org/wiki/Mobile_operating_system)

  • 2.1. Wybór platformy 6

    Wnioskując z rysunku 2.1, informacje podane przez Google wydają się potwierdzać.Niestety statystyk rynku samych tabletów próżno szukać. Są one często zaliczane do ogól-nych danych sprzedażowych smartfonów, gdyż tak na prawdę różnią się jedynie wielkościąekranu.

    2.1. Wybór platformy

    Wybór platformy na którą zostanie stworzony edytor nie jest przypadkowy. Obecnietablety wyposażone są w system Android lub iOS. Inne produkty są rzadko spotykane.Językiem programowania na platfomę Android jest jeden z najpopularniejszych językówprogramowania – Java. Aplikacje napisane w Javie działają pod kontrolą każdego systemu,dla którego istnieje maszyna wirtualna Javy. Co prawda system Android posiada własnąmaszynę wirtualną o nazwie Dalvik, jednak dla osoby tworzącej aplikacje nie ma to więk-szego znaczenia, gdyż język pozostaje taki sam. Dzięki temu bardzo szybko powstało wielebibliotek, umożliwiających uruchomienie istniejących aplikacji Java, bez konieczności prze-pisywania kodu źródłowego w innym języku. System iOS firmy Apple wykorzystuje językObjective-C, używanywOSX (system operacyjnyApple dla komputerów osobistych). Językjest specyficzny dla platformy i stosunkowo mało wykorzystywany poza nią.

    Drugim ważnym elementem decydującym o platformie docelowej była dostępność orazcena urządzeń. Apple proponuje dwie wersje swojego tabletu: iPad oraz iPad mini. Mniejszawersja dostępna jest od około półtora tysiąca polskich złotych. Ze względu, iż system iOSjest własnościowy, żadne inne produkty poza stworzonymi przez Apple raczej nie powstaną.Tablety z systemem Android są dostępne na rynku powszechniei. Ich ceny zaczynają sięod kilkuset polskich złotych a wybór modeli jest ogromny. Jest to znaczny plus systemuAndroid, gdyż nie ma konieczności posiadania względnie drogiego urządzenia.

    Kolejnym atutem systemu Android jest brak jakichkolwiek opłat za możliwość rozwija-nia aplikacji. Wszystkie narzędzia programistyczne dostarczane są za darmo. Jedyną opłatąjakąmusi wnieść programista jest 25 $ za założenie konta w sklepie Google Play. Tylko w tensposób każdy użytkownik będzie mógł ściągnąć jego aplikację. Opłata jest zwracana w mo-mencie likwidacji konta. Apple posiada odmienną politykę i proponuje 3 plany opłat: iOSDeveloper Program 99 $/rok, iOS Developer Enterprise Program 299 $/rok oraz plan darmowyiOS Developer University Program. O ile dla pracy inżynierskiej byłaby możliwość skorzysta-nia z planu bezpłatnego, to późniejsze rozwijanie aplikacji wiąże się z coroczną opłatą, którąmusi wnieść każdy programista z osobna.

    2.2. Segmentacja urządzeń

    Szeroka gama tabletów z systemem Android to jak stwierdzono powyżej duża zaleta.Ze względu na konkurencję ceny urządzeń są znacznie niższe. Jednak jest to tylko plus dlaużytkownikówurządzeń. Z punktuwidzenia programisty pojawia się problem segmentacji.Urządzenia posiadają procesory różniące się taktowaniem, a także liczbą rdzeni. Wyposa-żone są w różną ilość pamięci RAM, co wpływa na limity pamięci dostępne dla pojedynczejaplikacji. Posiadają różnego rodzaju ekrany, różniące się przede wszystkim przekątną aleco ważniejsze jego gęstością i rozdzielczością. Urządzenia mogą być wyposażone w kartęSIM, dostęp do sieci Wi-Fi, akcelerometr, żyroskop lub czujnik temperatury, lecz w cale niemuszą. Programista ma za zadanie tak zabezpieczyć aplikację, aby działała w każdych wa-runkach. Wymaga to od niego dużej wiedzy na temat budowy aplikacji oraz podjęcia decyzjiczy aplikację udostępnić na dany rodzaj urządzeń.

  • 2.3. Wymagana wersja systemu 7

    W przypadku urządzeń Apple praktycznie nie mamowy o segmentacji. Tworząc aplika-cję na wersję tabletu np. iPad i testując ją na takim urządzeniu, mamy pewność, że aplikacjabędzie wyglądała i działała identycznie u każdego użytkownika. Segmentacja na rynku ta-bletów z Androidem jest tak wielka, iż praktycznie niemożliwym jest posiadanie każdegodostępnego urządzenia. Pewnym zastępstwem może być emulator dostępny wraz z pozo-stałymi narzędziami programistycznymi. Za jego pomocą możliwe jest emulowanie para-metrów urządzeń oraz wersji systemu. Niestety nie jest to narzędzie doskonałe, ma swojeograniczenia jak np. brak możliwości emulacji wszystkich sensorów. Dodatkowo jest znacz-nie wolniejsze niż prawdziwe urządzenie. To wszystko przekłada się na znacznie większąilość pracy przy tworzeniu aplikacji dostępnej dla szerokiej gamy tabletów i smartfonów.

    2.3. Wymagana wersja systemu

    System Android jest stale rozwijany, dzięki czemu wprowadzane są nowe funkcjo-nalności oraz poprawiane są znalezione błędy. Za rozwój odpowiedzialna jest główniefirma Google Inc., która posiada także w sprzedaży własne urządzenia. Gdy na rynekwprowadzana jest nowa wersja systemu, produkty Google są zawsze aktualizowane.Niestety taki scenariusz nie odnosi się do globalnego rynku urządzeń z Androidem.Producenci sprzętu posiadają tak wiele różnorodnych wersji telefonów i tabletów, żewpierane są tylko najnowsze z nich. Starsze nie są aktualizowane, co powoduje segmentacjępod względem wersji systemu. Rysunki 2.2 i 2.3 przedstawiają rozkład wersji systemy wdwóch różnych okresach czasu.

    Rysunek 2.2. Rozkład wersji systemu na dzień 03.10.2012.(źródło: http://developer.android.com/about/dashboards/)

    Diagram 2.2 pokazuje stan na dzień rozpoczęcia pracy nad edytorem schematów, nato-miast 2.3 na dzień 1 maja 2013. Przez 7 miesięcy nastąpiły znaczące zmiany. Wersje poniżejEclair (2.1) praktycznie zniknęły z rynku, chociaż wcześniej zajmowały około 0.5%. Wersjadruga systemu (2.1 – 2.3.7) zmniejszyła swój łączny udział z 72.1% do 43.9%. Najważniejszą

  • 2.3. Wymagana wersja systemu 8

    Rysunek 2.3. Rozkład wersji systemu na dzień 01.05.2013.(źródło: http://developer.android.com/about/dashboards/)

    zmianą jest jednak przyrost urządzeń z najnowszą wersją systemu Jelly Bean, co pozwoliłona objęcie miana lidera z wynikiem 55.9% przez czwartą wersję systemu.

    W statystykach widnieje także wersja trzecia o nazwie Honeycomb. Jest to pierwsza ge-neracja systemu przeznaczona na urządzenia typu tablet. Założeniem wdrożenia systemuHoneycomb było odseparowanie dwóch różnych rynków - smartfonów i tabletów. Jak się oka-zało taki rodzaj podziału nie jest potrzebny (lub nawetmoże być przeszkodąw rozwoju), dla-tego też wersja czwarta stała się uniwersalnym, konfigurowalnym systemem, który możnazastosować w dowolnym urządzeniu.

    Wersja systemu to nie tylko nowe funkcjonalności dla użytkowników, ale także bogatszemożliwości programistyczne udostępnione deweloperom. Przy tworzeniu aplikacji progra-mistamusi określić wymaganąwersję systemu, dla którego przeznaczony jest tworzony pro-gram. Im niższy numer wersji, tym więcej użytkowników może zainstalować aplikację naswoich urządzeniach. Dla przykładu, przy zdefiniowaniuwymaganej wersji na API1 13 (Ho-neycomb) tracimy około 44% potencjalnych użytkowników. Ma to szczególne znacznie, gdyaplikacja jest płatna i naszym celem jest osiągnięcie jak największego zysku. Z drugiej stronywspieranie aplikacji dla bardzo starych wersji systemu może okazać się bardzo trudne.

    Android rozwija się bardzo dynamicznie, przez co przy zbyt nisko zdefiniowanej wersjiminimalnej nie mamy dostępu do najnowszych funkcjonalności. Wybór minimalnej wspie-ranej wersji to pewnego rodzaju kompromis pomiędzy rozmiarem rynku klientów a ogra-niczeniem możliwości programistycznych. Dla tworzonego edytora schematów, wymaganawersja systemy została ustawiona na 16-tą (Jelly Bean 4.1.x). Począwszy od tej wersji dostępnyjest szereg metod pozwalających zaimplementować niezbędne zachowania edytora. Apli-kacja nie jest wersją płatną, więc rozmiar rynku nie ma znaczenia z biznesowego punktuwidzenia. Jak pokazują wykresy, rozkład wersji systemu szybko się zmienia, dlatego też niewarto ograniczać się wsparciem dla starszych urządzeń.

    1 ang. Application Programming Interface – interfejs programowania aplikacji

  • 2.4. Ograniczenie pamięci RAM dla aplikacji 9

    2.4. Ograniczenie pamięci RAM dla aplikacji

    Bez względu na wybór miminalnej wersji systemu, na której będzie można uruchomićtworzoną aplikację, istnieją jeszcze dodatkowe ograniczenia, związane bezpośrednio z usta-wieniami fabrycznymi urządzenia. Podczas kompilacji systemu, producent ma możliwośćskonfigurować maksymalny rozmiar pamięci RAM zajmowany przez pojedynczą aplikację.Wartość ta jest wpisana na stałe do systemu i nie ma możliwości jej zmiany. W pierwszychwersjach systemu było to 16 MB lub 24 MB. Obecnie standardem jest 64 MB. Limit możezależeć nawet od rozdzielczości aparatu w który wyposażone jest urządzenie (np. 13 Mpixaparat potrzebuje nawet do 50 MB pamięci aby uchwycić zdjęcie). W wersji 3.x systemupojawiła się dodatkowa opcja, pozwalająca wymusić przyznanie jak największej ilościpamięci dla pojedynczej aplikacji (tzw. tryb dużej sterty). Jej użycie należy zdefiniowacw pliku AndroidManifest.xml, bedącym niezbędną częścią każdej aplikacji. Znajduje się onw głównym katalogu każdego projektu. Wymuszenie większej ilości pamięci RAM dlaaplikacji przedstawia wydruk 2.1.

    1

  • 2.4. Ograniczenie pamięci RAM dla aplikacji 10

    Pamięć dostępna dla pojedynczej aplikacji to 128 MB lub 512 MB w trybie dużej sterty (wy-muszone przez programistę). Drugie urządzenie to tablet GT-N8020. Wydajnościowo jest tosprzęt na podobnym poziomie co model GT-I9505, dodatkowo wyposażony jest w pamięćRAM o takiej samej pojemności. Mimo to producent zdecydował, że maksymalny rozmiarpamięci dla aplikacji to 64 MB, bez względu czy programista ustawi tryb dużej sterty. Po-zostałe dwa urządzenia to kilkuletnie smartfony. Posiadają znacznie mniej pamięci (odpo-wiednio 512 MB i 278 MB), jednak limit dla aplikacji także wynosi 64 MB. Brak danych wtrybie dużej sterty wynika z faktu, iż jest ona dostępna dopiero od wersji trzeciej systemu.

    Należywziąć pod uwagę, że całkowita dostępna pamięć na aplikacje, jest znaczniemniej-sza niż wynika z wiersza tabeli 2.4, ponieważ jest wykorzystywana także przez sam system.Gdyby pominąć ten fakt i założyć pesymistyczny wariant, iż każda aplikacja podczas dzia-łania zajmuje przydzielone 64 MB, to w pamięci RAM tabletu mogą znajdować się aż 32aplikacje w tym samym czasie. Z drugiej strony warto rozważyć przypadek, gdy urucho-miona jest dokładnie jedna aplikacja, która przekroczy dozwolony limit 64 MB. Mimo, żeprawie 2 GB pamięci jest kompletnie wolne, to aplikacja zakończy się błędem braku wolnejpamięci.

    Tworzony edytor schematów elektrycznych testowany był na urządzeniu GT-N8020. Re-strykcje dotyczące zajętości pamięci zostały zachowana z bezpieczym marginesem, dlategoteż nie powinno być żadnych problemów z uruchomieniem aplikacji na tabletach innychproducentów.

  • 3. Struktura programu

    Program edytora schematów elektrycznych składa się z dwóch głównych części. Jest toprojekt aplikacji na platformę Android oraz serwer na dowolną platformę, która posiada im-plementacjęmaszynywirtualej Java np. Windows, Linux czyMacOS. Aby połączyć oba pro-jekty, niezbędne byłowydzielenie częściwspólnej, zawierającej protokół komunikacji pomię-dzy klientem (edytorem) i serwerem. Dla ułatwienia rozwoju samego serwera, stworzonyzostał także prosty klient uruchamiany w JVM1, mający za zadanie emulować urządzeniemobilne. Potrzeba utworzenia emulatora podyktowana była perspektywą znacznie szyb-szego rozwoju, dzięki łatwiejszemu testowania i debugowania kodu. Komunikacja emula-tora (klienta) z serwerem poprzez lokalny interfejs sieciowy, nie wymaga zestawionego do-datkowego połączenia np. bezprzewodowego Wi-Fi. Byłoby to nieuniknione w przypadkutestowania aplikacji używając tabletu. W efekcie powstałe projekty połączone są ze sobąwspólną zależnością o nazwie et-common.

    Rysunek 3.1. Struktura zależności projektów.

    Projekty utworzone zostały przy pomocy zintegrowanego środowiska programistycz-nego Eclipse2 w wersji Eclipse IDE for Java Developers (Indigo). Środowisko jest w pełni dar-mowe, można je pobrać ze strony http://eclipse.org. Aby rozwijać aplikacje na platformęAndroid, niezbędna jest instalacja wtyczki ADT (Android Developer Tools). Więcej o konfigu-racji narzędzi można znaleźć na stronie Android Developers [1].

    Do budowy projektów et-common, et-server oraz et-client-javawykorzystano standardowąbibliotekę JDK (Java Development Kit), która zawiera także narzędzia do budowy graficznegointerfejsu użytkownika. Dodatkowo wykorzystane zostały trzy zewnętrzne biblioteki Bug-sense, Guava i SimpleXML opisane na końcu rozdziału.

    3.1. Edytor

    Projekt edytora schematów elektrycznych nosi nazwę et-client-android. Zawierakompletną implementację edytora schematów elektrycznych na platformę Android orazfunkcjonalość synchronizacji z serwerem. Wymagana jest kompilacja projektu w zgodnościz wersją 1.6 języka Java. Do stworzenia edytora schematów wykorzystany został Android

    1 Java Virtual Machine – maszyna wirtualna Javy2 Eclipse IDE – http://pl.wikipedia.org/wiki/Eclipse

    http://eclipse.orghttp://pl.wikipedia.org/wiki/Eclipse

  • 3.2. Pakiet wspólny 12

    SDK3, który dostarcza interfejs programistyczny oraz narzędzia deweloperskie do budowy,testowania i debugowania aplikacji na platformę Android.

    Struktura pakietów:pl.toro.et � pakiet gªówny

    config � konfiguracja rozmiarów powierzchni roboczej edytoradebug � funkcje do debugowania kodulogic � logika i model edytora

    editor � model pojedynczych elementów skªadaj¡cych si¦ na edytorscheme � model danych gotowego schematu elektrycznego

    component � modele elementów elektrycznychutil � pomocnicze klasy do opisu modeli

    synchro � serwis synchronizacji z serweremui � interfejs u»ytkownika edytora schematów

    activity � aktywno±ci (ang. activity) systemu Androidfragment � fragmenty interfejsu u»ytkownika skªadaj¡ce si¦ naaktywno±ci

    infomanager � okna ustawie« parametrów elementów elektrycznychpreference � ustawienia edytoraview � widoki zwi¡zane z reprezentacj¡ edytora

    component � widoki elementów elektrycznychline � widoki elementów specjalnych edytora (linie oraz punktypoª¡czeniowe)

    navigator � widoki nawigatora edtorautil � zbiór ró»nych widoków u»ywanych w caªej aplikacji

    3.2. Pakiet wspólny

    Projekt pakietu wspólnego nosi nazwę et-common. Zawarte są w niej interfejsy i klasywspółdzielone przez serwer i klientów. W pakiecie packet znajdują się definicje klasstanowiących protokół komunikacyjny. Z powodu różnic generowanego bytekodu dlaróżnych wersji JVM, pakiet wspólny musi być zgodny z najniższą wersją Javy użytą wpozostałych projektach (w tym przypadku 1.6).

    Struktura pakietów:pl.toro.et � pakiet gªówny

    config � wspólna konfiguracja serwera i klienta (ustawienia portu naktórym serwer oczekuje na poª¡czenia)

    io � interfejsy i abstrakcyjne klasy odpowiedzialne za komunikacj¦serwera i klienta

    packet � pakiety przesyªane pomi¦dzy klientem a serwerem (protokóªkomunikacji)

    3 Android SDK – http://developer.android.com/sdk

    http://developer.android.com/sdk

  • 3.3. Serwer 13

    3.3. Serwer

    Projekt serwera nosi nazwę et-server. Serwer może być uruchomiony w trybie zgraficznym interfejsem użytkownika oraz bez. W trybie z GUI4 wykorzystana zostałabiblioteka Swing5 dostępna w JDK. Konfiguracja portu na którym serwer oczekuje naklientów, zawarta jest w pakiecie wspólnym. Aby włączyć program serwera wymagana jestwirtualna maszyna Javy w wersji 1.7 lub wyższej.

    Struktura pakietów:pl.toro.et � pakiet gªówny

    config � dozwolone argumenty terminala przekazywane przy starcie serweraio � komunikacja z klientem (wysyªanie i odbieranie danych) orazzarz¡dzanie w¡tkami serwera

    main � klasa gªówna serwera, zawiera metod¦ mainmodel � stan serwera (logi, aktualny tryb pracy)resource � komunikaty serwera w j¦zyku angielskimview � elementy graficznego interfejsu u»ytkownika

    utils � widok menu, dolnego paska, listy logówwindows � widok gªównego okna serwera

    3.4. Klient

    Projekt klienta nosi nazwę et-client-java. Jest to emulator urządzenia mobilnego,komunikujący się z serwerem poprzez lokalny interfejs (ang. localhost), na standardowymporcie serwera. Klient posiada interfejs graficzny stworzony z użyciem biblioteki Swing. Douruchomienia programu wymagana jest wirtualna maszyna Javy w wersji 1.7 lub wyższej.

    Struktura pakietów:pl.toro.et � pakiet gªówny

    io � zestawianie poª¡czenia oraz utrzymywanie komunikacji z serweremmain � klasa gªówna emulatora klienta, zawiera metod¦ mainui � implementacja okna interfejsu graficznego emulatora

    3.5. Biblioteki zewnętrzne

    Zadaniem bibliotek zewnętrznych jest przyspieszenie rozwoju projektu lub dodanie spe-cjalistycznych funkcji. W aplikacji zastosowane zostały trzy biblioteki, Bugsense, Guava i Sim-pleXML, na licencjach Apache 2.0 orazMIT. Nie są to licencje wirusowe [2], zatem stworzonyedytor schematów elektrycznych może zostać wydany na dowolnej licencji.

    4 Graphical user interface – graficzny interfejs użytkownika5 Swing – http://pl.wikipedia.org/wiki/Swing_(Java)

    http://pl.wikipedia.org/wiki/Swing_(Java)

  • 3.5. Biblioteki zewnętrzne 14

    3.5.1. Bugsense

    Bugsense to narzędzie do śledzenia błędów aplikacji. Podczas rozwijania programuzazwyczaj urządzenie podłączone jest do komputera, więc przywystąpieniu błędu łatwo jestznaleźć przyczynę w logach. W przypadku gdy urządzenie nie jest podłączone, wszelkiedane o błędzie zostają utracone. Biblioteka Bugsense zbiera informacje o nieobsłużonychwyjątkach i błędach a następnie wysyła je na serwer, bez względu czy urządzenie w danymmomencie miało połączenie z internetem czy nie.

    Narzędzia tego typu są niezwykle przydatne, gdyż warunki w których wystąpił błądmogą być niekiedy bardzo trudne do odtworzenia. Informacje o błędzie zawierają kompletnyślad stosu (listę wywołań funkcji od punktu w którym aplikacja została uruchomiona dopunktuwktórymwystąpił błąd lubwyjątek), informacje o urządzeniu oraz jego stan (np. czyaktywne było połączenie z internetem). Deweloper może śledzić historię błędów poprzezkonsolę dostępną na stronie producenta biblioteki.

    Licencja: MIT6Adres: http://www.bugsense.com/

    3.5.2. Guava

    Guava to zbiór użytecznych narzędzi (klas) dla języka Java. Jest to projekt o otwartymkodzie źródłowym, tworzony głównie przez inżynierów firmy Google. Biblioteka zawieraimplementacje kolekcji, zapewnia lepsze wsparcie dla typów prymitywnych i łatwiejszetworzenie wielowątkowego kodu. W skrócie zawiera wiele udoskonaleń standardowegozestawu klas dostępnych w języku Java. Firma Google wykorzystuje tą bibliotekę przytworzeniu projektów w języku Java.

    W projekcie serwera oraz edytora wykorzystane zostały głównie niezmienne (ang. im-mutable) kolekcje, warunki sprawdzające argumenty przekazywane do metod oraz nie-zmienniki klas. Pomocne okazały się także funkcje niedostępne w standardowej klasiejava.util.Collections, a dostępne w Collections2 biblioteki Guava.

    Licencja: Apache 2.07Adres: https://code.google.com/p/guava-libraries/

    3.5.3. SimpleXML

    SimpleXML jest wysokowydajną biblioteką pozwalającą na serializację obiektów językaJava do postaci XML8. Jej celem jest zapewnienie jak najłatwiejszej konwersji obiektów na ję-zykXML.Wdrożenie SimpleXMLdoprogramuwymaga zaledwie kilku linijek. Wnaturalnysposób redukuje to ilość możliwych błędówwporównaniu zwłasnymi implementacjami se-rializacji. Konwersja jest możliwa w obie strony tzn. obiekty Java do XML oraz plik z XMLdo obiektów języka Java.

    Biblioteka została wykorzystana w projekcie edytora do zapisywania schematów elek-trycznych. Schematy w formie plików XML są przechowywane w pamięci stałej urządzeniamobilnego. Synchronizacja z serwerem polega na przesyłaniu schematu jako pliku. Wczy-tywanie utworzonych schematów jest całkowicie obsługiwane przez bibliotekę SimpleXML.

    Licencja: Apache 2.0Adres: http://simple.sourceforge.net/

    6 Licencja MIT – http://opensource.org/licenses/MIT7 Licencja Apache 2.0 – http://www.apache.org/licenses/LICENSE-2.0.html8 Extensible Markup Language – http://en.wikipedia.org/wiki/XML

    http://www.bugsense.com/https://code.google.com/p/guava-libraries/http://simple.sourceforge.net/http://opensource.org/licenses/MIThttp://www.apache.org/licenses/LICENSE-2.0.htmlhttp://en.wikipedia.org/wiki/XML

  • 4. Edytor

    Rozdział opisuje architekturę edytora schematów elekrycznych oraz zastosowane w nimalgorytmy. Podrodziały kolejno wyjaśniają budowę wzorca model-widok-kontroler, któryzostał zastosowany w aplikacji. Na końcu zawarte zostały dodatkowe informacje na tematfunkcjonalności edytora na platformę Android.

    4.1. Architektura

    Aplikacja została stworzona zgodnie z architekturą MVC1. Implementacja korzysta zewzorców Obserwatora [6] oraz Kompozytu [7], stąd często MVC nazywany jest złożonymwzorem projektowym, pozwalającym na separację reprezentacji informacji od interakcjiz użytkownikiem. Model składa się z danych oraz logiki ich przetwarzania. Widokjest tylko reprezentacją danych zawartch w modelu. Rolą kontrolera jest zarządzanieinterakcją z użytkownikiem. Wszystkie sygnały wejściowe dostarczone przez użytkownikasą odbierane przez kontroler, a następnie kierowane jako komendy do modelu lub widoku.Główną ideą wzorca MVC jest separacja odpowiedzialności poszczególnych części aplikacji.Umożliwienia to także ponownego użycie jego wydzielonych części w innych projektach.

    Rysunek 4.1. Działanie wzorca Model-Widok-Kontroler [4].

    1 Model-View-Controller – Model-Widok-Kontroler http://en.wikipedia.org/wiki/Model-View-Controller

    http://en.wikipedia.org/wiki/Model-View-Controllerhttp://en.wikipedia.org/wiki/Model-View-Controller

  • 4.1. Architektura 16

    Zastosowanie wzorca MVC jest często zalecane w programach zorientowanych obiek-towo, posiadających graficzny interfejs użytkownika [3]. W przypadku aplikacji edytoraschematów elektrycznych, zastosowanie separacji nawidok, model i kontrolerwydaje się na-turalne. Stan edytora, parametry elementrów elektrycznych, połączenia pomiędzy nimi orazhistoria operacji to elementy modelu. Są to dane, które następnie znajdują swoje odzwier-ciedlenie w postaci graficznej za pomocą widoków. Wszelka interakcja z użytkownikiempoprzez interfejs dotykowy urządzenia, trafia bezpośrednio do kontrolera, który odpowied-nio aktualizuje model oraz widoki w zależności od wykonanej akcji.

    Aplikacje dla systemu Android składają się z tzw. aktywności. Jedna wybrana aktyw-ność jest punktemwejściowym programu, można porównać ją dometodymain programuwjęzyku Java lub C. Pojedyncza aktywność traktowana jest jako kontener dla widoków. Przej-ście na kolejny ekran aplikacji oznacza zmianę aktywności. Niesie to ze sobą zmianę kon-tekstu, ponieważ aktywności nie współdzielą ze sobą utworzonych obiektów. Ze względuna specyfikę platformy mobilnej, utworzone wcześniej lecz niewidoczne (nie będące aktu-alnie na pierwszym planie) aktywności są kasowane w zależności od aktualnych potrzebsystemu [5].

    Cykl życia nie pozwala na użycie aktywności jako głównego konteneramodelu całej apli-kacji. Do tego celu przeznaczona jest klasa Application, która utrzymuje się w pamięci RAMdopóki aktywny jest systemowy proces2 powiązany z daną aplikacją. Klasa ta nazywanajest często globalnym kontekstem aplikacji, ponieważ dostęp do zgromadzonych w niej da-nych możliwy jest z dowolnej aktywności. Gdyby klasa Application nie istniała, identycznąfunkcjonalność osiągnąćmożna stosując wzorzec Singleton [8], który tworzy dokładnie jednąinstancję klasy, dostępną globalnie w całej aplikacji.

    Wydruk 4.1 przedstawia kompletną implementację głównego kontenera aplikacji.Konstruktor tworzy obiekt Model, który jest następnie przekazywany do nowo tworzonejinstancji kontrolera. Oba pola są finalne co zapobiega tworzeniu wielu obiektów typuModel i Controller. Poniżej konstruktora znajduje się jedyny akcesor, zwracający instancjękontrolera. W ten sposób niemożliwe jest pobranie modelu w żadnym miejscu aplikacji.

    1 public c l a s s App extends Applicat ion {

    private f ina l Model mModel ;private f ina l Cont ro l l e r mController ;

    5

    public App( ) {mModel = new Model ( ) ;mController = new Cont ro l l e r (mModel ) ;

    }10

    public Cont ro l l e r ge tCon t ro l l e r ( ) {return mController ;

    }

    15 }

    Wydruk 4.1. Główny kontener aplikacji. – App.java

    2 Proces systemowy – http://en.wikipedia.org/wiki/Process_(computing)

    http://en.wikipedia.org/wiki/Process_(computing)

  • 4.1. Architektura 17

    Aby w jakikolwiek sposób modyfikować dane należy najpierw pobrać instancjękontrolera z kontenera aplikacji. Kontroler udostępnia zestaw metod, które pozwalają nazmiany modelu oraz widoków. W ten sposób operacje dostępne na modelu nie są dostępnepublicznie, co zapobiega wykorzystaniu ich w niewłaściwy sposób. Kontroler stanowiinterfejs poprawnych operacji modyfikujących dane zgromadzone w modelu.

    1 public c l a s s Ed i to rAc t iv i t y extends Act iv i ty implements Observer {

    private Cont ro l l e r mController ;

    5 @Overridepublic void onCreate ( Bundle savedIns tanceS ta te ) {

    super . onCreate ( savedIns tanceS ta te ) ;

    App app = (App) getAppl ica t ion ( ) ;10 mController = app . ge tCon t ro l l e r ( ) ;

    mController . setUiChangeListener ( th i s ) ;}

    @Override15 public void update ( Observable observable , Object data ) {

    ModelChangeHolder holder = (ModelChangeHolder ) data ;. . .

    }

    20 }

    Wydruk 4.2. Pobranie instancji kontrolera wewnątrz aktywności.– EditorActivity.java

    Po pobraniu instancji kontrolera, aktywność rejestruje się w modelu, aby nasłuchiwaćzdarzeń aktualizacji interfejsu użytkownika (wydruk 4.2). W ten sposóbwidok rejestrowanyjest jako obserwator modelu. W przypadku, gdy użytkownik wykona akcję wymagającązmian w modelu i aktualizacji widoków, wywołana zostanie metoda update z argumentemtypu ModelChangeHolder. Zawiera on niezbędne informacje, jaką akcję należy podjąć, abyodświeżyć odpowienie elementy interfejs użytkownika.

    Dla przykładu wywołanie metody addToHistory dostępnej w klasie Model, spowodujedodanie komendy na stos, w celu ewentualnej możliwości jej cofnięcia (wydruk 4.3). Ele-menty stosu operacji ’ponów’ muszą zostać w tym przypadku usunięte. Dodatkowo na-leży zapewnić spójność pomiędzy danymi, a ich graficzną reprezentacją. Kolejno wywo-ływane są metody setChanged (ustawia flagę informującą o zmianie modelu) oraz notifyOb-servers. Jeżeli flaga changed została ustawiona, o zmianach powiadomieni zostaną wszy-scy zarejestrowani obserwatorzy. Aktywność edytora nasłuchująca na zmiany typu Model-Change.HISTORY_STACK_CHANGED spowoduje aktualizację przycisków ’ponów’ i ’cofnij’.

    Pozostałe widoki w identyczny sposób pobierają kontroler i za jego pomocą rejestrują sięw modelu. Aktywność edytora implementuje interfejs java.util.Observer, natomiast modelrozszerza klasę java.util.Observable. W ten sposób wykorzystana została standardowa imple-mentacja wzorca obserwatora, dostępna w języku Java.

  • 4.2. Model danych 18

    1 public c l a s s Model extends Observable {

    private void addToHistory (Command command) {mUndoCommands . push (command ) ;

    5 mRedoCommands . c l e a r ( ) ;

    setChanged ( ) ;not i fyObservers (new ModelChangeHolder (ModelChange .HISTORY_STACK_CHANGED, true , f a l s e ) ) ;

    10 }

    }

    Wydruk 4.3. Dodanie komendy do historii. – Model.java

    4.2. Model danych

    Dostępne na rynku edytory schematów elektrycznych wykorzystują siatkę jako modelpowierzchni roboczej. Dostępna przestrzeń składa się z ograniczonej ilości komórek, zazwy-czaj o kwadratowym kształcie. Użytkownik tworzący schemat może dodawać dowolne ele-menty elektryczne, jednakważne jest abyprogramnie pozwolil umieszczać elementów jedenna drugim. Podział powierzchni edytora na komórki, oraz przypisanie każdej z nich osob-nego modelu, pozwala jednoznacznie określić czy dozwolone jest umieszczenie elementu wdanym miejscu.

    Globalna konfiguracja wymiarów edytora zdefiniowana została w pliku GlobalPro-perties.java. Stałe zostały dobrane w proporcji 10:16 (wysokość : szerokość) z uwagi nafakt, że większość tabletów z systemem Android posiada podobny stosunek wymiarówekranu. Możliwa jest dowolna konfiguracja ilości komórek edytora. Ilość 200 rzędów i320 kolumn została dobrana tak, aby zapewnić możliwie jak największą powierzchnięroboczą i nie przekroczyć ilości dostępnej pamięci RAM dla aplikacji. Miejsca w kodzie,gdzie mają znaczenie rozmiary edytora, są zależne od wartości EDITOR_ROWS orazEDITOR_COLUMNS. Ewentualna zmiana ilości komórek poprzez wymienione stałe, niewymaga żadnych dodatkowych zmian w pozostałej części kodu. Należy jedynie dokonaćponownej komplilacji programu.

    1 public f ina l c l a s s Globa lProper t i es {public s t a t i c f ina l in t EDITOR_ROWS = 200 ;public s t a t i c f ina l in t EDITOR_COLUMNS = 320 ;

    }

    Wydruk 4.4. Konfiguracja ilośći komórek edytora. – GlobalProperties.java

    4.2.1. Klasa Model

    Klasa Model jest głównym kontenerem danych edytora. Wydruk 4.5 przedstawia kon-struktorw którym inicjalizowane są struktury danych przechowujące informacje. Wwierszu11 tworzona jest tablica obiektów typu Square odpowiadających pojedynczym komórkom.Tablica ma wymiary zgodne ze zdefiniowanymi w globalnych właściwościach.

  • 4.2. Model danych 19

    W kolejnych wierszach tworzone są dwa stosy mogące przechowywać komendy wyko-nywane przez użytkownika. Jako struktura danychwykorzystana została własna implemen-tacja stosu bazująca na liście java.util.LinkedList. Konstruktor klasy FixedSizeStack jako argu-ment przyjmuje maksymalną ilość elementów, do której stos będzie się powiększał. Przypróbie dodania nowego elementu, w przypadu gdy stos jest pełen, usuwany jest elementdodany najwcześniej. W ten sposób w historii trzymana jest tylko określona lista komend.W kodzie poniżej rozmiar historii został zdefiniowany na 50 komend.

    W linii nr 15 tworzony jest obiekt typu SparseArray przechowujący modele komponen-tów. Jest to klasa specyficzna dla platformy Android, niedostępna w standardowym JDK.Rzadkie tablice zostały wprowadzone do Android SDK, gdyż są znacznie wydajniejszeniż mapy haszujące (ang. HashMap) w przypadku stosowania kluczy typu int. Brakkonieczności zmiany typu prymitywnego int na obiekt Integer (niezbędnego w przypadkustosowania kolekcji HashMap) podczas dodawania lub pobierania elementów, ma znaczącywpływ na wydajność. Implementacja SparseArray oparta jest o dwie tablice: typu int orazObject. W przeciwieństwie do normalnych tablic obiektów, tablice rzadkie często posiadająwolną przestrzeń w indeksach. Ich użycie jest zalecane, jeżeli kluczem jest typ liczbowycałkowity [9]. W przypadku modeli komponentów, kluczem jest identyfikator danegomodelu, stąd użycie tablic rzadkich.

    1 public c l a s s Model extends Observable {

    Square [ ] [ ] mSquares ;SparseArray mComponentModels ;

    5

    private s t a t i c f ina l in t HISTORY_SIZE = 50 ;private f ina l FixedSizeStack mUndoCommands ;private f ina l FixedSizeStack mRedoCommands ;

    10 Model ( ) {mSquares =new Square [ Globa lProper t i es .EDITOR_COLUMNS] [ Globa lProper t i es .EDITOR_ROWS] ;mUndoCommands = new FixedSizeStack (HISTORY_SIZE ) ;mRedoCommands = new FixedSizeStack (HISTORY_SIZE ) ;

    15 mComponentModels = new SparseArray ( ) ;}

    }

    Wydruk 4.5. Inicjalizacja modelu. – Model.java

    Tablica komórek edytora tworzona jest w konstruktorze, jednak jej elementy niesą zachłannie inicjalizowane nowymi obiektami typu Square. W przypadku edytora owymiarach powierzchni roboboczej 200x320, tablica przechowuje 64tys. elementów. Zuwagi na restrykcje pamięci dla aplikacji mobilnych, dobrym rozwiązaniem w jest leniwainicjalizacja. Oznacza to, że dany element pozostaje wartością null do momentu pierwszejpróby odwołania się do niego. Gdy następuje próba dostępu do takiego obiektu, tworzony izwracany jest nowy obiekt, jeżeli do tej pory był on wartością null. W przeciwnymwypadkuzwracany jest już istniejący obiekt.

  • 4.2. Model danych 20

    Leniwa inicjalizacja bardzo dobrze sprawdza się w przypadku edytora schematów.Nawet skomplikowane układy wykorzystują małą ilość komórek w porównaniu do ichcałkowitej dostępnej ilości. Zachłanne tworzenie kilkudziesięciu tysięcy obiektów miałobynegatywnywpływna czas uruchamiania edytora, jak i niepotrzebnewykorzystanie pamięci.Aby uniknąć błędów związanych z próbami wywoływania metod niezainicjalizowanychkomórek, stworzony został akcesor realizujący lewiną inizjalizację, przedstawiony nawydruku 4.6.

    1 Square getSquareAtIndex ( in t x , in t y ) {/ / Lazy i n i t i a l i z a t i o ni f (mSquares [ x ] [ y ] == null ) {

    mSquares [ x ] [ y ] = new Square ( ) ;5 }

    return mSquares [ x ] [ y ] ;}

    Wydruk 4.6. Leniwa incjalizacja komórek. – Model.java

    4.2.2. Komórka edytora

    SquareTypeKażda zainicjalizowana komórka posiada informację na temat typów elementów, które

    są w niej przechowywane. Dostępne typy definiuje enumeracja SquareType, przedstawionana wydruku 4.7. Kolejność definicji nie jest przypadkowa. Decyduje ona, czy elementdanego typu może zostać dodany do komórki czy nie.

    1 public s t a t i c enum SquareType {EMPTY,SPACE,LINE ,

    5 NODE,NODE_DOT,COMPONENT;

    }

    Wydruk 4.7. Definicja typów elementów. – SquareType.java

    Tabela 4.2 przedstawia dozwolone operacje dodawania nowego typu. Wiersze oznaczająaktualny typ komórki, kolumny nowy dodawany typ. Znak – na przecięciu odpowiednichkolumn i wierszy oznacza niedozwoloną operację. Dla przykładu niedozwolona jest próbadodania typu SPACE, gdy aktualnie komórka przechowuje wartość COMPONENT.

    Komórka posiada zawsze conajmniej jeden typ (EMPTY), lecz może posiadać ich wiele– zgodnie z tabelą 4.2. Metoda getCurrentSquareType pozwala pobrać aktualny typ komórki.Zasada działania aktualnego typu została przedstawiona na przykładzie 4.3.

  • 4.2. Model danych 21

    EMPTY SPACE LINE NODE NODE_DOT COMPONENTEMPTY + + + + + +SPACE + + + + + -LINE + + + + + -NODE + + + + + -

    NODE_DOT + + + + - -COMPONENT + - - - - -

    Tabela 4.2. Macierz dozwolonych operacji dodawania nowego typu.

    Aktualny typ: EMPTY

    Dodaj typ: LINE

    Aktualny typ: LINE

    Dodaj typ: SPACE

    Aktualny typ: LINE (LINE > SPACE)

    Dodaj typ: COMPONENT (operacja niedozwolona)

    Rysunek 4.3. Zasada działania aktualnego typu komórki.

    W skrócie, im niżej typ komórki znajduje się w definicji SquareType, tym ma większypriorytet dla metody zwracającej aktualny typ komórki.

    Edytor posiada opcje debugowania modelu. Są one dostępne w ustawieniach aplikacji(możliwe jest ich włączenie w trakcie rysowania schematu). Typom komórek, przedstawio-nym na wydruku 4.7, przyporządkowane zostały kolory jak na rysunku 4.4. Rysunek 4.5przedstawia widoczne typy komórek w trybie debugowania. Typ EMPTY nie posiada żad-nego koloru (jest przezroczysty), dlatego nie jest widoczny na przykładzie.

    Typy komórek są niezwykle ważną częścią edytora. Na ich podstawie podejmowanajest decyzji czy element elektroniczny może zostać umieszczony w danym miejscu edytora.Każdy element posiada swoją reprezentację, opisaną typami komórek. Zostało to szerzejopisane w akapicie 4.2.3.

    SquarePojedyncza komórka reprezentowana jest przez obiekt typu Square. Element elektro-

    niczny dodany do schematu posiada własny unikalny numer identyfikujący. Jeżeli dana ko-mórka nie przechowuje żadnego komponentu, wartość obecnego identyfikatora ustawionajest na zero. Stąd zmiennejmCurrentIdw konstruktorze klasy Square przypisywane jest zero.Następnie tworzona jest nowa tablica rzadka, ze zdefiniowanym rozmiarem początkowym(równym dwa). W dużej ilości przypadków pojedyncza komórka nie będzie przechowy-wała więcej niż dwóch obiektów typu SquareComponentInfo, dlatego też została dobrana takawartość.

    W wierszu 10, wydruku 4.8, tworzony i dodawany jest nowy obiekt do tablicy rzadkiej– SquareComponentInfo. Jest to zaślepka oznaczająca daną komórkę jako pustą. Obecny in-dentyfikator ustawiony jest na wartość zero, oraz typ komórki na wartość EMPTY. Pozostałeargumenty przekazane do konstruktora nie mają w tym przypadku większego znaczenia.

  • 4.2. Model danych 22

    Rysunek 4.4. Kolory obiektów SquareType w trybie debugowania.

    Rysunek 4.5. Tryb debugowania z widocznymi typami komórek.

  • 4.2. Model danych 23

    1 public c l a s s Square {

    private SparseArray mArray ;private in t mCurrentId ;

    5

    public Square ( ) {super ( ) ;mCurrentId = 0 ;mArray = new SparseArray ( 2 ) ;

    10 mArray . append (mCurrentId ,new SquareComponentInfo ( 0 , Rotat ion . R0 , SquareType .EMPTY, null ) ) ;

    }

    }

    Wydruk 4.8. Konstrukcja komórki. – Square.java

    Stosowanie tablicy SparseArray wynika z możliwości nakładania się wielu elementówna siebie. W tej sytuacji niezbędne jest przechowywanie wszystkich elementów należącychdo danej komórki, bez względu na to kiedy zostały dodane. Tylko w ten sposób może zo-stać zachowana spójność danych, ponieważ elementy można dowolnie dodawać i kasować.Gdyby komórka posiadała informacje tylko o aktualnym elemencie, jego usunięcie oznacza-łoby oznaczenie komórki jako pustej – co może lecz nie musi być prawdą np. w przypadkugdy modele elementów nakładały się na siebie. Rysunki 4.6 oraz 4.7 przedstawiają opisy-waną sytuację.

    Przykładowo usunięcie rezystora z identyfikatorem 4 (rysunek 4.7), spowodowało kom-pletnewymazanie jego danych z siatki edytora oraz przywrócenie odpowiedniego kontekstukomórek. Szczególną uwagę należy zwrócić na komórkę z rysunku 4.6 oznaczoną numerami4,5 i 7. Po usunięciu rezystora należało przywrócić komórce jej aktualny typ – odpowiadającyelementówi o numerze 5, zatem w tym przypadku jest to typ LINE.

    Klasa Square posiada zmiennąmCurrentId. Pole to jest zawsze ustawione na identyfikatoraktualnego elementu. Ma ono za zadanie przyspieszać dostęp do informacji o komórce.Komórka z identyfikatorami 2,3,5 i 8 jest aktualnie typuNODE_DOT. Gdyby polemCurrentIdnie istniało, aby ustalić typ komórki należałoby iteracyjnie sprawdzić całą tablicę mArray.Wydruk 4.9 przedstawia implementację akcesorów klasy Square, często wykorzystywanychprzez kontroler do zapewniania poprawności modelu edytora.

    Wewnętrz metod na wydruku 4.9 wykorzystana została metoda checkNotNull z bibliotekiGuava. Pozwala ona na bardzo szybkie wykrywanie błędów, ponieważ gdy pobranazmienna ma wartość null, zostanie rzucony wujątek NullPointerException. To bardzo ważne,aby ewentualne błędy zauważyć u samego źródła (np. brak ustawionego typu komórki).Wystąpienie błędu gdzieś w środku kodu, znacząco utrudnia znalezienie przyczyny iwymaga zazwyczaj żmudnego debugowania. Praktyka szybkiego reagowania na błędyzwana jest fail-fast i zaleca się jej używania w projektach [12].

  • 4.2. Model danych 24

    Rysunek 4.6. Przykładowy schemat przedstawiający numery identyfikacyjne oraz aktualnetypy komórek.

    Rysunek 4.7. Stan po usunięciu jednego z rezystorów.

  • 4.2. Model danych 25

    1 public SquareType getCurrentSquareType ( ) {return checkNotNull (mArray . get ( mCurrentId ) . mSquareType ) ;

    }

    5 public ComponentType getCurrentComponentType ( ) {return checkNotNull (mArray . get ( mCurrentId ) . mComponentType ) ;

    }

    public Rotat ion getCurrentComponentRotation ( ) {10 return checkNotNull (mArray . get ( mCurrentId ) . mRotation ) ;

    }

    Wydruk 4.9. Akcesory informacji o komórce. – Square.java

    SquareComponentInfoKlasa SquareComponentInfo z wydruku 4.10 jest prostym kontenerem opisującym

    pojedynczą komórkę elementu elektrycznego. Zawiera o niej najważniejsze informacje –identyfikator, rotację, typ komórki oraz typ komponentu elektrycznego (np. rezystor). Typkomponentu został szerzej opisany w punkcie 4.2.2.

    1 public s t a t i c c l a s s SquareComponentInfo {

    f ina l in t mId ;f ina l Rotat ion mRotation ;

    5 f ina l SquareType mSquareType ;f ina l ComponentType mComponentType ;

    private SquareComponentInfo ( in t id , Rotat ion ro ta t ion ,SquareType squareType , ComponentType componentType ) {

    10 mId = id ;mRotation = ro t a t i on ;mSquareType = squareType ;mComponentType = componentType ;

    }15

    }

    Wydruk 4.10. Kontener opisujący komórkę elementu elektrycznego.– SquareComponentInfo.java

    RotationEnumeracja Rotation (4.11) reprezentuje rotację elementu elektrycznego względem siatki

    edytora. Dozwolone kąty obrotu to: 0, 90, 180 oraz 270 stopni. Możliwe jest także odbicielustrzane elementu, stąd łącznie dostępnych jest 8 różnych rotacji. Standardową wartościądla nowego elementu jest R0 (0 stopni). Informacja o tym, w jakim położeniu znajduje sędany element, jest potrzebna do odtworzenia jego rotacji w przypadku odczytania schematuz pliku.

  • 4.2. Model danych 26

    1 public enum Rotat ion {R0 ( 0 ) ,R90 ( 9 0 ) ,R180 ( 1 8 0 ) ,

    5 R270 ( 2 7 0 ) ,MR0( 0 ) ,MR90( 9 0 ) ,MR180 ( 1 8 0 ) ,MR270 ( 2 7 0 ) ;

    10

    private f ina l in t mDegrees ;

    private Rotat ion ( in t degrees ) {mDegrees = degrees ;

    15 }

    }

    Wydruk 4.11. Dozwolone rotacje elementów elektronicznych. – Rotation.java

    ComponentTypeEnumeracja ComponentType pełni rolę wiążącą pomiędzy modelem, widokiem oraz

    menadżerem parametrów elementu elektrycznego. Jej dokładne znaczenie zostało opisaniew punkcie 4.2.5. W skrócie ComponentType reprezentuje obiekty, które mogą zostaćnarysowane na siatce edytora.

    Lista przedstawia dostępne obiekty w aplikacji edytora schematów elektrycznych:

    — RESISTOR – rezystor,— CAPACITOR – kondensator,— INDUCTOR – cewka indukcyjna,— DIODE – dioda,— TRANSISTOR_BJT_NPN – tranzystor BJT NPN,— TRANSISTOR_BJT_PNP – tranzystor BJT PNP,— TRANSISTOR_MOSFET_NMOS – tranzystor MOSFET NMOS,— TRANSISTOR_MOSFET_PMOS – tranzystor MOSFET PMOS,— SOURCE_EXPONENTIAL – źródło wykładnicze,— SOURCE_PICE_WISE_LINEAR – źródło odcinkowo liniowe,— SOURCE_SINUSOIDAL – źródło sinusoidalne,— SOURCE_VOLTAGE_CONTROLLED_CURRENT – źródło napięciowe sterowane prądem,— SOURCE_VOLTAGE_CONTROLLED_VOLTAGE – źrodło napięciowe sterowane napięciem,— SOURCE_CURRENT_CONTROLLED_CURRENT – źrodło prądowe sterowane prądem,— SOURCE_CURRENT_CONTROLLED_VOLTAGE – źrodło prądowe sterowane prądem,— GND – uziemienie,— VCC – zasilanie,— LABEL – połączenie przez nazwę,— NODE_DOT – punkt łączący linie i węzły,— LINE – linia łącząca węzły elementów.

  • 4.2. Model danych 27

    4.2.3. Model komponentu

    ComponentModelWszystkie komponenty elektryczne posiadają wspólne cechy. Są nimi unikalny identy-

    fikator, nazwa elementu oraz punkty połączeniowe. Zgodnie z paradygmantem programo-wania obiektowego, wspólne cechy zostały wydzielone do abstrakcyjnej nadklasy Compo-nentModel, która jest następnie rozszerzana przez specyficzne komponenty.

    Klasa definiuje maksymalną długość nazwy komponentu równą 7 znaków. Nazwaskłada się z jednoliterowego prefiksu, zwracanego przez abstrakcyjną metodę getPrefix, oraznumeru identyfikacyjnego (linia 17, wydruk 4.12. Oznacza to, że maksymalny identyfikatormoże osiągnąć wartość 999999.

    Ilość punktów połączeniowych jest zależna od specyfiki komponentu. Dlatego konstruk-tor modelu przyjmuje parametr nodes, określający ilość fizycznych punktów połączeniowychelementu (potocznie nóżek).

    Klasa ComponentModel serializowana jest do pliku XML z wykorzystaniem adnotacjiz biblioteki SimpleXML. Na wydruku 4.12 zastosowane zostały adnotacje @Element oraz@ElementArray. Pola mId, mName oraz mNodes zostaną zapisane kolejno pod nazwami id,name i nodes w pliku wynikowym. Ostatnie pole zdefiniowane jest jako tablica, dzięki temuzapisane zostaną wszystkie jej pola. Przykładowy plik wynikowy przedstawiony jest nawydruku 4.14 (linie 2-7 włącznie).

    1 public abs t r a c t c l a s s ComponentModel {

    private s t a t i c f ina l in t MAX_NAME_LENGTH = 7 ;

    5 @Element (name = " id " )private f ina l in t mId ;

    @Element (name = "name" )private S t r ing mName;

    10

    @ElementArray (name = " nodes " )private f ina l Node [ ] mNodes ;

    ComponentModel ( in t nodes , in t id ) {15 mId = id ;

    mNodes = new Node[ nodes ] ;mName = ge tP r e f i x ( ) + In teger . t oS t r ing ( id ) ;checkSta te (mName. length ( )

  • 4.2. Model danych 28

    Różne komponenty elektryczne posiadają specyficzne właściwości. Rezystor posiadaokreśloną rezystancję, kondensator pojemność, a dioda szereg innych parametrów. W przy-padku prostych elementów elektrycznych, pojedyncza wartość pozwala odróżniać kompo-nenty od siebie np. rezystancja 4.7kohm oraz 2.2kohm (pomijając dokładność itp.). Z drugiejstrony komponenty posiadające szereg właściwości, opisywane są raczej nazwą modelu niżpojedynczymi parameterami.

    Podobna strategia została przyjęta w przypadku aplikacji edytora. Tylko niektóre typyposiadają możliwość zdefiniowania parametrów, a pozostałe wymagają podania nazwymodelu komponentu. Rezystor należy do grupy pierwszej – możliwe jest zdefiniowaniewartości rezystancji. Dla ułatwienia ustawiania odpowiedniej wartości rezystancji, należywprowadzić wartość liczbową oraz wybrać jednostkę (brak, kilo, mega, giga).

    ResistorModelKlasa ResistorModel rozszerza abstrakcję ComponentModel, dodając dwa pola – wartości

    rezystancji oraz jej jednostkę. W linii 3 wydruku 4.13 zdefiniowany został prefiks dlarezystora. Zalecane jest aby prefiksy były unikalne względem pozostałych modeli. Składająsię one na nazwę elementu prezentowaną na siatce edytora, stąd identyczne prefiksydla różnych komponentów mogą prowadzić do pomyłek. Z kontraktu dziedziczeniaobowiązkowe jest zaimplementowanie metody getPrefix będącej abstrakcyjną w nadklasie.Implementacja zwraca znak R, będący stałym prefiksem dla rezystora.

    1 public c l a s s ResistorModel extends ComponentModel {

    private s t a t i c f ina l char PREFIX = ’R ’ ;public s t a t i c f ina l double DEFAULT_VALUE = 1 . 0d ;

    5

    @Element (name = " value " )private double mValue ;

    @Element (name = " valueUnit " )10 private Unit mValueUnit ;

    ResistorModel ( in t id ) {super ( 2 , id ) ;mValue = DEFAULT_VALUE;

    15 mValueUnit = Unit .NONE;}

    @Overridepublic char ge tP r e f i x ( ) {

    20 return PREFIX ;}

    }

    Wydruk 4.13. Model rezystora. – ResistorModel.java

    Pola mValue oraz mValueUnit reprezentują wartość rezystancji. Standardowo ustawionajest ona na 1 ohm. Okno parametrów, opisane w części dotyczącej interfejsu użytkownika,pozwala na zmianę rezystacji komponentu. Podobnie jak w nadklasie, pola oznaczone sąadnotacjami biblioteki SimpleXML. Przykład serializacji modelu rezystora o parametrach

  • 4.2. Model danych 29

    4.7kohm, numerze identyfikacyjny 1, dwóch puntach połączeniowych o identyfikatorach 1i 2, został przedstawiony na wydruku 4.14. Wartość R1 w tagu to nazwa elementu,składająca się z prefiksu komponentu oraz jego numeru identyfikacyjnego.

    1

    5 R11K4 . 7

    10

    Wydruk 4.14. Model rezystora zapisany do pliku XML.

    Reprezentacja modelu przez SquareTypeKażdy komponent elektryczny posiada także reprezentację w formie dwuwymiarowej

    tablicy obiektów SquareType. Jej rozmiary definiują ilość zajmowanych komórek edytora.Gdy element dodawany jest przez użytkownika na siatkę edytora, do komórek przepisywanesą informacje o jego modelu (w postaci obiektów SquareType).

    1 private s t a t i c f ina l SquareType [ ] [ ] SQUARES_R0 = new SquareType [ ] [ ] {{ SquareType .EMPTY, SquareType . SPACE, SquareType . SPACE,SquareType . SPACE, SquareType .EMPTY} ,

    { SquareType .NODE, SquareType .COMPONENT, SquareType .COMPONENT,5 SquareType .COMPONENT, SquareType .NODE} ,

    { SquareType .EMPTY, SquareType . SPACE, SquareType . SPACE,SquareType . SPACE, SquareType .EMPTY} ,

    } ;

    Wydruk 4.15. Reprezentacja modelu rezystora w postaci komórek.

    Wydruk 4.15 przedstawia model rezystora. Wartości umieszczone są kolumnami, zaczy-nając od lewego górnego rogu. Pierwsza i trzecia kolumna posiada na obu końcach obiektyEMPTY, a w środku SPACE. Środkowa kolumna posiada na końcach dwa punkty połącze-niowe (NODE), natomiast środek wypełniony jest typem COMPONENT. Reprezentacja mo-delu rezystora w postaci graficznej przedstawiona była na rysunku 4.5.

    Z programistycznego punktu widzenia zastosowane zostały pewne optymalizacje dla re-prezentacji modeli. Tablice tworzone są dla wszystkich 8 rotacji podczas pierwszego użyciadanego komponentu, a potrzebna jest tylko deklaracja jednej – SQUARES_R0 dla rotacji R0.Dodatkowo definiowane są jako statyczne, co oznacza, że bez względu na ilość elementówdanego typu, liczba tablic pozostanie równa dokładnie 8.

    Te drobne ulepszenia mają znaczący wpływ na koszty obliczeniowe, zajętość pamięci, atakże uniknięcie błędów programistycznych przy definiowaniu reprezentacji modelu przyużyciu obiektów SquareType. Optymalizacja pamięci została uzyskana przez zadeklarowa-nie tablic jako statycznych (jedna instancja dla wszystkich obiektów klasy). Z powodu de-klaracji reprezentacji modelu tylko dla rotacji R0, operacje na innych rotacjach wymagałyby

  • 4.2. Model danych 30

    za każdym razem odpowienich przekształceń (czasochłonnych obliczeń). Problem zostałrozwiązany przez zadeklarowanie statycznych tablic dla każdej rotacji, których elementy sąwyliczane jeden raz na podstawie przekształceń tablicy SQUARES_R0.

    4.2.4. Komendy

    Operacja dodawania lub usuwania komponentów, zmieniające stan modelu edytora, na-zwane zostały komendami. Pojedyncza komenda reprezentowana jest przez klasęCommand.Zawiera ona wszelkie informacje, które są niezbędne do cofnięcia lub powtórzenia poprzed-nich akcji użytkownika. Za ich pomocą zrealizowane zostały funkcjonalności ’cofnij’ oraz’powtórz’.

    W przypadku gdy na siatkę edytora zostanie dodany komponent elektryczny, tworzonyi dodawany jest nowy obiekt Command na stos opcji cofnij. W przypadku cofnięcia komendy,następuje kompletne usunięcie dodanego elementu z modelu edytora, a następnie komendaprzenoszona jest na stos opcji powtórz (i na odwrót w przeciwnej sytuacji).

    Operacja przeniesienia elementu na siatce, złożona jest z dwóch komend – usunięciaobiektu z jego pierwotnego położenia oraz dodanie go w nowej lokalizacji. Chęć ewen-tualnego cofnięcia takiej operacji, nie wymaga dwukrotnego wykonania polecenia cofnij.Jest to przypadek szczególny, dlatego został odpowiednio oprogramowany, aby zachowaćspójnośc z operacjami dodawania, usuwania i kopiowania. Kopiowanie elementu jestoperacją podobną do dodawania elementu, z tym że zachodzi skopiowanie istniejącegomodelu, zamiast inicjalizacji nowego domyślnymi wartościami.

    1 public c l a s s Command {

    private f ina l in t mId ;private f ina l in t mX;

    5 private f ina l in t mY;private f ina l SquareType mSquares [ ] [ ] ;private f ina l ComponentType mComponentType ;private f ina l boolean mAdd;private f ina l Rotat ion mRotation ;

    10 private f ina l ComponentModel mComponentModel ;

    }

    Wydruk 4.16. Reprezentacja komendy. – Command.java

    Kod klasy Command przedstawiony jest został na wydruku 4.16. Wszystkie ustawianiewartości przekazywane są w konstruktorze, dlatego jego implementacja nie została załą-czona. Kolejne polamają następujące znaczenie: numer identyfikacyjny elementu, położenielewego górnego rogu na osi X siatki edytora, położenie lewego górnego roku na osi Y siatkiedytora, reprezentacja modelu przez SquareType, typ komponentu, typ komendy (dodanielub usunięcie obiektu), rotacja komponetu oraz jego model (parametry fizyczne). Większośćwymienionych pól została opisana we wcześniejszych punktach działu.

    Komendy pozwalają na przechodzenie pomiędzy spójnymi stanami modelu. Operacjausunięcia elementu elektrycznego powoduje utworzenie komendy z polem mAdd ustawio-nym na wartość false. Cofnięcie komendy przywraca model do identycznego stanu jaki byłprzed wykonaniem operacji usunięcia. To samo tyczy się pozostałych operacji.

  • 4.2. Model danych 31

    4.2.5. Asocjacja informacji elementów elektrycznych

    Lista dostępnych obiektów edytora reprezentowana jest przez enumerację Component-Type. Cztery zadeklarowane pola łączą niezbędne elementy w jedną całość. Komponentelektryczny posiada swoją reprezentację w postaci widoku (ComponentView) np. bitmapa donarysowania, modelu (ComponentModel), okna informacyjnego pozwalającego wprowadzićjegoparametry techniczne (identyfikator infoLayoutId) oraz posiada zrozumiałą dla użytkow-nika nazwę (identyfikator nameId).

    Mimo podziału aplikacji na niezależne struktury –widok, model i kontroler –w pewnymmiejscu aplikacji musi istnieć asocjacja pomiędzy tymi częściami. Szereg metod dostępnychw klasie ComponentType pozwala np. na odnalezienie obiektu Class reprezentującego widok,znając tylko nazwę komponentu elektrycznego. Taki sposób nawigacji jest niezbędny we-wnątrz kontrolera. Dla przykładu podczas wczytywania schematu, dostępny jest tylko typkomponentu, jednak dzięki klasie asocjacyjnej możliwe jest utworzenie i wstawienie odpo-wiedniego widoku na siatkę edytora.

    1 public enum ComponentType {/ / S p e c i a l components .NODE_DOT(NodeDotView . c lass , null , 0 , 0 ) ,LINE( LineView . c lass , null , 0 , 0 ) ,

    5 / / Normal components .RESISTOR( ResistorView . c lass ,

    ResistorModel . c lass , R . layout . component_info_res is tor ,R . s t r i ng . component_resistor ) ,

    . . .10

    private f ina l Class

  • 4.2. Model danych 32

    4.2.6. Podsumowanie

    Aplikacja edytora korzysta ze wzorca MVC dla separacji przepływu sterowania,danych oraz ich reprezentacji. Diagram klas składających się na model danych edytoraprzedstawiony został na rysunku 4.8. Zawarte są na nim najważniejsze elementy składowe,omówione w powyższych akapitach.

    Rysunek 4.8. Diagram klas składających się na model edytora.

    Model składa się z dwuwymiarowej tablicy typu Square będącej siatką edytora. Informa-cje o parametrach fizycznych komponentówprzechowywane sąw obiektach rozszerzającychabstrakcyjną klasę ComponentModel. Historia wykonywanch przez użytkownika czynnościprzechowywana jest przy pomocy dwóch stosów obiektów Command.

    Komponent elektryczny, oprócz parametrów fizycznych (np. rezystancji), posiada repre-zentację niezbędną do określenia jego położenia oraz zajętego obszaru siatki edytora. Wy-rażona jest ona za pomocą tablicy obiektów SquareType. Przykład reprezentacji rezystoraprzedstawiony jest na wydruku 4.15. W momencie dodania nowego elementu do edytora,za pomocą tablicy Squaretype, rotacji, typu oraz identyfikatora komponentu, tworzone sąobiekty SquareComponentInfo i zapisywane w odpowiednich komórkach Square.

    Zapisywanie oraz odczytywanie stanu modelu do i z plików XML realizowane jest zapomocą biblioteki SimpleXML. Pola klas które mają zostać poddane serializacji oznaczanesą adnotacjami @Element (lub odpowiednią wersją w zależności od typu pola np. tablica@ElementArray). Biblioteka zapewnia obsługę błędów oraz pozwala na proste definiowanienowych modeli. Wydruk 4.14 przedstawia model rezystora w języku XML.

  • 4.2. Model danych 33

    Typ komponentu jest klasą asocjacyjną łączącą modele, widoki i okna wprowadzania pa-rametrów technicznych. W ten sposób zachodzi przypisanie np. ResistorView do ResistorMo-del i nazwy R.string.component_resistor, co w efekcie daje obiekt RESITOR klasy Component-Type.

  • 4.3. Interfejs użytkownika 34

    4.3. Interfejs użytkownika

    Urządzenia mobilne wyposażone są w interfejs dotykowy służący do interakcji z użyt-kownikiem. W przypadku komputerów jest to zazwyczaj klawiatura i myszka. Wymusza toodmienny sposób sterowania aplikacjami dostępnymi na platformy mobilne. Użytkownikwydaje komendy głównie za pomocą gestów wykonywanych palcami np. podwójne stuk-nięcie w ekran.

    Rozdział ten opisuje sposoby implementacji podstawowych funkcjonalności z punktuwidzenia sterowania aplikacją edytora schematów elektrycznych. Rozpoczynając od ideiukładu przycisków, przez budowęwidoku siatki edytora i elementu elekrycznego oraz dzia-łania gestów sterujących, zostaną opisane niezbędne elementy składowe interfejsu użytkow-nika.

    4.3.1. Funkcje edytora

    Każdy typ programów komputerowych wyposażony jest w specyficzne dla dziedzinyzastosowania funkcjonalności. W przypadku edytora graficznego będą to możliwościrysowania za pomocą różnych narzędzi, kolorowania, zaznaczania obszaru obrazu czykopiowanie i usuwanie tego obszaru. Bez względu na producenta programu, użytkownikspodziewa się podobnych, podstawowych funkcjonalności w produktach tego samego typu.Gdyby porównać edytory graficzne takie jak gimp3 oraz Photoshop4, okazuje się, że nawetikony mają podobny wygląd, co przestawiono na rysynku 4.9.

    Rysunek 4.9. Panel narzędzi programu gimp (po lewej) oraz Photoshop.

    3 GNU Image Manipulation Program – http://gimp.org4 Photoshop – http://photoshop.com

    http://gimp.orghttp://photoshop.com

  • 4.3. Interfejs użytkownika 35

    Edytory schematów elektrycznych także zawierają zestaw podstawowych funkcjonalno-ści, bez których niemożliwe byłoby tworzenie złożonych układów. Funkcje te zdefiniowanezostały w punkcie opisującym cel pracy 1.2.

    Komputerowy program EAGLE został przyjęty jako wzór dla interfejsu użytkownikaedytora schematów. Nazwa programu to skrót od Easily Applicable Graphical Layout Editor cojest w zupełności prawdą – nawet dla osoby używającej go po raz pierwszy, szybko staje sięprosty w obsłudze. EAGLE posiada także takie opcje jak tworzenie płytek drukowanych,jednak pod uwagę został wzięty tylko edytor schematów przedstawiony na rysunku 4.10.

    Rysunek 4.10. Widok edytora schematów programu EAGLE.

    Wygląd stworzonego edytora schematów elektrycznych przedstawiony jest na rysunku4.11. Umiejscowienie paska narzędzi jak oraz wygląd ikon inspirowane jest programemEAGLE.

    Poniżej opisane są dostępne w menu narzędzia oraz udostępniane przez nie funkcjonal-ności.

    Skalowanie i przesuwanie siatki edytora

    Narzędzie udostępnia opcje nawigacji po siatce edytora. Głównymi funkcjami są skalo-wanie i przemieszczanie siatki, dodatkowo wprowadzone zostały dwa gesty wykonywaneza pomocą dwukrotnego stuknięcia (ang. double tap). Ikona pierwsza przedstawia trybnieaktywny, natomiast druga tryb, w którym aktywne są wszystkie wymienione gesty.

  • 4.3. Interfejs użytkownika 36

    Rysunek 4.11. Widok edytora schematów elektrycznych na platformę Android.

    Skalowaniewykonywane jest za pomocą gestu uszczypnięcia (ang. pinch-to-zoom). Gestwymaga przyłożenia do ekranu dwóch palców ręki, następnie oddalanie ich od siebie (roz-suwanie) lub zbliżanie reguluje przybliżenie siatki edytora.

    Gest przesuwania siatkiwykonywany jest za pomocą jednego palca i zewzględu na swojąintuicyjność nie wymaga dodatkowego opisu.

    Możliwości przesuwania jak i skalowania siatki zostały ograniczone programowo. Wi-dok sam dostosowuje się do wolnej przestrzeni. W przypadku gdy zostanie przesunięty lubprzeskalowany przez użytkownika tak, że pozostaje wolne miejsce, jest on automatycznieprzywracany do położenia, w którym wypełnia całą dostępną przestrzeń.

    Działanie gestu dwukrotnego stuknięcia jest zależne od aktualnego przybliżenia edy-tora. Dla minimalnego przybliżenia, gdy widoczny na ekranie jest cały edytor, dwukrotnestuknięcie na siatce powoduje maksymalne przybliżenie obszaru, w którym gest zostałwykonany. W pozostałych przypadkach (przybliżenie inne niż minimalne), gest powodujepowrót do minimalnego przybliżenia.

    Dodawanie komponentów elektrycznych

    Narzędzie dodawania nowych komponentów na siatkę edytora reprezentowane za po-mocą ikony diody. Pierwsza ikona to tryb nieaktywny (stan 1), druga oznacza dodanie po-jedynczego element (stan 2), natomiast trzecia to tryb dodawania ciągłego (stan 3).

    W celu wybrania typu komponentu elektrycznego, ikona powinna zostać jednokrotnienaciśnięta w stanie 2 lub 3. Gdy akcja zostanie pomyślnie wykonana, na ekranie pojawisię okno dialogowe z dostępnymi komponentami jak na rysunku 4.12. Naciśnięcie ikony wstanie 1 powoduje aktywację stanu 2. Aby włączyć tryb dodawania ciągłego należy przezchwilę przytrzymać ikonę (ang. long click) niezależnie w jakim stanie jest obecnie.

  • 4.3. Interfejs użytkownika 37

    Gdy przycisk jest w trybie 2 lub 3 dotknięcie siatki edytora spowoduje dodanie wybra-nego komponentu (standardowo wybrany jest rezystor). Widok komponentu pojawia się wmiejscu dotknięcia ekranu. Możliwe jest dowolne przesuwanie widokuw ramachwidocznejsiatki. W momencie ’puszczenia’ elementu, zostaje on na stałe dodany do modelu edytora.Jeżeli wybrany był tryb pojedynczego wprowadzania, edytor automatycznie powróci do po-przednio aktywnego narzędzia zaraz po dodaniu nowego komponentu. W trybie 3 możliwejest dodawanie wielu komponentów jeden po drugim.

    Niemożliwe jest dodawanie komponentów w taki sposób aby kolidowały ze sobą np.jeden na drugim czy komponent na linii połączeniowej. Gdy pozycja jest niedozwolonawidok komponentu zmienia kolor na mocno czerwony.

    Aby wyłączyć tryb dodawania komponentu, należy wybrać inny z dostępnych trybóww menu. Jest to jedyny przycisk w menu edytora, który posiada tak rozbudowane opcje.

    Rysunek 4.12. Okno wyboru typu komponentu elektrycznego.

    Przemieszczanie komponentów elektrycznych

    Narzędzie służy do przemieszczania komponentów elektrycznych w obrębie siatki edy-tora. Oprócz samej zmiany położenia elementu, możliwe jest jego obracanie oraz tworzenieodbicia lustrzanego. W tym trybie także wprowadzane są parametry techniczne kompo-nentu. Pierwsza ikona oznacza tryb nieaktywny, druga tryb aktywny.

    W trybie aktywnym dostępne są podobne opcje jak przy skalowaniu siatki edytora. Niekolidują one z głównymi funkcjami opcji przemieszczania. W celu zmiany położenia kompo-nentu znajdującego się na siatce edytora, należy przez dłuższy czas przytrzymać jegowidok.Następnie można go przemieszczać podobnie jak w trybie dodawania nowego komponentu.Wszelkie informacje o elemencie tj. rotacja i parametry techniczne pozostają zachowane.

    Pojedyncze stuknięcie elementu włącza menu rotacji pokazane na rysunku 4.13. Dozwo-lone rotacje opisane są przez klasę Rotation opisaną w punkcie 4.2.2. Łącznie z odbiciamidostępnych jest 8 różnych położeń komponentu (cztery rotacje co 90 stopni oraz warianty zodbiciem).

    Przyciski menu rotacji pozostają zawsze aktywne, jednak w sytuacjach gdy nowa rotacjaelementu naruszałaby więzy spójności nałożone przez model, wyświetlany jest komunikat’Rotation is not allowed’, a sam element pozostaje w obecnym położeniu.

  • 4.3. Interfejs użytkownika 38

    Rysunek 4.13. Widok menu rotacji i odbić.

    Rysunek 4.14. Okno dialogowe wprowadzania parametrów technicznych.

    Podwójne stuknięcie widoku elementu włącza okno dialogowe z parametrami tech-nicznymi jak na rysunku 4.14. W zależności od typu komponentu, wyświetlane jest oknoumożliwiające wprowadzanie właściwości związanych z danym komponentem elektrycz-nym. Niektóre elementy posiadają wprowadzone standardowe wartości, zdefiniowane wich modelach. Aby zapisać dokonane zmiany należy użyć przycisku ’Change’.

    Kopiowanie komponentów elektrycznych

    Operacja kopiowania komponentów elektrycznych jest podobna do ich przemieszczania.Jedyną różnicę stanowi efekt długiego przytrzymania elementu – tutaj następuje utworzeniejego wiernej kopii, którą następnie możemy umieścić na siatce edytora. Pierwsza ikonaoznacza tryb nieaktywny, druga aktywny.

    W trybie aktywnym dostępne są wszystkie opcje co w narzędziu skalowania oraz prze-mieszczania elementów, z wyjątkiem gestu długiego przytrzymania jak opisano powyżej.Istnieje zarówno dostęp domenu rotacji jak i okna dialogowego wprowadzania parametrówtechnicznych.

    W momencie wykrycia gestu długiego naciśnięcia, wykonywana jest wierna kopiakomponentu wraz z jego parametrami technicznymi. Element uzyskuje jedynie nowy,unikalny numer identyfikujący. Ewentualna zmiana parametrów technicznych czy rotacjiskopiowanego elementu, nie wpływa na element oryginalny.

  • 4.3. Interfejs użytkownika 39

    Usuwanie obiektów z siatki edytora

    Narzędzie służy do usuwania dowolnych obiektów, znajdujących się na siatce edytora.Pierwsza ikona oznacza tryb nieaktywny, druga aktywny.

    W trybie aktywnym dostępne są wszelkie opcje jak w narzędziu skalowania (cztery ge-sty). Opcja usuwania dodaje gest pojedynczego stuknięcia dowolnego obiektu, co powodujejego usunięcie.

    W przypadku gdy obiekty nakładają sie na siebie np. linie czy punkty połączeniowe,decyzja o tym, który element zostanie usunięty podejmowana jest na podstawie aktualnegotypu komórki SquareType. W przypadku gdy istnieje więcej niż jeden element o tym samymtypie, usuwany jest ostatni dodany element (najwyższego typu).

    Rysowanie linii połączeniowych

    Narzędzie pozwala tworzyć połączenia pomiędzy obiektami znajdującymi się na siatceedytora. Pierwsza ikona oznacza tryb nieaktywny, druga aktywny.

    Gdy opcja jest aktywna, jakakolwiek interakcja z siatką edytora rozpoczyna rysowanielinii połączeniowej. Pojedyncza linia rysowana jest kolorem zielonym, i może składać sięmaksymalnie z dwóch odcinków, połączonych pod kątem prostym. Kierunek pierwszejlinii (góra-dół/lewo-prawo) zależy od tego w którą stronę został wykonany pierwszy ruchz punktu początkowego.

    Rysunek 4.15. Prowadzenie linii połączeniowej.

    Rysunek 4.15 przedstawia dwie linie mające początek i koniec w tym samym punkcie(relatywnie). Pierwszy ruch z punktu początkowego w przypadku pierwszej linii (lewastrona), został wykonany w górę. W ten sposób kierunek linii to góra-prawo. W przypadkudrugiej linii pierwszy ruch został wykonanywprawo, zatem otrzymany kierunek rysowaniato prawo-góra. Aby zmienić kierunek początkowy, należy wrócić do punktu startowego iwykonać ruch w pożądaną stronę.

  • 4.3. Interfejs użytkownika 40

    Jeżeli linia ma swój początek w komórce typu NODE (SquareType), automatycznierysowany jest punt połączeniowy. Przykład przedstawia rysunek 4.16. To samo tyczysię punktu końcowego linii. Punkty połączeniowe nie są automatycznie rysowane,gdy linia przechodzi przez węzeł połączeniowy elementu. Mogłoby to prowadzić doniezamierzonych przez użytkownika połączeń, a w konsekwencji błędnego schematu.

    Rysunek 4.16. Połączenia lin