Image
22.6.2016 0 Comments

Java pod lupou I. /18.časť

Späť na úvod >> Späť na programovanie >> Späť na seriál

Dodatky

Posledná časť seriálu patrí niekoľkým témam, ktoré nie sú natoľko bežné (vnorené a anonymné triedy) alebo už nie sú také populárne (applety), bolo by však škoda nevenovať im aspoň niekoľko riadkov.

Applety

Applet je zdrobneninou slova application (teda nijaké „jabĺčko“, ako sa možno niekde dočítať). V súčasnosti applety ustupujú do pozadia, ale ešte nedávno boli nadmieru populárne ako súčasť webových stránok. Až natoľko, že to zaváňalo gýčom a zlým vkusom.

Applet je javovská aplikácia, ktorá nie je určená na samostatné fungovanie – na svoj beh potrebuje hosťovské prostredie, ktorým je typicky, ale nie výhradne internetový prehliadač. Na rozdiel od klasických aplikácií applet nemusí obsahovať metódu main(). Jadrom appletu je trieda odvodená od štandardnej systémovej triedy java.applet.Applet. Trieda Applet je potomkom grafického komponentu java.awt.Panel, z čoho môžeme dedukovať, že applety disponujú grafickým rozhraním. S grafikou sa v rámci appletu pracuje rovnako ako pri iných komponentoch AWT: applet má definovaný manažér layoutu, možno doň pridávať iné komponenty (java.awt.Panel je kontajnerom), definovať obsluhu udalostí a pod. Na pamäti treba mať iba skutočnosť, že hlavné okno appletu, ako súčasť hosťovského prostredia, obyčajne nemôže meniť svoju polohu. Na zmenu veľkosti nájdeme v triede Applet metódu resize(), ktorá však nezaručuje, že túto zmenu hosťovské prostredie povolí.

Životný cyklus appletu možno rozdeliť do štyroch metód: init(), start(), stop() a destroy(). Prvú metódu, init(), volá prostredie po natiahnutí appletu do pamäte. Metóda je volaná práve raz a je vhodné do nej vložiť kód na inicializáciu appletu – alokáciu prostriedkov, vytvorenie pomocných objektov, threadov a pod. „Spustenie“ appletu má na starosti metóda start(), ktorú prostredie volá, keď je applet zobrazený a prístupný používateľovi. Ak sa applet dostane mimo zobrazenej plochy (napríklad odrolujeme webovú stránku) alebo je neprístupný iným spôsobom, prostredie zavolá metódu stop(). Logicky si domyslíme, že metódy start() a stop() sa najlepšie hodia na rozbehnutie a pozastavenie prípadných bežiacich threadov. Poslednú metódu destroy() volá prostredie pred odstránením appletu z pamäte (opäť práve raz). Treba však vziať do úvahy, že spôsob, ako a kedy hosťovské prostredie volá spomenuté metódy, je úplne otázkou jeho implementácie.

Applet disponuje metódami na zisťovanie informácií o prostredí, v ktorom beží. Metóda getDocumentBase() vracia URL adresu dokumentu, v ktorom je applet vložený. Iná metóda, getCodeBase(), vracia URL adresu samotného appletu (môže byť odlišná od dokumentu URL). Pomocou metódy getParameter() môže applet zisťovať svoje parametre, zadané ako súčasť dokumentu, v ktorom je applet vložený. Metódu showStatus() applet využije na zmenu textu v stavovom riadku hosťovského prostredia. Ďalšie dve metódy, getImage() a getAudioClip(), slúžia na natiahnutie obrázka alebo zvukového súboru zo zadanej adresy URL. Zvukový súbor možno prehrať pomocou metódy play(). Posledná metóda getAppletContext() vracia objekt implementujúci rozhranie java.applet.AppletContext, ktorého metódy slúžia na interakciu s hosťovským prostredím.

Ukážkový applet

Ukážme si príklad jednoduchého appletu, ktorý vo svojom okne zobrazí text zadaný pomocou parametra:

public class Display extends java.applet.Applet
{
  private final String defaultText = "Hello, world!";
  private String text;
 
  public void init()
  {
    text = getParameter("DisplayText");
    if (text == null)
      text = defaultText;
  }
 
  public void paint(java.awt.Graphics g)
  {
    setBackground(new java.awt.Color(0xFFECC0));
    g.drawString(text, 20, 30);
  }
}

