Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_ _ z 78. JavaFX 8.0. Rudolf Pecinovský

Podobné dokumenty
Při studiu tohoto bloku se předpokládá, že student je zvládá základy programování v jazyce Java s využitím vývojového prostředí NetBeans.

GUI. JavaFX. Java UI, letní semestr 2017/2018 1

Copyright Rudolf Pecinovský, Soubor: 02_Rozhraní x Interfejs.doc, verze , uloženo čt :44 1z 55. Rozhraní. interface (interfejs)

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

Aplikace s grafickým uživatelským rozhraním

IRAE 07/08 Přednáška č. 7. Začátek (head)

Programátorská příručka

1 Uživatelská dokumentace

1. Programování proti rozhraní

Java aplety. Předávání parametrů z HTML

Vlákno (anglicky: thread) v informatice označuje vlákno výpočtu neboli samostatný výpočetní tok, tedy posloupnost po sobě jdoucích operací.

01. HODINA. 1.1 Spuštění programu VB Prvky integrovaného vývojového prostředí. - pomocí ikony, z menu Start.

TÉMATICKÝ OKRUH Softwarové inženýrství

Generické programování

Tento projekt je spolufinancován Evropským sociálním fondem a státním rozpočtem České republiky. PORTÁL KUDY KAM. Manuál pro administrátory. Verze 1.

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

02. HODINA. 2.1 Typy souborů a objektů. 2.2 Ovládací prvky Label a TextBox

Úvod do počítačových sítí

Procesy a vlákna (Processes and Threads)

Další nutný soubor je laydiv.js, ve kterém jsou uloženy funkce pro zobrazování virů na ploše a funkce pro odkaz na Teachers Guide.

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

Reliance 3 design OBSAH

GUI - úvod. V této kapitole si ukážeme návod, jak vytvořit jednoduchou grafickou aplikaci a umístit do ní některé další grafické prvky.

Management procesu I Mgr. Josef Horálek

Úvod do JavaFX RICHARD LIPKA

Služba ve Windows. Služba (service) je program

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Architektura rodiny operačních systémů Windows NT Mgr. Josef Horálek

MATLABLINK - VZDÁLENÉ OVLÁDÁNÍ A MONITOROVÁNÍ TECHNOLOGICKÝCH PROCESŮ

Google Web Toolkit. Martin Šurkovský, SUR března Katedra informatiky

Tematický celek Proměnné. Proměnné slouží k dočasnému uchovávání hodnot během provádění aplikace Deklarace proměnných

GUI. Systémová integrace pro desktopové aplikace

Nový způsob práce s průběžnou klasifikací lze nastavit pouze tehdy, je-li průběžná klasifikace v evidenčním pololetí a školním roce prázdná.

Zpravodaj. Uživatelská příručka. Verze

PŘETĚŽOVÁNÍ OPERÁTORŮ

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Základy objektové orientace I. Únor 2010

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Instalace programu ProVIS

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

Výčtový typ strana 67

MBI - technologická realizace modelu

Konstruktory a destruktory

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

OPS Paralelní systémy, seznam pojmů, klasifikace

Téma 1: Práce s Desktop. Téma 1: Práce s Desktop

NetBeans platforma. Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti

Trosečník v džungli, adventura

Tabulka symbolů. Vazba (binding) Vazba - příklad. Deklarace a definice. Miroslav Beneš Dušan Kolář

2 Grafický výstup s využitím knihovny

20. Projekt Domácí mediotéka

Metodika. Architecture First. Rudolf Pecinovský

Typy souborů ve STATISTICA. Tento článek poslouží jako přehled hlavních typů souborů v programu

Popis ovládání. Po přihlášení do aplikace se objeví navigátor. Navigátor je stromově seřazen a slouží pro přístup ke všem oknům celé aplikace.

DUM 06 téma: Tvorba makra pomocí VBA

Příručka pro aplikaci KSnapshot

První kapitola úvod do problematiky

1. Dědičnost a polymorfismus

11 Diagram tříd, asociace, dědičnost, abstraktní třídy

KTE / ZPE Informační technologie

TAOS321. Administrace. příručka správce systému. informační terminál systému JSVV

Principy operačních systémů. Lekce 5: Multiprogramming a multitasking, vlákna

MS WINDOWS I. řada operačních systémů firmy Microsoft *1985 -? Historie. Práce ve Windows XP. Architektura. Instalace. Spouštění

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

Zdokonalování gramotnosti v oblasti ICT. Kurz MS Excel kurz 6. Inovace a modernizace studijních oborů FSpS (IMPACT) CZ.1.07/2.2.00/28.

TECHNOLOGIE ELASTICKÉ KONFORMNÍ TRANSFORMACE RASTROVÝCH OBRAZŮ

Algoritmizace a programování

7. Datové typy v Javě

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

Přidělování CPU Mgr. Josef Horálek

Vzorce. Suma. Tvorba vzorce napsáním. Tvorba vzorců průvodcem

Struktura programu v době běhu

UJO Framework. revoluční architektura beans. verze

Vaše jistota na trhu IT. Balíčky. Rudolf Pecinovský

NSWI096 - INTERNET JavaScript

Abstraktní datové typy: zásobník

typová konverze typová inference

Tento projekt je spolufinancován Evropským sociálním fondem a státním rozpočtem České republiky. PORTÁL KUDY KAM. Manuál pro editaci ŽS. Verze 1.

Uživatelský manuál. Aplikace GraphViewer. Vytvořil: Viktor Dlouhý

OMO. 4 - Creational design patterns A. Singleton Simple Factory Factory Method Abstract Factory Prototype Builder IoC

Obsah přednášky. 12. Dokumentace zdrojového kódu Tvorba elektronické dokumentace UML. Co je diagram tříd. Ing. Ondřej Guth

Třídy. Instance. Pokud tento program spustíme, vypíše následující. car1 má barvu Red. car2 má barvu Red. car1 má barvu Blue.

8. GRAFICKÉ UŽIVATELSKÉ ROZHRANÍ

Obslužný software. PAP ISO 9001

Úvod...1 Instalace...1 Popis funkcí...2 Hlavní obrazovka...2 Menu...3 Práce s aplikací - příklad...5

Java a XML. 10/26/09 1/7 Java a XML

GUI. Systémová integrace pro desktopové aplikace

Quo vadis programování? Automatizace vyhodnocování studentských úloh

Komponenty v.net. Obsah přednášky

Návrhové vzory. Jakub Klemsa, Jan Legerský. 30. října Objektově orientované programování.

44 Organizace akcí. Popis modulu. Záložka Seznam akcí

UniLog-D. v1.01 návod k obsluze software. Strana 1

MS Excel makra a VBA

Teoretické minimum z PJV

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Implementace LL(1) překladů

PALSTAT s.r.o. systémy řízení jakosti PALSTAT CAQ verze Výstupní kontrola 07.1/ Obsah

Datové struktury. alg12 1

