Image
27.6.2016 0 Comments

Programujeme v Jave /2.časť

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

V pokračovaní nášho seriálu sa budeme venovať naďalej appletom, konkrétne si povieme niečo o správcoch umiestnenia a o jednotlivých komponentoch, ktoré môžete v appletoch používať.

Základné pojmy o komponentoch

Aj keď sa komponentom budeme venovať trochu neskôr, hneď po tom, ako si vysvetlíme fungovanie správcov umiestnenia, musíme si objasniť nejaké základy už teraz, a to práve pre spomínaných správcov umiestnenia.

Pokiaľ už máte skúsenosti s programovaním vo vizuálnych programovacích prostrediach, ako je napr. Visual Studio alebo Delphi, tak vám pojem komponent určite nie je neznámy. Komponenty predstavujú súčasti, z ktorých zostavujete program. Delia sa na vizuálne a nevizuálne. Medzi tie vizuálne patria tie, ktoré má používateľ možnosť priamo vidieť, ako napríklad tlačidlo, nápis alebo tabuľka. K nevizuálnym komponentom môže patriť napríklad pripojenie k databáze. Použitie komponentov umožňuje veľmi jednoduché a efektívne znovupoužitie už vytvoreného kódu. Komponenty sa využívajú najmä v tzv. RAD (Rapid Application Development) vývojárskych prostrediach, pričom aj pre Javu ich existuje niekoľko. V Jave je každý komponent reprezentovaný príslušnou triedou, obyčajne odvodenou od triedy Component (AWT) alebo JComponent (Swing).

Špeciálnym prípadom komponentov sú kontajnery. Kontajner predstavuje komponent, ktorý je určený na to, aby sa doň pridávali ďalšie komponenty. Kontajner môže byť inštanciou triedy Container alebo nejakej triedy odvodenej od triedy Container. Keďže trieda JComponent je takisto potomkom triedy Container, každý komponent odvodený od JComponent predstavuje aj kontajner, a teda môžete doň teoreticky pridávať ďalšie komponenty, ale odporúčam na to používať iba tie triedy, ktoré sú na tento účel priamo určené. Trieda Container poskytuje okrem iného niekoľkokrát preťaženú metódu add(), ktorej úlohou je, ako ste už určite uhádli, pridať komponent do kontajnera. Na opačný účel slúžia metódy remove() a removeAll(). V AWT implementácii je samotná trieda Applet takisto kontajnerom, do ktorého môžete priamo pridávať komponenty a umiestňovať ich tak na applet. Toto je možné priamo volaním metódy add() inštancie triedy Applet. Aplikáciou tohto postupu pri používaní knižnice Swing však dosiahnete vyvolanie výnimky, pretože jej implementácia triedy JApplet je mierne odlišná. Kontajner, do ktorého môžete pridávať jednotlivé komponenty, musíte získať volaním metódy getContentPane() (vracia objekt typu Container) inštancie appletu a jeho metódou add() potom môžete pridávať komponenty.

Poďme sa pozrieť na jednoduchý príklad. V ňom vytvoríme jednoduchý komponent JLabel a pridáme ho na plochu appletu:

// <applet code=MojApplet width=150 height=30>
// </applet>
 
import javax.swing.*;
import java.awt.*;
 
public class MojApplet extends JApplet {
 
  public void init() {
    this.setSize(new Dimension(150, 30));
    JLabel napis = new JLabel("Prvy komponent");
    Container kontajner = getContentPane();
    kontajner.add(napis);
  }
 
}

Výsledok po spustení v appletvieweri vidíte na obrázku 1. Tento jednoduchý applet vo svojej metóde init() vytvoril inštanciu triedy JLabel, čo nie je nič iné než vizuálny komponent textový nápis. Má niekoľko konštruktorov, my sme použili ten, ktorý preberá ako parameter jednoduchý reťazec, ktorý je obsahom nápisu. Následne do premennej kontajner bol uložený kontajner appletu, do ktorého bol textový nápis pomocou metódy add() vložený. Celý tento zápis je možné skrátiť na jeden riadok takto:

    getContentPane().add(new JLabel("Prvy komponent"));

Vo väčších programoch sa tento zápis neodporúča, pretože za to často zaplatíte zníženou prehľadnosťou kódu.

Správcovia umiestnenia komponentov

