Office week Slevový týden - Květen
Pouze tento týden sleva až 80 % na e-learning týkající se MS Office
30 % bodů zdarma na online výuku díky naší Slevové akci!

Lekce 5 - Layouty v Java Swing

V minulé lekci, Java GUI, jsme si ukázali GridBagLayout a také to, jak obsluhovat více tlačítek.

V dnešním tutoriálu si popíšeme práci s tzv. layouty. Java má pro lepší práci s komponentami k dispozici 8 layoutů. Každý má svůj vlastní účel a hodí se na něco jiného. Jejich seznam je následující:

  • FlowLayout
  • BoxLayout
  • BorderLayout
  • CardLayout
  • GridBagLayout
  • GridLayout
  • GroupLayout
  • SpringLayout

Všechny výše zmiňované layouty si postupně popíšeme a pokusím se zmínit hlavně jejich výhody.

FlowLayout

FlowLayout v Javě

Tento layout staví komponenty vedle sebe na řádek. Pokud šířka komponentů přesáhne šířku okna, řádek se zalomí a komponenty se začnou řadit na dalším řádku.

Konstruktor:

FlowLayout fl = new FlowLayout();   // základní nastavení komponenty centruje na střed
FlowLayout fl = new FlowLayout(argument); //druhá verze konstruktoru

Argument může nabývat následujících hodnot:

  • FlowLayout.LEFT = komponenty se řadí od levé strany.
  • FlowLayout.RIGHT = komponenty se řadí na pravou stranu.
  • FlowLayout.CENTER = komponenty se řadí na střed. (základní nastavení)

Existují ještě argumenty (FlowLayout.LEADING - řazení od horní strany a FlowLayout.TRAILING - řazení od dolní strany).

FlowLayout fl = new FlowLayout(argument, int horizontal, int vertical); // tretí verze konstruktoru.
  • horizontal = vodorovná mezera mezi jednotlivými komponentami a mezera mezi komponentami a postranním rámem kontejneru.
  • vertical = svislá mezera mezi komponentami a horním rámem kontejneru.

BoxLayout

BoxLayout v Javě

Tento layout rovná komponenty vedle sebe, nebo za sebou podle nastavení.

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Konstruktor:

Container pane = this.getContentPane();
pane.setLayout(new BoxLayout(pane, args));

args = rozložení komponentů. Může nabývat následujících hodnot:

  • BoxLayout.PAGE_AXIS - seřadí komponenty od shora dolů.
  • BoxLayout.LINE_AXIS - seřadí komponenty vedle sebe.

Vlastnosti:

rigid area = pevná plocha - použijeme, pokud chceme zaplnit velikost mezi dvěma komponentami. Slouží k tomu příkaz: Box.createRigi­dArea(new Dimension(x,y)); Zkusme si následující příklad:

Container pane = this.getContentPane();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
JButton  prvni = new JButton("prvni");
JButton druhy = new JButton("druhy");
pane.add(prvni);
pane.add(Box.createRigidArea(new Dimension(5,10)));
pane.add(druhy);

glue - Použijeme, když chceme komponenty od sebe roztáhnout. Každou komponentu na jinou stranu. Slouží k tomu dva příkazy:

  • Box.createHori­zontalGlue(); // vodorovné odsazení
  • Box.createVer­ticalGlue(); // svislé odsazení

Opět uvedu příklad:

Container pane = this.getContentPane();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
JButton prvni = new JButton("prvni");
JButton druhy = new JButton("druhy");
pane.add(prvni);
pane.add(Box.createVerticalGlue());
pane.add(druhy);

custom Box.Filler - nastavuje se zde minimální, preferovaná a maximální velikost. Např:

Container pane = this.getContentPane();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
pane.add(prvni);
Dimension min = new Dimension(5, 5O);
Dimension pref = new Dimension(5, 100);
Dimension max = new Dimension(20, 100);
pane.add(new Box.Filler(min, pref, max));
pane.add(druhy);

BorderLayout

