Funkčná časť programu DynaSim

Z Kiwiki
Verzia z 18:55, 29. júl 2010, ktorú vytvoril Juraj (diskusia | príspevky)
(rozdiel) ← Staršia verzia | Aktuálna úprava (rozdiel) | Novšia verzia → (rozdiel)
Skočit na navigaci Skočit na vyhledávání

Funkčná časť programu DynaSim

V predošlých kapitolách sme vybudovali základný framework pre simulátor. Vieme vytvoriť grafickú časť komponentov a dátovú časť, ktorá v sebe drží určité informácie ako je poloha vstupov a výstupov, ich typ, vnútorné hodnoty komponentu a popis komponentu. To však na vykonanie simulácie nie je dostačujúce. Každý z komponentov musí mať svoj simulačný algoritmus, ktorý sa cyklicky opakuje počas behu simulácie.

Globálny simulačný algoritmus

Globálny simulačný algoritmus je veľmi jednoduchý a dá sa rozdeliť na 2 kroky. V kroku číslo 1 si komponent načíta hodnoty z vlastných vstupov a vykoná funkciu – simulačný algoritmus. Po výpočte sa prenesú výsledky funkcie na výstupy komponentu. Tento postup sa zopakuje pre všetky komponenty v schéme. V kroku číslo 2 sa vykoná prenos z jednotlivých výstupov komponentov na vstupy s ktorými sú prepojené spojovacími čiarami. Tento postup sa cyklicky opakuje s periódou určenej dĺžky.

Obr.15 Globálny simulačný algoritmus

Celý tento algoritmus sa vykonáva v rámci triedy DynaSimScene. Ako časovač sa používa ScheduledExecutorService. V triede DynaSimScene sa nachádza metóda runSimulation(), ktorá sa volá po stlačení príslušného toolbar tlačítka na spustenie simulácie. V nej sa vytvorí nová inštancia nášho časovača.

 exec = Executors.newSingleThreadScheduledExecutor();

Následne sa zavolá metóda simulate, ktorá vypadá nasledovne:

 public void simulate() {
    final Runnable simulator = new Runnable() {
       public void run() { simulation(); }
    };
    exec.scheduleAtFixedRate(simulator,100, 100, TimeUnit.MILLISECONDS);
 }

V nej sa vytvorí inštancia rozhrania Runnable a do jeho metódy run() sa zavolá metóda, ktorá sa má cyklicky opakovať, v našom prípade je to metóda simulation(). Nakoniec sa zavolá metóda nášho časovača scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit). Prvý parameter je Runnable, tam sa dosadí náš vytvorený Runnable, tu sa jedná práve o metódu, ktorá sa bude opakovane pomocou tohto časovača vykonávať. Parameter initialDelay je oneskorenie s akým sa časovač spustí, period je perióda s akou sa bude Runnable vykonávať a nakoniec unit, je časová jednotka pre druhý a tretí parameter. To znamená, že po stlačení tlačítka pre spustenie simulácie sa začne cyklicky vykonávať metóda simulation() s periódou 100 milisekúnd. Tá má na starosti vykonávanie globálneho simulačného algoritmu, kde sa nájdu všetky widgety na scéne a následne im pridelené simulačné komponenty typu Component. Tie postupne vykonajú svoje funkcie, výsledky svojich funkcií prenesú na výstupy. Potom sa zavolá metóda na prenos z výstupov na vstupy ďalších komponentov s ktorými sú spojené.

Simulačné komponenty

Čo presne sú simulačné komponenty? Doteraz pre nás boli iba XML a SVG dokumenty, tie však predstavujú iba dátovú štruktúru týchto komponentov. Aby tieto komponenty mohli vykonávať svoje simulačné algoritmy, musia nevyhnutne obsahovať nejaký druh zdrojového kódu, ktorý určuje ich funkcie. Každý jeden komponent má vlastný .java súbor ktorý obsahuje triedu daného komponentu. V nej má zapísané svoje metódy. Každá takáto trieda dedí z rodičovskej triedy Component. Aby sme teda mohli pochopiť ako fungujú jednotlivé komponenty, treba začať od vrchu hierarchie.