Transkript:

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 1 z 78 JavaFX 8.0 Rudolf Pecinovský rudolf@pecinovsky.cz

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 2 z 78 Obsah 1. Seznámení s koncepcí 2. Základní stavební prvky 3. Oživujeme aplikaci 4. Přidáváme formátování 5. Další potřebné prvky

1. Seznámení s koncepcí Obsah 1.1 Historický úvod 1.1.1 Abstract Window Toolkit AWT 1.1.2 Swing 1.1.3 Standard Widget Toolkit SWT 1.1.4 JavaFX 1.2 Cíle 1.3 Oddělení práce grafiků a programátorů 1.4 Některá specifika knihovny/platformy JavaFX 1.5 Vlákna 1.5.1 Paralelní procesy 1.5.1 Kooperativní plánování 1.5.2 Preemptivní plánování 1.5.3 Procesy vlákna 1.5.4 Přístup platformy JavaFX k vláknům Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 3 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 4 z 78 1.1 Historický úvod Java se rychle uchytila jako hlavní jazyk pro výuku v univerzitních začátečnických kurzech programování Její hlavní výhodou bylo, že byla multiplatformní a navíc zabalila do jednoho produktu několik klíčových funkcionalit, které do té doby nevyly běžné nebo byly řešené odděleně v samostatných knihovnách a jednoúčelových jazycích Velmi dobrou podporu objektového paradigmatu Automatickou správu paměti Integrovanou podporu práce s vlákny Integrovanou podporu serializace Poměrně efektivní nástroj na vytváření platformně nezávislého GUI Postupně se prosazovaly různé nástroje pro návrh GUI AWT Swing SWT JavaFX

1.1.1 Abstract Window Toolkit AWT Základní knihovna, která byla součástí verze 1.0 Rozhodnutí o začlenění GUI padlo měsíc před uvedením produktu Používá komponenty OS, nad nímž běží Výhoda: Rychlá a jednoduchá Nevýhoda: Problém největšího společného dělitele Může používat pouze komponenty, které jsou součástí všech OS Když některé OS začaly zavádět další druhy komponent, nabylo možno je začlenit Ve verzi 1.1 zavedla systém událostí, který se používá dodnes Pro nezávislost definice vzhledu na použitém OS zavedla správce rozvržení layout managers Správci se liší strategií uspořádání jednotlivých komponent kontejneru Ke kontejneru přiřadíme správce podle požadované strategie Správce pak po každé změně automaticky přeuspořádá komponenty Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 5 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 6 z 78 1.1.2 Swing Knihovna byla začleněna ve verzi 2.0 Používá systém událostí a správců rozvržení knihovny AWT Přidává některé nové správce rozvržení Od OS přebírá pouze modul pro vyhrazení oblasti na obrazovce, vlastní zobrazení obsahu okna již řeší po svém Výhody: Lze snadno přidávat nové komponenty (tabulky, stromy, ) Umí zavést průsvitná okna a okna libovolných tvarů Nevýhoda: Je výrazně pomalejší, i když u současných počítačů to již není tak patrné Lze dynamicky nastavovat koncepci vzhledu tzv. look and feel Je naprogramována čistě objektově, takže ji lze snadno rozšířit

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 7 z 78 1.1.3 Standard Widget Toolkit SWT Knihovna SWT vznikla v IBM jako pokus o vytvoření knihovny s rychlostí knihovny AWT a tvárností knihovny Swing Inspirací byla starší knihovna napsaná v IBM v jazyku Smalltalk Nad touto knihovnou je postaveno vývojové prostředí Eclipse Knihovna nemá takové možnosti rozšíření jako Swing, takže nakonec musela být do Eclipse musel zařazeny nástroje umožňující efektivní vývoj programů nad knihovnou Swing

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 8 z 78 1.1.4 JavaFX S nástupem nových poznatků, možností a technologií sílila potřeba výrazné přepracování knihovny Swing Firma Sun přišla s alternativním řešením jazykem JavaFX Script V roce 2007 byl zveřejněn jako open source Následně byla vytvořena knihovna Javy se stejnou funkcionalitou Od verze 8 je integrální součástí standardní knihovny, knihovna Swing již není dále vyvíjena, pouze se v ní opravují chyby Většina aplikací postupně přechází ze Swing na JavaFX, protože ta lépe podporuje poslední technologie a možnosti

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 9 z 78 1.2 Cíle Knihovna je navržena tak, aby vyvinuté aplikace mohly běhat stejně dobře v různých prostředích: na desktopu, v appletu v nějakém zařízení (telefon, set-top box, ) Formátování lze definovat několika způsoby Klasicky programem Prostřednictvím XML souborů typu FXML Prostřednictvím souborů CSS Snaha používat především deklarativní styl programování: Říkat čeho chceme dosáhnout Nemuset říkat jak toho dosáhnout

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 10 z 78 1.3 Oddělení práce grafiků a programátorů Na vývoji GUI se podílejí dvě skupiny vývojářů: Grafici a odborníci na UI, kteří navrhují obsah a rozvržení jednotlivých dialogových oken a dalších ovládacích prvků Programátoři, kteří mají na starosti funkčnost navrženého GUI Každá skupina má jiný přístup k návrhu a preferuje jiné nástroje V klasicky navržených knihovnách se špatně rozdělují zodpovědnosti za jednotlivé části návrhu JavaFX umožňuje, aby každá skupina navrhla svoji část do vlastních souborů, jejichž obsah druhá skupina nijak neovlivní Grafici navrhují uspořádání do souboru FXML a formát do souborů CSS Programátoři navrhují funkčnost ve zdrojových souborech použitého programovacího jazyka (Java, Groovy, Scala, )

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 11 z 78 1.4 Některá specifika knihovny/platformy JavaFX Souřadnice i rozměry se zadávají jako čísla typu double Jakékoliv operace, které se mají vzápětí projevit na obrazovce, je třeba provádět z vlákna JavaFX Application Operace, které trvají delší dobu, je třeba provádět v jiném vlákně a vlákno JavaFX Application pověřovat pouze zobrazením výsledku

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 12 z 78 1.5 Vlákna Dění v okolním světě probíhá paralelně Každý jedinec žije relativně nezávisle na ostatních Každá buňka v jedinci žije relativně nezávisle na ostatních Pro přežití spolu musí jednotliví jedinci/buňky komunikovat Je-li program simulací dějů ve světě, musí umět tuto skutečnost nějak modelovat Paralelismus se v programech často využívá: Vytížení počítače při čekání na externí časově náročné akce Čekání na uživatelský vstup Úlohy typu producent konzument (sdílení prostředků) Simulace

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 13 z 78 1.5.1 Paralelní procesy Současné operační systémy dokáží dělat několik věcí najednou, a to i tehdy, mají-li k dispozici pouze jeden procesor Každá akce se spustí jako tzv. proces, kterému pak přidělován procesor Výhodou takto zorganizované práce je celkové urychlení Proces, který musí počkat na odezvu nějakého pomalejšího zařízení, může vrátit procesor, aby byl na dobu tohoto čekání přidělen jinému procesu Podpora paralelismu bývá začleněna i do instrukčního souboru mikroprocesorů Přidělováním procesorů je pověřen speciální program označovaný jako plánovač procesů (anglicky process scheduler) Dva přístupy k řízení paralelních procesů Kooperativní plánování Preemptivní plánování

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 14 z 78 1.5.1 Kooperativní plánování Plánovač přidělí procesor vybranému procesu a ten se jej po nějaké době dobrovolně vzdá Lze provozovat na jakémkoliv procesoru Příliš závislé na správném naprogramování každý proces se musí v pravidelných intervalech dobrovolně vzdát procesoru Zablokování chodu jednoho procesu zastaví chod všech ostatních Příklad (pro pamětníky): Windows 3.11 Kooperativní plánování paralelních procesů používají některé levnější telefony