BorderLayout je rozdělen na 5 částí (tzv. oblasti), do kterých můžeme přidávat komponenty a to následující:

  • PAGE_START
  • LINE_START
  • CENTRUM
  • LINE_END
  • PAGE_END

Pro lepší představu vám přikládám obrázek, který vystihuje rozložení všech pěti částí BorderLayoutu.

BorderLayout v Javě

Tento layout funguje tak, že oblast CENTRUM se roztáhne tolik, kolik je jí dovoleno a ostatní oblasti se roztáhnou jen natolik, kolik je potřeba. Ukážeme si jak to vypadá v praxi.

Container pane = this.getContentPane();
pane.setLayout(new BorderLayout());
JButton prvni = new JButton("prvni");
JButton druhy = new JButton("druhy");
JButton treti = new JButton("treti");
pane.add(prvni, BorderLayout.PAGE_START);
pane.add(druhy, BorderLayout.CENTER);
pane.add(treti, BorderLayout.LINE_END);

Tenhto layout je hodně používaný, protože do jednotlivých částí můžeme přidat jiné layouty. Např do části LINE_END můžeme přidat BoxLayout. Do části PAGE_START můžeme přidat CardLayout atd.

CardLayout

CardLayout v Javě

Tento layout slouží k přepínání komponent, které sdílí v jednom programu stejný prostor. Vidět je pouze jeden panel. Pokud si do panelu s cardLayoutem uložíme třeba 10 panelů, které budou obsahovat rozdílné komponenty, můžeme přepínat, ale viditelný bude vždy jen jeden.

Tentokrát uvedu trochu rozsáhlejší příklad. Doufám, že to z něj pochopíte. Nejdříve si napíšeme třídu MyFrame, ve které si nadefinujeme náš formulář.

import javax.swing.*;
import javax.swing.border.*;  // importotváno kvůli rámu
import java.awt.*;
import java.awt.event.*;     // importováno kvůli nastavení událostí
public class MyFrame extends JFrame
{
   JPanel card;
   JPanel hlavniPanel;
   JPanel panel1, panel3;
   JPanel panel2;
   CardLayout cards;
   JButton dalsi,predchozi;
   JLabel a;
   JButton o, but;
   public MyFrame()
   {
      this.setTitle("cardLayout");
      this.setSize(500, 300);
      this.setKomponents();
      this.setListeners();
   }

   public void setKomponents(){
      Container pane = this.getContentPane();
      pane.setLayout(new BorderLayout());
      Border outline = BorderFactory.createLineBorder(Color.black); // nastavení borderu
      this.hlavniPanel = new JPanel();
      this.hlavniPanel.setBorder(outline);
      this.dalsi = new JButton(">>");
      this.predchozi = new JButton("<<");
      this.hlavniPanel.add(this.predchozi);
      this.hlavniPanel.add(this.dalsi);
      pane.add(this.hlavniPanel, BorderLayout.PAGE_START);

      cards = new CardLayout();
      card = new JPanel();
      card.setLayout(cards);
      cards.show(card, "Vybíráme");

      /**
       * definice panelů a komponentů uvnitř CardLayoutu
       */
      panel1 = new JPanel();
      panel1.setBackground(Color.YELLOW);
      this.a = new JLabel("blablabla");
      this.a.setBackground(Color.GREEN);
      panel1.add(this.a);
      panel2 = new JPanel();
      panel2.setBackground(Color.RED);
      this.o = new JButton("pokus");
      panel2.add(this.o);
      panel3 = new JPanel();
      panel3.setBackground(Color.BLUE);
      this.but = new JButton("pokusU2");
      panel3.add(this.but);
      /**
       * přidání panelů
       */
      card.add(panel1, "první");
      card.add(panel2, "druhý");
      card.add(panel3, "třetí");
      pane.add(card, BorderLayout.CENTER);
   }

   public void setListeners(){
      this.dalsi.addActionListener(
      new ActionListener() {
          public void actionPerformed(ActionEvent e){
            cards.next(card);
          }
      });
      this.predchozi.addActionListener(
      new ActionListener(){
          public void actionPerformed(ActionEvent e){
           cards.previous(card);
        }
      });
   }