Na to, aby bolo možné kontrolovať, kam budú jednotlivé komponenty umiestňované a koľko miesta budú zaberať, slúžia správcovia umiestnenia (angl. layout manager). Knižnice AWT a Swing poskytujú niekoľko správcov rozmiestnenia, takže pri návrhu svojej aplikácie by ste nemali mať žiadny problém vytvoriť akýkoľvek zložitý layout.

Najjednoduchší správca umiestnenia je poskytovaný triedou BorderLayout. Tento správca rozmiestnenia je nastavený implicitne, pokiaľ nenastavíte iného správcu metódou setLayout(), ktorú poskytuje objekt Container, ktorý môžeme získať volaním metódy getContentPane(). BorderLayout umožňuje umiestňovať komponenty na pevne určené pozície dané konštantami NORTH, SOUTH, EAST, WEST a CENTER, definovanými v tejto triede. Na každú pozíciu je možné umiestniť najviac jeden komponent, takže spolu môžete na plochu spravovanú správcom BorderLayout umiestniť maximálne päť komponentov. Pridávanie komponentov je takisto realizované metódou add(), ale s použitím aj druhého parametra, ktorým je jedna zo zmienených konštánt. Správca BorderLayout nám umožňuje definovať aj minimálnu veľkosť horizontálnej a vertikálnej medzery medzi jednotlivými komponentmi pomocou metód setHgap() a setVgap(). Najlepšie si všetky tieto veci ukážeme na nasledujúcom príklade, kde použijeme práve správcu umiestnenia BorderLayout, umiestnime na plochu appletu päť tlačidiel a nastavíme medzi nimi vertikálnu medzeru 5 a horizontálnu medzeru 15:

// <applet code=MojApplet width=300 height=200>
// </applet>
 
import javax.swing.*;
import java.awt.*;
 
public class MojApplet extends JApplet {
 
  public void init() {
    this.setSize(new Dimension(300, 200));
 
    BorderLayout spravca = new BorderLayout();
    spravca.setVgap(5);
    spravca.setHgap(15);
 
    Container kontajner = getContentPane();
    kontajner.setLayout(spravca);
    JButton tlacidlo = new JButton("Stred");
    kontajner.add(tlacidlo, BorderLayout.CENTER);
    tlacidlo = new JButton("Sever");
    kontajner.add(tlacidlo, BorderLayout.NORTH);
    tlacidlo = new JButton("Juh");
    kontajner.add(tlacidlo, BorderLayout.SOUTH);
    tlacidlo = new JButton("Vychod");
    kontajner.add(tlacidlo, BorderLayout.EAST);
    tlacidlo = new JButton("Zapad");
    kontajner.add(tlacidlo, BorderLayout.WEST);
  }
 
}
 
V tomto jednoduchom programe sme v metóde init() najprv nastavili veľkosť appletu, potom sme vytvorili nového správcu umiestnenia, nastavili požadované veľkosti medzier a tohto správcu sme priradili kontajneru appletu pomocou metódy setLayout(). Následne sme pridávali pomocou metódy add() do appletu tlačidlá, pričom sme umiestnenie komponentu špecifikovali druhým parametrom tejto metódy. V skratke sa ešte zmienim o komponente JButton, keďže sme ho v predchádzajúcej ukážke niekoľkokrát použili. Ako ste si určite všimli, JButton predstavuje komponent tlačidlo. Opäť má niekoľko konštruktorov, pričom my sme použili ten, ktorý vyžaduje ako parameter reťazec, ktorý bude zobrazený na tlačidle. Komponentom sa budeme venovať až po tom, čo skončíme výklad správcov umiestnenia, a preto sa tu teraz o tomto komponente nebudem rozpisovať. 
Ďalším správcom umiestnenia, ktorému sa budeme venovať, je FlowLayout. Ide opäť o veľmi jednoduchého správcu, o nič zložitejšieho, než je BorderLayout, ale už sa ho netýkajú obmedzenia, ako je maximálny počet komponentov. Možno ste už podľa názvu odhadli, že ide o správcu, do ktorého môžete voľne pridávať komponenty. Tie sú zobrazované postupne, ako ich pridávate, vedľa seba zľava doprava, až kým je zaplnený celý riadok. Vtedy správca FlowLayout prejde na ďalší riadok a opäť pokračuje v pridávaní komponentov vedľa seba zľava doprava. Každý riadok s komponentmi je zarovnaný na stred. Takisto stojí za povšimnutie fakt, že komponenty sú zmenšené na najmenšiu možnú veľkosť, čo v prípade textových nápisov a tlačidiel znamená takú najmenšiu veľkosť, aby sa na ne zmestil žiadaný text. Správca FlowLayout rovnako ako BorderLayout poskytuje metódy setVgap() a setHgap() na nastavenie minimálnej vertikálnej a horizontálnej medzery. Nasledujúci príklad pridá do appletu 5 tlačidiel pri použití správcu FlowLayout. Pre úspornosť uvádzam iba metódu init(), zvyšok kódu je zhodný s predchádzajúcim:
  public void init() {
    this.setSize(new Dimension(200, 100));
    Container kontajner = getContentPane();
    kontajner.setLayout(new FlowLayout());
 
    for (int i = 1; i <= 5; i++) {
      kontajner.add(new JButton("Tlacidlo " + i));
    }
  }

