Tentokrát se dozvíte něco o grafickém uživatelském rozhraní, používaném v jazyce Java. Na příkladech si ukážeme, jak v oknech aplikace či appletu sestavit prvky uživatelského rozhraní (tlačítka, seznamy…), jak je seskupovat do kontejnerů a jak s nimi manipulovat.

Grafické uživatelské rozhraní slouží pro komunikaci s uživatelem aplikace pomocí grafických prvků (tlačítek, ikon, seznamů, posuvníků…) tak, jak je běžné v dnešních „okenních“ operačních systémech. Jazyk Java díky své přenositelnosti mezi jednotlivými platformami nemůže využívat přímo všech prostředků konkrétního operačního systému. Proto bylo třeba vytvořit abstraktní uživatelské rozhraní, které bude možné implementovat na všech platformách. Takové prostředí se jmenuje AWT (Abstract Windows Toolkit), je dostupné ve všech verzích Javy a obsahuje základní prvky uživatelského rozhraní.

Od verze JDK 1.2 je k dispozici nové prostředí Swing, které je graficky i funkčně propracovanější a obsahuje více uživatelských prvků. Obě uživatelská rozhraní jsou nezávislá na platformě, poběží vám tedy (přibližně) stejně na Windows, Linuxu i Solarisu.

Na začátku tohoto seriálu jsme si řekli, že budeme používat pouze třídy, které jsou v Javě 1.1, proto si důkladně rozebereme prostředí AWT. Prostředí Swing má základní princip podobný prostředí AWT, obsahuje pouze více prvků a umožňuje podrobnější nastavení vzhledu aplikace (je však také náročnější na programování).

Pokud používáte programátorské prostředí jako Borland JBuilder, NetBeans Developer a podobné, obvykle se vyhnete dlouhému definování vzhledu okna díky grafickému návrháři, ve kterém si myší „nataháte“ uživatelské prvky a on za vás zdrojový kód automaticky napíše. V tom případě můžete klidně použít Swing, máte–li jistotu, že budete aplikaci spouštět alespoň v Javě 1.2.

První příklad

První příklad, který si probereme, je applet:

package interval;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/**
* Title: Příklad grafického rozhraní AWT
* Company: Interval
* @author Jiří Semecký (jiri.semecky@interval.cz)
*/
public class prvniPrikladAWT extends Applet {
  Label label1 = new Label(); // nápis „Vítá Vás Interval“
  Label label2 = new Label(); // nápis „toto je…“
  TextField textField1 = new TextField(); // pole pro zadání textu
  Button button1 = new Button(); // tlačítko
  Button button2 = new Button(); // tlačítko
  Panel spodnipanel = new Panel(); // panel s tlačítky a polem pro zadání textu
  BorderLayout borderLayout1 = new BorderLayout(); // správce rozvržení FlowLayout
  FlowLayout flowLayout1 = new FlowLayout(); // správce rozvržení BorderLayout
  // konstruktor applety
  public prvniPrikladAWT() {
  }
  // inicializtace grafického rozhraní
  public void init() {
    label1.setAlignment(Label.CENTER);
    label1.setForeground(Color.white);
    label1.setText(„Vítá Vás Interval“);
    label2.setAlignment(Label.CENTER);
    label2.setFont(new java.awt.Font(„Dialog“, 0, 20));
    label2.setForeground(Color.orange);
    label2.setText(„toto je ukázka grafického rozhraní AWT“);
    button1.setLabel(„potvrdit“);
    this.setLayout(borderLayout1); // nastavení rozvržení okna
    button2.setLabel(„nepotvrdit“);
    textField1.setColumns(0);
    textField1.setText(„vstupní text“);
    this.setBackground(new Color(0, 40, 104));
    spodnipanel.setLayout(flowLayout1); // nastavení rozvržení spodního panelu
    spodnipanel.add(textField1);
    spodnipanel.add(button1);
    spodnipanel.add(button2);
    this.add(label1, BorderLayout.NORTH);
    this.add(label2, BorderLayout.CENTER);
    this.add(spodnipanel, BorderLayout.SOUTH);
  }
}

Jedná se o applet, který obsahuje několik proměnných pro uživatelské prvky grafického rozhraní, konstruktor a metodu init(). Ta je volána na začátku při inicializaci appletu a obsahuje definici vlastností a umístění komponent (dvě tlačítka Button, dva nápisy Label, Panel a editační řádku TextField).