1.5.2 Preemptivní plánování Preempt: 1) předejít, zabránit; 2) získat předkupním právem; 3) přivlastnit si, uzurpovat Plánovač přidělí spuštěnému procesu procesor, takže daný proces může začít vykonávat požadovanou činnost Po nějaké době (řádově desítky až stovky milisekund) mu procesor opět odebere Přitom si musí zapamatovat důležité informace o aktuálním stavu přerušeného procesu, aby jej mohl posléze do tohoto stavu vrátit a přidělí procesor jinému procesu Nejprve jej ale uvede do stavu, ve kterém mu byl procesor odebrán Protože se toto přepínáním procesů děje velmi rychle, běžnému uživateli připadá, že všechny procesy běží současně. Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 15 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 16 z 78 1.5.3 Procesy vlákna Ukládání informací o stavu přerušovaného procesu vyžaduje nezanedbatelnou režii musí si pamatovat Stav procesoru, tj. obsah jednotlivých registrů Oblasti paměti, do nichž má přístup Potřeba zvýšení efektivity přepínání mezi procesy přimělo autory OS, aby jednotlivým procesům umožnily vytvářet jednodušeji koncipované podprocesy, které označujeme jako vlákna (thread) Vlákna na rozdíl od procesů sdílejí paměť Procesy (podprocesy, vlákna) sdílí řadu zdrojů, o které soupeří Sdílení zdrojů sníží režií při jejich přepínání Soupeření o zdroje zvyšuje pravděpodobnost, že při jejich získávání a uvolňování nastanou problémy Jedním ze zdrojů je i obrazovka a další periferie ovládané platformou JavaFX

1.5.4 Přístup platformy JavaFX k vláknům JavaFX řeší tuto problematiku obdobně jako naprostá většina současných platforem pro tvorbu GUI: reaguje pouze na požadavky přišedší z jejího vlákna Pro požadavky přímo ovlivňující dění na obrazovce (a dalších zařízeních) je vytvořeno vlákno JavaFX Application Thread Přišedší požadavky jsou řazeny do fronty a zpracovávány jeden po druhém Nepříjemný důsledek: dlouhotrvající operace zastaví GUI Řešení: JavaFX umožňuje spustit dlouhotrvající akci v jiném vláknu a požadavek na překreslení zařadit do fronty, až bude akce hotova Nepříjemný vedlejší efekt: Studenti občas tento mechanizmus omylem spustí a pak je překvapí zdánlivě podivuhodné chování programu Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 17 z 78

2. Základní stavební prvky Obsah 2.1 Aplikace javafx.application.application 2.1.1 Spuštění aplikace bez metody main(string[]) 2.1.2 Spuštění a ukončení s metodou main(string[]) 2.1.3 Alternativní spuštění 2.1.4 Ukončení aplikace 2.2 Třída javafx.application.platform 2.3 Standardní životní cyklus aplikace 2.3.1 Poznámky k životnímu cyklu 2.3.2 Demo: C00_EmptyApplicatioon 2.4 Jeviště javafx.stage.stage 2.4.1 Nejpoužívanější metody jeviště 2.4.2 Metody ovlivňující pozici okna 2.4.3 Metody ovlivňující velikost okna 2.4.4 Metody ovlivňující viditelnost okna 2.4.5 Superjednoduchá aplikace s jevištěm 2.5 Scéna javafx.scene.scene 2.5.1 Konstruktory scény 2.5.2 Nejpoužívanější metody scény 2.6 Grafické prvky (uzly) javafx.scene.node 2.6.1 Základní spouštěcí třídy 2.6.2 Demonstrační aplikace s pasivním tlačítkem Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 18 z 78

2.1 Aplikace javafx.application.application Hlavním objektem celého GUI je instance třídy, která musí být potomkem třídy javafx.application.application Ta při spuštění: Zjistí základní vlastnosti prostředí, pod nímž běží (většinou operační systém či prohlížeč) Velikost oblasti, kterou má k dispozici pro zobrazení Barevnou hloubku (jak předávat informace o zobrazovaných barvách) Odkaz na pomocné knihovny (DirectX, OpenGL, ) Další potřebné informace Získá od prostředí objekt pro budoucí primární okno Propojí tento objekt s tzv. jevištěm (objekt typu javafx.stage.stage) Vytvoří vlákni událostí JavaFX Application Thread Zavolá metodu start(stage) zodpovědnou za inicializaci GUI a předá ji primární jeviště Potomek musí mít veřejný bezparametrický konstruktor a musí přebít abstraktní metodu start(stage) Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 19 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 20 z 78 2.1.1 Spuštění aplikace bez metody main(string[]) Aplikace v JavaFX teoreticky nepotřebuje metodu main(string[]) Jako hlavní třídu aplikace je možno definovat i třídu, která je potomkem třídy javafx.application.application Při práci v NetBeans: má-li být třída považována za hlavní třídu aplikace i bez main(string[]), je potřeba pro daný projekt nastavit Properties Deployment Switch Project to JavaFXDeployment Model a zadat pak příslušnou třídu jako hlavní Toto nastavení však není možno jednoduše vrátit Příslušná nastavení se musí vrátit zpět ručně opravou příslušných konfiguračních souborů Doporučuji proto dát přednost klasické cestě používající hlavní třídu s metodou main(string[])

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 21 z 78 2.1.2 Spuštění a ukončení s metodou main(string[]) Platforma se spouští zavoláním statické metody třídy Application se signaturou: public static void launch(class<? extends Application> appclass, String... args) Voláme-li tuto metodu z potomka třídy Application, můžeme volat zjednodušenou verzi se signaturou public static void launch(string... args) Tato metoda si zjistí třídu, jejíž metoda ji volá, a zavolá předchozí verzi, které předá class-objekt volající třídy jako parametr

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 22 z 78 2.1.3 Alternativní spuštění Vlákno JavaFX je možno spustit i pouhým vytvořením instance některé vhodné třídy Jedna z možností: new JFXPanel(); Jeviště si pak aplikace vytvoří zavoláním příslušného konstruktoru

