Inhaltsverzeichnis API Einführung Java Entwicklungs-Kit Erste Programme Java-Grundwissen Erste Objekte Ein/Ausgabe in Java Oft benutzte Java-Werkzeuge Graphische Oberfläche Applets Threads Netzwerk Das TopDraw-Projet

Das vollständige TopDraw-Programm

  1. Das vollständige TopDraw-Programm
    1. Übersicht
    2. Entwurf
      1. Funktionalität
      2. Design
        1. Werkzeugleisten.
        2. Aktionen.
        3. Dialoge.
        4. Datei-Selektor.
        5. Farb-Selektor.
      3. Datenverarbeitung
        1. Serialisierung
      4. Zeichenelemente

Übersicht

In den vorhergenden Kapiteln wurde angefangen ein Zeichenprogramm zu entwerfen, dieses Beispiel soll jetzt wie ein richtiges Programm wieder aufgenommen werden und entsprechend entworfen und programmiert werden.

Entwurf

Erst müssen wir uns klar werden, was wir erreichen wollen:

Funktionalität

Design

Die Benutzerschnittstelle könnte fogendermaßen aussehen:

Um diese Applikation zu erschaffen werden noch ein paar nict vorgestellter Konstrukte gebraucht.

Werkzeugleisten.

ist ein Container der dafür geschaffen wurde um JButtons zu beherbergen. Der Vorteil dieses Element einem normalen JPanel z.B. gegenüber ist der das bestimmte Funktionalitäten die Werkzeugleisten interessant machen darin vorgesehen sind. Z.B. das verschieben der Werkzeugleisten, befindet sich eine Werkzeugleiste und ein aktives anderes Element in einem Container mit BorderLayout, so kann die Werkzeugleiste auf jeden Rand gezogen werden.

Das ezeugen einer Leiste erfolgt wie üblich:

JToolBar toolBar = new JToolBar();
JButton button = new JButton(new ImageIcon("images/left.gif"));
toolBar.add(button);
add(toolBar, BorderLayout.NORTH);

Die Möglichkeit die Werkzeugleiste zu verschieben kann mit toolBar.setFloatable(false); unterbunden werden. Dies wird nötig, wenn ein bestimmtes Layout aufgebaut werden soll.

Weiterhin ist es möglich Gruppen von Knöpfen zu erzeugen, indem zwischen Gruppen Leerbereiche (toolBar.addSeparator();) eingefügt werden.

Da diese Leiste von JComponent erbt, kann sie neben JButtons natürlich jedes andere JComponent auch aufnehmen. In dieser Hinsicht kann es wichtig sein die Ausrichungsmethode der Elemente zu ändern. Normalerweise werden die Elemente zentriert, bei Elementen verschiedener Größe, kann es ästhetischer sein nach der oberen oder unteren Kante auszurichten, dies kann mit der Methode setAlignmentY(TOP_ALIGNMENT), die bei jedem in der Werkzeugleiste liegenden Element aufgerufen werden muß, erreicht werden.

Aktionen.

In der aufgezeigten Struktur werden mehrere Aktionen von mehreren Stellen aus getriggert, so können Aktionen von den Menus ausgehen, von der Werkzeugleiste und von anderen Knöpfen.

Bis jetzt wurden Aktionen über die Implementierung des ActionListeners gehandhabt. Jetzt wird es langsam kompliziert die übersicht über alle einsprung-Punkte von Aktionen zu verwalten. Um dieses Problem zu vereinfachen, wird jetzt der umgekehre Weg gegangen: es wird eine aktion definiert, diese kann auf Wunsch einen Knopf oder ein MenuItem zurückgeben, und erlaubt eine für jede Aktion zentraliserte Verwaltung.

Damit wird es möglich z.B. bestimmte Aktionen momentan auszuschalten, indem nur ein Objekt manipuliert wird. In unserem Beispiel ist es irrelevant ob die Funktionalität füllen aktiviert oder daktiviert wird wenn offene Polygone gezeichnet werden, damit könnte diese Funktionalität in diesem Zeichenmodus ausgeschaltet werden.

Dialoge.

Dialoge sind unter-Fenster welche je nach Bedürnis sichtbar und unsichtbar gemacht werden können. Diese Dialoge werden z.B. von an Knöpfen angebundenen Aktionen getriggert, und werden in der Regel dazu benutzt zusätzliche Informationen vom Benutzer abzufragen.

Schnell könnte man dazu verleitet werden alle Dialoge beim Hochfahren der Applikation zu erzeugen, dies hat natürlich den Vorteil, daß sie sehr schnell sichtbar gemacht werden können, hat aber auch den Nachteil, daß sie permanent im Speicher gehalten werden.

Eine häufige Aufgabe von Dialogen ist die Bestätigung einer Eingabe oder das Einlesen von einer zusätzlichen Zeichenkette. Die Swing-Dialog-Klasse stellt solche Dialoge schon fertig zur Verfügung. Ein einfaches Bestätigungsdialog könnte auf folgende Weise geöffnet werden:

JOptionPane.showMessageDialog(frame, "Dies ist ein Zeichen-Programm");

