4. díl - Layouty v Javě (podruhé)

Java Swing Swing bez grafického návrháře Layouty v Javě (podruhé)

Vítejte v pokračování minulého dílu, který popisoval první 4 layouty (FlowLayout, BoxLayout, BorderLayout a CardLayout). Dnes se podíváme jak fungují zbylé layouty a ukážeme si jejich využití.

GridBagLayout

GridBagLayout v Javě

Tento layout je jedním z nejvíce složitých layoutů, které Java poskytuje. Nebudeme se proto učit všechna nastavení, které tento layout má, ale jen ta základní, které nám budou bohatě stačit.

Tento layout používá tzv. buňky (cells), které mají vlastní stejnou výšku i šířku. Konstruktor:

Container pane = this.getContentPane();
pane.setLayout(new GridBagLayout());
GridBagConstraints g = new GridBagConstraints();

Metody:

  • gridx - určuje v kolikátém sloupci se má prvek vyskytnout
  • gridy - určuje v kolikátém řádku se má prvek vyskytnout
  • gridwidth - určuje přes kolik sloupců se má komponenta roztáhnout
  • gridheight - určuje přes kolik řádků se má komponenta roztáhnout
  • fill - určuje výplň prostoru. Má 4 parametry (NONE - výchozí, HORIZONTAL - vytvoří komponenty dostatečně široký na pokrytí plochy a nemění jeho výšku, VERTICAL - vytvoří komponenty dostatečně vysoké a nezmění jeho šířku, BOTH - zcela vyplní svou plochu)
  • anchor - definuje, na kterém místě se má komponenta zobrazit. Jako parametry můžete uvést následující možnosti:
anchor
  • ipadx - určuje vnitří odsazení(výplň). Např. pokud bude mít komponenta šířku 30px a nastavíme ipadx = 10, přidá se výplň na obou bočních stranách 10px, takže celkový prostor bude činit 50px.
  • ipady - pracuje stejně jako ipadx, akorát vertikálně.
  • weightx, weighty - nastavuje prostor mezi komponentou a okrajem kontejneru, ve kterém je komponenta (určují se čísla z rozsahu 0,0 až 1,0)
  • insets - padding. Celým zápisem - insets(botton,lef­t,right,top);

1 příklad (falešná klávesnice):

