4.1. GUI saskarnes

Ievads

Mērķi

  • Aprakstīt AWT (Abstract Windowing Toolkit) pakotni un tās komponentus.
  • Definēt jēdzienus konteiners (container), komponents (component) un izvietojuma pārvaldnieks (layout manager), un aprakstīt, kā tie mijiedarbojas, veidojot lietotāja grafisko saskarni.
  • Lietot izvietojuma pārvaldniekus FlowLayout, BorderLayout un GridLayout, lai iegūtu vēlamo dinamisko izvietojumu.
  • Prast pievienot komponentus konteineram.
  • Atbilstoši lietot Frame un Panel konteinerus
  • Aprakstīt, kā darbojas sarežģīti izvietojumi ar daudzlīmeņu konteineriem.
  • Javas programmā prast atrast konteinerus, tiem atbilstošos izvietojuma pārvaldniekus un visu komponentu izvietojuma hierarhiju.

Motivācija: Būdama platformneatkarīga valoda, Java arī GUI platformu veido platformneatkarīgi. Kā tas notiek?

AWT (Abstract Window Toolkit) pakotne

  • Satur grafiskās saskarnes (GUI) komponentus, ko lietot Javas apletos un aplikācijās
  • Satur klases, kuras var paplašināt ar mantošanu, arī abstraktas klases
  • Katrs GUI komponents ir apakšklase vai nu abstraktajai klasei Component vai MenuComponent
  • Container ir abstrakta apakšklase klasei Component, un tam savukārt ir apakšklases Panel un Window

Pakotne java.awt

AWT klašu hierarhija

Konteineri

  • Komponentus tiem pievieno ar add() metodi.
  • Divi galvenie konteineru veidi ir Window un Panel.
  • Window ir parasts aplikācijas logs.
  • Panel ir konteiners, kuru satur cits konteiners, piemēram aplikācijas logs vai aplets.

Komponentu izvietošana

  • Komponenta atrašanās vietu un izmēru nosaka to ietverošā konteinera izvietojuma pārvaldnieks
  • Komponentu var novietot konteinerā arī pie atspējota izvietojuma pārvaldnieka. (Šai gadījumā jālieto setLocation(), setSize() vai setBounds() metodes uz komponentēm, lai tās novietotos konteinerā).

Freims (Frame)

  • Klases Window apakšklase
  • Satur virsrakstjoslu un ir staipāms aiz stūriem
  • Sākumā nav redzams, bet freimu var parādīt, izsaucot setVisible(true)
  • Tam noklusētais izvietojuma pārvaldnieks ir BorderLayout
  • Var izsaukt setLayout metodi, lai uzstādītu citu izvietojuma pārvaldnieku

FrameExample.java

1  import java.awt.*;
2  
3  public class FrameExample {
4    private Frame f;
5  
6    public FrameExample() {
7      f = new Frame("Hello Out There!");
8    }
9  
10    public void launchFrame() {
11      f.setSize(170,170);
12      f.setBackground(Color.blue);
13      f.setVisible(true);
14    }
15  
16    public static void main(String args[]) {
17      FrameExample guiWindow = new FrameExample();
18      guiWindow.launchFrame();
19    }
20  }

FrameExample.java

AWT logu piemēri

Panelis (Panel)

  • Vieta, kur izvietot komponentus
  • Apakšpaneļos var būt katrā savs izvietojuma pārvaldnieks

FrameWithPanel.java

1  import java.awt.*;
2  
3  public class FrameWithPanel {
4    private Frame f;
5      private Panel pan;
6  
7    public FrameWithPanel(String title) {
8      f = new Frame(title);
9          pan = new Panel();
10  }
11  
12    public void launchFrame() {
13      f.setSize(200,200);
14      f.setBackground(Color.blue);
15      f.setLayout(null);  // atspējo noklusēto izvietotāju
16  
17      pan.setSize(100,100);
18      pan.setBackground(Color.yellow);
19      f.add(pan);
20      f.setVisible(true);
21    }
22  
23    public static void main(String args[]) {
24      FrameWithPanel guiWindow =
25          new FrameWithPanel("Frame with Panel");
26      guiWindow.launchFrame();
27    }
28  }

FrameWithPanel.java

AWT logs ar Panel komponentu

