====== PJV úkoly ====== ===== Úkol č. 1 - intervaly ===== Doplňte kostru metod a tříd do funkčního celku. Projekt tvoří dvě třídy. První reprezentuje jednoduchý interval a několik operací s ním. Druhá představuje množinu jednoduchých intervalů. U obou objektů chceme mít metodu, která určuje, zda-li leží nějaký prvek v intervalu. Dále počítáme průnik nebo sjednocení intervalů (množin intervalů). Veškeré požadované části úkolu jsou pokryté testy. ==== Body ==== * 50% (8b) - za splněné testy //IntervalTest// a //SlozenyIntervalTest//. * 50% (8b) - za navíc (tj. včetně těch z první kategorie) splněný test //SlozenyIntervalTezsiTest// - Tady je potřeba umět slučovat intervaly při pridávání. Vše je popsáno v kódu. * Za neúplně splněné testy - dle individuálního posouzení, ale spíš 0. 100% bodů automaticky obdrží také ten, který najde nějakou chybu v testech (tj. že neodpovídají kýženému chování). ==== Jak na to ==== Stáhněte si projekt pro Netbeans nebo samostatné zdrojáky s Ant skriptem. Vyplňte prázdné, popř. jinak označené metody. *{{:pjvomo:ukoly:ukol1-netbeans.zip|}} - Projekt pro Netbeans. Je tam jeden soubor, který má zavislosti na mém počítači. Tipuju, že si ho budete muset přepsat, je to ''nbproject/private/private.properties''. *{{:pjvomo:ukoly:ukol1-src.zip|}} - Zdrojové kódy - Je nutno si nainstalovat samostatně Ant nebo kompilovat/spouštět ručně. ==== Odevzdání ==== Mailem do 20h dne před dalším cvičením PJV. Takže **6.4. @ 20:00** Předmětem odevzdání jsou soubory ''Interval.java'' a ''SlozenyInterval.java''. ===== Úkol č. 2 - spojový seznam ===== Doplňte kostru metod a tříd do funkčního celku. Projekt tvoří jeden jediný soubor, ''list/MyList.java'', ve kterém jsou definovány 3 třídy. - MyListItem - privátní v balíku, reprezentuje "vagónek" zřetězeného seznamu. - MyList - samotný spojový seznam. - MyListIterator - privátní v balíku, reprezentuje iterátor. Jak se má iterátor přesně chovat najdete nejlépe v dokumentaci interface [[http://java.sun.com/javase/6/docs/api/java/util/ListIterator.html|ListIterator]] a samozřejmě v testech. Iterátor bude umět všechny zde popisované operace. Oproti knihovní implementaci není potřeba detekovat změny na seznamu, které nejsou způsobené aktuálním iterátorem (např. souběžná modifikace seznamu pomocí dvou iterátorů by měla vyhodit výjimku) - to neřešte (nebo jen kdo chce, ale není to pokryto testy). Metody, které mají vyhazovat nějaké výjimky, jsou v kostře kódu patřičně zdokumentované. Veškeré požadované části úkolu jsou pokryté testy. ==== Body ==== * 10b za kompletně splněné testy. * Za neúplně splněné testy - dle individuálního posouzení, ale spíš 0. * Minusové body za "nepěkný" kód. ==== Jak na to ==== Stáhněte si projekt pro Netbeans nebo samostatné zdrojáky s Ant skriptem. Vyplňte prázdné, popř. jinak označené metody. **Pozor:** aktualizováno k 11.4. *{{:pjvomo:ukoly:ukol2-netbeans.zip|}} - Projekt pro Netbeans. Je tam jeden soubor, který má zavislosti na mém počítači. Tipuju, že si ho budete muset přepsat, je to ''nbproject/private/private.properties''. *{{:pjvomo:ukoly:ukol2-src.zip|}} - Zdrojové kódy - Je nutno si nainstalovat samostatně Ant nebo kompilovat/spouštět ručně. Testy se spouští příkazem ''ant test''. ==== Odevzdání ==== Mailem do 20h dne před dalším cvičením PJV. Takže **20.4. @ 20:00** Předmětem odevzdání je soubor ''MyList.java''. ===== Úkol č.3 ===== Pro třetí úkol je možno si vybrat **právě jedno** ze dvou možných zadání (jinak bych se asi uopravoval). Ani na jedno nejsou testy a obě jsou za max. 10 bodů, bude se zde přihlížet k dokonalosti programu. První je asi pracnější, ale lépe se ladí. Druhé je co do počtu řádek asi kratší, ale zato se při ladění více zapotíte. ==== Prohlížeč obrázků ==== Vaším úkolem je vytvořit aplikaci, která bude vypadat asi takto: {{ :pjvomo:ukoly:ukol-screen3.png |}} Objekty v okně jsou zleva tlačítko, panel, tlačítko zarovnané v BorderLayoutu. Všechny objekty ovšem bude nutné podědit a vytvořit vlastní modifikované verze. Tlačítka budou mít vlastní styl vykreslovaní (fantazii se meze nekladou, tohle je pouze příklad) pomocí překryté metody paint + budou měnit vzhled při **kliknutí** a při **přejetí myši**. K tomu vám poslouží MouseListener. Jak asi na to: po obdržení události modifikujte nějakou vnitřní proměnnou tlačítka a zavolejte nad tlačítkem ''repaint()'', čímž docílíte překreslení, které se provede v závislosti na té nastavené proměnné. 1. tlačítko otevře dialog pro otevření souboru (JFileChooser, popř. doplněný o nastavený filtr typů souborů - FileNameExtensionFilter) a po úspěšném otevření zobrazí obrázek na prostřední panel. K načtení se vám hodí třída ImageIO, a asi nejvíce její metoda ''read''. 2. tlačítko obrázek z panelu odstraní a uvede jej do původního stavu. Panel bude mít také vlastní styl překreslování. V prázdném stavu bude proškrtnut jako na obrázku. Pokud bude obsahovat obrázek, bude se tento obrázek zvětšovat/zmenšovat v závislosti na změně velikosti okna, a to se zachováním poměru výšky a šířky. Tedy například takto: {{:pjvomo:ukoly:ukol-screen2.png|}} nebo takto: {{:pjvomo:ukoly:ukol-screen1.png|}} Ovšem pozor. Pro zvětšování/zmenšování nepotřebujete žádné listenery. Stačí jen opět překrýt metodu paint a překreslovat správně obrázek. Proto je výhodnější si obrázek po výběru načíst do paměti v originální velikosti (ano, něco to bude žrát) a pak jej pokaždé jen vykreslovat se změněnou velikostí. ==== Producenti a konzumenti ==== Tohle je úloha na synchronizaci vláken. Máme množinu producentů, kteří produkují nějaké úkoly/výrobky do společné fronty. A pak máme množinu konzumentů, kteří prvky z fronty vyjímají a zpracovávají. V našem případě nám bude stačit výpis na std. výstup. Každý producent i konzument bude představován vláknem. Konstruktorem mu dodáme společnou frontu. Producent si na začátku rozmyslí, kolik výrobků celkem vyrobí, zvolte nějaké vhodné rozmezí. Pro generování náhodných čísel poslouží metoda Math.random(). Producent se bude chovat asi takto (neberte doslova) while (--pocet > 0) { dejSiPauzu(); //uspí se náhodný počet milisekund vygenerujPrvek(); //vygeneruje náhodný prvek (třeba číslo) a vloží jej do fronty } Konzument pak asi takto while (true) { dejSiPauzu(); //usni na nahodne dlouhy okamzik zpracujPrvek(); //vytiskni prvek z fronty } Hlavní vlákno (metoda main) má za úkol spustit všechny producenty a konzumenty a poté vyčkat na jejich ukončení, popř. jim přikázat ukončit (konzumentům). Jakmile každý producent vytvoří všechny produkty, ukončí se. U konzumentů to bude horší, takže klidně je může hlavní vlákno "zabít", jakmile zjistí, že už není co konzumovat (nebo to může nějak poznat každý konzument zvlášť, záleží na vaší vynalézavosti). Pro frontu můžete použít například LinkedList a jeho metody addFirst a removeLast. Ale pozor, fronta není thread-safe, takže bude nejlepší skládáním vytvořit vlastní a ošetřit paralelní přístup pomocí synchronized sekce. Fronta bude mít omezenou kapacitu. I když linked list je (teoreticky) neomezený, ve frontě musí být v jeden okamžik nějaký předem stanovený maximální počet prvků. Producenti, pokud nemohou vkládat do přeplněné fronty, čekají. Konzumenti, pokud nemají co konzumovat, taky čekají (případně se ukončí, pakliže už producenti skončili). Nejjednodušší implementace je pomocí dvou semaforů (třída Semaphore), z jednoho odebíráme při vkládání a do druhého přidáváme, u druhého obráceně. Samozřejmě musíte semafory patřičně inicializovat. Vzpomeňte si na cviko s vlákny. Tak zajistíte, že se producent/konzument uspí při plné/prázdné frontě. Pozor na některé sychronizační prohřešky: - nikdy nepoužívejte tzv. aktivní čekání, tj. ''while(není prvek) {čekej}'' apod. - nepoužívejte sleep, kromě funkce dejSiPauzu - ta je tam od toho, aby spřeházela pořadí práce vláken. - Pro čekání používejte výhradně prostředků k tomu určených. Synchronized sekce, Semafory, wait a notify, případně join apod. - nezamykejte dva zámky najednou, např. v synchronized sekci fronty nezamykejte semafor. Pokud se vlákno zastaví na semaforu, zámek od synchronized se neuvolní a máte zaděláno na deadlock. ==== Odevzdání ==== do 4.5. do 20h. Odevzdávejte tentokrát kompletní zdrojáky.