   public static Frame nastav(){
      MyFrame i = new MyFrame();
      i.setLocationRelativeTo(null);
      i.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      i.setVisible(true);
      return i;
   }
}

Poté spustíme program přes třídu Start, kterou si teď nastavíme:

public class Start
{
   public static void main(String args[]){
       MyFrame.nastav();
    }
}

Můžeme si samozřejmě nastavit více druhů ovládání. Přepínat panely po jednom, nebo dokonce na začátek a na konec. To se může hodit, pokud by náš Cardlayout obsahoval větší množství panelů. Pro přehlednost vypíšu všechny funkce:

  • first() - přepne na první panel
  • previous() - přepne na předchozí panel
  • next() - přepne na následující panel
  • last() - přepne na poslední panel
  • show () - můžeme volat konkrétní panel pomocí příkazů show(param); param = název panelu, který se má zobrazit.

Všechny obrázky které jsem použil(kromě obrázku BorderLayoutu), pochází ze stránky http://docs.oracle.com/…/visual.html

Ostatní layouty si ukážeme v dalším díle, Layouty v Javě (podruhé). Pro úplnost přikládám zdrojový kód k poslední ukázce práce s CardLayoutem.


 

Stáhnout

Staženo 316x (5.13 kB)
Aplikace je včetně zdrojových kódů v jazyce java

 

 

Článek pro vás napsal Milan Gallas
Avatar
Jak se ti líbí článek?
5 hlasů
Autor se věnuje programování, hardwaru a počítačovým sítím.
Předchozí článek
Java GUI
Všechny články v sekci
Java Swing bez grafického návrháře
Miniatura
Následující článek
Layouty v Javě (podruhé)
Aktivity (3)

 

 

Komentáře

Avatar
Kit
Redaktor
Avatar
Kit:24.7.2013 11:50

Pěkné. Jen se mi jeví metoda setKomponents() jako příliš dlouhá. Zřejmě proto, že že nastavuje vlastnosti jiných tříd, do kterých jí nic není. Přitom je ta metoda de facto úplně zbytečná.

Odpovědět
24.7.2013 11:50
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Redaktor
Avatar
Kit:24.7.2013 12:24

Když metodu setVisible(true) zavoláš až nakonec, zmizí to nepříjemné probliknutí v levém horním rohu.

Odpovědět
24.7.2013 12:24
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Homo
Člen
Avatar
Odpovídá na Kit
Homo:24.7.2013 12:50

Ta metoda se z pravidla ma davat na konec. Vyhneme se tim tak nemilym komplikacim, kdy nam muzou i nektere komponenty chybet, nebo okno bude delat neco co nechceme. Jde videt ze fuulll nevi poradne o cem pise. Pise dokumentacni komentare uvnitr metody, to jsem jeste nikdy nevidel a uprimne jsem se par minut smal :-D . Nektere metody jsou i nesikovne pojmenovane. Napr nastav.Z prikladu mohu rict, ze ma problemy s anglictinou. Aplikace je napul anglicky, napul cesky. Snazi se byt "cool" a psat program anglicky, jenze ma malou slovni zasobu, takze co nevi, napise cesky. Take me fascinuje jak nekteri programatori vsude cpou this kdyz tam neni vubec treba.

Odpovědět
24.7.2013 12:50
1010011 1000101 1011000
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na Homo
Milan Gallas:24.7.2013 16:11

jo nejsem nejlepší jako ty :D this si snad můžu psát jak chci to je můj styl. Do mé angličtiny ti nic není tak vychladni.

 
Odpovědět
24.7.2013 16:11
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na Kit
Milan Gallas:24.7.2013 16:12

Díky za info.

 
Odpovědět
24.7.2013 16:12
Avatar
Benjibs
Člen
Avatar
Odpovídá na Milan Gallas
Benjibs:24.7.2013 16:17

Trápi ťa, že sa do teba stará, ale to že ti chce pomôcť, je ti fuk :P