Text, ktorý sa má zobraziť v okne appletu, zistíme pomocou metódy getParameter(). Vhodným miestom na jej použitie je metóda init(). Ak náhodou parameter nie je zadaný, metóda getParameter() vráti null a applet zobrazí preddefinovaný text „Hello, world!“.

Stránka s appletom môže vyzerať napríklad takto:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Display Applet</title>
</head>
<body>
 
<p>Here comes the Display applet:</p>
 
<object classid="java:Display.class" width="140px" height="60px">
<param name="DisplayText" value="Any other text">
</object>
 
</body>
</html>

V starších materiáloch sa možno stretnúť s vkladaním appletov do stránky pomocou elementu APPLET. Ten je už pekných pár rôčkov považovaný za zastaraný (deprecated) a podľa špecifikácie HTML 4.01 je na vkladanie objektov určený element OBJECT. Syntax tohto elementu nebudeme opisovať, informácie možno nájsť na adrese http://www.w3.org/TR/html401. Parameter appletu zadáme pomocou elementu PARAM.

Čitateľ sa môže pokúsiť prerobiť applet tak, aby aj farbu jeho pozadia bolo možné zadať pomocou parametra. Metóda getParameter() však vracia reťazec, ktorý je potrebné vhodne konvertovať, podľa použitého konštruktora triedy Color.

Obmedzenia appletov

Na applety sa vzťahujú určité obmedzenia. Applet napríklad nemôže vytvoriť sieťové spojenie s iným počítačom, než z ktorého bol natiahnutý jeho kód. V prípade, že applet používa ďalšie triedy, musia byť tieto triedy umiestnené na rovnakom serveri. Je, samozrejme, možné mať stránku a applet na rôznych serveroch – umiestnenie appletu potom treba spresniť pomocou atribútu codebase elementu OBJECT. Ak sa počas behu appletu používa viac ako jedna trieda, je vhodné celý balík transformovať do archívu JAR a v stránke sa odvolávať na tento archív (ušetríme dačo z prenosovej kapacity, pretože sa bude sťahovať menší objem dát).

Pri ladení appletov je dobré mať na pamäti, že prehliadače si natiahnutý kód ukladajú do pamäte cache a po opätovnom preklade zdrojového textu triedy obyčajne nestačí znovu natiahnuť stránku s appletom; treba prehliadač ukončiť a znovu spustiť.

Statické inicializátory

Za skonštruovanie inštancie triedy je zodpovedná špeciálna metóda, konštruktor. Kto sa však postará o inicializáciu statických zložiek triedy? Dosiaľ sme mlčky predpokladali, že tieto zložky inicializujeme triviálnym spôsobom ako súčasť deklarácie:

static int x = 1;

Niekedy však jeden riadok kódu nestačí: potrebovali by sme nejakú analógiu konštruktora, ale pre statické členy. Takýto „statický konštruktor“ nazývame statickým inicializátorom. V deklarácii triedy sa môže statický inicializátor nachádzať aj viackrát a poznáme ho podľa kľúčového slova static nasledovaného zloženým príkazom:

static
{
  // inicializácia...
}

Kód statických inicializátorov sa nachádza na rovnakej deklaračnej úrovni ako kód ostatných metód. Aktivuje sa po natiahnutí triedy do pamäte pri prvom pokuse o vytvorenie inštancie triedy. Ak trieda obsahuje viac statických inicializátorov, ich kódy sa vykonajú sekvenčne, v takom poradí, v akom sa inicializátory nachádzajú v zdrojovom texte.

Statické vnorené triedy

Až do tejto chvíle sme v príkladoch pracovali s triedami, ktoré boli deklarované na súborovej (najvyššej) úrovni. V ďalšom texte ich budeme označovať ako top-level triedy. Java však dovoľuje používať aj vnorené triedy (nested), deklarované v rámci inej triedy alebo dokonca v rámci metódy.

Pri triedach deklarovaných v rámci inej triedy hrá rolu prítomnosť či neprítomnosť modifikátora static. Vnorené triedy, deklarované ako statické, sa v zásade nelíšia od top-level tried. Používame ich rovnakým spôsobom a na ich obsah sa nevzťahujú nijaké obmedzenia. Jediným rozdielom je ich plne kvalifikovaný názov: medzi „balíkovú“ identifikáciu a názov vnorenej triedy musíme doplniť ešte názov tzv. obklopujúcej (enclosing) triedy, t. j. triedy, v ktorej je vnorená trieda deklarovaná. Príklad:

package my.pkg;
class TopLevel
{
  // ...
  public static class Nested
  { ... }
}

Vnorená trieda Nested je súčasťou obklopujúcej triedy TopLevel. Plne kvalifikovaný názov vnorenej triedy je my.pkg.TopLevel.Nested. Ak vhodne použijeme príkaz import alebo sa pohybujeme v rámci implicitného balíka, úplný názov triedy je TopLevel.Nested.

Statická vnorená trieda nesmie byť deklarovaná inde ako v top-level triede. Iné triedy môžu k vnorenej triede pristupovať podľa toho, ktorý modifikátor prístupu (public, protected, private) pri deklarácii tejto triedy použijeme. Obklopujúca trieda má k vnorenej triede vždy plný prístup. Statická vnorená trieda môže pristupovať len k statickým premenným a metódam obklopujúcej triedy.

Členské triedy

Vnorené triedy, deklarované bez kľúčového slova static, sa nazývajú členskými triedami. Členské triedy majú na rozdiel od statických vnorených tried prístup ku všetkým členom a metódam obklopujúcej triedy. To je možné vďaka obmedzeniu, podľa ktorého každá inštancia členskej triedy je zviazaná práve s jednou inštanciou obklopujúcej triedy (tzv. obklopujúcou inštanciou). Pri vytváraní inštancie členskej triedy dostane jej konštruktor referenciu na obklopujúcu inštanciu prostredníctvom skrytého parametra. Logicky môžeme usúdiť, že vytvorenie inštancie členskej triedy je možné len v niektorej z metód obklopujúcej triedy.

Prístup k členským triedam „zvonka“ je riadený podobne ako v predchádzajúcom prípade modifikátormi prístupu. V rámci členských tried nemožno deklarovať statické premenné, metódy ani inicializátory, s výnimkou statických konštánt (deklarovaných s modifikátorom final).

Lokálne triedy

Deklarácia vnorenej triedy môže byť takisto súčasťou tela metódy (nazvime ju obklopujúcou metódou). Takejto triede hovoríme lokálna. Inštancia lokálnej triedy je viditeľná len v rámci tela obklopujúcej metódy. Lokálna trieda má prístup ku všetkým premenným a metódam obklopujúcej triedy (rovnaký princíp ako pri členských metódach). Okrem toho môže lokálna trieda pristupovať k lokálnym premenným a parametrom obklopujúcej metódy za podmienky, že sú tieto premenné či parametre deklarované s modifikátorom final. Doba platnosti lokálnych premenných sa predlžuje na neurčito, pokiaľ existuje inštancia lokálnej triedy, ktorá sa na ne odvoláva.

Lokálne triedy možno vhodne použiť pri obsluhe udalostí ako tzv. adaptérové triedy. Vráťme sa o jedno či dve čísla časopisu naspäť a spomeňme si, že komponenty GUI umožňujú iným objektom „prihlásiť sa“ na odber oznámení o výskyte udalostí. Interakcia je zabezpečená pomocou listenerov, čo sú špeciálne objekty implementujúce vybrané rozhranie. Komponent GUI pri výskyte „svojej“ udalosti postupne zavolá príslušné metódy všetkých prihlásených listenerov. Objekty pracujúce v úlohe listenerov sú obyčajne inštanciami vnorených tried: členských, lokálnych či anonymných (pozri ďalej).

Príklad použitia lokálnej triedy pri reakcii na stlačenie tlačidla:

public void setUpButton()
{
  final Button b;
  b = new Button("Any text");
  b.addActionListener(new ButtonListener());
  add(b);
 
  class ButtonListener implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    { b.setLabel("Clicked!"); }
  }
}

Metóda setUpButton() slúži na vytvorenie tlačidla (trieda Button) a jeho pridanie do kontajnera (metóda add(); treba si predstaviť, že metóda setUpButton() je súčasťou objektu kontajnera). Pomocou metódy addActionListener() pridáme k tlačidlu listener – inštanciu lokálnej triedy ButtonListener. V rámci obsluhy udalosti sa vyvolá metóda actionPerformed() tejto triedy. Metóda má prístup k objektu tlačidla pomocou finálnej premennej b, čo demonštrujeme zmenou textu tlačidla.

Anonymné triedy

