From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+Die Menüeinträge sind die elementaren Bestandteile
+eines Menüs. Sie besitzen einen Text, mit dem sie dem Anwender
+die dahinterstehende Funktion anzeigen. Wenn der zugehörige Menüpunkt
+aufgerufen wird, sendet das Programm eine Nachricht an das zugehörige
+Fenster, die dann zum Aufruf der entsprechenden Methode führt.
+
+
+Menüeinträge werden in Java mit der Klasse MenuItem
+erzeugt. Ihr Konstruktor erwartet als Parameter einen String,
+der den Namen des Menüeintrags angibt:
+
+
+Auch nach der Konstruktion eines Menüeintrags ist ein Zugriff
+auf seinen Namen möglich. Mit der Methode getLabel
+kann der Name des Menüeintrags abgefragt und mit setLabel
+sogar verändert werden:
+
+
+Neben einem Namen besitzt ein Menüeintrag eine interne Zustandsvariable,
+die anzeigt, ob er aktiv ist oder nicht. Nur ein aktiver Eintrag
+kann vom Anwender ausgewählt werden und so eine Nachricht auslösen.
+Ein inaktiver Eintrag dagegen wird im Menü grau dargestellt,
+kann vom Anwender nicht mehr ausgewählt werden und daher auch
+keine Nachricht mehr auslösen.
+
+
+Nach dem Aufruf des Konstruktors ist ein Menüeintrag zunächst
+aktiviert. Er kann durch Aufruf von setEnabled(false)
+deaktiviert und mit setEnabled(true)
+aktiviert werden. Durch Aufruf von isEnabled
+kann der aktuelle Zustand abgefragt werden:
+
+
+Neben der Klasse MenuItem
+gibt es mit der Klasse CheckboxMenuItem
+eine zweite Klasse zum Erzeugen von Menüeinträgen. CheckboxMenuItem
+ist aus MenuItem
+abgeleitet und bietet als zusätzliches Feature eine interne Zustandsvariable,
+die zwischen true
+und false
+umgeschaltet werden kann. Die visuelle Darstellung der Zustandsvariablen
+erfolgt durch Anfügen oder Entfernen eines Häkchens neben
+dem Menüeintrag. Der Nutzen der Klasse CheckboxMenuItem
+besteht darin, dass eine logische Programmvariable durch Auswählen
+des Menüpunkts abwechselnd an- und ausgeschaltet werden kann.
+
+
+Die Instanzierung eines CheckboxMenuItem
+erfolgt wie bei einem MenuItem.
+Zusätzlich stehen die beiden Methoden setState
+und getState
+zum Setzen und Abfragen des Zustands zur Verfügung:
+
+
+Das folgende Programm stellt alle bisher erwähnten Eigenschaften
+in einem Beispiel dar. Es leitet dazu die Klasse MainMenu1
+aus MenuBar
+ab und erzeugt im Konstruktor die Menüs und Menüeinträge.
+Gegenüber der einfachen Instanzierung von MenuBar
+bietet die Ableitung den Vorteil, dass die neue Klasse Methoden zur
+Verfügung stellen kann, die zum Zugriff auf Menüs oder Menüeinträge
+verwendet werden können.
+
+
+
+
+
+
+ Titel
+ Inhalt
+ Suchen
+ Index
+ DOC
+ Handbuch der Java-Programmierung, 5. Auflage
+
+ <<
+ <
+ >
+ >>
+ API
+ Kapitel 30 - Menüs
+
+
+
+
+
+30.4 Menüeinträge
+
+
+
+
+
+
+
+
+30.4.1 Einfache Menüeinträge
+
+
+
+
+
+
+
+
+
+
+public MenuItem(String label)
+
+
+
+java.awt.MenuItem
+
+
+
+
+
+
+
+
+
+public String getLabel()
+
+public void setLabel(String label)
+
+
+
+java.awt.MenuItem
+
+
+
+
+
+
+
+
+
+
+
+
+public void setEnabled(boolean b)
+
+public boolean isEnabled()
+
+
+
+java.awt.MenuItem
+30.4.2 CheckboxMenuItem
+
+
+
+
+
+
+
+
+
+
+public void setState(boolean state)
+
+public boolean getState()
+
+
+
+java.awt.CheckboxMenuItem
+
+
+
+Listing 30.1: Erzeugen von Menüs
+
+
+
+
+
+001 /* Listing3001.java */
+002
+003 import java.awt.*;
+004 import java.awt.event.*;
+005
+006 class MainMenu1
+007 extends MenuBar
+008 {
+009 private MenuItem miRueck;
+010 private CheckboxMenuItem miFarbe;
+011
+012 public MainMenu1()
+013 {
+014 Menu m;
+015
+016 //Datei
+017 m = new Menu("Datei");
+018 m.add(new MenuItem("Neu"));
+019 m.add(new MenuItem("Laden"));
+020 m.add(new MenuItem("Speichern"));
+021 m.addSeparator();
+022 m.add(new MenuItem("Beenden"));
+023 add(m);
+024 //Bearbeiten
+025 m = new Menu("Bearbeiten");
+026 m.add((miRueck = new MenuItem("Rueckgaengig")));
+027 m.addSeparator();
+028 m.add(new MenuItem("Ausschneiden"));
+029 m.add(new MenuItem("Kopieren"));
+030 m.add(new MenuItem("Einfuegen"));
+031 m.add(new MenuItem("Loeschen"));
+032 add(m);
+033 //Optionen
+034 m = new Menu("Optionen");
+035 m.add(new MenuItem("Einstellungen"));
+036 m.add((miFarbe = new CheckboxMenuItem("Farbe")));
+037 add(m);
+038 //Rueckgaengig deaktivieren
+039 enableRueckgaengig(false);
+040 //Farbe anschalten
+041 setFarbe(true);
+042 }
+043
+044 public void enableRueckgaengig(boolean ena)
+045 {
+046 if (ena) {
+047 miRueck.setEnabled(true);
+048 } else {
+049 miRueck.setEnabled(false);
+050 }
+051 }
+052
+053 public void setFarbe(boolean on)
+054 {
+055 miFarbe.setState(on);
+056 }
+057 }
+058
+059 public class Listing3001
+060 extends Frame
+061 {
+062 public static void main(String[] args)
+063 {
+064 Listing3001 wnd = new Listing3001();
+065 }
+066
+067 public Listing3001()
+068 {
+069 super("Menüs");
+070 setLocation(100,100);
+071 setSize(400,300);
+072 setMenuBar(new MainMenu1());
+073 setVisible(true);
+074 addWindowListener(new WindowClosingAdapter(true));
+075 }
+076 }
+
+
+Listing3001.java
+
+Das Programm erzeugt eine Menüzeile mit den drei Einträgen +»Datei«, »Bearbeiten« und »Optionen«, +die in Abbildung 30.1 dargestellt +werden: +
+ +
+Abbildung 30.1: Erzeugen von Menüs
+ + + + ++
![]() |
+![]() |
+
+
+ +In den meisten Programmen lassen sich Menüs nicht nur mit der +Maus bedienen, sondern über Beschleunigertasten auch mit +der Tastatur. Im JDK 1.0 konnten Beschleunigertasten unter Windows +95 ganz einfach dadurch eingefügt werden, dass an beliebiger +Stelle im Menütext das Zeichen »&« eingefügt +und so die nachfolgende Taste als Beschleuniger definiert wurde. Dies +war natürlich nicht portabel, funktionierte nur unter Windows +und wurde folglich als Bug angesehen und eliminiert. |
+
+
|
+![]() |
+
+Das JDK 1.1 implementiert nun ein eigenes Beschleunigerkonzept, das +über Plattformgrenzen hinweg funktioniert. Dazu wurde die Klasse +MenuShortcut +eingeführt, mit deren Hilfe Beschleunigertasten definiert und +an einzelne Menüeinträge angehängt werden können. +Eine Beschleunigertaste ist dabei immer ein einzelnes Zeichen der +Tastatur, das zusammen mit der systemspezifischen Umschalttaste +für Beschleuniger ([STRG] +unter Windows und Motif, [COMMAND] +unter MAC-OS) gedrückt werden muss, um den Menüeintrag aufzurufen. + +
+Um einen Beschleuniger zu definieren, muss zunächst eine Instanz +der Klasse MenuShortcut +erzeugt werden: +
+
+
++public MenuShortcut(int key) + +public MenuShortcut(int key, boolean useShiftModifier) ++ + |
++java.awt.MenuShortcut | +
+Der erste Konstruktor erwartet den virtuellen Tastencode der gewünschten +Beschleunigertaste (siehe Kapitel 29). +Für einfache alphanumerische Zeichen kann hier auch das Zeichen +selbst übergeben werden. Die Übergabe einer Funktionstaste +ist leider nicht ohne weiteres möglich, denn deren virtuelle +Tastencodes überschneiden sich mit den ASCII-Codes der Kleinbuchstaben. +Funktionstasten können daher nur dann als Beschleuniger verwendet +werden, wenn ihre virtuellen Tastencodes die Umwandlung in Großbuchstaben +unverändert überstehen (z.B. VK_DELETE). +Der zweite Konstruktor erlaubt zusätzlich die Übergabe eines +booleschen Parameters useShiftModifier, +der dafür sorgt, dass der Beschleuniger nur dann greift, wenn +neben der systemspezifischen Umschalttaste für Beschleuniger +zusätzlich die Taste [UMSCHALT] +gedrückt wird. + +
+Um einen Beschleuniger an einen Menüpunkt zu binden, ist das +MenuShortcut-Objekt +als zweites Argument an den Konstruktor von MenuItem +zu übergeben: +
+
+
++public MenuItem(String label, MenuShortcut s) ++ + |
++java.awt.MenuItem | +
+Alternativ kann auch die Methode setShortCut +aufgerufen werden: +
+
+
++public void setShortcut(MenuShortcut s) ++ + |
++java.awt.MenuItem | +
+Durch Aufruf von deleteShortCut +kann der einem Menüeintrag zugeordnete Beschleuniger gelöscht +werden: +
+
+
++public void deleteShortcut() ++ + |
++java.awt.MenuItem | +
+Aufgrund eines Bugs im AWT (der auch im JDK 1.2 noch enthalten war) +muss nach der Definition eines Beschleunigers zusätzlich die +Methode setActionCommand +aufgerufen werden, um den String, +der beim Auslösen des Beschleunigers an den ActionListener gesendet +werden soll, festzulegen: +
+
+
++public void setActionCommand(String command) ++ + |
++java.awt.MenuItem | +
+Ohne diesen Aufruf würde ein null-Objekt +gesendet werden. Eine beispielhafte Aufrufsequenz zur Erzeugung eines +Menüeintrags mit Beschleuniger sieht damit so aus: + + +
+
+
+
+001 Menu m;
+002 MenuItem mi;
+003 MenuShortcut ms;
+004
+005 //Datei
+006 m = new Menu("Datei");
+007
+008 ms = new MenuShortcut(KeyEvent.VK_N);
+009 mi = new MenuItem("Neu",ms);
+010 mi.setActionCommand("Neu");
+011 mi.addActionListener(listener);
+012 m.add(mi);
+
+ |
+
+Hier wird der Menüeintrag »Neu« wie im vorigen Beispiel +generiert und mit der Beschleunigertaste [STRG]+[N] +ausgestattet. + +
+Das folgende Beispiel zeigt eine Menüleiste mit zwei Menüs +»Datei« und »Bearbeiten«, bei denen alle Menüeinträge +mit Beschleunigern ausgestattet wurden: + + +
+
+
+
+001 /* MainMenu2.inc */
+002
+003 class MainMenu2
+004 extends MenuBar
+005 {
+006 public MainMenu2()
+007 {
+008 Menu m;
+009 MenuItem mi;
+010 MenuShortcut ms;
+011
+012 //Datei
+013 m = new Menu("Datei");
+014
+015 ms = new MenuShortcut(KeyEvent.VK_N);
+016 mi = new MenuItem("Neu",ms);
+017 mi.setActionCommand("Neu");
+018 m.add(mi);
+019
+020 ms = new MenuShortcut(KeyEvent.VK_L);
+021 mi = new MenuItem("Laden",ms);
+022 mi.setActionCommand("Laden");
+023 m.add(mi);
+024
+025 ms = new MenuShortcut(KeyEvent.VK_S);
+026 mi = new MenuItem("Speichern",ms);
+027 mi.setActionCommand("Speichern");
+028 m.add(mi);
+029
+030 ms = new MenuShortcut(KeyEvent.VK_E);
+031 mi = new MenuItem("Beenden",ms);
+032 mi.setActionCommand("Beenden");
+033 m.add(mi);
+034 add(m);
+035
+036 //Bearbeiten
+037 m = new Menu("Bearbeiten");
+038
+039 ms = new MenuShortcut(KeyEvent.VK_X);
+040 mi = new MenuItem("Ausschneiden",ms);
+041 mi.setActionCommand("Ausschneiden");
+042 m.add(mi);
+043
+044 ms = new MenuShortcut(KeyEvent.VK_C);
+045 mi = new MenuItem("Kopieren",ms);
+046 mi.setActionCommand("Kopieren");
+047 m.add(mi);
+048
+049 ms = new MenuShortcut(KeyEvent.VK_V);
+050 mi = new MenuItem("Einfügen",ms);
+051 mi.setActionCommand("Einfügen");
+052 m.add(mi);
+053 add(m);
+054 }
+055 }
+
+ |
++MainMenu2.inc | +
+Wir werden später eine Methode vorstellen, die den Aufwand für +das Erzeugen und Einfügen von Beschleunigern vermindert. + +
+Die im JDK 1.1 eingeführten Beschleuniger haben Vor- und Nachteile. +Ihr Vorteil ist, dass sie einfach zu erzeugen sind und über Plattformgrenzen +hinweg funktionieren. Die Nachteile sind allerdings ihre eingeschränkte +Funktionalität und die Unterschiede im Look-and-Feel gegenüber +den speziellen Beschleunigern des jeweiligen Betriebssystems. So gibt +es unter Windows beispielsweise keine Beschleuniger mehr in der Menüleiste +([ALT]+Buchstabe), und auch +Menüeinträge können nicht mehr mit [ALT]+Tastenkürzel +aufgerufen werden (sie zeigen auch keinen unterstrichenen Buchstaben +mehr an). + +
+Außerdem wird eine Beschleunigertaste zwangsweise an die systemspezifische +Umschalttaste gebunden. Es ist damit nicht möglich, einfache +Tasten wie [EINFG] oder [ENTF] +als Beschleuniger zu definieren. Des weiteren lassen sich wegen der +unglücklichen Umwandlung des virtuellen Tastencodes in Großbuchstaben +viele Funktionstasten nicht als Beschleuniger verwenden. Dies sind +sicherlich gravierende Restriktionen, die die Bedienung nicht unerheblich +einschränken. Es bleibt zu hoffen, dass die nächste Version +des AWT hier Verbesserungen bringt und eine umfassendere Menge der +plattformspezifischen Features portabel zur Verfügung stellt. + + + + +
+Menüs lassen sich auf einfache Art und Weise schachteln. Dazu +ist beim Aufruf der add-Methode +anstelle einer Instanz der Klasse MenuItem +ein Objekt der Klasse Menu +zu übergeben, das das gewünschte Untermenü repräsentiert. +Das folgende Beispiel erweitert das Menü »Optionen« +der Klasse MainMenu1 um den +Menüeintrag »Schriftart«, der auf ein Untermenü +mit den verfügbaren Schriftarten verzweigt (der Code zur Erzeugung +des Untermenüs steht in den Zeilen 034 +bis 041): + + +
+
+
+
+001 /* MainMenu3.inc */
+002
+003 class MainMenu3
+004 extends MenuBar
+005 {
+006 private MenuItem miRueck;
+007 private CheckboxMenuItem miFarbe;
+008
+009 public MainMenu3()
+010 {
+011 Menu m;
+012
+013 //Datei
+014 m = new Menu("Datei");
+015 m.add(new MenuItem("Neu"));
+016 m.add(new MenuItem("Laden"));
+017 m.add(new MenuItem("Speichern"));
+018 m.addSeparator();
+019 m.add(new MenuItem("Beenden"));
+020 add(m);
+021 //Bearbeiten
+022 m = new Menu("Bearbeiten");
+023 m.add((miRueck = new MenuItem("Rueckgaengig")));
+024 m.addSeparator();
+025 m.add(new MenuItem("Ausschneiden"));
+026 m.add(new MenuItem("Kopieren"));
+027 m.add(new MenuItem("Einfuegen"));
+028 m.add(new MenuItem("Loeschen"));
+029 add(m);
+030 //Optionen
+031 m = new Menu("Optionen");
+032 m.add(new MenuItem("Einstellungen"));
+033
+034 //Untermenü Schriftart
+035 Menu m1 = new Menu("Schriftart");
+036 m1.add(new MenuItem("Arial"));
+037 m1.add(new MenuItem("TimesRoman"));
+038 m1.add(new MenuItem("Courier"));
+039 m1.add(new MenuItem("System"));
+040 m.add(m1);
+041 //Ende Untermenü Schriftart
+042
+043 m.add((miFarbe = new CheckboxMenuItem("Farbe")));
+044 add(m);
+045 //Rueckgaengig deaktivieren
+046 enableRueckgaengig(false);
+047 //Farbe anschalten
+048 setFarbe(true);
+049 }
+050
+051 public void enableRueckgaengig(boolean ena)
+052 {
+053 if (ena) {
+054 miRueck.setEnabled(true);
+055 } else {
+056 miRueck.setEnabled(false);
+057 }
+058 }
+059
+060 public void setFarbe(boolean on)
+061 {
+062 miFarbe.setState(on);
+063 }
+064 }
+
+ |
++MainMenu3.inc | +
+Ein Aufruf des Untermenüs wird folgendermaßen dargestellt: +
+ +
+Abbildung 30.2: Geschachtelte Menüs
+| Titel + | Inhalt + | Suchen + | Index + | DOC + | Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 + |
| << + | < + | > + | >> + | API + | © 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de + |