Trieda Component

Trieda Component je abstraktná trieda a slúži na tvorbu tried pre jednotlivé simulačné komponenty. Ich .java súbory sa nachádzajú v knižnici medzi XML a SVG súbormi. Problém však je, že nedokážeme priamo dynamicky vytvoriť inštancie tried obsiahnutých v .java súboroch, vzhľadom na to, že tieto súbory nie sú v podstate nič viac ako textové dokumenty. To znamená, že ich treba skompilovať a vzniknuté .class súbory sa už dajú použiť na tvorbu inštancií za behu programu. Ich inštancie sa tvoria priamo v metóde createComponent, ktorá patrí triede Component. Tejto metóde je predaný parameter typu String s názvom className. To je meno .class triedy, má tvar napríklad sk.tnuni.dynasim.kategória.meno, kde kategória je meno kategórie, ktorej komponent patrí a meno je meno .class súboru bez prípony. Na nájdenie tejto cesty sa opäť používa FolderSearcher. Jeho metóda getClassFolder vráti presnú cestu k adresáru s .class súbormi. K nemu sa už podľa potreby z MyNode pripne kategória a meno tým získame hľadaný className parameter. Ako sa vytvára inštancia zo známeho className môžeme vidieť na príklade:

 Component component = null;
 Class  [] classParm  = null;
 Object [] objectParm = null;

 try
 {
     Class cl = Class.forName(className);
     java.lang.reflect.Constructor co = cl.getConstructor(classParm);
     component = (Component)co.newInstance(objectParm);
 }

Najskôr vytvoríme inštanciu Class pre zadané meno. Potom sa pokúsime vytvoriť jej konštruktor. Tomu predávame prázdne pole parameterov, to znamená, že chceme vytvoriť bezparametrický konštruktor. Nakoniec sa vytvorí inštancia triedy Component z novovytvoreného konštruktora. Treba si uvedomiť, že týmto sme nepriamym spôsobom vytvorili inštanciu triedy nejakého konkrétneho simulačného komponentu podľa zadanej cesty v className parametri. Inštancie triedy Component sa tvoria v metóde attachNodeWidget v triede DynaSimScene. To znamená, že krátko po vytvorení ľubovoľného dátového uzla sa volá táto metóda, aby sa mu priradil príslušný grafický widget a práve tu sa vytvorí aj jeho funkčná časť – inštancia triedy Component. Trieda Component má niekoľko členských premenných, ktoré sú potrebné pre jej metódy. Drží v sebe inštanciu MyNode, teda dátový uzol ktorému patrí, aby mala táto trieda prístup k jej vnútorným hodnotám. Ďalej je to jej prislúchajúci SVG_Widget, ten sa volá pre potreby vytvorenia meniteľného textu priamo vo widgete. Inštancia DynaSimScene je tiež jednou z jej premenných a je potrebná na prekreslovanie scény v prípade, že vykonané zmeny týmto komponentom majú nejaký dopad na jej grafickú reprezentáciu. Nakoniec v sebe drží 2 polia referencií na všeobecný dátový typ Value. Jedno pole sú referencie na vstupné hodnoty terminálov a druhé referencie na výstupné hodnoty. Jednotlivé položky týchto polí sú obvykle volané v simulačnom alogritme komponentov. Teraz sa pozrieme na metódy tejto triedy.

public abstract void toDo() – Metóda, ktorú musí mať každý simulačný komponent. Táto metóda obsahuje simulačný algoritmus komponentu a je volaná v metóde simulation(), ktorá sa pri spustenej simulácii cyklicky opakuje.

