autor: Ivan Kupka

Verzia 1

home uvod K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 K13 K14

 

Java 13

 

2. GUI . Správcovia rozmiestnenia. Ďalšie komponenty

 

Cieľom kapitoly je predovšetkým ukázať, ako pracujú správcovia rozmiestnenia pri rozmiestňovaní prvkov na komponentu. Zoznámime sa aj s niektorými novými komponentami.

 

Obsah celej tejto kapitoly sa bude tak trochu podobať na katalóg. Najprv si predstavíme niektoré grafické prvky v práci. Medzi nimi aj pár nových.

Hlavnou náplňou kapitoly je ukázať, akým spôsobom sa pracuje s jednotlivými správcami rozmiestnenia.

 

Textové pole s posuvnou lištou.  Použitie HTML

V nasledujúcom kóde uvidíme, ako jednoducho sa definuje textové pole s posuvnou lištou.  Takisto si ukážeme, ako možno formátovať text pomocou HTML. Ukážeme si to na príklade tlačítka. Ľubovoľný ovládací prvok, ktorý dokáže prevziať text, dokáže takisto prevziať text, formátovaný v jazyku HTML. Takýto text musí začínať značkou <HTML> . Môžu sa v ňom používať všetky bežné značky tohto jazyka. Všimnite si, že nie je vždy nutné uvádzať aj zakončovacie značky. 

 

  Kód GR2.1

         

          //program vypíše zadaný počet riadkov textu

          // prvky:

          // popiska, textové políčko, tlačítko s HTML textom

          // Textové pole s  posuvnou lištou

         

          // pouzitie HTML

                    import javax.swing.*;

          import java.awt.*;

           import java.awt.event.*;

           

           class Daj{

           

            public  String vyznanie(String pocetRiadkov){

                    int riadky = 0;

                    String zaklad = " milujem ta viac a viac";

                    String riadok = zaklad;

                    String vystup = "Chyba v texte. \n Zadajte cislo prosim. ";

                    try{

                             

             riadky = Integer.parseInt(pocetRiadkov); 

              vystup = zaklad;

             for(int i = 1; i < riadky; i++) {

                                          riadok+= " a viac";

                                          zaklad = vystup;

                              vystup+= "\n " +riadok;

                        }//EOFor

                              }

                   

                    catch(NumberFormatException e){

                  vystup+= " \n \" " + pocetRiadkov + "\"  nie je cislo." ;     

                             

                    }

                    finally{

                    return vystup;

                    }

            }//EOMethod

           

           

           

          }//EOClass

          public class Prvky  {

             

            private JFrame ram = new JFrame("Invertovanie");

            private JLabel pocRiad = new JLabel("Udaj pocet riadkov:");

            private JTextField policko  = new JTextField(4);

            private JButton gombik = new JButton("<HTML> <BODY BGCOLOR =yellow>   SPUSTI ");

            private JTextArea pole = new JTextArea(8,20);

              private Daj daj = new Daj();

             

          class PosluchacG implements ActionListener {

    public void actionPerformed(ActionEvent e) {

      String text = policko.getText();

     

      text = daj.vyznanie(text);

      pole.setText(text);

    }

  }

      PosluchacG   ucho = new PosluchacG();

 

 

                    public void init(){

           

                    Container cp = ram.getContentPane();

           cp.setLayout(new FlowLayout());

           cp.add(pocRiad);

           cp.add(policko);

                    cp.add(gombik);

                    // prida JTextArea "pole" uz zabalene tak,

                    // ze ma pridane posuvne listy

                    cp.add(new JScrollPane(pole));

                    //mohli by sme pridat posluchaca az tu

                    gombik.addActionListener(ucho);

                    ram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                    ram.setSize(300,250);

                                        ram.setVisible(true);

                    }

                    public static void main(String[] args){

                              Prvky prvy = new Prvky();

                              prvy.init();

                   

            }//EOMain

          }//EOClass

 

 

 

 

Správcovia rozmiestnenia

Triedy JApplet, JFrame JWindow, a JDialog vedia vytvoriť objekt typu  Container pomocou metódy  getContentPane( ).  Tento objekt môže obsahovať a zobrazovať jednotlivé komponenty. (Najprv ich však naň musíme uložiť). Trieda Container má tiež k dispozícii metódu setLayout( ). Tá slúži na to, aby sme si mohli zvoliť vhodného správcu rozmiestnenia.