Odpovědět
24.7.2013 16:17
1 + 1 = 2
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na Benjibs
Milan Gallas:24.7.2013 16:21

To že metodu setVisible(true) mám zavolat nakonec, to mi řekl už kit. This tam prostě píšu a jinak snažím se psát co nejvíce česky, protože anglicky moc dobře neumím a proto že píší na českém serveru. Jen mě fascinuje sebevědomí některých lidí.

 
Odpovědět
24.7.2013 16:21
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Milan Gallas
David Čápka:24.7.2013 16:23

Tak to piš raději celé česky :) Já to v článcích také tak dělám.

Odpovědět
24.7.2013 16:23
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Benjibs
Člen
Avatar
Odpovídá na Milan Gallas
Benjibs:24.7.2013 16:25

Nadobudnúť lepší štýl písania imho tiež nie je od veci :P
Predtým som ale taktiež písal (nie Javu) programy v polo-angličtine-slovenčine, kvôli zlepšeniu AJ.

Odpovědět
24.7.2013 16:25
1 + 1 = 2
Avatar
Kit
Redaktor
Avatar
Odpovídá na Benjibs
Kit:24.7.2013 16:29

Proč to nepsat všechno česky? :)

JButton první = new JButton("první");
JButton druhý = new JButton("druhý");
JButton třetí = new JButton("třetí");

Tohle normálně funguje, ale v SW firmě by tě za to rádi neměli.

Odpovědět
24.7.2013 16:29
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Benjibs
Člen
Avatar
Odpovídá na Kit
Benjibs:24.7.2013 16:34

Prečo som si vždy myslel, že kompiler/interpret ma za premennú čerešnička zbuzeruje.. ;(

Odpovědět
24.7.2013 16:34
1 + 1 = 2
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Kit
David Čápka:24.7.2013 16:35

Takhle mi to přijde pro výukové účely ok:

JButton buttonPrvni = new JButton("první");
JButton buttonDruhy = new JButton("druhý");
JButton buttonTreti = new JButton("třetí");

Pecinovský to píše v té jeho knize dokonce s diakritikou, ale to už mi přijde trochu HC :D

Odpovědět
24.7.2013 16:35
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Kit
Redaktor
Avatar
Odpovídá na David Čápka
Kit:24.7.2013 16:53

V tomto případě bych se zastal Pecinovského. Java (a mnoho dalších jazyků) umožňuje používání diakritiky v názvech objektů a tříd. Proč toho pro výukové účely nevyužít?

V zaměstnání pak stejně budou vyžadovat anglické názvy, takže jediná změna bude v tom, že programátor zamění české názvy za anglické.

Co se týká tvého přístupu, tak sám jsem to dovedl do takového stavu, že v aplikaci se mi nevyskytuje žádný český string kromě komentářů. Přitom vstupy a výstupy jsou samozřejmě česky. Umožňuje to psát multijazyčné programy.

Odpovědět
24.7.2013 16:53
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na Kit
Milan Gallas:24.7.2013 17:04

to je pravda :D

 
Odpovědět
24.7.2013 17:04
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
domino.turak
Člen
Avatar
domino.turak:28.7.2013 21:41

Chcem sa opýtať, to this.niečo je potrebné? Nie je to nevyhnutné len v prípade že nastavujeme napr konstruktor(int vek,int vaha) a this pouzijeme iba vtedy? proste ak chceme konkretnu premennu priradit k uz predtym zadefinovanej premennej?

Odpovědět
28.7.2013 21:41
"Never give up!"
Avatar
Kit
Redaktor
Avatar
Odpovídá na domino.turak
Kit:28.7.2013 21:51

this je nutné, pokud dochází ke kolizi názvu proměnné objektu s názvem lokální proměnné metody nebo parametrem. Typicky se používá u setterů, např.

class Osoba {
   private int vyska;

   setName(int vyska) {
      this.vyska = vyska;
   }
}

this.vyska a vyska jsou různé proměnné. První je proměnnou objektu, druhá formálním parametrem. Pokud by se jejich názvy lišily, "this" by nebylo potřebné.

Editováno 28.7.2013 21:52
Odpovědět
28.7.2013 21:51
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
domino.turak
Člen
Avatar
domino.turak:28.7.2013 21:58

Aha, tak to som nevedel :) Ďakujem za objasnenie :)

