Image
27.6.2016 0 Comments

Programujeme v Jave /11.časť

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

Použitie pop-up menu a udalostí vstupu, desktopové aplikácie

V tejto časti seriálu o programovaní v Jave sa najprv vrátime k predchádzajúcemu pokračovaniu, kde som sľúbil príklad na použitie udalostí pop-up menu a používateľského vstupu.

Príklad

Náš jednoduchý príklad bude spočívať v naprogramovaní základnej funkčnosti pop-up menu umožňujúceho základné editovacie operácie v komponente JTextArea, ako sú Copy, Paste a Cut. Sprístupnenie týchto operácií bude závisieť od toho, či bude v textovom komponente označený nejaký text. Operácia Paste bude k dispozícii vždy, zatiaľ čo operácie Copy a Cut budú k dispozícii len v prípade, že v komponente JTextArea je označený nejaký text. Tieto akcie bude možné vyvolať aj prostredníctvom klávesových skratiek – ich funkčnosť je v tomto komponente už síce implementovaná, ale pre názornosť si ich implementáciu vyskúšame sami.

Začneme deklaráciou našej triedy (nazvanej EventsTest):

// <applet code=EventsTest width=250 height=190>
// </applet>
 
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.*;
 
public class EventsTest extends JApplet {
  private JTextArea jta;               // hlavny komponent JTextArea (editor)
  private JPopupMenu jpm;              // pop-up menu hlavneho komponentu
  private JMenuItem cut, copy, paste;  // jednotlive akcie pop-up menu
}

Ako vidíte, nastavili sme potrebné parametre pre appletviewer, potom sme deklarovali triedu EventsTest a deklarovali jej tri atribúty – jta obsahuje referenciu na komponent JTextArea, ktorý bude hlavným komponentom nášho programu, bude obsahovať editovaný text. Atribút jpm bude obsahovať referenciu na pop-up menu, ktoré sa bude zobrazovať po kliknutí na hlavný komponent pravým tlačidlom a bude obsahovať tri položky umožňujúce základné operácie s editorom. Odkazy na tieto položky budú uložené v troch atribútoch typu JMenuItem našej triedy EventsTest.

Teraz však potrebujeme triedu, resp. poslucháča udalosti myši, ktorý zachytí udalosť kliknutia pravým tlačidlom myši na komponent editora JTextArea. Práve na to slúži metóda mouseClicked() rozhrania poslucháča MouseListener. Keďže nám však stačí len obsluha tejto jedinej udalosti, resp. implementácia tejto jedinej metódy, ide o klasický príklad na vhodné nasadenie triedy MouseAdapter:

 
  class JTAListener extends MouseAdapter {
 
    public void mouseClicked(MouseEvent me) {
      if (me.getButton() == MouseEvent.BUTTON3) {
        EventsTest.this.cut.setEnabled(true);
        EventsTest.this.copy.setEnabled(true);
        EventsTest.this.paste.setEnabled(true);
        if (EventsTest.this.jta.getSelectedText() == null) {
          EventsTest.this.cut.setEnabled(false);
          EventsTest.this.copy.setEnabled(false);
        }
        EventsTest.this.jpm.show((Component) me.getSource(), me.getX(), me.getY());
      }
      else {
        EventsTest.this.jpm.setVisible(false);
      }
    }
 
  }

Túto triedu je potrebné umiestniť priamo do tela našej hlavnej triedy EventsTest.

Trieda JTAListener je odvodená od triedy MouseAdapter a bude teda slúžiť ako poslucháč udalosti myši pre náš komponent editora JTextArea jta. Metóda mouseClicked() je volaná pri kliknutí myšou na komponent, pri ktorom je poslucháč zaregistrovaný, akýmkoľvek tlačidlom. Keďže nás zaujíma len udalosť kliknutia pravým tlačidlom, musíme ju od tých ostatných odfiltrovať – pomocou metódy getButton() získaného objektu udalosti MouseEvent získame informáciu o tom, ktoré tlačidlo bolo stlačené. V prípade, že ide o pravé tlačidlo (identifikované konštantou BUTTON3 v triede MouseEvent), vykonáme potrebné úpravy pred zobrazením položiek menu – najprv zaktívnime všetky položky a následne, pokiaľ nie je vybraný žiadny text v hlavnom komponente (túto informáciu získame metódou getSelectedText()), zneaktívnime položky Cut a Copy. Posledným krokom je zobrazenie pop-up menu na mieste, kde používateľ klikol myšou. Vo vetve else nášho filtra ošetrujeme ostatné prípady kliknutia, teda kliknutia iným než pravým tlačidlom myši – v takom prípade naše pop-up menu jednoducho skryjeme.

