next up previous contents index
Nächste Seite: Inhalt Aufwärts: Programmieren in Java Vorherige Seite: Ein-/Ausgabe   Inhalt   Index

Unterabschnitte

Grafische Benutzungsschnittstellen

Das Paket java.awt ( abstract windowing toolkit) dient zur Realisierung grafischer Benutzungsschnittstellen:

Das awt-Paket wurde für Java1.1 stark revidiert.



Vor allem: Ersetzen der nicht-objektorientierten Ereignisbehandlung.




Entwicklung einer grafischen Benutzungsschnittstelle erfordert 4 Schritte:







Das Ereignis-Modell des AWT (ab JDK1.1)

Ereignisse werden von Ereignisquellen erzeugt. Ein oder mehrere Listener melden sich an, um über die Ereignisse an einer Quelle informiert zu werden.



Das Modell heißt Delegation :

die Ereignisbehandlung wird an irgendein Objekt delegiert, das das zum Ereignis passende Interface implementiert.

Zur Ereignisbehandlung brauchen wir folgendes

1.
Eine Klasse für die Ereignisbehandlung. Sie muß das Interface für das zugehörige Ereignis implementieren, z.B.:


   public class MyEvtHdl
   implements ActionListener
   { ...

2.
Anmelden eines Listeners bei einer Ereignisquelle, z.B.:


   quitknopf.addActionListener(
                  new MyEvtHdl());

3.
Implementierung der versprochenen Event-Handling-Methoden, z.B.:


   public void actionPerformed(
       ActionEvent e)
   { // irgendwie auf das
     // Ereignis reagieren


Beispiel: Ein piepsender Knopf

Hier ist der ActionListener selbst Besitzer des Knopfes. Das muß natürlich nicht so sein.




import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Beeper 
   extends Applet 
   implements ActionListener 
{ Button button;
  public void init() 
  { setLayout(new BorderLayout());
    button = new Button("Click Me");
    add("Center", button);
    button.addActionListener(this);
  }

  public void actionPerformed(
                  ActionEvent e) 
  { Toolkit.getDefaultToolkit().beep();
  }
}


Oft nutzt man die neuen inneren Klassen für die Eventbehandlung:


public class Beeper1 
   extends Applet 
{ Button button;
  public void init() 
  { setLayout(new BorderLayout());
    button = new Button("Click Me");
    add("Center", button);
    button.addActionListener(
          new BeepAction());
  }

  class BeepAction 
    implements ActionListener 
  { public void actionPerformed(
              ActionEvent e) 
    { Toolkit.getDefaultToolkit().beep();
    }
  }
}


Wenn nur ein Handler-Objekt benötigt wird: anonyme Klassen :


public class Beeper2
   extends Applet 
{ Button button;
  public void init() 
  { setLayout(new BorderLayout());
    button = new Button("Click Me");
    add("Center", button);
    button.addActionListener(
          new ActionListener()
          { public void actionPerformed(
                  ActionEvent e) 
            { Toolkit.getDefaultToolkit().
                      beep();
            }
          }
          );
  }
}


Zum Vergleich: das alte Ereignisbehandlungsmodell

Nicht objektorientiert. Anwender macht Fallunterscheidung über Event-Typen und Event-Ziele:


public class Beeper3
   extends Applet 
{ // JDK 1.0 Event Handling
  Button button;
  public void init() 
  { setLayout(new BorderLayout());
    button = new Button("Click Me");
    add("Center", button);
  }
  public boolean action(Event e,
                        Object arg)
  { if (e.target.equals(button))
      Toolkit.getDefaultToolkit().beep();
    else return super.action(e,arg);
    return true;
  }
}



Adapterklassen

Wenn ein Listener-Interface mehrere Methoden fordert (z.B. MouseListener), man aber nur an einer Art von Event interessiert ist, ist es lästig, alle geforderten Methoden (mit leerem Rumpf) zu implementieren.




Adapterklassen lösen das Problem, indem sie für alle Methoden des Interfaces leere Default-Implementierungen bereitstellen. Man erbt von einer Adapterklasse und überschreibt die benötigte Eventhandling-Methode:





    MyClass extends MouseAdapter
    { ....
      public void mouseClicked(
                     MouseEvent e)
      { ...
      }
    }
    ...
    button.addMouseListener(new MyClass());


Listener und Behandlungsmethoden

Für alle Eventarten mit mehr als einer Behandlungsmethode existiert eine Adapterklasse entsprechenden Namens.



Beispiel: Listener: KeyListener Adapter: KeyAdapter




Listener Interface Methoden
ActionListener actionPerformed
AdjustmentListener adjustmentValueChanged
ComponentListener componentHidden
  componentMoved
  componentResized
  componentShown
ContainerListener componentAdded
  componentRemoved
FocusListener focusGained
  focusLost
ItemListener itemStateChanged
KeyListener keyPressed
  keyReleased
  keyTyped
MouseListener mouseClicked
  mouseEntered
  mouseExited
  mousePressed
  mouseReleased


Listener Interface Methoden
MouseMotionListener mouseDragged
  mouseMoved
TextListener textValueChanged
WindowListener windowActivated
  windowClosed
  windowClosing
  windowDeactivated
  windowDeiconified
  windowIconified
  windowOpened





Die Komponenten im Java AWT

Unterklassen der Klasse Component

\psfig {figure=bilder/komponent.ps}




Diese Oberfläche (Java-Quellcode) enthält die meisten vordefinierten Komponenten des AWT:

\psfig {figure=bilder/guiunix.ps}




Button

Die Klasse Button stellt Schaltflächen mit Aufschrift zur Verfügung. Klicken erzeugt einen ActionEvent.


  Button cancel = new Button("Geh weg");
  this.add(cancel);
  // Event-Handling dafür
  ActionListener buttonlistener = 
     new ActionListener() 
     { public void actionPerformed(
                          ActionEvent e) 
       { // Behandle Ereignis 
         ...
       }
     };
 cancel.addActionListener(buttonlistener);





Canvas

Freie rechteckige Fläche zum Zeichnen. Wird auch zur Erzeugung eigener Grafik-Komponenten verwendet. Zur Darstellung des Canvas:: paint-Methode überschreiben.

Checkbox

Grafische Schaltkomponente, die entweder ein- oder ausgeschaltet sein kann ( true oder false). Klicken schaltet zwischen den beiden Zuständen hin und her.


     add(new Checkbox("one", true));
     add(new Checkbox("two"));
     add(new Checkbox("three"));




Radioknöpfe (nur einer ist angeschaltet), können mit der Klasse CheckboxGroup realisiert werden:


     CheckboxGroup ckg = new CheckboxGroup();
     add(new Checkbox("one", ckg, true));
     add(new Checkbox("two", ckg));
     add(new Checkbox("three", ckg));





Choice

Die Klasse Choice realisiert ein Pop-Up-Menu zur Auswahl. Die aktuell gültige Auswahl wird als Titel des Menüs angezeigt.


   Choice ColorChooser = new Choice();
   ColorChooser.add("while");
   ColorChooser.add("If-then-else");
   ColorChooser.add("switch");





Label

Komponente, mit der man Read-Only-Text in einem Container plazieren kann.


     add(new Label("Hi There!")); 
     add(new Label("Another Label"));





List

Listen von Texteinträgen, aus denen ein oder mehrere ausgewählt werden können.


  List lst = new List(3, false);
  lst.add("Apfel");
  lst.add("Birne");
  lst.add("Kirsche");
  lst.add("Banane");
  container.add(lst);

Der zweite Parameter des Konstruktors steuert, ob mehrere Einträge auswählbar sind.

TextAreas und TextFields

Eine TextArea-Komponente ist ein mehrzeiliger Bereich in dem Text angezeigt und/oder eingegeben werden kann.

Eine TextField-Komponente ist ein einzeiliger Bereich zur Texteingabe.



Beispiel:




// Import-Klauseln gelöscht
public class TextDemo 
extends Applet 
implements ActionListener 
{ TextField zeile;
  TextArea feld;
  public void init() 
  { zeile = new TextField(20);
    feld = new TextArea(5, 20);
    feld.setEditable(false);
    add(zeile);
    add(feld);
    zeile.addActionListener(this);
  }
  public void actionPerformed(
                 ActionEvent evt) 
  { feld.append(zeile.getText()
                + "\n");
    zeile.selectAll();
  }
}


\psfig {figure=bilder/textdemo.ps}






Die Container im Java AWT

Container sind Grafikkomponenten, die andere Komponenten aufnehmen können.

Zugefügte Komponenten (Methode add()), werden in einer Liste gespeichert und von einem Layout Manager angeordnet.




Panel

Einfachste Container-Klasse. Ein Bereich, in dem die Applikation andere Komponenten anordnen kann.




ScrollPane

Container-Klasse, die horizontales und vertikales Scrollen für eine enthaltene Komponente zur Verfügung stellt.




Window

Top-Level-Fenster ohne Rahmen oder Menu. Kann zum Beispiel zur Implementierung von Pop-Up-Menus verwendet werden.

Solange es offen ist, blockiert es die Eingabe in andere Fenster.




Dialog und FileDialog

Unterklasse von Window zur Gestaltung von Benutzer-Dialogen bzw. Dateiauswahl.

Dialoge hängen von anderen Fenstern ab, sie werden z.B. zerstört wenn das Grundfenster zerstört wird.




Frame

Top-Level-Fenster mit Titel und Rahmen. Kann Menüs haben. Jede Applikation braucht mindestens einen Frame.

Aus dem Beispiel von Seite [*]


public class AllComponents 
  extends Frame 
  implements ActionListener 
{ public AllComponents(String title) 
  { super(title);
    // Reaktion auf Fensterschließen
    this.addWindowListener(
          new WindowAdapter() 
          { public void windowClosing(
                          WindowEvent e) 
            { System.exit(0); 
            }
          }
          );
   public static void main(String[] args) 
   { Frame f = new AllComponents(
                      "Erste AWT Demo");
     f.pack();
     f.show();
   }
}






Menüs

Menüs werden aus den Komponenten

konstruiert:





  // Menü-Leiste
  mb = new MenuBar();
  setMenuBar(mb);
            
  // Ein Menü
  m1 = new Menu("Datei");
  mb.add(m1);

  // Menüeinträge
  schl = new MenuItem("Schließen");
  m1.add(schl);

  // usw.





Menü-Aktionen lösen Action-Events aus:


  // Eintrag mit Shortcut 
  MenuItem open = 
     new MenuItem("Öffne", 
                  new MenuShortcut(
                        KeyEvent.VK_O));
  open.setActionCommand("open");
  open.addActionListener(this);

  ....
  public void actionPerformed(
                        ActionEvent e) 
  { String command = e.getActionCommand();
    if (command.equals("open")) 
    { ...




Nur Container, die die MenuContainer-Schnittstelle implementieren können Menüs haben (z.B. ein Frame).





Layout Manager

Jeder Container hat einen Standard Layout Manager, der dafür zuständig ist, die enthaltenen Komponenten anzuordnen. Dieser voreingestellte Layout Manager kann durch einen anderen ersetzt werden.

Das AWT bietet:




Beispiel

Zuordnung eines Layout-Managers zu einem Container:


   meinContainer.setLayout(new CardLayout());





BorderLayout

Anordnung der Komponenten an den vier Rändern und in der Mitte.

\psfig {figure=bilder/bolay.ps}


import java.awt.*;
     import java.applet.Applet;
     public class ButtonDir extends Applet {
       public void init() {
         setLayout(new BorderLayout());
         add("North",  new Button("North"));
         add("South",  new Button("South"));
         add("East",   new Button("East"));
         add("West",   new Button("West"));
         add("Center", new Button("Center"));
       }
     }





CardLayout

Überlagerung der Komponenten.

\psfig {figure=bilder/calay.ps}


  cards = new Panel();
  cards.setLayout(new CardLayout());
  ...// Erzeuge Panel p1 mit Knöpfen
  ...// Erzeuge Panel p1 mit Textfeld
  cards.add("Panel with Buttons", p1);
  cards.add("Panel with TextField", p2);





Die Strings dienen zur Identifikation der Karten. Das Umschalten zwischen sich verdeckenden Karten muß man ausprogrammieren, z.B.:


  (CardLayout)cards.getLayout()).
       show(cards,"Panel with TextField");




FlowLayout

Komponenten der Reihe nach angeordnet.

\psfig {figure=bilder/flolay.ps}


  setLayout(new FlowLayout());
  setFont(new Font("Helvetica", 
                    Font.PLAIN, 14));
  add(new Button("Button 1"));
  add(new Button("2"));
  add(new Button("Button 3"));
  add(new Button("Long-Named Button 4"));
  add(new Button("Button 5"));

Durch Konstruktorargument kann angegeben werden, ob die Komponenten innerhalb einer Zeile zentriert (Default), rechts- oder linksbündig angeordnet werden.




GridLayout

Komponenten in einem Matrix-Raster.

\psfig {figure=bilder/grilay.ps}


  // Beliebigviele Reihen, 2 Spalten
  setLayout(new GridLayout(0,2));
  add(new Button("Button 1"));
  add(new Button("2"));
  add(new Button("Button 3"));
  add(new Button("Long-Named Button 4"));
  add(new Button("Button 5"));





GridBagLayout

Komponenten in einem flexiblen Matrix-Raster. Mächtigster aber auch kompliziertester Layout Manager:

\psfig {figure=bilder/gribalay.ps}

Das Layout wird durch GridBagConstraints spezifiziert:


  GridBagLayout gridbag = new GridBagLayout();
  GridBagConstraints c = new GridBagConstraints();
  setLayout(gridbag);

 //...Nach Setzen der Attribute von c:
 add(irgendeineKomponente, c);


Die wichtigsten Attribute von GridBagConstraints sind:



Die Knöpfe 8 und 9 der Oberfläche (Seite [*]) wurden z.B. wie folgt erzeugt:


  GridBagLayout griba = new GridBagLayout();
  GridBagConstraints c = 
                 new GridBagConstraints();
  setLayout(griba);
           
  c.fill = GridBagConstraints.BOTH;

  c.gridwidth = 1;
  c.gridheight = 2;
  c.weighty = 1.0;
  add(new Button("Button8"), c);

  c.weighty = 0.0; 
  c.gridwidth = 
  GridBagConstraints.REMAINDER; 
  c.gridheight = 1;

  add(new Button("Button9"), c);



next up previous contents index
Nächste Seite: Inhalt Aufwärts: Programmieren in Java Vorherige Seite: Ein-/Ausgabe   Inhalt   Index
Peter Pfahler, 1997