public void updateComponentProperties() – V triede Component je to prázdna metóda bez kódu. Jej detské triedy ju však môžu prepísať a doplniť do nej kód, ktorý sa má vykonávať vždy keď je zaznamenaná nejaká zmena v Property okne, či už to je nastavovanie nejakej hodnoty alebo jej zmena vplyvom simulácie. Môžeme túto metódu chápať ako listener pre Property okno a kód v nej sa vykoná vždy keď dôjde k nejakým zmenám ľubovoľnej položky v tomto okne.

public void updateTerminals() – Metóda, ktorá sa cyklicky opakuje počas spustenej simulácie. Je volaná vždy pred toDo() metódou. Nájdu sa všetky vstupné terminály tohto komponentu typu MyPin a do jednotlivých položiek Value sa uložia hodnoty týchto vstupov. Rovnaký proces sa vykoná s výstupmi. Jedná sa teda o inicializáciu hodnôt vstupov a výstupov.

public void sendToNextTerminal() – Ďalšia z metód ktorá sa cyklicky opakuje v metóde simulation(). Táto sa začne vykonávať pre každý terminál až v momente, keď už všetky komponenty na scéne dokončili svoju metódu toDo(). Táto metóda slúži na prenos výstupných hodnôt, ktoré sú uložené vo výstupných termináloch na pripojené vstupné terminály. Táto metóda slúži na vykonanie druhého kroku globálneho simulačného algoritmu.

public void public void setChangableText(int x,int y, String text) – Každý SVG_Widget má 1 meniteľný text, ktorý dáva triede Component k dispozícii, užívateľ môže nastaviť jeho polohu a obsah textu. Text je centrovaný v bode x,y.

public int getIntProperty(String key) – táto metóda slúži ako prístupový mostík k dátam z MyNode. Existujú ekvivalentné metódy getterov pre všetky používané typy premenných, tak isto aj settery. Pomocou String key určíme, hodnotu ktorej premennej chceme. Premenné sú určené kľúčom v XML súbore v elemente <key>.

Teraz sa pozrieme na spôsob tvorby nejakého konkrétneho simulačného komponentu. Treba si na príklade uvedomiť, ktoré časti sú nutné a ktoré sú nepovinné. ConstInteger je jednoduchý komponent, ktorý nemá žiadne vstupy a výstup je nejaká celočíselná hodnota, ktorú si užívateľ zadá v Properties okne.

 public class ConstInteger extends Component {
     int value = 0;
     public ConstInteger(){}
 	
     public void toDo(){
         ((ValueInt) out[0]).value = value;
     }
 
     public void updateComponentProperties(){
         value = getIntProperty("VALUE");
         setChangableText(Integer.toString(value));
     }
 }

Prvú vec ktorú si môžeme všimnúť z tohto príkladu je, že náš ConstInteger dedí z triedy Component. Toto je nutnosť pre všetky simulačné komponenty, práve z dôvodu, že sú tvorené cez Component triedu. Konštruktor musí byť vždy prázdny a bezparametrický! Metóda toDo je samotný simulačný algoritmus komponentu. Tu môžeme vidieť, akým spôsobom sa zadaná hodnota value odosiela na výstup tohto komponentu. Premenná out[0] je typu Value a je to referencia na hodnotu prvého výstupu. Preto je treba pretypovať ju na niektorú zo skutočných hodnôt. ValueInt predstavuje integer. Týmto špeciálnym triedam sa venuje ďalšia podkapitola. Prístup ku vstupným premenným máme cez in[x], kde x je poradové číslo terminálu. Terminály sú číslované od 0. K výstupom máme prístup cez out[x]. Nakoniec tu je metóda updateComponentProperties(). Táto nie je nutná, ale je vhodná práve pre updatovanie hodnôt z Properties okna. Ako bolo povedané táto metóda sa volá vždy po vykonaní nejakej zmeny v Properties okne. To znamená, že keď v tomto okne zmeníme nejakú položku, napríklad hodnotu integera, táto metóda sa zavolá. V takom prípade sa do hodnoty value zapíše nová hodnota, získaná z property okna. Na druhom riadku sa nastaví widgetu meniteľný text na súradniciach (0,0) a jeho popis bude novozískaná hodnota z property okna.

