Eine Mini-CD-Verwaltung

Schauen Sie sich die folgende kleine unvollstaendige CD-Verwaltung an. Anhand der Kommentare und Ihrem bisherigem Wissen muessten Sie inzwischen in der Lage sein die Funktionsweise des Programmes zu verstehen:

CDAnwendung.java, CD.java, CDInputDialog.java, CDTableModel.java

Übung: Speichern Sie alle Klassen in ein Verzeichnis und kompilieren Sie das Programm und fuehren es aus. Sehen Sie sich den Quellcode aller Klassen an und versuchen Sie die Funktionsweise des Programms nachzuvollziehen. Wie sie sehen besteht die Anwendung bis jetzt aus den folgend aufgelisteten Bestandteilen, die schon einen Teil der gesamten Aufgaben des vollstaendigen Programms erledigen koennen:

1) CDAnwendung.java: In der Anwendung werden die Menues definiert und eine Tabelle ins Fenster gezeichnet.

2) CD.java: Die Fachkonzeptklasse CD mit nur einem Attribut.

3) CDInputDialog.java: Das Dialogfenster fuer die Eingabe der CD.

4) CDTableModel.java: Die Definition der Eigenschaften und Faehigkeiten der Tabelle.

Dieser Anwendung fehlen zunaechst folgende Moeglichkeiten:

A: Der Beenden-Menue-Punkt funktioniert nicht.

B: Der Abbrechen-Knopf des Dialogs funktioniert nicht.

Wenn Sie diese Anwendung weiter entwickeln wollen, gehen Sie am besten Schrittweise mit kleinen Schritten vor. Halten Sie Ihr Programm nach jeder Aenderung funktionsfaehig !!

Übung:Fuegen Sie dem Menuepunkt "Beenden" eine Aktion hinzu, die das Programm mit Hilfe der folgenden Methode beendet:
 
void DateiEnde_actionPerformed(ActionEvent e) {
    System.exit(0);
    }
Mit der Methode dispose() (beseitigen) laesst sich ein Fenster loeschen.

Übung:Benutzen Sie die Methode dispose() um den Abbrechen-Knopf des Eingabe-Fensters mit einer Aktion zu verbinden, die das Eingabe-Fenster beseitigt. (Tipp: Machen Sie dies aehnlich wie bei dem "Beenden"-Menue. )

Die Tabelle

Schauen Sie sich nun die Klasse CDTableModel.java an. Hier werden die Eigenschaften der Tabelle festgelegt. In dieser Klasse wird z.B. definiert, wie die Spalten-Ueberschriften der Tabelle lauten und wie die Tabellen-Elemente ermittelt werden.

Übung: Aendern Sie die Anzahl der Zeilen und Spalten der Tabelle. Aendern Sie die Ueberschriften und Inhalte der Tabelle.

Viele CDs

Jetzt wollen wir statt wie bisher nur eine CD eine beliebige Anzahl an CDs verwalten. Schauen Sie Sich dazu zunaechst die Container-Klasse an, die mit hilfe der Klasse Vector die CD-Sammlung beinhaltet:

CDContainer.java

Durch den folgenden Aufruf koennen Sie dem Container eine neue CD hinzufuegen:
CD newAlbum=new CD();
newAlbum.setTitel("Mensch");

CDContainer.getInstance().addCD(newAlbum);
In den ersten beiden Zeilen wird eine CD angelegt und das Attribut geaendert. Danach wird die CD mit CDContainer.getInstance().addCD(newAlbum);in die Sammelung aufgenommen.

Übung: Das Eingabe-Fenster aendert die Attribute einer neu angelegten CD. Fuegen Sie diese CD dem Container hinzu. (Hinweis: Die Variable der neu angelegten CD heisst in der Mini-Verwalung nicht newAlbum.) Fuer Testzwecke ist in der Klasse CDContainer.java die Methode TestAusgabe() programmiert, welche alle Titel der CDs in der Sammliung auf dem Bildschirm ausgibt. Damit sie sehen, dass die CDs der Sammlung hinzugefuegt wurde, lassen Sie sich an der Stelle wo Sie die CD dem Container hinzufuegen die Sammlung mit dem folgenden Befehl ausgeben:
CDContainer.getInstance().TestAusgabe();
Hinweis: Fuegen Sie ihrem Eingabe-Fenster-Objekt eine Moeglichkeit hinzu, die es erlaubt abzufragen, ob der OK-Button gedrueckt worden ist. In Abhaengigkeit davon koennen Sie dann in der Anwendung die CD hinzufuegen oder nicht. Das ist am einfachsten in der Klasse CDInputDialog.java durch hinzufuegen des Attributs okstatus und der Methode getOKstatus(),die den Status zurueckliefert, zu machen:
boolean okstatus = true;

 boolean getOKstatus()
        {
        return okstatus;
        }