Teraz je načase pripraviť naše pop-up menu – implementujeme chránenú metódu preparePopupMenu(), ktorej úlohou bude inicializovať atribúty s referenciami na pop-up menu a jeho jednotlivé položky a vykonať všetky ďalšie potrebné kroky na zabezpečenie ich budúcej správnej funkčnosti:

 
  protected void preparePopupMenu() {
    this.jpm = new JPopupMenu();
    this.cut = new JMenuItem("Cut");
    this.copy = new JMenuItem("Copy");
    this.paste = new JMenuItem("Paste");
 
    this.cut.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        EventsTest.this.jta.cut();
      }
    });
    this.cut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_DOWN_MASK));
 
    this.copy.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        EventsTest.this.jta.copy();
      }
    });
    this.copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK));
 
    this.paste.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        EventsTest.this.jta.paste();
      }
    });
    this.paste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK));
 
    this.jpm.add(this.cut);
    this.jpm.add(this.copy);
    this.jpm.add(this.paste);
  }

Táto metóda v prvom rade vytvorí inštanciu pop-up menu a takisto inštancie jeho položiek, ktoré inicializuje ich textovými opismi. Následne s každou položkou pop-up menu vykoná dva kroky – priradí jej poslucháča typu ActionListener a potom jej priradí akcelerátor. Priradenie poslucháča ActionListener je potrebné na základné fungovanie položiek menu, pretože jeho jediná metóda actionPerformed() má za úlohu vykonať akciu spojenú s danou položkou menu. V našom prípade sú to veľmi jednoduché akcie, ide len o volanie príslušných metód hlavného komponentu editora [cut(), copy() a paste()], takže ich telá sa skladajú iba z jediného riadka (jediného volania metódy). Z toho dôvodu môže byť táto jednoduchá implementácia vložená priamo do tela metódy actionPerformed() a nie je potrebné ju delegovať na iné metódy triedy. Druhý krok (nastavenie akceleračného klávesu) by teoreticky nebol nevyhnutný, pretože, ako som už spomenul v niektorej z predošlých častí tohto seriálu, komponent JTextArea už má potrebnú funkčnosť podpory horúcich klávesov Ctrl + X, Ctrl + C a Ctrl + V implementovanú. My však dotiahneme tento príklad do konca a nastavíme si akcelerátory sami, čo má ešte jeden vedľajší efekt – zobrazenie textového opisu príslušných klávesových skratiek pri jednotlivých položkách menu.

Inicializácia pop-up menu ďalej pokračuje a zároveň sa končí pridaním týchto troch položiek do nášho pop-up menu kontajnera.

Posledným krokom, ktorý nám ešte zostáva, je inicializácia hlavného komponentu editora a aj celého appletu. Na to nám poslúži stará známa metóda init():

 
  public void init() {
    this.preparePopupMenu();
    this.jta = new JTextArea("Sem vpisujte svoj text...", 9, 20);
    this.jta.addMouseListener(new JTAListener());
 
    Container cp = getContentPane();
    cp.setLayout(new FlowLayout());
    cp.add(new JScrollPane(this.jta));
  }

Metóda init() najprv požiada o inicializáciu pop-up menu volaním metódy preparePopupMenu(). Následne inicializuje hlavný komponent editora vytvorením novej inštancie JTextArea. Premenná jta teraz bude obsahovať referenciu na inštanciu nášho hlavného komponentu, a preto je následne využitá na zaregistrovanie poslucháča typu JTAListener, ktorého implementáciu sme už rozoberali. Posledným krokom je inicializácia layoutu kontajnera appletu a následné vloženie hlavného komponentu editora do inštancie JScrollPane a pridanie tejto inštancie do kontajnera appletu.

Obe uvedené metódy [init() a preparePopupMenu()], ako aj trieda JTAListener patria do tela hlavnej triedy EventsTest. Uvedený zdrojový kód si môžete takisto stiahnuť z domovskej stránky PC REVUE (www.pcrevue.sk).