Samozrejme tu sa jedná len o triviálny príklad, obsah metódy toDo() obvykle býva komplexnejší a užívateľ si môže vytvárať v triede komponentu aj vlastné metódy, triedy a volať akékoľvek dostupné Java knižnice, takže vo svojej podstate môže dať komponentu ľubovoľnú funkcionalitu.

Value – univerzálny dátový typ

Trieda Value a jej detské triedy sa nachádzajú v balíčku sk.tnuni.dynasim.numeric. Jedná sa o zbierku tried, ktoré reprezentujú rôzne dátové typy a umožňujú medzi sebou vzájomné konverzie. Tieto triedy pôvodne vytvoril RNDr. Peter Fabo pre svoj simulačný program. Keďže výstupný terminál môže byť iného dátového typu ako vstupný terminál s ktorým je spojený, za normálnych okolností chceme, aby došlo k pretypovaniu hodnoty prichádzajúcej z výstupu, na hodnotu očakávanú na vstupe. Trieda Value nám ponúka jedno z možných riešení tohto problému. Value je abstraktná trieda a má len niekoľko abstraktných metód, zväčša na matematické operácie. Má ale niekoľko detských tried, ktoré z nej dedia a to sú: ValueAny, ValueBoolean, ValueChar, ValueInt atď. Tieto triedy už v sebe držia nejakú skutočnú hodnotu value, ktorej dátový typ zodpovedá triede. Teda ValueChar má premennú value dátového typu char, ValueInt má value typu int atď. Jej hodnota sa nastavuje v konštruktore. Ako príklad si zoberme konštruktor ValueInt. V prvom konštruktore sa hodnota value nastaví z parametru typu int. Zaujímavejší je ale druhý konštruktor ktorý má tvar:

 public ValueInt(Value x){
    this.value=parse(x);
 }

Tu sa konštruktoru predáva parameter typu Value. To môže byť teda ľubovoľný dátový typ. V metóde parse sa zistí o aký dátový typ ide a podľa toho sa vykoná príslušná metóda na konverziu na int. Rovnaký tvar a funkciu má aj metóda setValue(Value x), ktorá slúži na nastavenie hodnoty už existujúcej inštancii. Trieda Component v sebe drží pole vstupný a výstupných hodnôt in[] a out[] ako inštancie triedy Value, lebo sa nedá dopredu zistiť aké dátové typy im budú pridelené. Preto sa vykonáva v toDo() metóde konverzia z Value na príslušný dátový typ, napr. ValueInt ako to bolo ukázané v príklade tvorby simulačného algoritmu komponentu.

Interaktívne komponenty

Dedením z triedy Component sme mohli síce vytvoriť simulačné komponenty, ktoré vykonávali nejakú funkciu, ale ťažko by sa dali označiť za interaktívne. Interaktívne komponenty dávajú užívateľovi možnosť priamo zasahovať do simulačného procesu a za behu simulácie teda môže ovplyvňovať hodnoty stláčaním rôznych tlačidiel, alebo menením hodnôt pomocou slideru. Tak isto za interaktívne komponent môžeme považovať aj rôzne displeje a zobrazenia grafov, ktoré sa dynamicky menia počas behu simulácie.

Na tvorbu takéhoto druhu komponentov sa používa dedenie z abstraktnej metódy ComponentInteractive. Ten dedí priamo z triedy Component, takže má všetky vlastnosti bežných komponentov, ale navyše dokáže vytvoriť „plávajúce okná“ v ktorých môžu byť obsiahnuté rôzne riadiace a zobrazovacie prvky. Jedná sa o samostatné okná, ktoré je možno ľubovoľne presúvať podľa potreby po celej pracovnej ploche. Sú aktívne a zobrazené napríklad aj po minimalizácii aplikácie DynaSim a ak je spustená simulácia, je stále možné s nimi upravovať hodnoty vstupujúce do simulačného procesu a tým meniť jeho výstupy. Ako také interaktívne komponenty v našom programe vypadajú môžeme vidieť na obr.16.