Iespējamie izvietojumi konteineros

  • FlowLayout
  • BorderLayout
  • GridLayout
  • CardLayout
  • GridBagLayout

Noklusētie izvietotāji

Noklusētie izvietotāji dažādiem konteineriem atšķiras

Piemērs ar izvietojumu FlowLayout

1  import java.awt.*;
2  
3  public class LayoutExample {
4    private Frame f;
5    private Button b1;
6    private Button b2;
7  
8    public LayoutExample() {
9      f = new Frame("GUI example");
10      b1 = new Button("Press Me");
11      b2 = new Button("Don't press Me");
12    }
13  
14    public void launchFrame() {
15      f.setLayout(new FlowLayout());
16      f.add(b1);
17      f.add(b2);
18      f.pack();
19      f.setVisible(true);
20    }
21  
22    public static void main(String args[]) {
23      LayoutExample guiWindow = new LayoutExample();
24      guiWindow.launchFrame();
25    }
26  }
AWT aplikāciju pogas

Izvietojums FlowLayout

  • Noklusētais izvietojums klasei Panel
  • Komponentus pievieno no kreisās puses uz labo
  • Pēc noklusēšanas izlīdzinājums (alignment) ir iecentrēts - FlowLayout.CENTER
  • Izmanto komponentu vēlamos (prefered) izmērus
  • Ar FlowLayout konstruktora parametriem var skaņot šī izvietojuma pārvaldnieka uzvedību

FlowExample.java

Staipīšanas iespaids uz komponentu izvietojumu

FlowExample.java

1  import java.awt.*;
2  
3  public class FlowExample {
4    private Frame f;
5    private Button button1;
6    private Button button2;
7    private Button button3;
8  
9    public FlowExample() {
10      f = new Frame("Flow Layout");
11      button1 = new Button("Ok");
12      button2 = new Button("Open");
13      button3 = new Button("Close");
14    }
15  
16    public void launchFrame() {
17      f.setLayout(new FlowLayout());
18      f.add(button1);
19      f.add(button2);
20      f.add(button3);
21      f.setSize(100,100);
22      f.setVisible(true);
23    }
24  
25    public static void main(String args[]) {
26      FlowExample guiWindow = new FlowExample();
27      guiWindow.launchFrame();
28    }
29  }

Izvietojuma pārvaldnieks BorderLayout

Noklusētais izvietojums klasei Frame. Komponentus pievieno norādītajiem reģioniem Komponentu uzvedība staipīšanas (resizing) rezultātā:

  • Ziemeļu, dienvidu un centra reģioni (BorderLayout.NORTH, BorderLayout.SOUTH, BorderLayout.CENTER) var mainīt savus horizontālos izmērus
  • Austrumu, rietumu un centra reģioni (BorderLayout.EAST, BorderLayout.WEST, BorderLayout.CENTER) var mainīt savus vertikālos izmērus
BorderLayout staipīšanas shēma

BorderExample.java

1  import java.awt.*;
2  
3  public class BorderExample {
4    private Frame f;
5    private Button bn, bs, bw, be, bc;
6  
7    public BorderExample() {
8      f = new Frame("Border Layout");
9      bn = new Button("B1");
10      bs = new Button("B2");
11      bw = new Button("B3");
12      be = new Button("B4");
13      bc = new Button("B5");
14    }
15  
16    public void launchFrame() {
17      f.add(bn, BorderLayout.NORTH);
18      f.add(bs, BorderLayout.SOUTH);
19      f.add(bw, BorderLayout.WEST);
20      f.add(be, BorderLayout.EAST);
21      f.add(bc, BorderLayout.CENTER);
22      f.setSize(200,200);
23      f.setVisible(true);
24    }
25  
26    public static void main(String args[]) {
27      BorderExample guiWindow2 = new BorderExample();
28      guiWindow2.launchFrame();
29    }
30  }

BorderExample.java

BorderLayout piemērs ar pogām

Izvietojuma pārvaldnieks GridLayout

  • Komponentus pievieno, aizpildot režģi pa rindām - no kreisās uz labo pusi un no augšas uz leju.
  • Visi reģioni ir vienāda izmēra taisnstūri.
  • Konstruktors norāda rindu un kolonnu skaitu režģī.

GridExample.java