Odpovědět
28.7.2013 21:58
"Never give up!"
Avatar
BLADE
Člen
Avatar
BLADE:9.8.2013 16:17

Prosím vás aký zmysel má príkaz this.dalsi.se­tActionComman­d("KOKO"); ?

 
Odpovědět
9.8.2013 16:17
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na BLADE
Milan Gallas:9.8.2013 16:24

Promiň to tam nemá co dělat. Omlouvám se psal jsem to už dříve a zapoměl jsem to smazat :[

 
Odpovědět
9.8.2013 16:24
Avatar
Odpovídá na Milan Gallas
Michal Žůrek - misaz:9.8.2013 16:28

a jen tak ze srandy co to vůbec mělo dělat?

 
Odpovědět
9.8.2013 16:28
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na BLADE
Milan Gallas:9.8.2013 16:33

Tento příkaz nastavuje název akce daného tlačítka, ale to jsem nepatří. Pro více informací můžeš navštívit stránku
http://docs.oracle.com/…/button.html
kde je to dost dobře popsaný.

 
Odpovědět
9.8.2013 16:33
Avatar
Milan Gallas
Redaktor
Avatar
 
Odpovědět
9.8.2013 16:34
Avatar
BLADE
Člen
Avatar
BLADE:9.8.2013 17:26

ok, ďakujem za odpoveď no hlavne za vysvetlenie cardlayoutu ,zrovna nedávno som rozmýšľal ako v programe spraviť aby mal viac "pozadí" teda aby sa mi napríklad po kliknutí na tlačítko úplne zmenil vzhľad programu.

 
Odpovědět
9.8.2013 17:26
Avatar
Kit
Redaktor
Avatar
Odpovídá na Milan Gallas
Kit:10.8.2013 10:29

Na http://docs.oracle.com jsem už našel dost bludů hlavně kolem OOP, ale jako on-line i off-line dokumentace je perfektní.

Je dobré se naučit programovat v Javě tak, abys používal co nejméně teček při volání metod. Program je pak přehlednější a čistější.

Odpovědět
10.8.2013 10:29
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
BLADE
Člen
Avatar
BLADE:13.8.2013 18:54

Prosím vás mám jeden problém keď robím cez ten cardlayout tak mám tam 3 tie karty no v nich chcem tlačítka a label no nejde mi tam nadstaviť ich umiestnenie teda predstavoval som si to tak že napr Label by som mal v ľavo hore a tlačítka v strede ale nie pri sebe no stále to mám na defaultnej pozícií nedá sa to dať napr cez setbounds a ručne si to nadstaviť ? :(

 
Odpovědět
13.8.2013 18:54
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na BLADE
Milan Gallas:14.8.2013 15:24

Každému panelu který do CardLayoutu přídáš můžeš nastavit layout pomocí příkazu

.setLayout();

a můžeš si nastavit co chceš. třeba místo přednastaveného panelu1, který je v článku si zkus dát následující kód:
http://www.itnetwork.cz/dev-lighter/174
a tak si můžeš hrát a dělat si co chceš :)

 
Odpovědět
14.8.2013 15:24
Avatar
mnauik
Člen
Avatar
mnauik:6.4.2014 11:35

Ahoj, rad bych se zeptal, jaky layout pouzit na nepravidelnou mrizku - prvni sloupec rozdelim na 2 radky a druhy sloupec jen na jeden radek (2 radky ve druhem sloupci jakoby spojim).

Nebo to zkusim formulovat lepsim jazykem:

<table border=2>
<tr><td>1</td><td rowspan=2>3</tr>
<tr><td>2</td></tr>
</table>

Dekuji za odpoved

Odpovědět
6.4.2014 11:35
minusuj mě, ale zdůvodni to ;)
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 28 zpráv z 28.