Obr.16 Interaktívne komponenty programu DynaSim

Ako už bolo povedané, ComponentInteractive je abstraktná trieda. Obsahuje 4 metódy a jednu zahniezdenú abstraktnú triedu View. Triedou View sa vytvárajú naše plávajúce komponenty. Metóda showComponent() sa volá v prípade, keď chceme náš plávajúci komponent zobraziť, hideComponent() sa volá ak ho chceme skryť, a deleteComponent() v prípade, že ho chceme úplne odstrániť. Posledná metóda je abstraktná a má meno createView. V nej sa vytvára inštancia triedy View. ComponentInteractive je teda navonok jednoduchá trieda.

Teraz sa pozrieme na triedu View, ktorá dedí z JFrame. Jej konštruktor má 2 parametre a to width a height a rozmery tohto JFrame sa nastavia pomocou týchto parametrov. V konštruktore sa vytvorí nový Container. Ten má v sebe 1 JLabel, čo je horná uchopiteľná modrá lišta a je v nej napísané meno komponentu, ktorému toto okno patrí (obr.16). Druhý komponent, ktorý sa do Containeru pridá je JPanel. Toto miesto je vyhradené pre samotné zobrazenie interaktívneho komponentu, čo môže byť obyčajné tlačítko, či slider, ale môže ísť aj o komplexnejšie zobrazenie ako displej, alebo obrazovka osciloskopu. Trieda View má ešte 2 privátne metódy na manipuláciu presunu plávajúceho okna s myšou.

Teraz sa pozrime na ďalší príklad, tento krát na tvorbu Slideru. Po presunutí komponentu Slider z palety na editačnú plochu sa na nej vytvorí widget predstavujúci slider z grafiky načítanej z SVG súboru, ale mimo to aj plávajúci komponent, ktorým je možné meniť jednu z jeho vnútorných hodnôt (obr.16).

public class Slider extends ComponentInteractive{

    public SliderView sliderView;

    public class SliderView extends View{
        public JSlider slider;
        public boolean changed = false;

        public SliderView(){
            super(150,50);
            slider=new JSlider(JSlider.HORIZONTAL,0,100,0);
            slider.setBounds(5,5,140,25);
            slider.addChangeListener((ChangeListener) new SliderListener());
            panel.add(slider);
            setVisible(true);
        }

        class SliderListener implements ChangeListener{
            public void stateChanged(ChangeEvent e){
                changed = true;
                setIntProperty("VALUE", slider.getValue());
            }
        }
    }
}

Táto časť kódu pokrýva len vytvorenie samotného plávajúceho slideru. Ako vidno v našej triede simulačného komponentu Slider, ktorý je detskou triedou triedy ComponentInterractive v sebe vytvoril novú triedu SliderView, ktorá dedí z abstraktej triedy View. V ňom sa nastaví changeListener. Ten po akejkoľvek zmene polohy posuvníka na slidere zavolá setIntProperty metódu. Tá má na starosti úpravu príslušnej hodnoty v našom dátovom uzle typu MyNode a taktiež zmenu hodnoty v Property okne. Tento slider sa pridá na panel plávajúceho okna a nastaví sa ako viditeľný. Inštancia tejto triedy sa vytvára v metóde createView.

public void createView(){
    view = sliderView = new SliderView();
}

Samozrejme v tejto triede, keďže dedí z triedy Component, musí byť aj metóda toDo().

public void toDo(){
    ((ValueInt)out[0]).value = sliderView.slider.getValue();
}

Tu je simulačný algoritmus opäť jednoduchý. Na prvý výstup out[0] sa pošle aktuálna hodnota zo slideru. K tomu sa pristupuje cez sliderView, čo je inštancia zahniezdenej triedy SliderView.

Tvorba aplikácie