třída MyFrame:

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
{
   JButton c,v,b,n,m,alt,mezernik,enter;
   public MyFrame()
   {
        this.setTitle("cardLayout");
        this.setSize(400, 200);
        this.setKomponents();
   }

   public void setKomponents(){
      Container pane = this.getContentPane();
      pane.setLayout(new GridBagLayout());
      GridBagConstraints g = new GridBagConstraints();
      c = new JButton("c");
      g.fill = GridBagConstraints.HORIZONTAL;
      g.gridx = 0;
      g.gridy = 0;
      pane.add(c, g);
      v = new JButton("v");
      g.fill = GridBagConstraints.HORIZONTAL;
      g.gridx = 1;
      g.gridy = 0;
      pane.add(v, g);
      b = new JButton("b");
      g.fill = GridBagConstraints.HORIZONTAL;
      g.gridx = 2;
      g.gridy = 0;
      pane.add(b, g);
      n = new JButton("n");
      g.fill = GridBagConstraints.HORIZONTAL;
      g.gridx = 3;
      g.gridy = 0;
      pane.add(n, g);
      m = new JButton("m");
      g.fill = GridBagConstraints.HORIZONTAL;
      g.gridx = 4;
      g.gridy = 0;
      pane.add(m, g);

      enter = new JButton("ENTER");
      g.fill = GridBagConstraints.HORIZONTAL;
      g.gridx = 5;
      g.gridy = 0;
      g.gridwidth = 2;
      g.gridheight = 2;
      g.ipadx = 30;
      g.ipady = 30;
      g.insets = new Insets(0,20,0,0);
      pane.add(enter, g);

      alt = new JButton("alt");
      g.fill = GridBagConstraints.HORIZONTAL;
      g.gridx = 0;
      g.gridy = 1;
      g.insets = new Insets(0,0,0,0);
      g.gridheight = 1;
      g.gridwidth = 1;
       g.ipadx = 0;
      g.ipady = 0;
      pane.add(alt, g);
      mezernik = new JButton("mezernik");
      g.fill = GridBagConstraints.HORIZONTAL;
      g.gridx = 1;
      g.gridy = 1;
      g.gridwidth = 5;
      pane.add(mezernik, g);
  }


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

třída Start:

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

Ještě jedna poznámka: Pokud nastavíte nějaké komponentě nějakou vlastnost (např. g.gridwidth = 5), musíte u další komponenty tuto vlastnost zase zrušit (pokud tedy chcete) g.gridwidth = 5. Jinak by se všechny komponenty roztáhly přes 5 sloupců.

Tak to by bylo k tomuto těžkému layoutu všechno. Myslím, že jste rádi. Naučit se tento layout dá hodně zabrat, ale pokud s ním umíte, dokážete perfektně umístit své komponenty.

GridLayout

Díky tomuto layoutu rozdělíme panel na několik vždy stejně velkých částí, které dostanou maximální možnou velikost. Jednoduše velikost okna se vydělí počtem buněk, které vytvoříme. Rozhodně je tento layout jednoduchý a příjemný k použití.

GridLayout v Javě

Konstruktor:

Container pane = this.getContentPane();
pane.setLayout(new GridLayout(řádky, sloupce));

Jednoduchý příklad:

Container pane = this.getContentPane();
pane.setLayout(new GridLayout(2, 2));
JButton a = new JButton("a");
JButton b = new JButton("b");
JButton c = new JButton("c");
JButton d = new JButton("d");
pane.add(a);
pane.add(b);
pane.add(c);
pane.add(d);

GroupLayout

GroupLayout v Javě

Tento layout pracuje odděleně s vertikálním a horizontálním rozložení. Je definován pro každou dimenzi samostatně. To znamená, že každá komponenta musí být definována 2x.

Dále tento layout používá dva parametry: sequential (sekvenční) - komponenty jsou uspořádané jedna po druhé. Poloha jednotlivých komponent je definována jako relativní vzhledem k předchozí komponentě. parallel (paralelní) - komponenty jsou uspořádány pod sebe ve stejném prostoru. Může nabývat hodnou:

  • baseline: výchozí
  • top: od shora
  • bottom: od zdola

Podél vodorovné osy mohou být zarovnány:

  • left: vlevo
  • right: vpravo
  • center: na střed

Gaps(mezery) - Pomocí mezer lze řídit vzdálenost mezi jednotlivými komponentami. Můžeme nastavit i automatické mezery. Velikosti těchto mezer se vypočítají dynamicky na základě celkové velikosti. Slouží k tomu následující příkazy:

  • layout.setAuto­CreateGaps(tru­e);
  • layout.setAuto­CreateContainer­Gaps(true);

Tyto metody musíte vždy zavolat, aby jste mohli nastavit následující funkce: addPreferredGap(La­youtStyle.Com­ponentPlacemen­t.param); param:

  • RELATED - použití u vodorovného nastavení
  • UNRELATED - vzdálenost je o něco málo větčí než u RELATED
  • INDENT - používá se u horizontálního nastavení, kdy je buďto horní nebo spodní komponenta umístěná s odsazením.

Zarovnání - slouží k tomu příkaz Alignment.param:

  • LEADING - nahoru
  • TRAILING - dolů
  • CENTER - doprostřed
  • BASELINE - základní nastavení

Pro úplnost a snadné pochopení přikládám jednoduchý příklad i s popisky.

třída MyFrame:

import java.awt.*;
import javax.swing.*;

public class MyFrame extends JFrame
{
  JButton a,s,d,f,g,h;
  public MyFrame()
  {
       this.setSize(400,400);
       this.setTitle("GroupLayout");
       this.setKomponents();
  }

  public void setKomponents(){
        /**
         * nastavení tlačítek
         */
        a = new JButton("a");
        s = new JButton("s");
        d = new JButton("d");
        f = new JButton("f");
        g = new JButton("g");
        h = new JButton("h");

           /**
         * konstruktor GroupLayoutu
         */
        Container layout = this.getContentPane();
        GroupLayout gl = new GroupLayout (layout);
        layout.setLayout(gl);
        /**
         * nastavení automatických mezer
         */
        gl.setAutoCreateGaps(true);
        gl.setAutoCreateContainerGaps(true);
        /**
         * rozvržení komponent
         */
        gl.setHorizontalGroup(  // horizontální nastavení
         gl.createSequentialGroup()
         // vytvorení sekvenční skupiny, kterou jmse si již popsali
         .addComponent(a)
         .addComponent(s)
         .addComponent(d)
         .addGroup(gl.createParallelGroup(GroupLayout.Alignment.LEADING))
         // přidání paralelních skupin, o kterýcg jsme si již také říkali
         .addComponent(f)
         .addComponent(g)
         .addGroup(gl.createParallelGroup(GroupLayout.Alignment.TRAILING))
         .addComponent(h)
         );
         gl.setVerticalGroup(  // vertikální nastavení
          gl.createSequentialGroup()
          .addGroup(gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
           .addComponent(a)
           .addComponent(s)
           .addComponent(d))
           .addGroup(gl.createParallelGroup(GroupLayout.Alignment.BASELINE)
           .addComponent(f)
           .addComponent(g))
           .addComponent(h)
         );
    }

    public static Frame nastav(){
        MyFrame m = new MyFrame();
        m.setLocationRelativeTo(null);
        m.setVisible(true);
        return m;
    }
}

Vše spustíme přes třídu Start:

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

Jak se tedy tento layout tvoří máte popsáno. Ještě uvedu celý příkaz, kterým můžeme komponenty přidat. Vypadá takto:

addComponent(Com­ponent comp, int min, int pref, int max);

Nakonec jen uvedu metody které nám vrátí nastavené velikosti:

  • getMinimumSize() - vrátí minimální velikost komponenty
  • getPreferredSize() - vrátí preferovanou velikost komponenty
  • getMaximumSize() - vrátí maximální velikost komponenty

 

  Aktivity (1)

Článek pro vás napsal Milan Gallas
Avatar
Autor se věnuje programování, hardwaru a počítačovým sítím.

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 


Miniatura
Předchozí článek
Layouty v Java Swing
Miniatura
Všechny články v sekci
Java Swing bez grafického návrháře
Miniatura
Následující článek
JComboBox a dialogy v Java Swing

 

 

Komentáře
Zobrazit starší komentáře (16)

Avatar
Milan Gallas
Redaktor
Avatar
Milan Gallas:

fakt co přesně je udělané špatně? Kromě jiného stylu zápisu, který se prostě s tvým stylem neschoduje. To ale neznamená že je to špatně.

Editováno 25.8.2013 15:15
 
Odpovědět 25.8.2013 15:14
Avatar
Kit
Redaktor
Avatar
Odpovídá na Milan Gallas
Kit:

Od základu je špatně, že z jednoho objektu měníš atributy jiného objektu. To se v OOP prostě nedělá. Je to nejen méně přehledné, ale i pomalejší.

Editováno 25.8.2013 15:17
Odpovědět 25.8.2013 15:16
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Milan Gallas
Redaktor
Avatar
Milan Gallas:

Jediné co tam máš špatně je že příkazy:

gbc.weightx = 0.5;
       gbc.weighty = 0.5;

musíš přiřadit až poslednímu tlačítku.
celý kód najdeš zde:
http://www.itnetwork.cz/dev-lighter/188

 
Odpovědět 25.8.2013 15:36
Avatar
Tomhaus
Člen
Avatar
Tomhaus:

Cs, mam problém s vybráním správného layoutu.
Chci si komponenty umisťovat podle pozic a libovolně měnit jejich velikost.
Nevíte jakej by byl nejlepší layout?

Odpovědět 5.12.2014 17:58
Být lepší a chytřejší je důležité, ale někdy se musíme spokojit s tím, co máme.
Avatar
Tomhaus
Člen
Avatar
Tomhaus:

A chtěl bych ještě aby se mi to skládalo od horního levého rohu :)

