IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Java GUI

Dnes si upravíme našej primitívne kalkulačku. Naučíme sa hlavne nový Layout a obsluhovať viac tlačidiel. Výsledná kalkulačka by mala vyzerať takto:

vysledok - Java Swing bez grafického návrhára

Zhrnutie

Myslím, že by neuškodilo ľahké zhrnutie:

Aby sme vytvorili okno, vytvoríme si vlastnú triedu, ktorá dedí z triedy JFrame. Ďalej našej inštanciu nadefinujeme rôzne parametre (veľkosť okna, defaultná operáciu - zatvorenie, viditeľnosť). Do okna pridávame tzv. Komponenty (tlačidlá, labely, textové polia atď.). To sú inštancie tried (JLabel, JTextField ...). Pridávame ich do okna metódou add. Teraz pozor! Až doteraz sme ich pridávali priamo do okna. To môžeme samozrejme robiť aj naďalej. Problém však nastane, ak budeme chcieť zmeniť pozadie okna. Na to existuje metóda setBackground (parameter farba). Pokiaľ ju však pridáme priamo, nestane sa nič. Musíme použiť tzv. Kontajner. Kontajner si môžeme predstaviť ako papier, ktorý vyplní celé okno. Získame ho cez metódu getContentPane (). Pozadie potom nastavíme konejneru a budeme do neho aj naďalej pridávať všetky komponenty. Farbu už vytvoriť vieme, nadefinujeme ju teda na nejakú príjemnú farbičku pomocou číslic RGB. Pridáme komponenty rovnako ako v predchádzajúcich dieloch:

public class Gui extends JFrame{

    private JLabel labCislo1, labCislo2, labVysledek;
    private JButton butSecti, butOdecti, butVydel, butVynasob;
    private JTextField tfCislo1;
    private JTextField tfCislo2;

    public Gui()
    {
        super("Kalkulačka");

        Container con = getContentPane();
        con.setBackground(new Color(210, 244, 255));
}

GridBagLayout

FlowLayout, ktorý sme používali do teraz, je jednoduchý, ale nie je veľmi použiteľný. Oveľa mocnejším nástrojom je tzv. GridBagLayout. Okno nám rozdelí na tabuľku s bunkami. K bunkám pristupujeme podľa súradnicového systému X, Y. Vytvoríme inštanciu triedy GridBagLayout. Ďalšou nutnou vecou je instace triedy GridBagConstraints, ktorá slúži na určenie súradníc. Layout nastavíme rovnako. Pekné by bolo, keby bol medzi bunkami nejaký priestor. To docielime príkazom:

GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);

Znázornenie pre lepšie pochopenie:

gbLayout - Java Swing bez grafického návrhára

Pridáme na kontajner komponenty. U každej zložky musíme určiť polohu X a Y. Ďalšou zmenou je parameter metódy add (). Na druhé miesto pridáme objekt gbc. To nám zaručí správnosť rozmiestnenie.

labCislo1 = new JLabel("Zadejte první číslo:");
    gbc.gridx = 0;
    gbc.gridy = 0;

    con.add(labCislo1, gbc);

    tfCislo1 = new JTextField(4);
    gbc.gridx = 1;
    gbc.gridy = 0;
    con.add(tfCislo1, gbc);

    labCislo2 = new JLabel("Zadejte druhé číslo:");
    gbc.gridx = 0;
    gbc.gridy = 1;
    con.add(labCislo2, gbc);

    tfCislo2 = new JTextField(4);
    gbc.gridx = 1;
    gbc.gridy = 1;
    con.add(tfCislo2, gbc);

    butSecti = new JButton("+");
    gbc.gridx = 0;
    gbc.gridy = 2;
    con.add(butSecti, gbc);

    butOdecti = new JButton("-");
    gbc.gridx = 1;
    gbc.gridy = 2;
    con.add(butOdecti, gbc);

    butVynasob = new JButton("/");
    gbc.gridx = 0;
    gbc.gridy = 3;
    con.add(butVynasob, gbc);

    butVydel = new JButton("*");
    gbc.gridx = 1;
    gbc.gridy = 3;
    con.add(butVydel, gbc);

    labVysledek = new JLabel("Výsledek:");
    gbc.gridx = 1;
    gbc.gridy = 4;
    con.add(labVysledek, gbc);

Obsluha tlačidiel

Teraz sa dostávame k samotnej funkčnosti. Ku každému z tlačidiel musíme pridať poslucháč udalosti z nejakej triedy, do ktorej implementuje rozhranie ActionListeneru. Asi nás napadne, že by sme mohli vytvoriť štyri triedy. Jedna by sčítavali, druhá odčítala atď., Ale bol by v tom zbytočný zmätok a navyše by sme dospeli k duplicite kódu. Preto vytvoríme len jednu triedu - Event. Inštanciu event pridáme na všetky tlačidlá.