Übung: An welcher Stelle sollte man das Attribut okstatus auf false setzen ?

Die Tabelle mit dem Container verbinden

Um die Tabelle mit dem Container zu verbinden, fangen wir damit an, die Tabellenzeilen mit der Anzahl der CDs in dem Container zu verknuepfen. Die Anzahl der CDs erhalten Sie ueber den CD-Container mit:
CDContainer.getInstance().getCDNumber();
Übung: Aendern Sie das Tabellenmodell so, dass die Zeilenzahl der Tabelle dem Wert der bisher gespeicherten CDs entspricht. (Sie sehen, dass die Tabelle aber leider nicht laenger wird, wenn man eine CD hinzugefuegt hat.)

Damit die Tabelle auch aktualisiert wird, muss man der Tabelle mitteilen, das sich etwas an ihr geaendert hat. Dazu dient die Klasse TableModelEvent, die Sie im folgenden speziell an der MiniCD-Verwaltung kennenlernen sollen:

Zunaechst muss die Klasse TableModelEvent in der Anwendung (CDAnwendung.java) importiert werden:
import javax.swing.event.TableModelEvent;
Der Anwendung (CDAnwendung.java) sollte ein weiteres Attribut hinzugefuegt werden:
TableModelEvent mytme;
Wenn Ihre Anwendung startet ( hier in jbInit()) muessen Sie das Tabellen-Modell mit dem Tabellen-Ereignis verknuepfen, damit man der Tabelle eine Aenderung mitteilen kann. Das geht hier mit der Befehlszeile:
mytme = new TableModelEvent(unserTabellenModell);
An der Stelle, wo sich die die Tabelle aendern soll, koennen Sie der Tabelle mitteilen, dass sich die Tabelle geaendert hat. Sie zeichnet sich darauf hin neu. Das wird in unserem Beispiel mit dem folgenden Befehl gemacht:
CDTabelle.tableChanged(mytme);
Übung: Fuegen Sie die das Attribut TableModelEvent mytme; der Anwendung hinzu und teilen Sie Ihrer Tabelle mit (CDTabelle.tableChanged(mytme);), dass sie sich neu zeichnen soll, wenn dem Container eine CD hinzugefuegt wurde.

Übung: Aendern Sie Ihr Tabellenmodell so, dass in der Tabelle die Titel der CDs erscheinen.

Kleine Hilfe: Zunaechst muess in der Methode getValueAt(int row, int col) die CD an der Stelle row aus dem Container geholt werden:
CD theCD = CDContainer.getInstance().getCD(row);
Dann koennen Sie die den Titel der CD bestimmen und zurueckliefern:
return  theCD.getTitel();

Speichern der CDs

Jetzt wollen wir, dass die CDs nicht beim Schliessen des Programmes verloren gehen. Dazu sind schon ein paar Vorbereitungen getroffen worden. Die Klasse CD ist serialisierbar gemacht worden (Serializable). Dadurch ist es moeglich die gesamte Sammlung (alle CDs in dem Vektor der Container-Klasse) mit einem mal abzuspeichern. Die folgenden Methoden speichern() und laden() koennen Sie direkt in Ihrem Programm benutzen, um die Klasse CDContainer um die Moeglichkeit des Speicherns und Ladens zu erweitern. (Fuer Sie ist hier wichtig, dass der Dateiname angegeben werden kann und Sie den gesamten Vektor mit einem mal abspeichern koennen.)

Um die Ein-Ausgabe-Methoden benutzen zu koennen, muessen die Ein-Ausgabe-Klassen importiert werden.
import java.io.*;
void speichern(String filename)
   {
   try {
     //Filenamen setzen
     FileOutputStream fs = new FileOutputStream(filename);
     ObjectOutputStream os = new ObjectOutputStream(fs);
     // Das Objekt lnkCD (den Vektor) auf die Platte schreiben
     os.writeObject(lnkCD);
     os.close();
      }
   catch (IOException exc) {
         System.err.println(exc.toString());
      }
   }
 void laden(String filename)
    {
    try {
        // Filnamen festlegen
        FileInputStream fs = new FileInputStream(filename);
        ObjectInputStream is = new ObjectInputStream(fs);
        // Das eingelesene Objekt ist der Vector, der alle gespeicherten CDs enthaelt.
        lnkCD=(Vector)is.readObject();
        is.close();
        }
   catch (ClassNotFoundException e) {
         System.err.println(e.toString());
         }
   catch (IOException exc) {
        System.err.println(exc.toString());
        }
    }