Teraz vás už čaká len kompilácia a spustenie v appletvieweri. Ako vyzerá náš applet pri kliknutí pravým tlačidlom na hlavný komponent bez toho, aby v ňom bol vybraný nejaký text, máte možnosť vidieť na obrázku číslo 1. Obrázok číslo 2 zasa zobrazuje podobnú situáciu, ale už s vybraným textom v hlavnom komponente editora.

Desktopové aplikácie

Odteraz sa začneme venovať klasickým desktopovým aplikáciám v Jave. V praxi to znamená, že sa zbavíme nášho starého známeho appletviewera a skončíme s rozprávaním o appletoch.

Applety boli charakteristické tým, že sme potrebovali na ich spustenie nejaký špeciálny tool (buď práve spomínaný appletviewer, alebo browser). Takisto vďaka tomu je možné šíriť applety v prostredí webu, a preto sa tu kladie dôraz na bezpečnosť – applety majú rôzne obmedzenia, ako napríklad nemožnosť pristupovať k súborom na disku používateľa alebo možnosť otvárať sieťové spojenia jedine k serveru, z ktorého bol applet stiahnutý (aj keď k akémukoľvek portu). Tieto obmedzenia sa dajú obísť digitálnym podpísaním appletu a následným povolením citlivých operácií (ako prístup na disk) používateľom. Touto témou sme sa v našom seriáli síce nezaoberali, ale pokiaľ bude záujem, môžeme sa jej venovať v niektorej z nasledujúcich častí.

Inou možnosťou (než je digitálna signatúra), ako sa vyhnúť obmedzeniu appletov, je na ne úplne zabudnúť a ísť cestou desktopových aplikácií. Tieto aplikácie sú plnohodnotnými desktopovými aplikáciami, rovnocennými s ostatnými aplikáciami vo vašom OS. Jediný rozdiel spočíva v tom, že každý počítač, na ktorom budete chcieť svoju aplikáciu spustiť, musí mať nainštalovaný Java Runtime Environment (JRE), ktorý jej spustenie umožní. JRE je takisto súčasťou každého JDK. Javovské desktopové aplikácie už netrpia neduhmi, resp. obmedzeniami, ktoré mali applety, na druhej strane je ich tvorba rovnako jednoduchá a spôsob programovania rovnaký ako v prípade appletov. Spôsobom programovania mám na mysli použité triedy, kontajnery a ostatné komponenty.

Podobným základom, akým bola pri tvorbe appletov trieda JApplet, bude pre nás pri tvorbe desktopových aplikácií trieda JFrame. Táto trieda je k dispozícii ako súčasť knižnice Swing na podporu jej architektúry. V knižnici AWT bola na tvorbu desktopových aplikácií určená trieda Frame, ktorá je už vzhľadom na existenciu JFrame zastaraná a jej používanie sa neodporúča. Aj keď JFrame je potomkom triedy Frame, a teda by malo byť možné ju kedykoľvek použiť ako zástupcu triedy Frame, neplatí to tak úplne. Nekompatibilita spočíva v spôsobe prístupu k hlavnému kontajneru (grafického) obsahu aplikácie. V prípade triedy JFrame získavame odkaz na tento kontajner pomocou metódy getContentPane(), teda obdobným spôsobom ako v prípade triedy appletov JApplet. Naopak, pri používaní triedy Frame predstavovala táto trieda priamo samotný kontajner, teda premenná s referenciou na inštanciu triedy Frame bola zároveň referenciou na hlavný kontajner obsahu aplikácie. Teda pri každej operácii s kontajnerom [napr. pridávanie komponentov do tohto kontajnera – metóda add()] musíte v prípade triedy JFrame získať referenciu naň volaním spomínanej metódy getContentPane(), zatiaľ čo pri použití triedy Frame bola príslušná metóda [add()] volaná priamo na inštancii tejto triedy.