Event event = new Event();
    butOdecti.addActionListener(event);
    butSecti.addActionListener(event);
    butVydel.addActionListener(event);
    butVynasob.addActionListener(event);

Metóda actionPerformed má ako parameter inštanciu triedy ActionEvent. Vďaka nej môžeme zistiť podrobnosti o tlačidle, ktoré sme stlačili as niečím ich porovnať. K informácii sa dostaneme cez metódu getActionComand (), ktorú metódou equals () porovnáme s nápisom na tlačidle. Môžeme teda rozlíšiť, ktoré tlačidlo bolo stlačené.

public class Event implements ActionListener {

       public void actionPerformed(ActionEvent e)
       {
           if(e.getActionCommand().equals("+"))
           {

           }
           else if(e.getActionCommand().equals("-"))
           {

           }
           else if(e.getActionCommand().equals("/"))
           {

           }
           else if(e.getActionCommand().equals("*"))
           {

           }
       }

Teraz sa dostávame k logike programu. Samozrejme by sme mohli všetko nabouchat medzi "ify", ale keďže nie sme žiadni amatéri, urobíme to pekne OOP. Vytvoríme si teda novú triedu Vypocet. Bude vyzerať takto:

public class Vypocet {

    int cislo1;
    int cislo2;

    public Vypocet(int cislo1, int cislo2)
    {
        this.cislo1 = cislo1;
        this.cislo2 = cislo2;
    }

    public int secti()
    {
        return cislo1 + cislo2;
    }

    public int odecti()
    {
        return cislo1 - cislo2;
    }

    public int vydel()
    {
        return cislo1 / cislo2;
    }

    public int vynasob()
    {
        return cislo1 * cislo2;
    }
}

Všimnime si, že delenie nulou nie je ošetrené. K tomu sa však ešte dostaneme. Vrátime sa do metódy actionPerformed, ktorá bude vyzerať nasledovne:

public void actionPerformed(ActionEvent e)
    {
        int cislo1 = Integer.parseInt(tfCislo1.getText());
        int cislo2 = Integer.parseInt(tfCislo2.getText());
        String text = "";

        Vypocet v = new Vypocet(cislo1, cislo2);

        if(e.getActionCommand().equals("+"))
        {
            text = String.valueOf(v.secti());

        }
        else if(e.getActionCommand().equals("-"))
        {
            text = String.valueOf(v.odecti());
        }
        else if(e.getActionCommand().equals("/"))
        {
            text = String.valueOf(v.vydel());
        }
        else if(e.getActionCommand().equals("*"))
        {
            text = String.valueOf(v.vynasob());
        }

        labVysledek.setText(text);
    }

Výnimka

Teraz by mal program fungovať. Čo sa ale stane, ak budem deliť nulou alebo nezadáte celé čísla? GUI program síce nespadne, ale v termináli nám chyby samozrejme vyskočí. Keďže by sme museli ošetrovať všade vstupy ak tomu ešte delenie nulou, bolo by to pekných pár podmienok naviac. Oveľa lepším spôsobom sú tzv. Výnimky. Výnimka má dva bloky - try a catch.

try
{
// běh bez chyby
}
catch(Exception ex)
{
// běh s chybou
}

Jednoducho, ak nenastane chyba, vykoná sa blok try, pokiaľ nastane akákoľvek chyba, nastane blok catch - chyby môžeme ešte ďalej deliť, ale o tom snáď niekedy nabudúce. Za catch je parametrom objekt nejaké z výjimkových tried. My použijeme triedu Exception. Finálny kód bude teda vyzerať nasledovne:

public void actionPerformed(ActionEvent e)
{
    try
    {
        int cislo1 = Integer.parseInt(tfCislo1.getText());
        int cislo2 = Integer.parseInt(tfCislo2.getText());
        String text = "";

        Vypocet v = new Vypocet(cislo1, cislo2);

        if(e.getActionCommand().equals("+"))
        {
            text = String.valueOf(v.secti());

        }
        else if(e.getActionCommand().equals("-"))
        {
            text = String.valueOf(v.odecti());
        }
        else if(e.getActionCommand().equals("/"))
        {
            text = String.valueOf(v.vydel());
        }
        else if(e.getActionCommand().equals("*"))
        {
            text = String.valueOf(v.vynasob());
        }

        labVysledek.setText(text);
    }
    catch(Exception ex)
    {
        labVysledek.setText("Chyba");
    }

}

 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 919x (5.98 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Java GUI - udalosť
Všetky články v sekcii
Java Swing bez grafického návrhára
Preskočiť článok
(neodporúčame)
Layouty v Jave (druhýkrát)
Článok pre vás napísal Samik11
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje primárně programování v jazyce Java. Nestraní se ani C# nebo PHP.
Aktivity