Vlastnosti okna a komponent můžete dále měnit v průběhu běhu programu metodami setColor(), setFont(), setBackground(), setFont(), setLabel() a naopak zjišťovat metodami getColor(), getFont(), getBackground(), getFont(), getLabel() a dalšími.

Kontejnery

V prostředí Javy se komponenty třídy java.awt.Container (kontejner) a jejích potomků používají pro seskupování dalších komponent. Kontejner slouží jako schránka pro jiné komponenty, včetně dalších kontejnerů. Vzájemným vnořováním komponent a kontejnerů tedy definujete hierarchickou strukturu prvků v okně. Nejvyšším kontejnerem v této hierarchii je rámec java.awt.Frame, který reprezentuje plochu okna.

Správci rozvržení

Správci rozvržení (layout managers) jsou třídy používané k řízení velikosti a umístění jednotlivých komponent v kontejneru. Správci rozvržení se zpravidla starají i o zjištění optimální velikosti kontejneru pomocí metod getMinimumSize(), getMaximumSize() a getPreferedSize(). Použití správců rozvržení usnadní programování v Javě, neboť nemusíte zadávat přesné souřadnice jednotlivých prvků. Zadáte pouze hrubý tvar okna a správce rozvržení se sám stará o optimální rozmístění komponent i o jejich vhodné přeskupení při změně jeho velikosti.

Java poskytuje několik standardních správců rozvržení, kteří mají své výhody i nevýhody. Někteří jsou jednoduší, ale mají omezené možnosti, jiní jsou naopak složitější k použití, zato nabízejí vyšší flexibilitu.

V předchozím příkladu jste viděli funkci dvou správců rozvržení java.awt.BorderLayout a java.awt.FlowLayout. Asi nejjednodušší správce rozvržení je FlowLayout (spodniPanel). Komponenty, které se do něho přidávají, se řadí vedle sebe. V našem příkladu se jedná o pole pro zadání textu a obě tlačítka. Komponenty se do FlowLayoutu vkládají metodou add a lze jich tam vlažit libovolné množství:

  • spodnipanel.add(textField1);
  • spodnipanel.add(button1);
  • spodnipanel.add(button2);

  

Správce rozvržení BorderLayout může obsahovat pouze pět komponent. Jsou uspořádány tak, že jedna je ve středu plochy a další čtyři na okrajích. Do správce rozvržení se přidává komponenta rovněž pomocí metody add. První parametr specifikuje komponentu, druhý určuje její polohu a může nabývat následujících hodnot:

  • BorderLayout.CENTER (ve prostřed plochy)
  • BorderLayout.SOUTH (spodní okraj)
  • BorderLayout.NORTH (horní okraj)
  • BorderLayout.WEST (levý okraj)
  • BorderLayout.EAST (pravý okraj)

   

U každého okraje může být pouze jedna komponenta, může to však být další kontejner (například java.awt.Panel), jak je vidět v našem příkladu.

Složitější příklad

Na závěr si ukážeme rozsáhlejší příklad, ve kterém je vidět použití více komponent. Jedná se o aplikaci, nikoli applet, musíte ji tedy spustit příkazem java druhyPrikladAWT. Tento příklad zde nebude podrobně rozebrán, pokud se do něj budete chvíli dívat, jistě se v něm zorientujete. (K dispozici je vám rovněž archiv s oběma příklady.)