Wenn die Dokumentation zu Dialogen gelesen wird, taucht häufig das Wort 'modal' auf, weiterhin brauchen Dialogen eine Referenz zu einem Fenster. Beides ist gekoppelt, wenn ein Dialog modal ist, heißt dies, daß das zu kontrollierende Fenster solange wie das Dailog offen ist blockiert werden soll.

Kann das gewünschte Dialog nicht in der Liste vorgefertigter Dialoge gefunden werden, muß es per Hand aufgebaut werden. D.h., daß eine eigene Klasse von JDialog erzeugt werden, welche sonst wie ein normales JFrame aufgebaut wird.

So en Dialog wird gebraucht, um z.B. den Namen und Port des Zeichenservers abzufragen.

Datei-Selektor.

Ein spezial-Fall von Menu, ist das Dateien-Selektionsmenu. Es ist ein vorgefertigter Dialog zur Auswahl von Dateien.
JFileChooser fc = new JFileChooser();
int returnVal = fc.showOpenDialog(meinFenster);
if (returnVal == JFileChooser.APPROVE_OPTION)
{
  File file = fc.getSelectedFile();
  //this is where a real application would open the file.
  log.append("Opening: " + file.getName() + "." + newline);
} //if (returnVal == JFileChooser.APPROVE_OPTION)
else
{
  log.append("Open command cancelled by user." + newline);
}// else

Das Kommando showOpenDialog blockiert das angegebene Fenster solange bis die Eingabe beendet ist. Der Rückwert gibt den Erfolg oder nicht der Eingabe an.

Farb-Selektor.

Auch für die Auswahl von Farben gibt es ein fertiges Bauelement (Farb-Selektor). Es handelt sich hierbei um ein Element, muß also in einen Container gepackt werden.
JColorChooser tcc = new JColorChooser();

Ausgelesen wird dieses Element mit tcc.getColor()

Datenverarbeitung

Es wurde in den Anforderungen der Punkt angeführt das Bild abspeichern zu können um es später wieder laden zu können.

Als erstes muß klar gestellt werden wie die Daten organisiert werden. Dies ist grob gesehen Geschmackssache, wobei es von den Anforderungen an diese Datei abhängt was schlußendlich benutzt wird.

Wird ein kleines kompaktes Datenformat gewünscht bieten sich eigene komprimierte Datenformate an. Diese werden direkt in eine Datei geschrieben und gelesen.

Ist ein leicht einzulesendes Format erwünscht, das relatif einfach ein und aus geschrieben werden kann, sollte der Schritt über Property-Dateien laufen. In der Hinsicht sollten alle Konstruktoren idealerweise den gleichen Aufbau besitzen, damit eventuell über Reflection, generisch der Klassenname ermittelt, ein Konstruktor gefunden und mit den mitgelieferten Parametern aufgerufen werden kann.

Sollen die Sachen richtig, nach heutigen Standards gemacht werden, sollte eine XML-Bibliothek besorgt werden, und die Daten hierarchisch im XML-Format rausgeschrieben werden.

Serialisierung

Natürlich gibt es noch eine kurze (und in den meisten Fällen dreckige) Lösung dank der Serialisierung von Objekten.

Dabei handelt es sich um einen pfiffigen Mechanismus um Objekte durch irgendwelche 'Streams' zu bekommen. Angenommen eine Klasse entspricht dem Interface Serializable , dann wird damit der JVM signalisiert, daß diese Klasse tatsächlich in ein Datenpaket verwandelt werden kann, welches durch einen Datenfluß durchgejagt werden kann.

FileOutputStream out = new FileOutputStream("theTime");
            ObjectOutputStream s = new ObjectOutputStream(out);
            s.writeObject("Today");
            s.writeObject(new Date());
            s.flush();

Hier werden z.B. 2 Objekte (eine Zeichenkette und ein Datumsobjekt, alle Bibliotheksobjekte sind, außer anders angegeben, serialisierbar) serialisiert und in eine Datei geschrieben.

Zu wissen, daß als statisch oder transient markierte Variablen nicht eingepackt werden, dementsprechend müssen diese nach dem auspacken wieder hergestellt werden.

Zeichenelemente

Solange nur einfache Elemente gezeichnet werden, können diese direkt auf eine Zeichenfläche aufgebracht werden. Steigt die Komplexität, müssen dedizierte eigene von JComponent abgeleitete Klassen entworfen werden.

Diese Klassen müssen außer der Fähigkeit sich korrekt zeichnen zu können, auch noch die Fähigkeit besitzen selektierbar zu sein. Dazu müssen die Methoden public boolean contains(int x, int y) und public boolean contains(Point p) angepaßt werden, diese sollen nur dann auschlagen, wenn der Mauspointer direkt über dem Element ist.

In dieser Hinsicht kann die Klasse Polygon hilfreich sein.


Inhaltsverzeichnis API Einführung Java Entwicklungs-Kit Erste Programme Java-Grundwissen Erste Objekte Ein/Ausgabe in Java Oft benutzte Java-Werkzeuge Graphische Oberfläche Applets Threads Netzwerk Das TopDraw-Projet

Document mit wml erzeugt von Bruno Böttcher unter Benutzung von öffentlichen Dokumenten.