Lekce 15 - Java chat - Klient - Seznámení se s kostrou aplikace
V minulých lekcích jsme vytvořili základní Java server, který jsme dokončili lekcí Java server - Vylepšení systému pluginů.
Počínaje dnešní lekcí začneme tvořit slibovaný chat jako ukázkovou aplikaci využívající tento univerzální Java server.
Architektura
Klienta budeme psát samozřejmě v Javě v JavaFX frameworku. Budeme se držet MVC architektury, abychom udrželi čitelný kód. Veškeré pohledy budeme psát do samostatných fxml souborů. Logika bude v modelu a vše se bude propojovat přes controller.
Funkce
Chat bude obsahovat ty nejzákladnější funkce pro komunikaci:
- odeslání zprávy
- notifikace, že uživatel začal psát zprávu
Nebudu zde implementovat žádné přidávání přátel k jednotlivým kontaktům. Každý uživatel si bude moct psát s každým. Nebude zde také žádný proces registrace/prihlášení. Při připojení na server pouze uživatel zadá své jméno/přezdívku, pod kterým bude na chatu vystupovat. Pokud bude zájem, implementujeme i end2end šifrované posílání zpráv.
Kostra klienta
Abychom se nezdržovali, vytvořil jsem základní kostru klienta, do které budeme postupem času doplňovat kód. Stáhněte si prosím archiv přiložený na konci lekce, který obsahuje kostru klienta (kromě již vyplněného kódu z dnešní lekce pro případ, že by vám něco nefungovalo).
Archiv obsahuje:
- kód z předchozích lekcí o tvorbě serveru
- kostru klienta v modulu
client
Modul client
obsahuje následující souborovou strukturu:

V balíčku controller
se nachází třídy, které
reprezentují kontroler pro jednotlivou funkcionalitu.
MainController
bude obsahovat logiku hlavního okna, které se
zobrazí po zapnutí aplikace. ConnectController
bude spravovat
okno, ve kterém se budeme připojovat k serveru. Balíček model
bude obsahovat veškeré modely, které během aplikace vytvoříme a budeme
používat. V balíčku service
se budou nacházet třídy
starající se o komplexnější funkčnost, jako například
ChatService
, která bude obsahovat metody pro odesílání
zpráv.
Třída ChatApp
inicializuje JavaFX aplikaci. Třídu
LanServerFinder
jsme vytvořili v minulé lekci a v budoucnu ji
použijeme k hledání serverů v lokální síti. Složka
resources/
obsahuje dodatečné soubory nezbytné pro běh
aplikace. Prozatím se zde nacházejí pouze fxml soubory,
které slouží jako view pro jednotlivé kontrolery.
Seznámení se s aplikací
Pokud aplikaci spustíme příkazem ./gradlew :client:jfxRun
,
zobrazí se nám základní okno aplikace.

Toto okno je definováno v souboru main.fxml
a jeho kontroler se
nachází ve třídě MainController
.
Okno se skládá ze tří částí:
- menu: obsahuje pouze tlačítka pro připojení k serveru a ukončení aplikace
- vlevo se nachází listView, ve kterém se budou zobrazovat připojení uživatelé
- vpravo je komunikační okno, ve kterém se pro každého uživatele vytvoří samostatná záložka pro komunikaci
Zobrazení lokálních serverů
Druhé samostatné okno, které v aplikaci existuje, se stará o
připojení/odpojení k/od serveru. Dále se v tomto okně budou zobrazovat
servery z lokální sítě. Okno, které se uživateli zobrazí, je definováno
v souboru connect.fxml
. Kontroler tohoto okna je ve třídě
ConnectController
. Obrázek výsledného okna je vidět na obrázku
níže.

Okno je rozděleno do tří části:
- v horní části se nachází informace a aktuálně připojeném serveru a tlačítko odpojit, které nás odpojí od serveru
- ve spodní části se nachází textová pole pro zadání adresy a portu serveru a přezdívky, pod kterou budeme v chatu vystupovat; vpravo dole je tlačítko pro připojení k zadanému serveru
- uprostřed se budou zobrazovat všechny nalezené servery v lokální síti
V balíčku controller
se nachází celkem tři kontrolery. Dva
z nich jsme si již odprezentovali a logicky by měl přijít na řadu poslední
ChatController
. Tento kontroler nebude mít vlastní okno, místo
toho se bude zobrazovat v hlavním okně a bude obsahovat konverzaci uživatelů
a textové pole pro vytvoření nové zprávy s tlačítkem pro odeslání
zprávy.
Threadpool
Než začneme s implementací konkrétní logiky pro chat klienta,
vytvoříme třídu ThreadPool
, pomocí které budeme snadno
spouštět úlohy na pozadí. Třídu umístíme do kořenového balíčku vedle
hlavní třídy klienta:
package cz.stechy.chat; public final class ThreadPool { public static final ExecutorService COMMON_EXECUTOR = ForkJoinPool.commonPool(); public static final Executor JAVAFX_EXECUTOR = Platform::runLater; public static final ScheduledExecutorService SCHEDULER = Executors.newSingleThreadScheduledExecutor(); static void shutDown() { COMMON_EXECUTOR.shutdown(); SCHEDULER.shutdown(); try { COMMON_EXECUTOR.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } try { SCHEDULER.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } } private ThreadPool() { throw new AssertionError(); } }
Ve třídě se nacházejí tři veřejné třídní konstanty:
COMMON_EXECUTOR
- Obecný threadpool na standardní úkonyJAVAFX_EXECUTOR
- Executor pro vykonání kódu v hlavním vlákněSCHEDULER
- Executor pro pozdější spuštění úlohy
Metodou shutdown()
bezpečně ukončíme činnost jednotlivých
exekutorů. Tuto metodu budeme volat při zavření hlavního okna aplikace.
Metodami shutdown()
nad jednotlivými exekutory zahájíme proces
ukončování exekutorů. Pokud se ukončení z nějakého důvodu nezdaří do
pěti vteřin, ukončíme je násilně metodou awaitTermination()
.
Ve třídě ChatApp
, kde se sestavuje hlavní okno, musíme přidat
listener na zavření okna:
stage.setOnCloseRequest(windowEvent -> ThreadPool.shutDown());
Tímto bychom měli hotové seznámení se s kostrou klientské aplikace.
Příště, v lekci Java chat - Klient - Zobrazení lokálních serverů, implementujeme zobrazení nalezených serverů v lokální síti a připojení k serveru.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 26x (225.32 kB)
Aplikace je včetně zdrojových kódů v jazyce Java