David Štrupl
Události
Uvedené příklady ukazovaly, jak vytvořit uživatelské rozhraní. To však samo o sobě nestačí. Ještě je třeba napsat kód, který bude něco provádět, např. při stisknutí tlačítka. Musíme naprogramovat reakci na události, které mohou v programu nastat.
Chceme-li např. zareagovat na stisk tlačítka, můžeme přepsat metodu action u apletu:
import java.awt.*;
import java.applet.*;
public class Test2 extends Applet{
Button okButton = new Button("OK");
public void init() {
add(okButton);
}
public boolean action(Event e, Object what){
if (e.target == okButton) {
Systém.out.println("Stisknut button");
}
return true;
}
}
Podobným způsobem je možné reagovat na události, které vzniknou kliknutím myši, stisknutím klávesy na klávesnici apod. Jména metod, které zpracovávají události, se bohužel změnila od verze 1.0 k verzi 1.1, takže je vždy potřeba dávat pozor na to, kterou verzi překladače a prostředí máme k dispozici. Verze 1.1 podporuje i volání metod z verze 1.0, tj. zpětná kompatibilita byla zachována, musíme však dávat pozor, abychom nepoužili volání z verze 1.1, máme-li k dispozici pouze verzi 1.0 (např. v prohlížeči).
Layout Manager
V předchozích příkladech jsme si ukazovali, jak přidávat komponenty do kontejnerů pomocí metody add. Při prohlížení běžících programů vás jistě napadlo, že jsme nikdy nezadávali žádné souřadnice, kam se dané komponenty mají zobrazit. To většinou není třeba, neboť v knihovně AWT máme k dispozici objekty, které se o umisťování komponent starají za nás. Těmto objektům se říká Layout Managery, protože implementují rozhraní Layout Manager.
Použití Layout Managerů by se mohlo zdát na první pohled zbytečné a těžkopádné -- proč bychom nemohli umisťovat komponenty na přesně určené souřadnice? Problém s umisťováním na absolutní souřadnice je v tom, že nikdy nevíme, jak bude vypadat fyzické zařízení, na kterém se budou naše komponenty zobrazovat -- nemůžeme vědět, jaké bude mít uživatel k dispozici rozlišení obrazovky, jak velké budou fonty atd. Layout Manager by nás jako programátory měl od těchto detailů odstínit.
S každým kontejnerem (potomkem třídy Container) je svázán jeden Layout Manager. Pokud jej nezměníme, je použit defaultní -- pro třídu Panel (a tedy i pro jejího potomka Applet) je použit FlowLayout.
FlowLayout
Objekt této třídy pracuje tak, že umisťuje jednotlivé komponenty za sebou podle pořadí vkládání příkazem add. Pokud se další komponenta nevejde na řádek, pokusí se ji umístit na další řádek. Toto chování je vhodné, pokud do kontejneru umisťujeme malé množství objektů (např. dva Buttony apod.). Pokud chceme tento LayoutManager použít i v objektech, pro které není defaultní, můžeme použít příkaz:
setLayout(new FlowLayout());
Tento příkaz je třeba vyvolat na příslušný kontejner, např. na Frame.
GridLayout
Pokud chceme umisťovat objekty do mřížky, můžeme příkazem
setLayout(new GridLayout(x,y));
aktivovat nový GridLayout. Parametry x a y určují rozměry mřížky. Podívejme se na applet, do kterého vložíme čtyři tlačítka:
import java.awt.*;
import java.applet.*;
public class Test2 extends Applet{
public void init() {
setLayout(new GridLayout(2,2));
add(new Button("Prvni"));
add(new Button("Druhy"));
add(new Button("Treti"));
add(new Button("Ctvrty"));
}
}
Po spuštění si můžeme vyzkoušet, co se bude dít, budeme-li měnit velikost našeho appletu.
BorderLayout
Dalším z nejběžnějších správců je BorderLayout -- umožňuje nám určit, na kterém místě se přidávaná komponenta objeví. Používá k tomu variantu příkazu add, která má navíc ještě jeden argument, který je předán Layout Manageru. Při použití tohoto objektu již nezáleží na pořadí vkládání komponent jako v předchozích případech. Použití si opět budeme ilustrovat na příkladu appletu:
import java.awt.*;
import java.applet.*;
public class Test3 extends Applet{
public void init() {
setLayout(new BorderLayout());
add("North", new Button("Prvni"));
add("South", new Button("Druhy"));
add("East", new Button("Treti"));
add("West", new Button("Ctvrty"));
add("Center", new Button("Ctvrty"));
}
}
Ostatní
V knihovně AWT máme kromě již uvedených Layout Managerů ještě možnost použít následující objekty:
- CardLayout -- slouží k vytvoření několika karet, které můžeme na obrazovce střídat. Je to užitečné v případech, kdy chceme měnit vzhled rozhraní za běhu.
- GridBagLayout -- tento správce je nejsložitější ze standardních správců. Pomocí objektů třídy GridBagConstraints umožňuje u každé komponenty stanovit vlastnosti při změně velikosti kontejneru.
Pokud nechceme použít žádný Layout Manager, můžeme pomocí příkazu:
setLayout(null);
vypnout jejich používání. Potom se musíme starat o souřadnice, na které dané komponenty umisťujeme, a proto to není doporučovaný způsob psaní aplikací v Javě.
Vytváření GUI
Při vytváření uživatelského rozhraní nemusíme používat jeden Layout Manager pro celé okno, do kterého umisťujeme komponenty. Můžeme si plochu okna rozdělit a v každé části použít jiný druh správce rozmístění. Rozdělení plochy okna nám umožní nejjednodušší potomek třídy Container -- Panel.
Panel je komponenta, která slouží k umisťování dalších komponent. Můžeme jej umístit do libovolného kontejneru, tj. můžeme vytvořit hierarchickou strukturu panelů, které realizují rozmisťování komponent. U každého panelu nastavíme Layout Manager tak, aby celkový vzhled GUI odpovídal naší představě.
V následujícím příkladu si ukážeme použití několika panelů pro lepší rozvržení komponent v appletu:
import java.awt.*;
import java.applet.*;
public class Test4 extends Applet{
public void init() {
Panel p1, p2, p3;
setLayout(new BorderLayout());
add("East", p1 = new Panel());
add("South", p2 = new Panel());
add("West", p3 = new Panel());
p1.setLayout(new GridLayout(3,1));
p1.add(new Checkbox("Jedna"));
p1.add(new Checkbox("Dve"));
p1.add(new Checkbox("Tri"));
p3.setLayout(new GridLayout(3,1));
p3.add(new Checkbox("Maslo"));
p3.add(new Checkbox("Pivo"));
p3.add(new Checkbox("Rohlik"));
p2.add(new Button("Ok"));
}
}
Tato ukázka po spuštění zobrazí applet, ve kterém budou jednotlivé komponenty umístěny ve skupinách určených jednotlivými panely.
Pomocí panelů a několika málo Layout Managerů se dá dosáhnout slušné úrovně zobrazení bez toho, aniž bychom nastavili jedinou souřadnici, kam se mají jednotlivé komponenty zobrazovat.