Programowanie komputerów - język JAVA

Ćwiczenie: |  1  |  1b  |  2  |  3  |  4  |  5  |  6  |  home  |

Ćwiczenie nr 2
Pakiet AWT w aplikacjach Javy

Cel ćwiczenia
Celem ćwiczenia jest poznanie podstawowych obiektów pakietu AWT, zasad konstruowania aplikacji wykorzystujących AWT, obsługi zdarzeń generowanych przez obiekty kontrolne.


Podstawy aplikacji wykorzystujących AWT
W tej części utworzona zostanie przykładowa aplikacja wykonująca dodawanie dwóch liczb typu double. Okno główne aplikacji:



Podczas konstruowania aplikacji wykorzystującej AWT powinniśmy zadbać o poprawną definicję następujących elementów składowych aplikacji:

  • klasa główna aplikacji (w tym obsługę zdarzeń z okna głównego),
  • obiekty kontrolne (komponenty) aplikacji,
  • rozkład komponentów (Layout),
  • obsługa zdarzeń z obiektów kontrolnych.

    Podstawowa klasa aplikacji wykorzystującej bibliotekę AWT może mieć postać jak na przykładzie 1.

    Przykład 1
    import java.awt.*;
    import java.awt.event.*;
    
    public class AppAWT extends Frame
    {
       public AppAWT()
       {
         this.addWindowListener(new WindowAdapter(){
           public void windowClosing(WindowEvent e){
           dispose();
           System.exit(0);
           }});
        }
    }
            
    public static void main(String args[])
    {
      System.out.println("Starting App");
      AppAWT f = new AppAWT();
      f.setSize(100,100);
      f.show();
    }
    Klasa AppAWT dziedziczy po klasie Frame (ramka). Dzięki temu będzie możliwa poprawna obsługa zdarzeń przychodzących od okna aplikacji. Konstruktor klasy AppAWT() wywołuje metodę addWindowListener, która definiuje obiekt (WindowAdapter) odbierający zdarzenie windowClosing (zamknięcie okna) przychodzące z głównego okna aplikacji. Bez tej definicji niemożliwe byłoby poprawne zamknięcie okna po uruchomieniu aplikacji. Obsługa zdarzeń zostanie omówiona w dalszej części ćwiczenia. Na tym etapie przyjmijmy tak zdefiniowaną klasę jako wzorzec od którego rozpoczynamy tworzenie aplikacji.

    Głownym zadaniem metody main jest utworzenie obiektu (instancji) klasy AppAWT, ustawienie rozmiarów okna aplikacji (setSize) i uaktywnienie okna metodą show (pokaż okno). Na tych działaniach kończy się rola metody main i dalsze działanie aplikacji zależy już od definicji klasy AppAWT.

    Kolejnym etapem będzie zdefiniowanie obiektów kontrolnych tworzonej aplikacji w konstruktorze klasy. Definicja obiektów:

      field1 = new TextField(5); // pierwszy argument
      add(field1);
     
      add(new Label("+"));       // tekst "+"
             
      field2 = new TextField(5); // drugi argument
      add(field2);
             
      add(new Label("="));       // tekst "="
             
      field3 = new TextField(5); // wynik dzialania
      add(field3);
    
      dodaj = new Button("Dodaj"); // przycisk "Dodaj"
      add(dodaj);
    
    Dla każdego komponentu konieczne jest wykonanie dwóch działań. Zainicjowanie obiektu np. field1 = new TextField(5), oraz dodanie utworzonego obiektu do głównego kontenera aplikacji np. add(field1). W omawianym przykładzie głównym kontenerem jest główne okno aplikacji - klasa AppAWT.

    Ważnym elementem każdej aplikacji jest tzw. rozkład (Layout) zdefiniowany dla każdego kontenera. Jest to element decydujący o ostatecznym wyglądzie interfejsu aplikacji. Konstruktor klasy AppAWT wywołuje metodę setLayout definiującą sposób rozkładu:

      setLayout(new FlowLayout()); 
    
    W przykładzie zastosowano rozkład FlowLayout. W takim rozkładzie dodawane kolejno komponenty będą umieszczane kolejno od lewej do prawej strony z wyśrodkowaniem wewnątrz kontenera. Jest to najprostrzy sposób rozkładu komponentów.

    Kolejnym etapem będzie zdefiniowanie obsługi zdarzeń z obiektów kontrolnych. Aby poprawnie obsłużyć zdarzenie z obiektu należy wykonać trzy działania:

    Jedynym obiektem generującym zdarzenie będzie obiekt dodaj (będzie generowane polecenie "Dodaj" - zgodne z tekstem na przycisku). Zdefiniowana metoda public void actionPerformed(ActionEvent ev) będzie miała postać:

    public void actionPerformed(ActionEvent ev)
    {
     String label = ev.getActionCommand();
     if (label.equals("Dodaj"))
      {
       try 
       {
        double arg1 = Double.parseDouble(field1.getText());
        double arg2 = Double.parseDouble(field2.getText());
        Double d = new Double(arg1+arg2);
        field3.setText(d.toString());
       } 
       catch (NumberFormatException e)
       {
        System.out.println("Blad argumentow!? Wpisz poprawne wartosci!");
       } // koniec obslugi wyjatku
      } // koniec if
    }
    
    Metoda pobiera polecenie do zmiennej label (String label = ev.getActionCommand()) z klasy ActionEvent. Następnie sprawdzana jest zawartość zmiennej label. Jeżeli jest to "Dodaj" wykonywane jest odpowiednie działanie. Pobierane są wartości argumentów (field1 i field2). Tworzona jest zmienna pomocnicza typu Double (klasa Double - obiektowy odpowiednik zmiennej typu double) zawierająca sumę argumentów. Wynik operacji dodawania jest wpisywany do pola tekstowego field3 (setText). Ciąg tych operacji umieszczony został w części try obsługi wyjątku NumberFormatException. Dzięki temu w przypadku błędu argumentów (zła zawartość pół field1, field2) wygenerowany zostanie tekst informacyjny o błędzie (część catch obsługi wyjątku). Obsługa tego wyjątku nie jest konieczna, ale bez tej definicji błąd argumentów spowoduje wygenerowanie domyślnej obsługi wyjątku (cały ciąg informacji) nieczytelnej dla przeciętnego śmiertelnika:-).
    Ostatnim elementem obsługi zdarzenia będzie zdefiniowanie obiektu odbierającego zdarzenie dla obiektu dodaj (przycisk "Dodaj") w konstruktorze klasy:
      dodaj.addActionListener(this);
    
    Pełny kod aplikacji będzie wyglądał następująco:

    Przykład 2
    import java.awt.*;
    import java.awt.event.*;
    
    public class AppAWT extends Frame implements ActionListener {
    
     // obiekty kontrolne aplikacji:
     TextField field1; // pierwszy argument
     TextField field2; // drugi argument
     TextField field3; // wynik
     Button dodaj;
    
    public AppAWT()
     {
      super("Dodawanie liczb double"); // konstruktor klasy macierzystej
      setLayout(new FlowLayout()); 
      setBackground(Color.lightGray);  // zmiana koloru tla
     
      field1 = new TextField(5); // pierwszy argument
      add(field1);
     
      add(new Label("+"));       // tekst "+"
             
      field2 = new TextField(5); // drugi argument
      add(field2);
             
      add(new Label("="));       // tekst "="
             
      field3 = new TextField(5); // wynik dzialania
      add(field3);
    
      dodaj = new Button("Dodaj"); // przycisk "Dodaj"
      dodaj.addActionListener(this);
      add(dodaj);
    
      this.addWindowListener        (new WindowAdapter(){
                    public void windowClosing(WindowEvent e){
                            dispose();
                            System.exit(0);
                    }
            });
     }
    
    public void actionPerformed(ActionEvent ev)
    {
     String label = ev.getActionCommand();
     if (label.equals("Dodaj"))
      {
       try 
       {
        double arg1 = Double.parseDouble(field1.getText());
        double arg2 = Double.parseDouble(field2.getText());
        Double d = new Double(arg1+arg2);
        field3.setText(d.toString());
       } 
       catch (NumberFormatException e)
       {
        System.out.println("Blad argumentow!? Wpisz poprawne wartosci!");
       } // koniec obslugi wyjatku
      } // koniec if
    }
    
    public static void main(String args[])
     {
      System.out.println("Aplikacja Java AWT:");
      System.out.println("Dodawanie dwoch liczb typu double");
      AppAWT f = new AppAWT();
      f.setSize(320,70);
      f.show();
     }
    
    [Pobierz AppAWT.java]


    Przykłady

    Przykład 3
    [Pobierz GraphicsApp.java]



    Prosty przykład wykorzystania metody paint. Każdy komponent pakietu AWT posiada zdefiniowaną metodę paint. Metoda paint jest wywoływana po każdym żądaniu (zdarzeniu) ponownego narysowania komponentu. W tym przykładzie nadpisywana jest metoda paint klasy Frame. Chcąc odświeżyć wygląd obiektu (tutaj AppAWT) należy wywołać metodę repaint() (tutaj niewykorzystana), która wywoła metodę paint. Rysując na obiekcie korzystamy z metod klasy Graphics (zobacz API - Graphics). Klasa ta zawiera cały szereg operacji graficznych.
    Przykład 4
    [Pobierz ControlApp.java]



    Prosty przykład obiektów kontrolnych z pakietu AWT. Program nie wykonuje nic pożytecznego, jedynie prezentuje różne rodzaje obiektów oraz obsługę zdarzeń z tych obiektów.
    Przykład 5
    [Pobierz BorderApp.java]



    Prosty przykład prezentujący zasadę rozkładu BorderLayout (jeden z najczęściej stosowanych rozkładów). Komponent może być umieszczony wewnątrz kontenera (np. Frame lub Panel) w pięciu położeniach: North, South, West, East, Center. Wewnątrz kontenera może być umieszczone pięć i tylko pięć komponentów (nie mogą istnieć komponenty o tym samym położeniu, np. dwa komponenty z położeniem North)
    Zadania do wykonania na zajęciach i "w domu"
    1. Napisać program "Kalkulator":
      - utworzyć interfejs jak na rysunku

      dla klawiatury kalkulatora należy użyć rozkładu GridLayout(4,5,5,5),
      - zdefiniować odpowiednie działanie klawiatury (metoda actionPerformed).
    2. Napisać program "Telefon":
      - utworzyć interfejs jak na rysunku

      dla klawiatury telefonu należy użyć rozkładu GridLayout(5,3,15,6),
      - zdefiniować odpowiednie działanie klawiatury (metoda actionPerformed).
    3. Napisać program "Kalkulator":
      - utworzyć interfejs jak na rysunku

      dla klawiatury kalkulatora należy użyć rozkładu GridLayout(5,5,5,5),
      - zdefiniować odpowiednie działanie klawiatury (metoda actionPerformed).

    Programowanie w języku JAVA - Dariusz Rataj - 2002 (C)
    Kontakt: rataj@tu.koszalin.pl