Variáciou na lokálne triedy sú anonymné triedy. Nemajú vlastný názov, nesmú obsahovať konštruktor a sú určené na ad hoc použitie spájajúce deklaráciu s vytvorením inštancie. Deklarácia anonymnej triedy nahradzuje názov typu vo výraze pre alokáciu nového objektu. Predchádzajúci príklad s využitím anonymnej triedy bude vyzerať takto:

public void setUpButton()
{
  final Button b;
  b = new Button("Any text");
  b.addActionListener(new ActionListener()
  {
    public void actionPerformed(ActionEvent e)
    { b.setLabel("Clicked!"); }
  });
  add(b);
}

Všimnime si, že za kľúčovým slovom new sa nachádza názov rozhrania ActionListener. Anonymná trieda bude potomkom triedy Object implementujúcim toto rozhranie. Ak namiesto rozhrania uvedieme triedu, anonymná trieda bude potomkom tejto triedy.

Implementácia vnorených tried

Binárny kód javovských tried je uložený v súboroch s príponou .class. Názov každého súboru je (bez prípony) totožný s názvom príslušnej triedy. Pre vnorené triedy však tento mechanizmus treba upraviť, pretože dve vnorené triedy v rámci jedného balíka sa môžu volať rovnako, ak sú deklarované v rôznych triedach.

Riešenie je jednoduché: názov súboru vznikne spojením mena obklopujúcej triedy a vnorenej triedy. Obe mená sú oddelené znakom $. Trieda TopLevel.Nested z vyššie uvedeného odseku bude napríklad uložená v súbore s názvom TopLevel$Nested.class. Rovnaké pravidlo platí pre triedy členské i lokálne.

Malý háčik predstavujú anonymné triedy: tie nemajú meno, preto ich prekladač pri preklade očísluje vo vzostupnom poradí od jednotky a tieto čísla použije ako „názvy“ tried na účely vytvorenia mena binárneho súboru. Ak teda budeme mať napríklad triedu MyClass a v nej dve anonymné triedy, prekladač vygeneruje tri binárne súbory:

MyClass.class
MyClass$1.class
MyClass$2.class

Ak je vnorená trieda súčasťou inej vnorenej triedy, uvedené pravidlo sa uplatní rekurzívne. Môžeme sa potom stretnúť hoci so súborom Outer$FirstLevel$SecondLevel$Inner.class.

Koniec

Seriál je na konci. V Jave ako jazyku toho veľa nezostáva, a ak, tak len najpokročilejšie témy, v praxi málokedy používané. Väčší priestor ponúka Java ako platforma – to sme si však vysvetlili na úvod predošlej časti: opis ďalších balíkov by zabral priveľa miesta a sotva by bol dostatočne užitočný, azda len ako slovenský preklad originálnej dokumentácie. Zostáva teda veriť, že čitateľ za svoje peniaze dostal adekvátnu protihodnotu a že programátorov, ktorí sa vedia orientovať v Jave, je vďaka seriálu o niečo viac.

 

 


Nechajte si posielať prehľad najdôležitejších správ emailom

Mohlo by Vás zaujímať

Ako na to

Tipy a triky: Ako na snímku obrazovky na akomkoľvek počítači s Windows?

02.12.2016 00:13

Ak snímky obrazovky robíte často apotrebujete napríklad funkcie na posun stránok alebo snímanie zobrazenia pri vyššom rozlíšení displeja, zrejme používate nejakú špecializovanú aplikáciu. Väčšina použ ...

Ako na to 1

Tipy a triky: Ako aplikácii prednastaviť spúšťanie s administrátorskými právami?

30.11.2016 00:10

Väčšina aspoň trochu skúsenejších používateľov vie, že aj keď máte na operačnom systéme Windows vytvorený administrátorský účet, aplikácie pre bezpečnosť nefungujú vždy splnými administrátorskými práv ...

Ako na to 2

Tipy a triky: Ako vypnúť uzamykaciu obrazovku vo Windows 10?

29.11.2016 00:10

Rozčuľuje vás, že pred každým prihlásením doúčtu vášho počítača musíte prejsť uzamykacou obrazovkou? Windows 10 na tejto obrazovke ukazuje čas,dátum anejakú zaujímavú fotografiu zrôznych kútov sveta. ...

Žiadne komentáre

Vyhľadávanie

Kyocera - prve-zariadenia-formatu-a4-s-vykonom-a3

Najnovšie videá