Ak sa pozrieme v triednej hierarchii ešte vyššie, zistíme, že trieda Frame je priamym potomkom triedy Window. Táto trieda predstavuje okno na najvyššom stupienku v hierarchii. Toto okno je úplne bez akýchkoľvek základných súčastí, ktoré má väčšina okien, ktoré z bežných aplikácií poznáte. Nemá titulkový pruh a ani menu. Existuje aj trieda JWindow, ktorá je od triedy Window priamo odvodená. Táto trieda tiež predstavuje okno bez základných prvkov, ako sú titulkový pruh alebo menu, a základný kontajner, ktorý je možné zobraziť kdekoľvek na obrazovke. Nie je tu však priama dedičná spojitosť medzi triedami JWindow a JFrame (tak ako je to v prípade Window a Frame), pretože JFrame je priamym potomkom triedy Frame (a teda nepriamym potomkom triedy Window). Ako som však už spomenul, pre nás v tomto seriáli bude základom trieda JFrame, ktorá poskytuje základné nástroje na vzhľad okna, a preto sa budeme venovať hlavne jej. Informácie o existencii tried Window a JWindow však môžu byť dôležité, a preto som ich sem umiestnil.

Štruktúra desktopovej aplikácie

Vnútorná programová štruktúra klasickej aplikácie sa líši od appletu hlavne v tom, že bežná javovská (aj negrafická) aplikácia obsahuje metódu main(). Pri tvorbe aplikácií GUI a implementácii metódy main() sa uplatňujú dva postupy. Prvým je vytvorenie samostatnej triedy s metódou main(), ktorá počas behu vytvorí inštanciu triedy JFrame (alebo triedy od nej odvodenej), vykoná jej potrebnú inicializáciu a nakoniec ňou reprezentované okno zobrazí. Druhou možnosťou je vytvorenie vlastnej triedy, odvodenej od triedy JFrame, do ktorej vložíme metódu main() a ktorá vykoná rovnaké kroky ako v prvom prípade. Oba postupy si demonštrujeme na jednoduchom príklade typu Hello World:

 
import javax.swing.*;
 
public class HelloWorld1 {
 
  public static void main(String[] args) {
    JFrame frame = new JFrame("Hello World");
    frame.getContentPane().add(new JLabel("Hello World example"));
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }
 
}

Trieda HelloWorld1 demonštruje prvý spomínaný postup – obsahuje len metódu main() a vytvorí inštanciu triedy JFrame počas jej behu. Následne vykoná všetky potrebné inicializačné operácie a zobrazí okno. Pokiaľ vám niektoré veci nie sú jasné, nemusíte zúfať, podrobne sa im budeme venovať v budúcom pokračovaní tohto seriálu.

Druhý príklad demonštruje druhý postup, teda prípad, keď trieda obsahujúca metódu main() je zároveň samotnou triedou okna, odvodenou od JFrame:

 
import javax.swing.*;
 
public class HelloWorld2 extends JFrame {
 
  public HelloWorld2() {
    super("Hello World Example");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.getContentPane().add(new JLabel("Hello World example"));
  }
 
  public static void main(String[] args) {
    JFrame frame = new HelloWorld2();
    frame.pack();
    frame.setVisible(true);
  }
 
}

 

Ako vidíte, väčšina inicializačného kódu je umiestnená v konštruktore, pričom metóda main() zabezpečí len to najnevyhnutnejšie – vytvorenie inštancie svojej triedy a správne zobrazenie okna.

Kompilácia týchto dvoch príkladov je jednoduchá a prebehne rovnako ako v prípade appletov:

javac HelloWorld1.java

javac HelloWorld2.java

Spustenie programov však už nie je zabezpečované appletviewerom, ale priamo binárkou java.exe (ak používate OS Windows):

java –classpath . HelloWorld1
java –classpath . HelloWorld2

Parameter –classpath sme definovali preto, aby virtuálny stroj jazyka Java vedel, kde má vaše skompilované triedy hľadať, v uvedenom príklade predpokladáme, že tieto súbory .class sa nachádzajú v aktuálnom adresári, z ktorého príkaz zadávate. Výsledok po spustení niektorého z príkladov by mal byť podobný ako na obrázku 3.

Záver

Prekročili sme pomyselnú hranicu a zakončili sme ucelenú tému o appletoch. Trochu sme sa začali venovať desktopovým aplikáciám, ale šlo len o úvod do problematiky. V nasledujúcej časti sa do nej trošku zahĺbime a budeme sa im venovať podrobnejšie. Dovtedy dovidenia.

 

 

Autor: Andrej Chu

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á