Aj keď je program po skompilovaní funkčný, pre koncového užívateľa zrejme tento fakt nebude mať príliš veľkú hodnotu, pokiaľ program nebude jednoducho spustiteľný nejakým spúšťacím súborom. Vytvorenie stand-alone aplikácie na platforme NetBeans je veľmi jednoduché. V NetBeans IDE v okne Projects si nájdeme našu aplikáciu postavenú na platforme NetBeans. Klikneme na ňu pravým tlačítkom a vyberiem položku Build ZIP Distribution. Tu si však treba dať pozor, lebo naša aplikácia musí byť nastavená ako stand-alone aplikácia a nie ako kolekcia prídavných modulov. Aby sme si to overili, treba kliknúť na našu aplikáciu pravým tlačítkom v Projects okne a vybrať položku Properties. Tu si v menu na ľavej strane menom Categories vyberieme položku Application (obr.17). V tomto menu musí byť označená položka „Create Standalone Application“. V Branding name si vyberieme aké meno bude mať priečinok našej novej aplikácie a jej spúšťacie súbory. Application Title je meno NetBeans aplikácie, ktoré sa zobrazuje v IDE. V ľavom menu Categories si môžeme vybrať položku Splash Screen, kde sú možné všetky nastavenia okna, ktoré sa objaví počas spúšťania aplikácie. Nakoniec v poslednej položke v Categories je možné povoliť resp. zakázať určité akcie s oknami v rámci našej aplikácie, ako napríklad presúvanie okien, menenie ich veľkosti a podobne.

Obr.17 Tvorba stand-alone aplikácie

Ak sme si teda overili, že vytvárame stand-alone aplikáciu a v Properties sme si nastavili všetky potrebné náležitosti, môžeme kliknúť na Build ZIP Distribution. Teraz je potrebné nájsť miesto na disku kde sa nachádza náš projekt. V ňom je adresár s názvom „dist“ a ten by mal obsahovať jeden .zip súbor s názvom, aký sme zadali v Properties v položke Branding name. Zip súbor treba rozbaliť a dostaneme priečinok s našou aplikáciu. V jej adresári menom „bin“ sa nachádza jeden .exe súbor a bash script. Exe súborom sa spúšťa aplikácia v operačnom systéme Windows. Bash scrip pre zmenu slúži ako spúšťací súbor v systéme Linux. Takto vytvorená aplikácia je spustiteľná v týchto dvoch systémoch bez nutnosti, aby na nich bol nainštalovaný NetBeans. Jediné, čo je pre ich spustenie potrebné je mať v týchto operačných systémoch nainštalované Java JRE, čiže aplikácia postavená na platforme NetBeans má rovnaké nároky na spustenie ako obyčajné Java aplikácie.

Tu si ale treba uvedomiť, že po postavení tejto aplikácie sa náš modul menom DynaSim, v ktorom bola uložená knižnica komponentov, zmenil na .jar súbor. Naša trieda FolderSearcher, ktorá rieši prístup k týmto súborom sa do .jar súboru nedokáže dostať. To znamená, že treba knižnicu v ktorej sú uložené XML a SVG súbory skopírovať do našej novovytvorenej aplikácie. To isté platí aj o knižnici class súborov. V systéme Windows môžu byť tieto knižnice umiestené v ľubovoľnom mieste našej aplikácie, v systéme Linux ale musia byť umiestené v adresári „bin“, čiže na mieste, kde sa nachádza aj spúšťací bash script. Ak sú splnené všetky tieto podmienky, aplikácia je teraz spustiteľná jedným zo spúšťacích súborov.

Záver