Nebenbemerkung: Die sogenannten try-catch-Bloecke dienen der Behandlung von evtl. auftretenden Fehlern bei der Ein- oder Ausgabe.

Übung: Erweitern Sie die Klasse CDContainer.java um die Methoden speichern() und laden().

Die neu eingefuegten Methoden lassen sich wie folgt in der Anwendung (CDAnwendung.java) benutzen:

Speichern aller CDs in die Datei "daten.ser" , die in (dem Vektor) der Container-Klasse vorhanden sind:
CDContainer.getInstance().speichern("daten.ser");
Laden der CDs, die in der Datei "daten.ser" gespeichert sind:
CDContainer.getInstance().laden("daten.ser");
Übung: Fuegen Sie der Mini-Verwalung die Menue-Punkte Oeffnen und Speichern hinzu. Verknuepfen Sie die Menuepunkte mit den Methoden laden und speichern. Fangen Sie zunaechst mit dem Speichern an.

Loesung:

Loesung: Loesung_mini.zip

Ergaenzungen der Mini-CD-Verwaltung mit grosser Wirkung

Speichern Dialog:

Um den Speichern-Dialog muss sich sich der Programmierer, wenn er einmal weiss wie es geht, keine grossen Gedanken machen. Java stellt dafuer eine eigene FileDialog-Klasse zur Verfuegung. Es reicht im Wesentlichen zu wissen, dass es diese Klasse gibt und das man nach dem Aufruf des Dialoges den Dateinamen und das Verzeichnis als String erhalten kann.

Übung: Fuegen Sie Ihrer Anwendungs-Klasse das folgende Attribut mit dem Namen saveFileDialog hinzu:

 
private FileDialog saveFileDialog = new FileDialog(this, "Datei speichern", FileDialog.SAVE);

Dem Dialog wird hier mit der Variablen FileDialog.SAVE mitgeteilt, dass es sich um ein Speichern-Dialog handelt. Der Rahmen-Text des Fensters wird "Datei speichern". Weitere Informationen zu der Klasse FileDialog finden Sie auch in der Sun Dokumentation der Klasse FileDialog .

In der Loesung der Mini-CD-Verwaltung des letzten Termins wurde mit Hilfe der folgenden Befehlszeile der Inhalt des CD-Containers unter dem Namen "daten.ser" gespeichert:

CDContainer.getInstance().speichern("daten.ser");
Übung: Ergaenzen Sie die Methode, die Sie beim Abspeichern aufrufen, um den Aufruf des File-Dialogs. Dazu muessen Sie den File-Dialog mit der Methode show() der Klasse FileDialog sichtbar machen:
saveFileDialog.show();

Um die Datei nun auch unter einem neuen Namen zu speichern, muesssen aus dem Filedialog der Name der Datei und der Pfad ausgelesen werden. Dazu gibt es die Methoden getFile() und getDirectory()in der Klasse FileDialog.

Übung: Ergaenzen Sie Ihre Speichern-Methode, durch die folgenden Zeilen, die es ermoeglichen den eingegebenen Filenamen und das Verzeichnis als String zu erhalten:

 String filename = saveFileDialog.getFile();
 String directoryname = saveFileDialog.getDirectory();

Übung: Aendern Sie den Aufruf zum Abspeichern () , so dass das File unter dem eingegebenem Namen abgespeichert wird.

Hinweis: Strings koennen durch "+" aneinandergehaengt werden:

"Hallo"+"Welt" = "Hallo Welt" 

Oeffnen Dialog:

Übung: Fuegen Sie einen Oeffnen-Dialog in Ihr Programm ein. (Das funktioniert analog zu dem Speichen-Dialog)

Zusaetzliches Attribut:

private FileDialog openFileDialog = new FileDialog(this, "Datei öffnen", FileDialog.LOAD);
Sichtbar machen des Dialogs:
openFileDialog.show();
Bestimmen des Gewaehlten Dateinamens und Verzeichnisses:
String file = openFileDialog.getFile();
String directory = openFileDialog.getDirectory();