package interval;
import java.awt.*;
import java.awt.event.*;
/**
* Title: Příklad grafického rozhraní AWT
* Company: Interval
* @author Jiří Semecký (jiri.semecky@interval.cz)
*/
public class druhyPrikladAWT extends Frame {
  BorderLayout borderLayout1 = new BorderLayout();
  Checkbox tucne = new Checkbox();
  Checkbox sklonene = new Checkbox();
  CheckboxGroup checkboxGroup1 = new CheckboxGroup();
  Label label1 = new Label();
  Panel panel3 = new Panel();
  Label label2 = new Label();
  Label napis = new Label();
  Panel panel4 = new Panel();
  Label label5 = new Label();
  Button zavri = new Button();
  TextField editNapis = new TextField();
  GridBagLayout gridBagLayout1 = new GridBagLayout();
  GridLayout gridLayout2 = new GridLayout();
  Choice barva = new Choice();
  ScrollPane scrollPane1 = new ScrollPane();
  Label label3 = new Label();
  // Konstruktor
  public druhyPrikladAWT() {
    nastavKomponenty();
  }
  // Nastavení komponent uživatelského rozhraní
  private void nastavKomponenty() {
    this.setLayout(borderLayout1);
    this.setSize(new Dimension(505, 418));
    this.setTitle(„Druhý příklad AWT“);
    zavri.setLabel(„Zavři“);
    zavri.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) { System.exit(0); } }); // zavře okno
    tucne.setLabel(„tučně“);
    tucne.setVisible(true);
    tucne.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) { typPisma_itemStateChanged(e); } });
    sklonene.setLabel(„skloněné“);
    sklonene.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(ItemEvent e) { typPisma_itemStateChanged(e); } });
    label1.setAlignment(Label.CENTER);
    label1.setFont(new java.awt.Font(„Dialog“, 0, 20));
    label1.setLocale(java.util.Locale.getDefault());
    label1.setText(„Příklad aplikace využívající AWT“);
    panel3.setLayout(gridLayout2);
    label2.setFont(new java.awt.Font(„Dialog“, 1, 12));
    label2.setText(„typ písma:“);
    napis.setAlignment(Label.CENTER);
    napis.setBackground(Color.white);
    napis.setFont(new java.awt.Font(„Dialog“, 0, 50));
    napis.setText(„nápis“);
    label5.setFont(new java.awt.Font(„Dialog“, 1, 12));
    label5.setText(„nápis:“);
    editNapis.setText(„nápis“);
    editNapis.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) { editNapis_actionPerformed(e); } });
    panel4.setLocale(java.util.Locale.getDefault());
    panel4.setLayout(gridBagLayout1);
    gridLayout2.setColumns(1);
    gridLayout2.setHgap(0);
    gridLayout2.setRows(6);
    label3.setFont(new java.awt.Font(„Dialog“, 1, 12));
    label3.setText(„barva“);
    barva.add(„Cerna“);
    barva.add(„Cervena“);
    barva.add(„Zelena“);
    barva.add(„Modra“);
    barva.addItemListener(new java.awt.event.ItemListener() {
        public void itemStateChanged(ItemEvent e) { barva_itemStateChanged(e); } });
    panel3.add(label2, null);
    panel3.add(sklonene, null);
    panel3.add(tucne, null);
    panel3.add(label3, null);
    panel3.add(barva, null);
    panel3.add(zavri, null);
    panel4.add(editNapis, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0
        ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 3, 13, 17), 217, 11));
    panel4.add(label5, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
        ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 30, 14, 0), 102, 4));
    scrollPane1.add(napis, null);
    this.add(panel3, BorderLayout.EAST);
    this.add(scrollPane1, BorderLayout.CENTER);
    this.add(label1, BorderLayout.NORTH);
    this.add(panel4, BorderLayout.SOUTH);
  }
  // změna textu
  void editNapis_actionPerformed(ActionEvent e) {
    napis.setText(editNapis.getText());
  }
  // změna typu písma
  void typPisma_itemStateChanged(ItemEvent e) {
    napis.setFont(new Font(null, (sklonene.getState()?Font.ITALIC:0)+(tucne.getState()?Font.BOLD:0), 30));
  }
  // změna barvy písma
  void barva_itemStateChanged(ItemEvent e) {
    if (barva.getSelectedItem().equals(„Cervena“)) napis.setForeground(Color.RED);
      else if (barva.getSelectedItem().equals(„Zelena“)) napis.setForeground(Color.GREEN);
      else if (barva.getSelectedItem().equals(„Modra“)) napis.setForeground(Color.BLUE);
      else if (barva.getSelectedItem().equals(„Cerna“)) napis.setForeground(Color.BLACK);
  }
  // hlavní metoda, která se na začátku spustí, vytvoří a zobrazí okno
  public static void main(String args[]) {
    (new druhyPrikladAWT()).show();
  }
}

V příštím článku bude řeč o dalších aspektech prostředí AWT, vysvětlíme si například mechanismus ošetřování událostí a vytvoříme si uživatelský dialog.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

1 Příspěvěk v diskuzi

Odpovědět