Niektoré triedy, ako napríklad JPanel, dedič triedy Container, umožňujú ukladať komponenty priamo. Ak chceme pri ukladaní na ne použiť správcu rozmiestnenia, zavoláme metódu setLayout() priamo z nich. Napríklad takto:

 JPanel jp = new JPanel();

 jp.setLayout(new BorderLayout());

 

 

 

V nasledujúcich kódoch si predvedieme ukladanie jednoduchých komponent. V každom príklade použijeme iného správcu rozmiestnenia. Zostaneme pri tejto „grafickej“ časti kódovania. Nebudeme definovať žiadnych poslucháčov a teda ani zachytávať žiadne udalosti.

 

Správca rozmiestnenia FlowLayout

Použitie správcu typu FlowLayout  sme už videli v kóde Gr1.2.  FlowLayout jednoducho ukladá prvky zľava doprava až kým sa horná časť formulára nezaplní. Potom začne ukladať prvky tým istým spôsobom na nasledujúci riadok. Pozrime sa príklad ukladania tlačítok pomocou tohto správcu. Základný kontajner s 25 tlačítkami sa zobrazí vo väčšom rozmere, po piatich sekundách sa zmení na menší. Tým sa zmení aj rozmiestnenie tlačítok.

Kód Gr2.2

 

import javax.swing.*;

 import java.awt.*;

// import javax.swing.*;

 

public class SkusFlowLayout  extends JFrame{

         

 public void spusti(int sirka, int vyska){

          Container cp = getContentPane();

          cp.setLayout(new FlowLayout());

     // umiestnime na kontajner 25 tlacitiek

       for(int i = 1; i < 26; i++){

       cp.add((new JButton("   " + String.valueOf(i) + "  ")));

       }

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      

        this.setSize(sirka, vyska);

        this.setVisible(true);

        }

         

     public static void main(String[] args){

       SkusFlowLayout prvy = new SkusFlowLayout();

       prvy.spusti(600,600);

       // cakaj 5 sekund

         long time = System.currentTimeMillis() + 5000;

         while(System.currentTimeMillis() < time) ;

         prvy.spusti(100,300);

    }//EOMain        

 }//EOClass

 

Správca rozmiestnenia GridLayout

  Tento správca umožňuje vytvoriť tabuľku komponent. Jeden z jeho konštruktorov umožňuje určiť počet riadkov a stĺpcov.  Pozmeňme kód z predchádzajúceho príkladu na tento:

Kód Gr2.3

import javax.swing.*;

import java.awt.*;

public class SkusGridLayout  extends JFrame {

           public void spusti(int sirka, int vyska){

          Container cp = getContentPane();      

          cp.setLayout(new GridLayout(9,3));

              // umiestnime na kontajner 25 tlacitiek

       for(int i = 1; i < 26; i++){

       cp.add((new JButton("   " + String.valueOf(i) + "  ")));

       }

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setSize(sirka, vyska);

        this.setVisible(true);

        }

 

     public static void main(String[] args){

       SkusGridLayout prvy = new SkusGridLayout();

       prvy.spusti(600,600);

       // cakaj 5 sekund

         long time = System.currentTimeMillis() + 5000;

         while(System.currentTimeMillis() < time) ;

         prvy.spusti(100,300);

    }//EOMain        

 }//EOClass

 

      

 

Poznámky: Aby sme pochopili prácu tohto správcu lepšie, treba si prezrieť aj výsledok programu keď príkaz „new GridLayout(9,3)“ nahradíme napríklad príkazom „new GridLayout(4,4)“ , „ new GridLayout(4,9)“ a podobne. Všimnime si tiež, že keď sa okno zjaví druhý raz, je na ňom už päťdesiat tlačítok. (Môžeme si okno  zväčšiť aby sme tlačítka videli.)  Po preskúmaní metódy „spusti(...)“ je jasné prečo.

 

 

Existuje správca s podobným názvom ako GridLayout, je to GridBagLayout. Umožňuje veľmi precízne určiť, ako presne budú príslušné oblasti na ploche rozmiestnené a ako sa bude meniť ich formát, keď sa bude meniť veľkosť okna.  Tento správca sa väčšinou využíva aplikáciami, určenými  pre tvorbu GUI. Na „ručnú“ obsluhu je prizložitý.

V Jave je možné definovať aj absolútne rozmiestnenie grafických komponent. Prvým krokom je nastavenie správcu na hodnotu „null“ pomocou príkazu „ setLayout(null)“. Znovu, ako pri GridBagLayoute, toto rozmiestnenie sa používa väčšinou pri automatizovanom generovaní kódu. 

 