1  import java.awt.*;
2  
3  public class GridExample {
4    private Frame f;
5    private Button b1, b2, b3, b4, b5, b6;
6  
7    public GridExample() {
8      f = new Frame("Grid Example");
9      b1 = new Button("1");
10      b2 = new Button("2");
11      b3 = new Button("3");
12      b4 = new Button("4");
13      b5 = new Button("5");
14      b6 = new Button("6");
15    }
16  
17    public void launchFrame() {
18      f.setLayout (new GridLayout(3,2));
19  
20      f.add(b1);
21      f.add(b2);
22      f.add(b3);
23      f.add(b4);
24      f.add(b5);
25      f.add(b6);
26  
27      f.pack();
28      f.setVisible(true);
29    }
30  
31    public static void main(String args[]) {
32      GridExample grid = new GridExample();
33      grid.launchFrame();
34    }
35  }

GridEx.java

Režģa izvietojums

ComplexLayoutExample.java

1  import java.awt.*;
2  
3  public class ComplexLayoutExample {
4    private Frame f;
5    private Panel p;
6    private Button bw, bc;
7    private Button bfile, bhelp;
8  
9    public ComplexLayoutExample() {
10      f = new Frame("GUI example 3");
11      bw = new Button("West");
12      bc = new Button("Work space region");
13      bfile = new Button("File");
14      bhelp = new Button("Help");
15    }
16  
17    public void launchFrame() {
18      // Add bw and bc buttons in the frame border
19      f.add(bw, BorderLayout.WEST);
20      f.add(bc, BorderLayout.CENTER);
21      // Create panel for the buttons in the north border
22      p = new Panel();
23      p.add(bfile);
24      p.add(bhelp);
25      f.add(p, BorderLayout.NORTH);
26      // Pack the frame and make it visible
27      f.pack();
28      f.setVisible(true);
29    }
30  
31    public static void main(String args[]) {
32      ComplexLayoutExample gui = new ComplexLayoutExample();
33      gui.launchFrame();
34    }
35  }

Aplikācijas ComplexLayoutExample.java logs

Staipīšanas iespaids uz saliktu izvietojumu

Zīmēšana ar AWT līdzekļiem

  • Zīmēt (ģeometriskas figūras un tekstu) var jebkurā Component instancē (AWT paredz klases Canvas un Panel tieši šim mērķim).
  • Parasti Jūs izveidosiet Canvas vai Panel apakšklasi un pārdefinēsiet tajā paint metodi.
  • Metode paint tiek izsaukta ikreiz, kad komponentu parāda uz ekrāna. AWT aplikācijas programmētājs šo metodi pats neizsauc. (paint tiek izsaukta gan pirmo reizi parādot logu, gan maksimizējot aplikācijas logu, gan, piemēram, ja aizver citu logu, kurš līdz šim pilnīgi vai daļēji aizklāja komponentu)
  • Katram komponentam ir savs Graphics objekts
  • Klase Graphics implementē daudzas zīmēšanas metodes

Kā zīmēt ar Graphics objektu

Dažādas figūras

Jautājumi paškontrolei

  • Raksturot AWT pakotni un GUI komponentus tajā
  • Definēt jēdzienus: container (container), komponents (component) un izvietojuma pārvaldnieks (layout manager), un aprakstīt, kā tie mijiedarbojas, veidojot GUI saskarni
  • Prast lietot izvietojuma pārvaldniekus
  • Prast lietot FlowLayout, BorderLayout un GridLayout pārvaldniekus, lai iegūtu vēlamo izvietojumu, un saprast, kas ar to notiek staipīšanas rezultātā
  • Prast pievienot konteineram komponentus
  • Prast lietot Frame un Panel konteinerus atbilstoši situācijai
  • Aprakstīt, kā darbojas saliktie izvietojumi konteineros, kuri ir ievietoti (nested) viens otrā.
  • Javas tehnoloģiju programmā prast atpazīt sekojošo:
    • Konteinerus
    • Ar tiem saistītos izvietojuma pārvaldniekus
    • Visu komponentu izvietojuma hierarhiju

Diskusiju tēma: Šajā nodaļā izskaidrots, kā veidot dažādus GUI elementus, un kā tos novietot uz aplikācijas ekrāna. Kas jādara, lai GUI saskarnei būtu laba lietojamība (usability)? Sal. MIT lekcijas par lietojamību - 1.lekcija un 2.lekcija