2.1.4 Ukončení aplikace Ukončení aplikace nezávisí na způsobu spuštění Aplikaci můžeme ukončit: Automaticky po zavření posledního okna Pokus se žádné okno neotevře, nemůže se ani zavřít, a proto po ukončení metody start(stage) aplikace stále běží Ručně zavoláním metody javafx.application.platform.exit() Možnost automatického ukončení je možno zakázat zavoláním javafx.application.platform.setimplicitexit(false) Naopak zavoláním javafx.application.platform.setimplicitexit(true) můžeme automatické ukončování opět povolit Implicitně je automatické ukončování povoleno (na rozdíl od zvyklostí v platformě swing) Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 23 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 24 z 78 2.2 Třída javafx.application.platform Knihovní třída řešící záležitosti platformy JavaFX Důležité metody void exit() Ukončí aplikaci boolean isimplicitexit() void setimplicitexit(boolean implicitexit) Zjistí, resp. nastaví, zda se po zavření posledního okna aplikace ukončí boolean isfxapplicationthread() Prozradí, zda volající kód běží ve vlákně JavaFX Application Thread void runlater(runnable runnable) Spustí metodu run() zadaného objektu ve vlákně JavaFX Application Thread

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 25 z 78 2.3 Standardní životní cyklus aplikace 1. Spouštěcí metoda launch(?) zjistí, jestli už byla volána, a pokud ano, vyhodí výjimku IllegalStateException která ohlásí: Application launch must not be called more than once 2. Inicializuje platformu a vytvoří a spustí vlákna JavaFX Launcher pro přípravu a posléze i ukončení celé platformy JavaFX Application, v němž se budou provádět operace ovlivňující podobu GUI 3. Vytvoří se instance spouštěného GUI (potomka Application) 4. Ve vláknu JavaFX Launcher se provede metoda init() zodpovědná za inicializaci objektů nesouvisejících přímo s GUI 5. Ve vláknu JavaFX Application se provede metoda start(stage) zodpovědná za realizaci a běh vlastního GUI nyní aplikace běží 6. Po ukončení se ve vláknu JavaFX Application provede metoda stop() zodpovědná za úklid prostředků, které nezvládla uklidit metoda start(stage) 7. Ukončí se celá aplikace

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 26 z 78 2.3.1 Poznámky k životnímu cyklu Nejsou-li definovány metody init() a/nebo stop() použijí se zděděné verze, které jsou prázdné Aplikace běží, dokud se neukončí metoda launch(?), která však čeká na ukončení metody start(stage) Může se proto stát, že spustíme druhou aplikaci, když ještě stále (byť neviditelně) běží ta první Nebezpečí je však menší než při použití knihovny Swing, protože implicitně stačí zavřít všechna okna a není třeba myslet na nutnost explicitního nastavení ukončení Metoda stop() se spustí nezávisle na tom, jedná-li se o řádné či mimořádné ukončení

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 27 z 78 2.3.2 Demo: C00_EmptyApplicatioon public class C00_EmptyApplicatioon extends Application { @Override public void init() { System.out.println("\nMetoda init() spuštěna\n"); } @Override public void start(stage primarystage) { System.out.println("\nMetoda start spuštěna\n" + "a ukončena\n"); // Platform.exit(); //Ukončí se i bez explicitního volání exit() } @Override public void stop() { System.out.println("\nMetoda stop() spuštěna\n"); } } public static void main(string[] args) { launch(args); }

2.4 Jeviště javafx.stage.stage Viditelnou část aplikace zobrazuje jeviště instance třídy javafx.stage.stage U desktopových aplikací je jevištěm aplikační okno, včetně případné titulkové lišty a dalších zdobení Aplikační okno může být i celoobrazovkové bez zdobení U appletů běžících v rámci nějaké webové stránky je jevištěm příslušná obdélníková oblast dané stránky U maloobrazovkových zařízení bez multiokenního operačního systému bývá jevištěm celá obrazovka Jeviště nemusí být jediné Primární jeviště konstruuje platforma při startu aplikace Program může během svého života vytvářet další jeviště a nepotřebná jeviště opět rušit Aby mělo jeviště co zobrazovat, musí se mu nastavit scéna O scéně pojednává subkapitola 1.6 Scéna javafx.scene.scene na straně 34 Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 28 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 29 z 78 2.4.1 Nejpoužívanější metody jeviště String gettitle() void settitle(string value) Vrátí, resp. nastaví titulek okna daného jeviště Scene getscene() void setscene(scene value) Vrátí, resp. nastaví scénu zobrazovanou na daném jevišti void show() Zobrazí okno daného jeviště void showandwait() Zobrazí okno daného jeviště a počká, až je uživatel zavře void close() void hide() Zavře, resp. skryje okno daného jeviště Tyto metody jsou si ekvivalentní boolean isshowing() Vrátí, zda je dané okno zobrazováno (neříká, jestli je vidět!)

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 30 z 78 2.4.2 Metody ovlivňující pozici okna public void centeronscreen() Vystředí okno na obrazovce double getx() double gety() Vrátí vodorovnou, resp. svislou pozici okna na obrazovce void setx(double value) void sety(double value) Nastaví vodorovnou, resp. svislou pozici okna na obrazovce Pro umístění na jiné obrazovce je možno používat i záporné souřadnice

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 31 z 78 2.4.3 Metody ovlivňující velikost okna public void sizetoscene() Nastaví velikost okna podle velikosti zobrazované scény double getwidth() void setwidth (double value) double getheight() void setheight(double value) Vrátí, resp. nastaví, šířku, resp. výšku okna daného jeviště boolean isresizable() void setresizable(boolean value) Vrátí, resp. nastaví, zda může uživatel měnit velikost okna boolean isfullscreen() void setfullscreen(boolean value) Vrátí, resp. nastaví, zda má být okno roztažené přes celou obrazovku boolean ismaximized() void setmaximized(boolean value) Vrátí, resp. nastaví, zda má být okno maximalizováno boolean isiconified() void seticonified(boolean value) Vrátí, resp. nastaví, zda má být okno minimalizováno

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 32 z 78 2.4.4 Metody ovlivňující viditelnost okna boolean isalwaysontop() void setalwaysontop(boolean value) Vrátí, resp. nastaví, zda má být okno daného jeviště vždy navrchu void toback() Přesune okna daného jeviště za ostatní okna void tofront() Přesune okna daného jeviště před ostatní okna double getopacity() void setopacity(double value) Vrátí, resp. nastaví průhlednost daného okna

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 33 z 78 2.4.5 Superjednoduchá aplikace s jevištěm public class C01_EmptyStage extends Application { @Override public void init() { JOptionPane.showMessageDialog(null, "Metoda init() spuštěna"); } } @Override public void start(stage primarystage) throws Exception { primarystage.settitle("prázdné jeviště bez scény"); primarystage.setx(-1250); primarystage.show(); } @Override public void stop() { JOptionPane.showMessageDialog(null, "Metoda stop() spuštěna"); } public static void main(string[] args) { launch(args); }

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 34 z 78 2.5 Scéna javafx.scene.scene Scéna (instance třídy javafx.scene.scene) je základním kontejnerem zobrazovaných grafických prvků Opakování: Kontejner je objekt určený k ukládání jiných objektů Scéna smí obsahovat pouze jediný grafický prvek, kterým je kontejner typu javafx.scene.parent Grafické prvky jsou instancemi některého z potomků abstraktní třídy javafx.scene.node Prvky jsou uspořádány do stromu, jehož kořenem je kontejner, který se zadává konstruktoru scény jako parametr Během života scény je možno tento kořen měnit

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 35 z 78 2.5.1 Konstruktory scény Scene(Parent root) Scene(Parent root, Paint fill) Scene(Parent root, double width, double height) Scene(Parent root, double width, double height, Paint fill) Scene(Parent root, double width, double height, boolean depthbuffer) Parametr depthbuffer má smysl pouze při zobrazování 3D grafiky Scene(Parent root, double width, double height, boolean depthbuffer, SceneAntialiasing antialiasing)

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 36 z 78 2.5.2 Nejpoužívanější metody scény Parent getroot() void setroot(parent value) Vrátí, resp. nastaví kořenový prvek strom grafických prvků double getx() double gety() Vrátí vodorovnou, resp. svislou souřadnici scény v okně void setx(double value) void sety(double value) Nastaví vodorovnou, resp. svislou souřadnici scény v okně double getwidth() double getheight() Vrátí šířku, resp. výšku okna dané scény Parent getroot() void setroot(parent value) Vrátí, resp. nastaví kořenový kontejner stromu grafických prvků

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 37 z 78 2.6 Grafické prvky (uzly) javafx.scene.node Scéna obsahuje grafické prvky, které jsou instancemi abstraktní třídy javafx.scene.node Speciálním druhem prvků jsou kontejnery; ty jsou instancemi třídy javafx.scene.parent nebo jejích potomků Třída Node má přes 300 vlastních metod, které začneme probírat vždy, až to bude vhodné Některé prvky jsou současně ovládací prvky a současně kontejnery; mezi takové patří např. tlačítko

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 38 z 78 2.6.1 Základní spouštěcí třídy javafx.application <<library>> Platform <<abstract>> Application MyApplication + start(primarystage : Stage) : void javafx.stage Window Stage + setscene(scene : Scene) : void + setscene(scene : Scene) : void javafx.scene <<abstract>> Node Parent + getchildren() : ObservableList<Node> Scene javafx.bean javafx.collections java.util <<interface>> Ovservable <<interface>> ObservableList<Node> <<interface>> List<Node>

2.6.2 Demonstrační aplikace s pasivním tlačítkem public class C02_h extends C01_EmptyStage { @Override public void start(stage primarystage) { primarystage.setx(x0); primarystage.settitle("jeviště se scénou s pasivním tlačítkem"); Button button = new Button("Já jsem tlačítko"); Scene scene = new Scene(button); } primarystage.setscene(scene); primarystage.show(); } public static void main(string[] args) { launch(args); } Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 39 z 78

3. Oživujeme aplikaci Obsah 3.1 Událostí a jejich ošetření 3.2 Návrhový vzor Pozorovatel 3.2.1 Princip práce 3.2.2 Diagram tříd vzoru Pozorovatel 3.2.3 Aplikované principy a možné implementace 3.3 Události a reakce na ně 3.3.1 Ovladače událostí EventHandler 3.3.2 Reakce tlačítka na stisk Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 40 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 41 z 78 3.1 Událostí a jejich ošetření Dřívější programy sledovaly vstup z klávesnice, a když uživatel něco zadal, tak na zadaný příkaz zareagovaly Problém je v tom, že požadavky lze zadávat mnoha různými způsoby a program pak musí sledovat několik zařízení současně Program, který vše sleduje, není triviální, a proto byl koncept čekání na požadavky a jejich zpracování změněn Současné programy nečekají na vstup aktivně, ale přenechají prvotní zpracování vstupu operačnímu systému Operační systém hlídá všechny možné vstupy, a nastane-li situace, na níž by uživatel mohl chtít zareagovat, vyrobí objekt specifikující vzniklou událost a oznámí vznik dané události všem, kteří se přihlásili jako čekatelé Celé řešení je postaveno na doporučeních návrhového vzoru Pozorovatel Posluchač Vydavatel-Předplatitel (Observer Listener Publisher-Subscriber)

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 42 z 78 3.2 Návrhový vzor Pozorovatel Pro tento návrhový vzor se používá více názvů Pozorovatel (Observer) Posluchač (Listener) Vydavatel Předplatitel (Publisher Subscriber) Princip Objekt čekající na výskyt nějaké události má dvě možnosti: Neustále se ptát iniciátora události, zda už nastala Oslík v 2. dílu Shreka se neustále ptá Už tam budem? Řidič čekající na zelenou neustále sleduje semafor Dohodne se s iniciátorem, že dohodnutým způsobem oznámí, až událost nastane V lůžkovém vlaku vás průvodčí vzbudí před cílovou stanicí Řidič na semaforu v klidu čte mapu v očekávání, že ti za ním na něj zatroubí SMS oznámí příchod peněz na konto Návrhový vzor Pozorovatel řeší problém druhým způsobem, je však třeba dohodnout způsob oznámení výskytu události

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 43 z 78 3.2.1 Princip práce Pozorovatel (posluchač/předplatitel) se přihlásí u pozorovaného (poslouchaného, vydavatele) objektu, a ten mu při vzniku očekávané události pošle o této události zprávu Pozorovaný (vysílač, vydavatel) je ochoten přijmout přihlášku pouze od objektů, jejichž mateřské třídy implementují interfejs definující jak objektu oznámit, že došlo k očekávané události Pozorovatel (posluchač/předplatitel) se po přihlášení o událost dál nestará a hledí si svého Zareaguje až v okamžiku, kdy pozorovaný (vysílač, vydavatel) pošle dohodnutou zprávu (zavolá příslušnou metodu) Takto koncipovaný program bývá označován jako program řízený událostmi (event driven program) Na této koncepci jsou postavena veškerá GUI

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 44 z 78 3.2.2 Diagram tříd vzoru Pozorovatel Prostředník <<interface>> Komunikující T1 T2 T3 T4 T5

3.2.3 Aplikované principy a možné implementace Hollywoodský princip: Nevolejte nám, zavoláme vám Někdy se v této souvislosti hovoří o principu inverze závislostí (dependency inversion) Aby pozorovaný (vysílač, vydavatel) nezávisel na oslovovaných objektech, tak je donutí implementovat jím deklarovaný interfejs a baví se s nimi jako s instancemi tohoto interfejsu Při této koncepci se musejí oslovované objekty naopak přizpůsobit oslovujícímu Můžeme použít tažnou nebo tlačnou strategii: Při tažné strategii si pozorovatel říká pozorovanému objektu o potřebné parametry, Při tlačné strategii předá pozorovaný objekt pozorovateli všechny parametry při volání upozorňovací metody Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 45 z 78

3.3 Události a reakce na ně Společný rodič všech tříd událostí na platformě Java je třída java.util.eventobject public Object getsource() Metoda vrací zdroj nastalé události většinou pozorovaný objekt (vysílač / vydavatele) Na platformě JavaFX jsou události instancemi jeho potomka javafx.event.event EventTarget gettarget() Metoda vrací cíl události, který specifikuje, kudy bude událost po svém odeslání probíhat static void fireevent(eventtarget eventtarget, Event event) Vyvolá zadanou událost se zadaným cílem Cílem může být libovolný objekt, jenž na ni umí zareagovat EventType<? extends Event> geteventtype() Vrátí typ dané události; na platformě JavaFX tvoří typy událostí stromovou strukturu Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 46 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 47 z 78 3.3.1 Ovladače událostí EventHandler Na vznik události reagují ovladače událostí, které jsou instancemi interfejsu javafx.event.eventhandler<t extends Event> Typ ovladač události je prostřednictvím svého typového parametru přímo napojen na typ události void handle(t event) Metoda definující reakci na vzniklou událost Ovladače se velmi často zadávají prostřednictvím lambda-výrazů, které tuto metodu definují

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 48 z 78 3.3.2 Reakce tlačítka na stisk Jednou z možných událostí, na které může reagovat tlačítko, je stisk daného tlačítka Reakci tlačítka na stisk zadáme zavoláním metody void setonaction(eventhandler<actionevent> value) Doplníme do metody na stráně 39 nadepsané 2.6.2 Demonstrační aplikace s pasivním tlačítkem kód: final boolean[] even = { false }; //Je-li sudý button.setonaction(event -> { double xx = primarystage.getx(); xx += even[0]? +100 : -100; even[0] =! even[0]; primarystage.setx(xx); } );

4. Přidáváme formátování Obsah 4.1 Kontejnery 4.1.1 Hierarchie kontejnerů 4.2 Uspořádání zobrazovaných objektů 4.2.1 Základní uspořádání pro BorderPane 4.3 Jednoduché GUI naší adventury GameGUI_0 4.3.1 Metoda start(stage primarystage) 1/2 4.3.2 Metoda start(stage primarystage) 2/2 4.3.3 Metoda ontextfieldevent(actionevent event) 1/2 4.3.4 Metoda ontextfieldevent(actionevent event) 2/2 4.4 Ovládací prvky 4.5 Nabídka 4.5.1 Položka typu javafx.scene.control.checkmenuite m 4.5.2 Položka typu javafx.scene.control.radiomenuite m 4.5.3 Ukázka programu třída MenuPane 4.5.4 Ukázka programu metoda gamemenu() 4.5.5 Ukázka programu metoda changegamefor() 4.5.6 Ukázka programu metoda optionsmenu() 4.5.7 Ukázka programu metoda helpmenu() Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 49 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 50 z 78 4.1 Kontejnery Každý uzel kromě kořenového má svého rodiče, který musí být instancí typu javafx.scene.parent nebo jeho potomka Kontejner má své prvky uložené v seznamu typu javafx.collections.observablelist<javafx.scene.node> ObservableList<E> definuje pro přidání, resp. odebrání prvků metody boolean addall(e... elements) boolean removeall(e... elements) přičemž návratová hodnota odpovídá kontraktu interfejsu Collection Jak z názvu vyplývá, seznam je pozorovatelný, takže se u něj můžeme přihlásit jako jeho pozorovatelé kterým je nahlášena každá změna jeho obsahu To v požadovaném GUI nebudeme potřebovat

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 51 z 78 4.1.1 Hierarchie kontejnerů javafx.scene.node javafx.scene.parent //Abstraktní třída javafx.scene.group //Každý prvek si musí objednat pozici //Přizpůsobuje svoji velikost velikosti obsahu javafx.scene.web.webview //Obsahuje HTML objekt typu WebEngine javafx.scene.layout.region //Společný rodič panelů javafx.scene.chart.axis<t> //Panel pro osy grafů a jejich příslušenství javafx.scene.chart.chart //Panel pro obsah grafu javafx.scene.layout.pane //Společný rodič panelů s rozvržením javafx.scene.layout.anchorpane //Umožňuje děti ukotvit k okrajům javafx.scene.layout.borderpane //Pět fixních částí javafx.scene.layout.flowpane //Umísťuje děti jako když píše javafx.scene.layout.gridpane //Rozmisťuje děti do chytré tabulky javafx.scene.layout.hbox //Ukládá děti vodorovně vedle sebe javafx.scene.layout.stackpane //Zobrazuje děti na sobě javafx.scene.layout.tilepane //Rozmisťuje děti do jednoduché tabulky javafx.scene.layout.vbox //Ukládá děti svisle pod sebe javafx.scene.control.control //

4.2 Uspořádání zobrazovaných objektů Některé kontejnery řídí uspořádání svých prvků, v jiných si jednotlivé prvky musejí objednat své umístění Pro aplikační okno se většinou používá kontejner typu BorderPane, který Rozděluje svěřenou oblast do 5 částí: Top, Bottom, Left, Right, Center Do každé části je ochoten přijmout jeden prvek, ne víc Potřebujeme-li do některé části dát víc prvků, použijeme kontejner BorderPane přizpůsobí některé rozměry svých částí rozměrům jejich prvků Sekce Top a Bottom přizpůsobí svoji výšku výšce obsaženého prvku Sekce Left a Right přizpůsobí svoji šířku šířce obsaženého prvku Sekce Center roztáhne prvek přes zbylou oblast Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 52 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 53 z 78 4.2.1 Základní uspořádání pro BorderPane @Override public void start(stage primarystage) { primarystage.setx(x0); primarystage.settitle("aplikační okno typu BorderPane"); BorderPane rootpane = new BorderPane(new Button("Center"), new Button("Top"), new Button("Right"), new Button("Bottom"), new Button("Left")); Scene scene = new Scene(rootPane); } primarystage.setscene(scene); primarystage.show();

4.3 Ovládací prvky Standardní součástí GUI jsou nejrůznější ovládací prvky, prostřednictvím nichž ovládáme aplikaci Většina je v balíčku javafx.scene.control V GUI své adventury budete používat prvky Button Tlačítko (Prozatím na něm byl text, ale lze na něj umístit i ikonu) TextArea Výstupní textové oblast (může být i vstupní, ale to jsme pro naši hru zakázali) TextField Vstupní testové pole Label Reprezentuje text umisťovaný do kontejneru, většinou popisek ovládacího prvku Menu, MenuBar, MenuItem, CheckMenuItem, SeparatorMenuItem Typy prvků souvisejících s nabídkou bude jim věnována samostatná pasáž Ovládací prvek může mít přiřazenu vlastní nápovědu a místní nabídku Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 54 z 78

4.4 Jednoduché GUI naší adventury GameGUI_0 Pro začátek vyzkoušíme aplikační okno, jehož scénu bude tvořit kontejner typu BorderPane který bude obsahovat: V centrální zóně textové pole typu TextArea pro odpovědi hry Přesně: javafx.scene.control.textarea Ve spodní zóně vstupní pole typu TextField pro zadávání příkazů hráče Přesně: javafx.scene.control.textfield Vstupní pole vyvolá po stisku klávesy ENTER při zadávání textu událost javafx.event.actionevent => musíme u něj přihlásit posluchače typu javafx.event.eventhandler<actionevent> Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 55 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 56 z 78 4.4.1 Metoda start(stage primarystage) 1/2 @Override public void start(stage primarystage) { primarystage.settitle("superjednoduché GUI hry"); primarystage.setx(x0); primarystage.sety(y0); //Musíme pro ně vytvořit proměnné, protože je budeme oslovovat textarea = new TextArea(); textfield = new TextField(); //Definujeme uspořádání aplikačního okna BorderPane borderpane = new BorderPane(); borderpane.setcenter(textarea); borderpane.setbottom(textfield); //Vytvořím scénu a zobrazím jeviště aplikační okno hry Scene scene = new Scene(borderPane, 640, 480); primarystage.setscene(scene); primarystage.show();

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 57 z 78 4.4.2 Metoda start(stage primarystage) 2/2 //Je třeba zabezpečit, aby uživatel nemohl ani omylem //psát do výstupního pole textarea.seteditable(false); //U vstupního pole je třeba zaregistrovat ovladač, //který bude pověřen zpracováním příkazů textfield.setonaction(textfieldeventhandler); //Zadání startovacího příkazu textfield.settext(""); } //Vlastní spuštění hry zavolám metodu pro ošetření události //přičemž jako parametr vytvořím novou, prázdnou událost //(mohl bych zadast i prázdný odkaz, protože metoda parametr nepoužívá, //ale to už bych dělal kód závislý na konkrétní implementaci) textfieldeventhandler.handle(new ActionEvent());

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 58 z 78 4.4.3 Metoda ontextfieldevent(actionevent event)1/2 /*************************************************************************** * Definuje reakci na zadání hodnoty do vstupního textového pole. * * @param event Událost, na níž se má reagovat - nepoužívá se */ private void ontextfieldevent(actionevent event) { String command; //Zadávaný příkaz String answer; //Odpověď hry //Převezme se uživatelův příkaz command = textfield.gettext(); //Příkaz se zadá hře a od hry se převezme její odpověď answer = game.executecommand(command); answer = decorate(answer, game); //Doplnění informace o stavu hry

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 59 z 78 4.4.4 Metoda ontextfieldevent(actionevent event)2/2 //Vyčistíme vstupní pole pro zadání dalšího příkazu textfield.settext(""); //Vypíšeme do výstupního pole příkaz a za ním odpověď hry textarea.appendtext(command + "\n \n" + answer + "\n===========================\n\n"); } //Pokud hra skončila, zpasivníme vstupní pole if (! game.isalive()) { textfield.setonaction(null); }

4.5 Nabídka Základní nabídka je umisťována na nabídkovou lištu instanci třídy javafx.scene.control.menubar Většinou se umisťuje do horního pole panelu typu BorderPane V každém jevišti může být jedna nabídka nastavena jako systémová; pak se bude chovat podle pravidel aktuální platformy Nabídková lišta je kontejner, jehož dětmi jsou jednotlivé nabídky instance třídy javafx.scene.control.menu Nabídky jsou opět kontejnery, jejichž dětmi jsou instance typy javafx.scene.control.menuitem Nabídka je sama potomkem MenuItem, takže může být svoji vlastní položkou podnabídkou Základní funkcionalitou instancí třídy MenuItem je (stejně jako u tlačítek) vyvolání události ActionItem její ovladače se nastavují stejně Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 60 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 61 z 78 4.5.1 Položka typu javafx.scene.control.checkmenuitem Položka typu CheckMenuItem je schopen přepínat svůj stav a zobrazovat jej jako zaškrtnutí Ve hře se hodí pro zobrazení stavu zobrazování mapy nebo žurnálu boolean isselected() Vrátí informaci o tom, je-li položka nastavená (zaškrtnutá) void setselected(boolean value) Nastaví zaškrtnutost dané položky

4.5.2 Položka typu javafx.scene.control.radiomenuitem Položka typu RadioMenuItem představuje jeden stav vícestavového přepínače void settogglegroup(togglegroup value) Přiřadí položce skupinu položek tvořících dohromady přepínač Skupinu je ale nejprve třeba vytvořit voláním konstruktoru ToggleGroup() ToggleGroup gettogglegroup() Vrátí skupinu položek přepínače, do níž daná položka patří boolean isselected() Vrátí informaci, je-li položka nastavená (definuje stav přepínače) void setselected(boolean value) Nastaví přepínač na danou položku Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 62 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 63 z 78 4.5.3 Ukázka programu třída MenuPane public class MenuPane extends MenuBar { //== CONSTUCTORS AND FACTORY METHODS =========================================== /*************************************************************************** * Soukromý konstruktor zabezečuje vytvoření jediné instance. */ private MenuPane() { getmenus().add(gamemenu()); getmenus().add(optionsmenu()); getmenus().add(helpmenu()); }

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 64 z 78 4.5.4 Ukázka programu metoda gamemenu() private Menu gamemenu() { String menuname; MenuItem mygame = new MenuItem(menuName = "Moje hra"); mygame.setonaction(changegamefor(my_game, menuname)); MenuItem demogame = new MenuItem(menuName = "Demonstrační hra"); demogame.setonaction(changegamefor(demo_game, menuname)); MenuItem restartgame = new MenuItem(menuName = "Restart aktuální hry"); restartgame.setonaction(changegamefor(demofxgui.getinstance()::getgame, menuname)); MenuItem separator = new SeparatorMenuItem(); MenuItem exit = new MenuItem(menuName = "Ukončení aplikace"); exit.setonaction(p -> Platform.exit()); } Menu gamemenu = new Menu("Hra"); gamemenu.getitems().addall(mygame, demogame, restartgame, separator, exit); return gamemenu;

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 65 z 78 4.5.5 Ukázka programu metoda changegamefor() private EventHandler<ActionEvent> changegamefor( Supplier<IGameG> gamefactory, String menuname) { EventHandler<ActionEvent> handler = (e) -> { IGameG nextgame = gamefactory.get(); OutputPane.getInstance().appendText( "\n\n======================================" + "\nakce: " + menuname + "\npřepínám na: " + nextgame.getclass() + "\n======================================" + "\n\n"); nextgame.stop(); DemoFXGUI.getInstance().startGame(gameFactory.get()); }; return handler; }

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 66 z 78 4.5.6 Ukázka programu metoda optionsmenu() private Menu optionsmenu() { CheckMenuItem showmap = new CheckMenuItem("Zobrazovat plánek"); showmap.setonaction((actionevent ae) -> { boolean selected = showmap.selectedproperty().get(); mapwindow.show(selected); }); mapwindow.setonshown (e->showmap.setselected(true )); mapwindow.setoncloserequest(e->showmap.setselected(false)); Menu optionsmenu = new Menu("Nastavení"); optionsmenu.getitems().addall(showmap); } return optionsmenu;

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 67 z 78 4.5.7 Ukázka programu metoda helpmenu() private Menu helpmenu() { MenuItem aboutitem = new MenuItem("Informace o aplikaci"); aboutitem.setonaction(this::showaboutwindow); MenuItem helpitem = new MenuItem("Popis hry a instrukce"); helpitem.setonaction(this::showhelpwindow); Menu helpmenu = new Menu("Nápověda"); helpmenu.getitems().addall(aboutitem, helpitem); } return helpmenu;

5. Další potřebné prvky Obsah 5.1 Zobrazení HTML nápovědy 5.1.1 Ukázka kódu pro načtení nápovědy 5.2 Obrázky v programu 5.3 Získání obrázku 5.3.1 Ukázka kódu: konstruktor MapWindow 5.3.2 Ukázka kódu: konstruktor MapWindow 5.4 Provázání vlastností 5.4.1 Ukázka: propojení pozice okna 5.4.2 Ukázka: reakce na událost Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 68 z 78

5.1 Zobrazení HTML nápovědy Zobrazování HTML souborů zprostředkovává kontejner typu javafx.scene.web.webview Tento kontejner ovládá procesor (nebo chcete-li parser) typu javafx.scene.web.webengine, který je zodpovědný za zpracování HTML obsahu Načte HTML stránku zavoláním metody void load(string url) Vytvoří její dokumentový model V případě potřeby aplikuje styly Je schopen zpracovat skripty v jazyku JavaScript Procesor získáme od WebView zavoláním metody WebEngine getengine() Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 69 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 70 z 78 5.1.1 Ukázka kódu pro načtení nápovědy private void showhelpwindow(actionevent event) { System.out.println("Zkoušíme připravit okno nápovědy"); URL helpurl = GUI.getGame().getHelpURL(); WebView webview = new WebView(); WebEngine engine = webview.getengine(); engine.load(helpurl.tostring()); Scene scene = new Scene(webView); Stage stage = new Stage(); stage.setscene(scene); } Stage primarystage = GUI.getPrimaryStage(); stage.setwidth (480); stage.setheight(300); stage.setx(primarystage.getx() + primarystage.getwidth()); stage.sety(primarystage.gety()); stage.show();

5.2 Obrázky v programu Obrázky jsou instancemi třídy javafx.scene.image.image JavaFX umí pracovat s obrázky ve formátech BMP, GIF, JPEG, PNG Pro obrázky vzniklé sejmutím obrazovky bývá nejlepší formát PNG Pro obrázky vzniklé jako fotografie bývá výhodnější formát JPG, resp. JPEG Pro získání obrázku je v našem případě nejvýhodnější použít konstruktor javafx.scene.image.image(inputstream is) Prvky scény s obrázky jsou instancemi třídy javafx.scene.image.imageview Objekt typu ImageView je v našem případě nejvýhodnější vytvořit zavoláním konstruktoru ImageView(Image image) Chceme-li v jenom prvku typu ImageView vyměňovat obrázky, použijeme metodu void setimage(image value) Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 71 z 78

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 72 z 78 5.3 Získání obrázku Soubory s obrázky objektů je nejlépe nazvat stejně jako jimi reprezentované objekty pak se dá z názvu zobrazovaného objektu odvodit název souboru s jeho obrázkem Pro obrázky je nejlépe vyhradit samostatnou složku, do níž vedle obrázků zařadíme i třídu definovanou např. public class Data {} Obrázek objektu s názvem v proměnné name pak získáme zadáním příkazu Image image = new Image(Data.class.getResourceAsStream(name)); Tlačítko, na němž je zobrazen příslušný objekt, pak získáme zadáním příkazu Button button = new Button("", new ImageView(image));

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 73 z 78 5.3.1 Ukázka kódu: konstruktor MapWindow /*************************************************************************** * Vytvoří prázdné okno, v němž se bude po spuštění hry zobrazovat * plánek dané hry spolu s hráčem umístěným v aktuálním prostoru. */ private MapWindow() { super(); //Rodičem je jeváiště - StageStyle.UNDECORATED); pane = new Pane(); Scene scene = new Scene(pane); setscene(scene); }

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 74 z 78 5.3.2 Ukázka kódu: konstruktor MapWindow /*************************************************************************** * Inicializuje se pro zadanou (nově spuštěnou) hru * načte obrázky jejího plánku a hráce a vloží je do přeipraveného okna. * * @param game Nově spouštěná hra */ @Override public void initializeforgame(igameg game) { this.game = game; this.map = game.getmap(); this.player = game.getplayer(); moveplayer(); ObservableList<Node> children = pane.getchildren(); children.clear(); children.addall(map, player); } show();

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 75 z 78 5.4 Provázání vlastností Značná část objektů platformy JavaFX je vybavena řadou sledovatelných vlastností K vlastnosti se mohu přihlásit jako její pozorovatel a pak reagovat na všechny její změny

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 76 z 78 5.4.1 Ukázka: propojení pozice okna /*************************************************************************** * Přilepit okno s plánkem zprava k zadanému oknu. * * @param conectetstage Okno, k němuž se budeme lepit */ void stayon(stage conectetstage) { positionlistener(null, null, null); conectetstage. xproperty().addlistener(this::positionlistener); conectetstage. yproperty().addlistener(this::positionlistener); conectetstage. widthproperty().addlistener(this::positionlistener); // primarystage.heightproperty().addlistener(this::positionlistener); }

Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 77 z 78 5.4.2 Ukázka: reakce na událost /*************************************************************************** * Přizpůsobuje svoji pozici velikosti a pozici hlavního okna. * Parametry nejsou používané. * * @param observable Pozorovaná hodnota * @param oldvalue Stará hodnota * @param newvalue Nově nastavená hodnoty */ private void positionlistener(observablevalue<? extends Number> observable, Number oldvalue, Number newvalue) { //Jak lze vypozorovat, metoda své parametry nevyužívá Stage primarystage = GUI.getPrimaryStage(); setx(primarystage.getx() + primarystage.getwidth()); sety(primarystage.gety()); }

5.5 KONEC Copyright Rudolf Pecinovský, Soubor: PR_JavaFX_8.0_17.02.6665_2017-03-03 78 z 78