In dieser Übung werden wir den bisher entwickelten Audioplayer
weiter verbessern.
Aufgabe 1: Programmzustände hinzufügen
Grafische Komponenten können je nach Programmzustand aktiviert und
deaktiviert werden. Je nachdem, ob die Benutzung einer gegebenen
grafischen Komponente in diesem Programmzustand sinnvoll ist oder
nicht. In unserer bisherigen Lösung können die Radio Buttons benutzt
werden, unabhängig davon, ob das Radio eingeschaltet ist oder
nicht. Dies ist sicherlich nicht sinnvoll. Ändern Sie das Radio so
ab, dass die Radio Buttons erst in dem Moment aktiviert werden, wenn
das Radio eingeschaltet wurde. Deaktivierte Komponenten erscheinen
ausgegraut und reagieren nicht auf Mausklicks:

Abb. 1: Deaktivierte Radio
Buttons bei ausgeschaltetem Audio Player
Erst nach dem Aktivieren erscheinen Sie wieder
in der normalen, kontraststarken Darstellung:

Abb. 2: Aktivierte Radio
Buttons bei eingeschaltetem Audio Player
Aufgabe 2: GUI erweitern
Unser Audioplayer hat noch einen weiteren Nachteil: Er bietet bisher nur
Platz für drei Sound Files (warum?). Glücklicherweise stellt dies
nicht wirklich ein Problem dar. Container sind auch Komponenten,
da die Container-Klassen Unterklassen der Klasse
Components sind. Aus diesem Grunde ist es möglich,
Container wie Komponenten zu benutzen und in andere Container zu
legen, um so Platz für weitere
Komponenten zu schaffen. Man bedient sich dabei eines speziellen
Containers: des JPanel. Das JPanel wird
einfach in einen freien Slot eines anderen Containers gelegt und ein
Layoutmanager definiert. Entsprechend der Layouttaktik des gewählten
Layoutmanagers werden dann die neu hinzugefügten Komponenten im
Panel angeordnet. Unter diesen Komponenten können sich natürlich wieder
JPanels befinden, sodass sich eine Containerhierarchie
aufbauen und beliebig viele Komponenten in der GUI unterbringen sowie
in der gewünschten Form anordnen lassen.
Wie jedes andere Objekt, so wird auch ein neues JPanel als
Klasseninstanz erzeugt, wobei auch sofort ein Layoutmanager
definiert werden kann:
JPanel myPanel = new JPanel(new GridLayout(1,5));
Wird kein Layoutmanager gewählt, so wird unter Java-Swing per
Voreinstellung Border Layout gewählt.
Implementieren Sie unter Benutzung eines JPanel
die unten angegebene GUI für fünf Sound Files:

Abb. 3: Fünf Radio
Buttons in eigenem Panel
Legen Sie zu diesem Zweck das Panel in einen freien Slot Ihres
JFrames, z. B. so:
cp.add(myPanel, BorderLayout.CENTER);
und die fünf Radio Buttons mit add() in das
Panel.
Dabei steht cp für das Content Panel des JFrames.
Aufgabe 3: Ikonen hinzufügen
Als nächsten Schritt werden wir die GUI des Internetradios um Ikonen
erweitern. Die in den folgenden Abbildungen verwendeten Ikonen
können Sie unter diesem Link
herunterladen. Legen Sie in dem Verzeichnis des Sketches zu Ihrer Anwendung
ein neues Verzeichnis mit dem Namen data an und entpacken Sie
die Bilddateien aus dem Archiv in dieses Verzeichnis, sodass sich am Ende in dem
Verzeichnis data ein Verzeichnis icons befindet,
indem wiederum die PNG-Dateien der Icons liegen.
Die ZIP-Datei enthält fünf verschiedene Ikonen für die folgenden
Zustände:
- Radio Buttons (Dateiname chXX.png: disabled, roll over, pressed, deselected, selected
- Checkbox: deselected, pressed, roll over jeweils für den ON- und OFF-Fall
Weisen Sie zunächst den Radio Buttons Ikonen zu, sodass folgende
Zustände berücksichtigt werden:

Abb. 4: Audioplayer im
ausgeschaltetem Zustand (Datei: "chXdisabled.png")

Abb. 5: Audioplayer im
eingeschaltetem Zustand (Datei: "chX.png")

Abb. 6: Roll-over-Effekt: Maus über
dem Radio Button (Datei: "chXRoll.png")

Abb. 7: Button-pressed-Effekt
(Datei: "chXpressed.png")

Abb. 8: Radio-Button selektiert
(Datei: "chXsel.png")
Sobald eine relativ große Anzahl von Ikonen in einem Programm
eingesetzt wird, ist es sinnvoll, diese in Feldern zu
verwalten. Legen Sie daher unterhalb des Klassenkopfes des Applets
jeweils ein Feld für die Ikone des
nicht selektierten Zustandes, des selektierten Zustandes usw. an. Hier
ein Beispiel für den nicht selektierten Zustand:
class Audioplayer extends JFrame {
.
.
.
Icon [] deselectedIcon = new Icon[5];
.
.
.
Sobald Sie für alle in Frage kommenden Zustände ein Feld definiert
haben, können Sie die Felder im Konstruktor der Anwendung
mit den entsprechenden Ikonen füllen:
public Audioplayer() {
.
.
String str = dataPath("");
deselectedIcon[0] = new ImageIcon(str + "/icons/ch1.png" );
.
.
.
Die Methode dataPath() liefert in diesem Zusammenhang den
absoluten Pfad zum data-Verzeichnis Ihres Sketches.
Weisen Sie schließlich noch dem Einschaltknopf seine Ikonen zu.
Hier ist das Zuweisen etwas aufwendiger, weil der Einschaltknopf seine
Ikonen-Sätze abhängig vom Einschaltzustand erhält. Jeder der beiden
Zustände hat also einen eigenen Satz von Ikonen. Entsprechend müssen diese
in dem Ereignisbehandler, der der Check Box des Einschaltknopfs zugewiesen wurde,
zugewiesen und dabei der Zustand der Check Box berücksichtigt werden. Zu beachten
ist ebenfalls, dass eine angekreuzte Check Box keinen Roll-Over-Effekt hat.
Für diesen Zustand braucht also keine Ikone zugewiesen zu werden.
Insgesamt sieht ihr Audioplayer am Ende für die beiden Schaltzustände so aus:

Abb. 9: Audioplayer ausgeschaltet: Einschaltknopf nicht selektiert
(Datei: "off.png")

Abb. 10: Audioplayer ausgeschaltet: Maus über Einschaltknopf
(Datei: "offroll.png")

Abb. 11: Audioplayer eingeschaltet
(Datei: "on.png")