Posledným správcom umiestnenia z tých jednoduchších, ktorým sa budeme venovať, je GridLayout. Tento správca vám jednoducho umožní vytvoriť tabuľku alebo – ak chcete – mriežku vopred daných rozmerov (počtu riadkov a stĺpcov), do ktorej budú pridávané komponenty. Do jednej bunky tabuľky sa vojde práve jeden komponent. Takisto poskytuje metódy setVgap() a setHgap() na nastavenie minimálnej veľkosti vertikálnej a horizontálnej medzery medzi jednotlivými komponentmi. Konštruktor triedy GridLayout preberá dva parametre – počet riadkov  mriežky a počet stĺpcov mriežky. Takisto môžete použiť aj preťažený konštruktor na nastavenie veľkosti minimálnej horizontálnej a vertikálnej medzery pomocou zadania ďalších dvoch parametrov (ukážka v nasledujúcom príklade). V príklade na správcu GridLayout si ukážeme, ako zmeniť implicitný smer umiestňovania komponentov na plochu kontajnera tak, aby komponenty neboli pridávané zľava doprava, ale naopak:

  public void init() {
    this.setSize(new Dimension(200, 100));
    Container kontajner = getContentPane();
    kontajner.setLayout(new GridLayout(3, 2, 10, 5));
    kontajner.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
 
    for (int i = 1; i <= 5; i++) {
      kontajner.add(new JButton("Tlacidlo " + i));
    }
  }

Po nastavení veľkosti plochy appletu sme nastavili správcu umiestnenia na GridLayout. Pomocou konštruktora sme nastavili počet riadkov na 3, počet stĺpcov na 2, veľkosť horizontálnej medzery na 10 a vertikálnej na 5. Následne sme metódou applyComponentOrientation(), poskytovanej triedou Container, nastavili orientáciu pridávaných komponentov. Preddefinovaný statický objekt RIGHT_TO_LEFT, poskytovaný triedou ComponentOrientation, oznamuje kontajneru, že komponenty majú byť zobrazované sprava doľava. Táto trieda ešte poskytuje objekt LEFT_TO_RIGHT, ktorý pre kontajner predstavuje orientáciu zľava doprava – oba tieto objekty sú inštanciami triedy ComponentOrientation, čo je vyžadovaný parameter metódy applyComponentOrientation(). Za zmienku ešte stojí fakt, že pokiaľ sa na niektorú bunku mriežky neujde nejaký komponent, zostane prázdna a správca umiestnenia nezabezpečí nijaké dodatočné zarovnanie neúplných riadkov alebo stĺpcov, čo máte možnosť vidieť aj na našom príklade (máme šesť buniek, ale pridávame iba 5 tlačidiel). 

Správca CardLayout