V tejto práci je rozobratý spôsob tvorby frameworku pre interaktívny simulačný program. Program obsahuje knižnicu niekoľkých základných simulačných komponentov, ktoré môžeme preniesť z palety na plochu editora a tie je možné vzájomne prepájať medzi sebou spojovacími čiarami. Tým docielime vzniku simulačnej schémy, ktorej simuláciu môžeme spustiť, resp. zastaviť pomocou príslušných tlačítok na toolbare. Boli implementované aj základné interaktívne komponenty, ktoré dávajú užívateľovi možnosť priamo zasahovať do procesu simulácie. Aj keď boli splnené všetky časti zadania tejto práce, len ťažko by sa dal program DynaSim považovať za finálny produkt. Tento fakt však vyplýva z jeho samotnej podstaty, lebo sa jedná o software, ktorý sa dá neustále vylepšovať a upravovať. Globálny simulačný algoritmus tohto programu je v súčasnej verzii veľmi jednoduchý a použiteľný len pre komponenty, ktoré sú schopné vypočítať svoju funkciu v jednom kroku, bez zásahov do iných komponentov v schéme počas doby výpočtu. Preto simulačné komponenty ako integrátor nie je zatiaľ možné začleniť do knižnice komponentov. Ďalším problémom je nemožnosť vytvoriť uzol priamo na spojovacej čiare, z ktorého by mohla viesť ďalšia spojovacia čiara. Tým by bolo možné jeden výstup z komponentu viesť priamo na vstup viacerých komponentov. Taktiež by bolo vhodné rozšíriť základnú sadu komponentov. Ďalšou z možných úprav by mohla byť zmena popisu funkcie komponentov z Java .class súborov na Jython súbory. Tie sa môžu kompilovať na bytecode v prípade potreby za behu programu. Tým by užívateľ, ktorý vytvára nové komponenty, nemusel kompilovať celý program na to, aby vytvoril class súbory.

Zoznam použitej literatúry

  1. HEROUT, Pavel: Učebnice Jazyka Java. Kopp, České Budějovice, 2000, ISBN 80-7232-115-3
  2. ECKEL, Bruce: Thinking in Java. Prentice HALL PTR, 1998, ISBN 0-13-659723-8
  3. CADENHEAD, Rogers – LEMAY, Laura: Sams Teach Yourself Java 6 in 21 Days. Sams Publishing, Indianapolis, 2007, ISBN-13: 978-0-672-32943-2
  4. BÖCK, Heiko: The Definitive Guide to NetBeans™ Platform. Apress, 2009, ISBN-13: 978-1-4302-2418-1
  5. NetBeans Visual Library Tutorial. Dostupné [2010.05.02]: <http://platform.netbeans.org/tutorials/nbm-visual_library.html>
  6. SVG - Scalable Vector Graphic. Dostupné: <http://www.xul.fr/en-xml-svg.html>
  7. Scalable Vector Graphics (SVG) 1.1 Specification - CSS Color Module Level 3. Dostupné [2010.05.02]: <http://www.w3.org/TR/css3-color/>
  8. Scalable Vector Graphics (SVG) 1.1 Specification - Basic Shapes. Dostupné [2010.05.02]: <http://www.w3.org/TR/SVG/shapes.html>
  9. Čo je NetBeans? Dostupné [2010.05.02]: <http://www.netbeans.org/index_sk.html>
  10. JDOM. Dostupné [2010.05.02]: <http://www.jdom.org/>
  11. NetBeans Visual Library in NetBeans Platform 6.0. Dostupné [2010.05.02]: <http://platform.netbeans.org/graph/>
  12. NetBeans Platform Learning Trail. Dostupné [2010.05.02]: <http://netbeans.org/kb/trails/platform.html>
  13. GTK+ Application in Netbeans 6.0. Dostupné [2010.05.02]: <http://wiki.netbeans.org/GtkApplicationInNetBeans>
  14. NetBeans Nodes, Explorer Manager, and Component Palette Tutorial. Dostupné [2010.05.02]: <http://platform.netbeans.org/tutorials/nbm-nodesapi3.html>
  15. NetBeans Nodes API Tutorial. Dostupné [2010.05.02]: <http://platform.netbeans.org/tutorials/nbm-nodesapi2.html>
  16. NetBeans Property Editor Tutorial. Dostupné [2010.05.02]: <http://platform.netbeans.org/tutorials/nbm-property-editors.html>