Správca rozmiestnenia BorderLayout

V kóde „Gr2.4 “ bude našou základnou triedou  JApplet. Zvolili sme ho z toho dôvodu, že má ako layout manažéra defaultne nastavený  práve BorderLayout. Na JApplet budeme ukladať komponenty – inštancie triedy JPanel.

Kód Gr2.4

 

 

import javax.swing.*;

import java.awt.*;

// applet nechceme spustat na sieti

// metodu init() mozeme vynechat

 

public class  SkusBorderLayout  extends JApplet{

         

          public void spusti(int sirka, int vyska){

                    Container cp = getContentPane();

      // JApplet ma defaultne nastaveny BorderLyout

      //  cp.setLayout(new BorderLayout()); // netreba

       cp.add(BorderLayout.NORTH,(new JPanel()).add(new JLabel("Sever")));

       cp.add(BorderLayout.SOUTH,(new JPanel()).add(new JLabel("Juh")));

      

       JPanel jp = new JPanel();

       jp.add(new JLabel("Vychodny "));

       jp.add(new JLabel("blok "));

        cp.add(BorderLayout.EAST,jp);

       

       cp.add(BorderLayout.WEST,(new JPanel()).add(new JLabel("Zapad")));

       cp.add(BorderLayout.CENTER,(new JPanel()).add(new JLabel("                                         STRED")));

       // cp.add((new JPanel()).add(new JLabel("                                  TIEZ STRED"))); //umiestni tiez do stredu

 

        JFrame frame = new JFrame("Skusam BorderLayout");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(this);

        frame.setSize(sirka, vyska);

        frame.setVisible(true);

        }

         

     public static void main(String[] args){

       SkusBorderLayout sbl = new SkusBorderLayout();

       sbl.spusti(400,100);

    }//EOMAin

  }//EOClass

 

 

Správca rozmiestnenia BoxLayout

 

  Táto trieda umožňuje riadiť rozmiestňovanie komponent jednak vo zvislom, jednak vo vodorovnom smere. Umožňuje tiež určiť medzery medzi jednotlivými prvkami. Ukážme si  použitie tohto správcu na dvoch jednoduchých príkladoch:

Kód Gr2.5

import javax.swing.*;

import java.awt.*;

 

public class SkusBoxLayout {

          JPanel vodorovny = new JPanel();

          JPanel zvisly         = new JPanel();

          JFrame ram  = new JFrame("Testing BoxLayout");

         

          public SkusBoxLayout(){

                    //

                    vodorovny.setLayout(new BoxLayout(vodorovny, BoxLayout.X_AXIS) );

                    for(int i = 1; i < 7; i++){

                      vodorovny.add(new Button(" " + i + " ")); 

                    }

     

       zvisly.setLayout(new BoxLayout(zvisly, BoxLayout.Y_AXIS) );

       for(int i = 1; i < 7; i++){

       zvisly.add(new Button(" " + i + " "));    

                    }

 

            Container cp = ram.getContentPane();

            cp.setLayout(new GridLayout(2,1));

            cp.add(vodorovny);

            cp.add(zvisly);

      ram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 

          }

         

          public void zobraz(int sirka, int vyska){

            ram.setSize(sirka,vyska);

            ram.setVisible(true);     

          }

          public static void main(String[] args){

                    SkusBoxLayout skus = new SkusBoxLayout();

                    skus.zobraz(400,400);

          }//EOMain

}//EOClass

 

Všimnime si riadok:

vodorovny.setLayout(new BoxLayout(vodorovny, BoxLayout.X_AXIS) );

Vidíme, že BoxLayout, na rozdiel od iných správcov, potrebuje mať v konštruktore ako prvý argument kontajner, ktorý bude spravovať.

V kóde zároveň vidíme možnosť kombinovania viacerých správcov rozmiestnenia.

V predošlom kóde pôsobí trochu kostrbato vytvorenie panelu príkazom

JPanel vodorovny = new JPanel();

a pridanie správcu príkazom

vodorovny.setLayout(new BoxLayout(vodorovny, BoxLayout.X_AXIS) );

Rovnaký efekt sa dá dosiahnuť jedným príkazom vďaka triede Box. Tá má statickú metódu, ktorá umožní vytvoriť kontajner typu Box, ktorý má už priamo, defaultne  nastavený vertikálny alebo horizontálny spôsob ukladania pomocou správcu typu BoxLayout. Princíp ľahko pochopíme po miernom prepísaní predchádzajúceho kódu:

Kód Gr2.6

 

import javax.swing.*;

import java.awt.*;

 

public class LepsiBoxLayout {

          Box vodorovny = Box.createHorizontalBox();

          Box zvisly         = Box.createVerticalBox();

          JFrame ram  = new JFrame("Testing BoxLayout");

         

          public LepsiBoxLayout(){

                    //

                    //vodorovny.setLayout(new BoxLayout(vodorovny, BoxLayout.X_AXIS) );

                    for(int i = 1; i < 7; i++){

                      vodorovny.add(new Button(" " + i + " ")); 

                    }

     

       for(int i = 1; i < 7; i++){

       zvisly.add(new Button(" " + i + " "));    

                    }

 

            Container cp = ram.getContentPane();

            cp.setLayout(new GridLayout(2,1));

            cp.add(vodorovny);

            cp.add(zvisly);

      ram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 

          }

         

          public void zobraz(int sirka, int vyska){

            ram.setSize(sirka,vyska);

            ram.setVisible(true);     

          }

          public static void main(String[] args){

                    LepsiBoxLayout skus = new LepsiBoxLayout();

                    skus.zobraz(400,400);

          }//EOMain

}//EOClass

 

Nasledujúci príklad ukazuje použitie „rozpier“ a „tmelu“. Rozpery (Struts) sú medzery-oddeľovače medzi komponentami, ktorých veľkosť je presne určená. Konkrétne je určená v pixeloch. Oddeľovače typu Tmel (Glue) oddelia od seba komponenty tak ďaleko, ako je to len možné.

 

Kód Gr2.7

 

 

import javax.swing.*;

import java.awt.*;

 

public class GlueAndStruts {

          Box vodorovny = Box.createHorizontalBox();

          Box zvisly         = Box.createVerticalBox();

          JFrame ram  = new JFrame("Testing BoxLayout");

         

          public GlueAndStruts(){

                    //

                    //vodorovny.setLayout(new BoxLayout(vodorovny, BoxLayout.X_AXIS) );

                    for(int i = 1; i < 5; i++){

                      vodorovny.add(new JLabel(" " + i + " ")); 

                      vodorovny.add(Box.createHorizontalGlue());

                    }

                    vodorovny.add(new JLabel("  a  "));  

                   vodorovny.add(Box.createHorizontalStrut(10));

                    vodorovny.add(new JLabel(" b  "));  

 

 

       for(int i = 1; i < 4; i++){

       zvisly.add(new Button(" " + i + " "));    

       zvisly.add(Box.createVerticalStrut(2*i));

                    }

      zvisly.add(new Button(" a "));      

      zvisly.add(Box.createVerticalGlue());

      zvisly.add(new Button(" b "));      

     

         

 

            Container cp = ram.getContentPane();

            cp.setLayout(new GridLayout(2,1));

            cp.add(vodorovny);

            cp.add(zvisly);

      ram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 

          }

         

          public void zobraz(int sirka, int vyska){

            ram.setSize(sirka,vyska);

            ram.setVisible(true);     

          }

          public static void main(String[] args){

                    GlueAndStruts skus = new GlueAndStruts();

                    skus.zobraz(400,550);

          }//EOMain

}//EOClass

 

Cvičenia

Cvičenie C13.1

V kóde Gr2.2 zmeňte iba jednu vec: naukladajte prvky na komponentu nie pomocou správcu typu FlowLayout, ale pomocou správcu BoxLayout. Sledujte, ako sa teraz zmení vzhľad okna, keď bude meniť svoju veľkosť.

Cvičenie C13.2

Uložte, podobne ako v kóde Gr2.3 viacero tlačítok na komponentu pomocou správcu GridLayout. Tentokrát ale použite jeho konštruktor tvaru
GridLayout(int rows, int cols, int hgap, int vgap)
ktorý určí aj veľkosť horizontálnych a verikálnych medzier medzi pridávanými prvkami.

Cvičenie C13.3

Pozrite si dokumentáciu k triede GridBagLayout. Spustite kód, ktorý je v dokumentácii uvedený ako príklad. Ak treba, upravte ho tak, aby používal JFrame miesto Frame a upravte príslušne pridávanie prvkov na komponentu. Snažte sa kódu porozumieť. Pridajte potom na komponentu pod staré prvky nový riadok prvkov, podľa svojich vlastných predstáv.

 

© Ivan Kupka

home uvod K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 K13 K14

Vaše komentáre: kupka@fmph.uniba.sk