Správca umiestnenia CardLayout je trošku zložitejší než tie predchádzajúce, a preto mu venujem osobitnú kapitolu. Tento správca vám umožní pridať ľubovoľné množstvo komponentov, pričom v jednom momente je zobrazený vždy iba jeden z nich. Každý z komponentov pri zobrazení zaberie celú plochu kontajnera. Aby sme si tohto správcu mohli ukázať na príklade, povieme si v skratke niečo o komponente JPanel. Tento komponent slúži ako kontajner a často sa používa pri zložitejších návrhoch. Komponenty, ktoré logicky patria k sebe, sa umiestňujú na jeden panel a panely sa potom umiestňujú na väčší panel alebo na plochu appletu či aplikácie. Takto sa dá dosiahnuť veľmi kvalitný návrh grafického rozhrania. Používanie triedy JPanel je veľmi jednoduché – stačí vytvoriť pomocou bezparametrického konštruktora jej inštanciu (táto trieda má viac konštruktorov, ale nám stačí iba ten bezparametrický, pokiaľ vás zaujímajú aj ostatné, nahliadnite do dokumentácie) a následne nastaviť jeho správcu umiestnenia zdedenou metódou setLayout(), preberajúcou inštanciu triedy správcu umiestnenia. My v našom príklade vytvoríme inštanciu triedy JPanel a nastavíme jej správcu umiestnenia CardLayout. Následne do tohto kontajnera pridáme tri komponenty – dva textové nápisy JLabel a jedno tlačidlo JButton. Celý tento kontajner umiestnime do appletu, ktorého správcom umiestnenia je implicitný správca BorderLayout. V prvom riadku (s umiestnením BorderLayout.NORTH) bude náš kontajner JPanel, v druhom (umiestnenie BorderLayout.SOUTH) tlačidlo na zobrazenie nasledujúceho komponentu v paneli, pričom na začiatku bude zobrazený prvý pridaný komponent. Zobrazenie prvého komponentu vyvoláte volaním metódy first(), zobrazenie nasledujúceho komponentu zasa metódou next(). Ďalšími metódami, ktoré ešte môžete prípadne použiť, sú previous() (zobrazí predchádzajúci komponent) a last() (zobrazí posledný komponent). Týmto metódam musíte odovzdať ako parameter inštanciu kontajnera, s ktorého správcom umiestnenia pracujete. Pri pridávaní komponentov na panel budeme používať ešte druhý parameter metódy add(), ktorým každému pridanému komponentu pridelíme unikátny textový reťazec. Vďaka tomu môžete vyvolať zobrazenie konkrétneho komponentu priamo metódou show() – ako prvý parameter jej musíte odovzdať inštanciu daného kontajnera a druhý parameter je spomínaný unikátny textový reťazec.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
 
public class MojApplet extends JApplet {
 
  public void init() {
    this.setSize(new Dimension(150, 70));
    final CardLayout layout = new CardLayout();
    final JPanel panel = new JPanel();
    panel.setLayout(layout);
    panel.add(new JLabel("Prvy napis"), "prvy");
    panel.add(new JLabel("Druhy napis"), "druhy");
    panel.add(new JButton("Tlacidlo"), "tlacidlo");
 
    Container kontajner = getContentPane();
    kontajner.add(panel, BorderLayout.NORTH);
    JButton dalsi = new JButton("Dalsi komponent");
    dalsi.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        layout.next(panel);
      }
    });
    kontajner.add(dalsi, BorderLayout.SOUTH);
  }
 
}

Pokiaľ nerozumiete časti, kde je volaná metóda addActionListener(), nič si z toho nerobte, všetko sa dozviete v časti venovanej udalostiam a udalostnému modelu. Tento kód slúži na to, aby pri stlačení tlačidla bola volaná metóda next() správcu umiestnenia CardLayout. Skúste si tento príklad skompilovať a spustiť. Pri klikaní na tlačidlo „Dalsi komponent“ by sa vám mali cyklicky striedavo zobrazovať pridané komponenty. 

Záver

V tejto časti ste sa dozvedeli čo-to o komponentoch a viete už používať správcov umiestnenia BorderLayout, FlowLayout, GridLayout a CardLayout. V budúcej časti seriálu sa budeme venovať správcovi GridBagLayout, ktorý sa dá považovať asi za toho najzložitejšieho, takže si ho podrobne rozoberieme.

 

Autor: Andrej Chu

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

Mohlo by Vás zaujímať

ITPro

Linux súkromne i pracovne v2.0 (14. časť): Small Business Server

09.11.2016 14:57

Pojem Small Business Server (malý firemný server) začala používať spoločnosť Microsoft ešte v roku 2000 na označenie servera, ktorý ­dokázal plniť úlohy niekoľkých samostatných serverov. Aplikačná vrs ...

ITPro

Industry 4.0: Fikcia alebo už realita?

09.11.2016 14:52

Štvrtá priemyselná revolúcia je pomenovanie rozsiahlych zmien prudko vstupujúcich do súčasného priemyslu. Nositeľom týchto zmien je digitalizácia výroby a optimalizácia všetkých podnikových procesov v ...

ITPro

Vývoj aplikácií UWP pre Xbox One II.

09.11.2016 14:47

V predošlej časti sme ukázali postup, ako si ­vytvoriť vývojársky účet a aktivovať vývojársky režim na hernej konzole Xbox One, aby ste mohli testovať svoje aplikácie. Výhodou hernej konzoly Xbox je v ...

Žiadne komentáre

Vyhľadávanie

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

Najnovšie videá