Odpovědět 5.12.2014 18:10
Být lepší a chytřejší je důležité, ale někdy se musíme spokojit s tím, co máme.
Avatar
Milan Gallas
Redaktor
Avatar
Odpovídá na Tomhaus
Milan Gallas:

grigBagLayout. Layouty můžeš do sebe i zanořit. Takže můžeš mít BorderLayout a v něm třeba ve BorderLayout.CENTER můžeš mít gridBagLayout.

Pokud chceš s objekty manipulovat za běhu programu, tak si pročti http://www.itnetwork.cz/…java-menubar .

 
Odpovědět 6.12.2014 15:29
Avatar
Tomhaus
Člen
Avatar
Odpovídá na Milan Gallas
Tomhaus:

A dal by se třeba nastavit JPanelu nějakej layout?
A dá se v GridBagLayoutu nastavit aby nevyplňoval celou plochu?
Nechci aby se mi roztahovaly tlačítka do šířky.

Editováno 7.12.2014 16:19
Odpovědět 7.12.2014 16:15
Být lepší a chytřejší je důležité, ale někdy se musíme spokojit s tím, co máme.
Avatar
forcabarca
Člen
Avatar
forcabarca:

Těch Layoutů prý má být 8 ale v obou dílech jsem jich našel jen 7, tak co ten osmý?

 
Odpovědět 17.11.2015 0:04
Avatar
vajkuba1234
Člen
Avatar
Odpovídá na forcabarca
vajkuba1234:

Zkoušel jsi hledat na internetu? Já tam toho našel celkem dost.

Odpovědět 17.11.2015 4:51
No hope, no future, JUST WAR! For world peace Israel must be DESTROYED!
Avatar
forcabarca
Člen
Avatar
Odpovídá na vajkuba1234
forcabarca:

Spíš jsem čekal že mi autor napíše proč ten jeden díl vynechal, nebo jestli jsem ho někde přehlédl. Na začátku čtu 8 layoutů a v článku jich najdu jen 7, tak mě zajímal důvod, nic víc.

 
Odpovědět 27.11.2015 18:01
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 10 zpráv z 26. Zobrazit vše