Beruflich Dokumente
Kultur Dokumente
Abstract
Das Huffman Code Applet nun ist eine Verständnishilfe für die Vorgehensweise des Huffman Code.
Insbesondere können mit diesem Applet die einzelnen Schritte bei der Erstellung des Kodebaumes
und der Generierung der Kodeworte verfolgt werden. Die Geschwindigkeit legt dabei allein der
Benutzer fest, auch gibt er den zu kodierenden Text vor.
Das Applet ist in Java erstellt worden und kann entweder mit dem Appletviewer (im Java
Development Kit enthalten) oder in einem Browser gestartet werden. Zu beachten ist dabei, dass
das Java-Plugin des Browsers (also die Java-VM) mindestens in der Version 1.2 installiert sein
muss.
Inhaltsverzeichnis
Abstract 3
Inhaltsverzeichnis 5
Einleitung 7
Anwendung 8
Voraussetzungen 8
Start 8
Benutzung 9
Design 11
Use Cases 13
Huffman kodieren 13
Kodieren 14
Anzeigen 15
Wahrscheinlichkeit der Zeichnen errechnen 15
Kodierung für Zeichen bestimmen 15
Nächsten Knoten anzeigen 16
Testergebnisse 17
Systeme 17
Bekannte Bugs 17
Ausblick 18
Stufenloser Zoom 18
Sortierung der Legende 18
Klasse HuffmanCodec 19
Inhalt 19
Konstanten 19
Funktionen 20
Öffentlich 20
Privat 20
Klassen VisualNode 22
Inhalt 22
Attribute 22
Konstruktor 23
Methoden 23
Klasse VisualTree 24
Inhalt 24
Attribute 25
Konstruktor 25
Methoden 25
Klasse Controller 27
Inhalt 27
Attribute 27
Konstruktor 28
Methoden 28
Stefan Schmitz, Ma tthia s Kloss, Ma tthia s Wita ßek 5
Huffman Code Applet 03.05.01
Klasse Zeichen 30
Inhalt 30
Attribute 30
Konstruktor 30
Methoden 30
Klasse NotEnoughLettersException 32
Inhalt 32
Konstruktor 32
Klasse huffman 33
Inhalt 33
Attribute 33
Konstruktor 34
Methoden 34
Klasse UpperCaseField 36
Inhalt 36
Attribute 36
Konstruktor 36
Klasse TreePanel 37
Inhalt 37
Attribute 37
Konstruktor 37
Methoden 38
Einleitung
Das Huffman Code Applet soll verdeutlichen, wie die Huffmankodierung funktioniert. Dabei
werden grundlegende Kenntnisse der Informatik vorausgesetzt. Als Beispiel sollten sowohl
Binärbäume als auch ASCII-Codes bekannt sein.
Dieses Applet ist sowohl für Studenten (zum Verständnis) als auch für Dozenten (zur Demonstration
während der Vorlesung) gedacht.
Anwendung
Voraussetzungen
Das Huffman Code Applet ist in Java implementiert und daher weitgehend systemunabhängig.
Lediglich eine Java Virtual Machine (JavaVM) in der Version 1.2 oder höher sowie ein Browser mit
diesem Plugin werden benötigt.
Start
Das Applet wird gestartet, indem die Datei huffman.html in den Browser geladen wird. Dieser
startet automatisch das Java-Plugin und die O berfläche des Applets erscheint.
Alternativ kann das Huffman Code Applet auch mit dem Appletviewer aus dem JDK ausgeführt
werden. Hierfür muss jedoch eine modifizierte HTML-Datei benutzt werden, da der Appletviewer
keine relativen Größenangaben unterstützt. Der Aufruf muss folgendermaßen aussehen:
appletviewer huffman_appletviewer.html
Es existiert noch ein dritte Möglichkeit, das Applet zu starten. Dafür muss auf dem System Java
derart installiert sein, dass die Dateiendung .jar mit der JavaVM verknüpft ist. Auf diese Weise
genügt ein Doppelklick auf HuffmanCodecApplet.jar.
Benutzung
Vom Benutzer muss nun eine Zeichenkette eingegeben werden, die kodiert werden soll. Diese ist
auf eine Länge von 30 Zeichen begrenzt, da sonst die Baumdarstellung riesenhafte Ausmaße
annehmen kann und schlichtweg nicht mehr übersichtlich ist.
Nach der Eingabe wird der Kodierungsprozeß gestartet, indem man auf den Button draw tree
klickt. Es erscheint der komplette Kodebaum. Gleichzeitig wird die Legende mit den Zeichen, deren
Wahrscheinlichkeiten und deren Binärkodierung gefüllt. Die daraus resultierende binäre
Zeichenkette wird im Feld cipherText angezeigt. Dabei wird zwischen der binären Darstellung
zweier Zeichen Platz gelassen, der besseren Lesbarkeit wegen.
Weiterhin wird der Kompressionsgrad angegeben, der aus dem Verhältnis zwischen Länge des
Eingabetextes und Länge das Kodetextes errechnet wird. Je größer dieser Grad, desto besser die
Komprimierung.
Um den Aufbau des Baumes schrittweise verfolgen zu können, müssen die Buttons „draw previous“
und „draw next“ verwendet werden. Dabei dient „draw previous“ dazu, zum vorherigen Schritt
zurück zu gehen, während man mit „draw next“ – welch Wunder – den nächsten Schritt dargestellt
bekommt.
Um den Aufbau von Anfang an zu sehen, löscht man zunächst mit der Schaltfläche „clear tree“ das
Anzeigefeld für den Baum. Danach wird mit jedem Klick auf „draw next“ die Zusammenfassung
der zwei niedrigstwahrscheinlichen Knoten zu einem neuen Knoten dargestellt. Der Baum wird
sequentiell aufgebaut.
Hat man den eingegebenen Text satt und möchte lieber einen anderen probieren, so ist dies
denkbar einfach zu erledigen: Den neuen Text anstelle des alten eintippen. Der Baum wird
automatisch neu erstellt, sobald man wieder auf „draw tree“ drückt.
Design
Das Huffman Codec Applet ist in drei logische Module gegliedert, dem objektorientierten Ansatz
Model-View-Controller (MVC) folgend:
Für die optimale grafische Darstellung des Kodebaumes wird ein normalisiertes Koordinatensystem
(Kantenlänge in x- und y-Richtung ist 1) benutzt. Die sich aus dem Kodierungsbaum ergebenden
Positionen eines jeden Knotens werden bereits im Huffman-Codec festgelegt.
Use Cases
Huffman kodieren
Name des UseCase Huffman kodieren
Beteiligte UseCase Kodieren
Anzeigen
Aktor Bediener
Kurzbeschreibung Kodierung der eingegebenen Zeichenketten und Ausgabe
des Kodebaumes
Auslöser Programmstart
Ergebnisse Ausgabe des Kodebaum mit Kodierung der einzelnen
Zeichen
Arbeitsschritte 1. Eingabe Zeichenkette
2. Starten der Kodierung
3. Darstellung des Kodebaumes
4. Nächstes Zeichen darstellen
Sonderfälle S1. Eingabe ist leer
Erläuterungen Arbeitsschritt wird solange wiederholt bis Baum komplett
aufgebaut ist
Bemerkungen
Kodieren
Name des UseCase Kodieren
Beteiligte UseCase Wahrscheinlichkeit der Zeichen errechnen
Kodierung für Zeichen bestimmen
Aktor Bediener
Kurzbeschreibung Durchführung des Algorithmus zur Huffmankodierung
Auslöser Arbeitschritt 2. UseCase Huffman kodieren
Ergebnisse Tabelle die den Codetree darstellt
Arbeitsschritte 1. Ermittlung der Zeichen im Eingabezeichen und deren
Wahrscheinlichkeit
2. Berechnung des Optimalkodes nach Huffman
3. Eintragung in Tabelle
Sonderfälle -
Erläuterungen -
Bemerkungen -
Anzeigen
Name des UseCase Anzeigen
Beteiligte UseCase Nächsten Knoten Anzeigen
Aktor Bediener
Kurzbeschreibung Anzeigen der Bildschirmelemente
Auslöser Arbeitsschritt 3. UseCase Huffman kodieren
Ergebnisse Visualisierung des Kodebaumes auf dem
Bildschirm
Arbeitsschritte 1. Aufbau des Zeichenbaumes
2. Nächstes Zeichen anzeigen
Sonderfälle -
Erläuterungen -
Bemerkungen -
Testergebnisse
Systeme
Das Huffman Code Applet wurde unter folgenden Systemen erfolgreich getestet:
Bekannte Bugs
• Unvollständige Anzeige des cipherText
Manchmal ist der binärkodierte Text nicht oder nur teilweise sichtbar.
Ausblick
Stufenloser Zoom
Der Verkleinerungsgrad bei der Ansicht des Kodebaumes ist bis jetzt mit einer unteren Schranke
festgelegt, so dass die Knoten nie ein gewisse Pixelgröße unterschreiten. Das hat jedoch den
Nachteil, dass sehr große Bäume sehr unübersichtlich dargestellt werden. Abhilfe würde hier eine
stufenlose Zoomfunktion schaffen, die zudem noch durch den Benutzer selbst gesteuert werden
kann. Auf diese Weise kann er sich den Baum nach seinen Wünschen zurecht rücken, Screenshots
werden auch bei großen Bäumen möglich.
Klasse HuffmanCodec
Inhalt
Für dieses Dokument wird vorausgesetzt, dass dem Leser die Funktionsweise der
Huffmankodierung bekannt ist.
HuffmanCodec erstellt aus einem gegebenen String den Huffmanbaum und ermittelt die
Zeichenkodierungen. Beides wird mit Hilfe der Interface-Klassen VisualTree und
VisualNode an den Controller übergeben. Der String darf nur aus ASCII-Zeichen bestehen.
Der Baum wird bereits bei der Instanziierung dieser Klasse berechnet.
Weiterhin werden die Koordinaten der Knoten des Baumes, die später für die Darstellung
benötigt werden, durch HuffmanCodec festgelegt. Dafür werden normalisierte Koordinaten
benutzt, die sich im Intervall [0.0, 1.0] befinden. Auf diese Weise kann der Baum in jeder
Auflösung dargestellt werden. Die dafür nötigen Punkte errechnet man durch Multiplikation
der normalisierten Koordinaten mit der gewünschten maximalen Auflösung.
Konstanten
BO RDERX Legt die rechte Intervallgrenze der normalisierten
Koordinaten für die x-Achse fest. Standardwert ist 1.0.
NODEDISTANCEFACTO R Mit jeder Ebene, um die ein Baum nach unten wächst, muss
er auch steiler werden. Sonst würden sich Knoten
überlappen, weil sie sich an der gleichen Position befinden.
Diese Erhöhung des Baumgefälles mit jeder neuen Ebene
wird duch NODEDISTANCEFACTO R gesteuert. Dabei wird
das Gefälle jedesmal mit diesem Faktor multipliziert. Der
Standardwert 2 bewirkt somit jeweils eine Verdopplung des
Gefälles.
Funktionen
Öffentlich
HuffmanCodec(String input)
VisualTree getTree()
float getRadius()
Privat
VisualTree calculateHuffmanTree(String input)
Erstellt den Huffmanbaum aus input. Dazu wird zunächst für jedes Zeichen in input,
für das noch kein Knoten existiert, einer angelegt. Gab es den Knoten bereits, wird
die Häufigkeit dieses Zeichens (entspricht dem Gewicht) erhöht. Auf diese Weise
erhält man eine unsortierte Liste von Knoten, die keinerlei Beziehungen zueinander
haben. Für jedes Zeichen dieser Knoten ist die Häufigkeit ermittelt worden.
Im nächsten Schritt wird aus dieser Liste der Baum mit den Beziehungen der Knoten
untereinander erstellt.
Dazu wird die vorhandene Liste nach aufsteigender Häufigkeit der Zeichen sortiert.
Anschließend wird aus den zwei geringsthäufigen Knoten ein neuer gebildet, der
deren Vater darstellt. Diesem neuen Knoten werden die beiden als Söhne
untergeordnet. Im nächsten Schleifendurchlauf wird die nun erweiterte Liste erneut
sortiert und die zwei geringsthäufigen Knoten auch wieder einem neuen Vater
untergeordnet. Dieser Vorgang wird so lange wiederholt, bis alle Knoten bearbeitet
wurden, inklusive der neu hinzugefügten. Als Ergebnis steht nun der Huffmanbaum
fest, der zurückgeliefert wird.
Über die Methode des rekursiven Abstieges wird aus dem Huffmanbaum der
Binärcode für die einzelnen Zeichen ermittelt. Startpunkt ist die Wurzel (node), der
der String code zugewiesen wird. Mit jeder Verzweigung (es wird einfach dem Pfad
entlang nach unten gefolgt) nach links wird dem Code eine Null hinzugefügt, rechts
kommt stattdessen eine Eins dazu. Die Funktion wird für die Kinder, sofern sie
vorhanden sind, rekursiv aufgerufen. Auf diese Weise wird mit zunehmender Tiefe
im Baum auch der Code länger.
Gleichzeitig mit der Ermittlung des Codes werden die Ausmaße des Baumes
bestimmt. Dazu dienen distanceHorizontal (horizontale Ausdehnung) und
distanceVertical (vertikale Ausdehnung). Mit stepHorizontal wird das Gefälle des
Baumes mit zunehmender Tiefe erhöht. Diese Werte entsprechen nicht den
normalisierten Koordinaten, sie dienen allerdings zu deren Bestimmung.
Mit Hilfe der in determineCode() gewonnenen Daten über die Ausdehnung des
Baumes werden hier die normalisierten Koordinaten berechnet. Auch hier kommt
das Prinzip des rekursiven Abstieges zum Einsatz, Startpunkt ist node.
Parallel zur Koordinatenberechnung wird ein zweidimensionales Feld mit den x-
Koordinaten der Knoten gefüllt. Dabei enthält die erste Dimension des Feldes die
Ebene im Baum, auf der sich der Knoten befindet. Die zweite Dimension ist dann
die Koordinate selbst. Dieses Feld wird in isO verlapDetected() zur Feststellung einer
Überlappung benutzt.
Klassen VisualNode
Inhalt
Die Objekte der Klasse VisualNode stellen die Knoten und Blätter des Baumes (siehe VisualTree)
dar, welcher bei der Huffman-Kodierung entsteht. Bei dem entstehenden Binärbaum entspricht
jedes Blatt einem konkreten Zeichen der Eingabezeichenkette, die Knoten entsprechen einem
virtuellen Zeichen, zusammengesetzt aus den Kindern des Knotens. Die Wahl der Blätter, welche zu
einem Knoten zusammengefaßt werden, hängt von ihrer Häufigkeit im Eingabestring ab, es werden
die mit der geringsten zuerst gewählt. Der so entstehende Knoten ersetzt seine beiden Kinder,
wobei sich die Wahrscheinlichkeit (Wahrscheinlichkeit = Häufigkeit / Anzahl Zeichen) des Knotens
aus der Summe der Wahrscheinlichkeiten der beiden Kinder ergibt. Dieser Vorgang wird solange
fortgesetzt, bis es nur noch einen Knoten (Root) mit der Wahrscheinlichkeit 1 gibt. Die Knoten
entsprechen nach diesem Schema den Blättern, da sie als Blatt des übergeordneten Knotens
angesehen werden können. Deshalb haben Blätter (Zeichen) und Knoten (virtuelle Zeichen)
dieselben Eigenschaften und werden in einer Klasse zusammengefaßt (ein VisualNode-Objekt kann
also die Rolle eines Zeichens und/oder eines Knotens spielen).
Attribute
Folgende Eigenschaften eines VisualNode ergeben sich aus der obigen Beschreibung:
Konstruktor
- VisualNode()
- VisualNode(char c, int w, String s, float x, float y, int lc, int rc, int p)
Parameter: c = codeLetter,
w = weight,
s = code,
x = xPositionNormal,
y = yPositionNormal,
lc = leftChild,
rc = rightChild,
p = parent.
Methoden
Zu jedem der oben aufgeführten Attribute gibt es get- und set- Methoden, wobei sich die
normalisierten Koordinaten durch die Methode setPositionXY() setzen lassen.
Weitere Funktionen sind:
- equals
Vergleicht den aufrufende VisualNode mit dem Parameter obj, wobei die Gleichheit gilt, wenn
beide Knoten den gleichen codeLetter haben. Bei Gleichheit wird ist der Rückgabewert true.
- hasChildren
Liefert den Rückgabewert true, wenn der aufrufende VisualNode Kinder hat. Ein Knoten im
Huffmanbaum hat entweder keine Kinder oder zwei Kinder.
- printNode
Klasse VisualTree
Inhalt
Die Klasse VisualTree entspricht einem Container, der alle Objekte des Typs VisualNode speichert.
Sie stellt also den Huffmanbaum dar, dessen Knoten und Blätter VisualNode-Objekte sind. Die
Hierarchie des Baumes wird durch die Position der Elemente und deren Verweise auf Kind- und
Vater-Objekte realisiert. Die Hierarchie und deren Abbildung im Baum stellt sich folgendermaßen
dar. Da der Huffmanbaum von unten aufgebaut wird, sind die ersten beiden Knoten auch die
untersten im Baum (sie werden auch als erstes auf dem Bildschirm gezeichnet!). Es gehören immer
zwei VisualNode-Objekte zusammen, sie sind die beiden Söhne des Knotens, auf den sie mit ihrem
parent-Attribut referenzieren. Sind die ersten beiden Paare und der zugehörige Vaterknoten
gezeichnet, bilden die nächsten beiden Knoten plus ihr Vater das nächste zu zeichnende Tripel.
Dabei ist der erste Knoten immer der Linke, der andere der Rechte. Die Abbildung und die dazu
gehörende Tabelle sollen dies verdeutlichen. Die roten Zahlen sollen nur die Knoten nummerieren
und sind im eigentlichen Programm nicht enthalten, zur Vereinfachung sind in der Tabelle nur die
hier wichtigen Attribute von VisualNode aufgeführt.
VisualNodeObjekt
KnotenNr.
Index codeLetter leftChild rightChild parent
(rote Ziffer)
(Index) (Index) (Index)
0 3 A -1 -1 5
1 4 B -1 -1 5
2 1 C -1 -1 4
3 2 D -1 -1 4
4 6 2 3 6
5 5 0 1 6
6 7 4 5 -1
Skizze des Speicherabbilds in VisualTree
Als Speicherstruktur wurde die Klasse ArrayList gewählt, weil diese dynamisch erweiterbar ist und
trotzdem ein Zugriff über Indizes möglich ist. Sie erlaubt es außerdem, beliebige Objekte darin
abzuspeichern.
Attribute
Konstruktor
- VisualNode()
Methoden
- addNode
Fügt bzw. erstellt ein VisualNode-Objekt an der mit index angegebenen Stelle ein. Ist kein
Objekt übergeben worden, so wird es aus den übergebenen Parametern erstellt.
- appendNode
Hängt bzw. erstellt ein VisualNode-Objekt an die ArrayList liste an. Ist kein Objekt übergeben
worden, so wird es aus den Parametern erstellt.
- containsNode
Überprüft ob ein VisualNode-Objekt mit dem Zeichen codeLetter schon enthalten ist. Die
Methode liefert –1 zurück, wenn es noch kein O bjekt in liste gibt, welches das Zeichen
codeLetter repräsentiert. Ansonten wird der Index des Objekts in liste zurückgegeben.
- removeNode
Nimmt das VisualNode-Objekt an der Stelle index in liste aus der ArrayList und gibt es zurück.
Die möglichen Verweise auf diese Objekt werden nicht korrigiert!
- getNode
Gibt eine Kopie des VisualNode-Objekts zurück, welches sich an der Stelle index in liste
befindet.
- exchangeNodes
Vertauscht die beiden Knoten, welche durch index1 und index2 in liste addressiert werden. Da
dieser Positionstausch Auswirkungen auf die Hierarchie hat, müssen die Verweise auf diese
Objekte neu angepaßt werden. Dabei müssen nur die beiden Kinder des Knotens
berücksichtigt werden. Es wird true zurückgegeben, wenn Methode erfolgreich ausgeführt
wurde.
- existsNode
Gibt true zurück, wenn an der Stelle index in liste ein Knoten existiert.
- getLast
Gibt den Index des letzten Elements in liste zurück. Ist liste leer, dann ist der Rückgabewert –1.
- printList
Gibt eine Liste aller in liste enthaltenden VisualNode-Objekte auf stdout aus.
Klasse Controller
Inhalt
Die Controller-Klasse definiert das Objekt, welches die Rolle der Vermittlung zwischen dem
HuffmanCodec-Objekt und dem Applet mit der GUI übernimmt. Dabei interpretiert der Controller
die Datenstruktur, die er vom HuffmanCodec durch die Schnittstelle VisualTree und VisualNode
erhält und übergibt sie der GUI. Die eigentliche Ereignisbehandlung bleibt jedoch im Applet.
Controller-Objekte werden von dem Applet angelegt und erhalten dabei den zu kodierenden Text.
Der Controller selbst instanziert ein HuffmanCodec-Objekt, welches den zu kodierenden Text
erhält. Der HuffmanCodec gibt die Kodierung in Form des VisualTrees zurück, dieser wird dann
vom Controller ausgewertet. Um die Knoten direkt zeichnen zu können, besitzt der Controller eine
Referenz auf das TreePanel des Applets.
Die Daten für die Legende werden ebenfalls durch den Controller erstellt, hierzu dient das Attribut
legend vom Typ Zeichen[]. Treten Fehler innerhalb des Controllers auf, so werden sie durch
Exception-Handling an das Applet weitergegeben.
Attribute
Konstruktor
- Controller(TreePanel p, String plainText) throws NotEnoughLettersException
TreePanel p ist eine Referenz auf das TreePanel des Applets und wird für die Methoden
drawNext(), drawAll() und drawLast() benötigt. String plainText ist der Eingabestring, der kodiert
werden soll. Innerhalb des Konstruktors wird eine Instanz von HuffmanCodec angelegt,
wodurch der Huffmanbaum erzeugt wird. Dieser wird dann durch tree referenziert.
Weiterhin wird der Eingabestring auf Korrektheit überprüft. Ist dieser kürzer als 2 Zeichen so
wird die NotEnoughLettersException geworfen. Dies geschieht ebenfalls, wenn der
Huffmanbaum nur einen Knoten enthält. Das ist der Fall, wenn der Eingabestring nur eine
Folge des selben Zeichens ist.
Methoden
- drawNext
Zeichnet zwei Knoten und den dazugehörenden Vaterknoten. Der Rückgabewert ist true, wenn
der letzte Knoten (Root) gezeichnet worden ist. Die schon gezeichnet Knoten erkennt man an
dem Wert indexVisualTree, der ein Index auf den VisualTree tree ist. Das Zeichnen der Knoten
und der Verbindungslinie geschieht durch aufrufen der Methoden drawNode und drawLine der
Klasse TreePanel.
- drawAll
Zeichnet den kompletten Baum durch ständiges Aufrufen der Methode drawNext bis der
Rückgabewert true ist.
- drawLast
Selbe Funktionsweise wie drawNext, nur in umgekehrter Richtung. Das Löschen der einzelnen
Knoten geschieht durch Überschreiben mit der Hintergrundfarbe.
- clearTree
Löscht bzw. setzt den Baum zurück. Da das Löschen den Panels vom Applet übernommen wird,
muß hier lediglich der Wert indexVisualTree auf 0 gesetzt werden.
- getProbability
- getCipherBit
Ermittelt den Bitwert, der an die Verbindungslinie zum Vaterknoten gehört. Es ist das letzte
Zeichen des Strings code von node.
- getCompressionDegree
Berechnet die Kompression des Eingabetextes durch die Huffmankodierung. Jedes Zeichen des
Eingabestrings wird dazu mit 8 Bit (ASCII-Kodierung) angesetzt. Die Kompression wird anhand
folgender Formel berechnet:
(Anzahl ASCIIBits – Anzahl HuffmanBits)/ Anzahl ASCIIBits = Kompression
Es wird auf 2 Stellen hinter dem Komma gerundet.
- buildLegend
Erzeugt eine Tabelle in der alle Zeichen mit ihrer Wahrscheinlichkeit und ihrer Kodierung
abgelegt sind. Für jedes Zeichen wird ein O bjekt Zeichen angelegt, welches in Zeichen[]
gespeichert wird. Da nur Blätter ein echtes Zeichen repräsentieren, wird nur für jedes Blatt ein
Objekt von Zeichen angelegt.
- getLegend
Gibt ein Array von Zeichenobjekten zurück, welche die Daten für die Legende des Applets
enthalten. Zum Erstellen der Legende wird die Methode buildLegend() aufgerufen, deren
Ergebnis in dem Attribut legend abgespeichert werden.
- getCipherText
Erzeugt einen String in dem jedes Zeichen des Eingabestrings durch seine Huffmankodierung
ersetzt wird. Zum schnelleren Zugriff auf die Kodierung werden die Daten aus legend gelesen.
Intern wird ein StringBuffer als Zwischenspeicher benutzt.
Klasse Zeichen
Inhalt
Die Legende des Applets listet alle Zeichen auf, um so dem Benutzer einen Überblick über den
Baum zu verschaffen. Zu jedem Zeichen werden noch die zusätzlichen Eigenschaften des
Wahrscheinlichkeit und Huffman- Kode angezeigt. Da in der Tabelle nur die echten Zeichen
aufgelistet werden sollen, werden Zeichenobjekte nur für jedes Blatt angelegt. Sie bilden die
Schnittstelle zwischen dem Controller und dem Applet und übergeben die Informationen die für die
Legende benötigt werden. Dies geschieht in einem eindimensionalem Array von Zeichen.
Attribute
Modifier Typ Name Kurzbeschreibung
private float fProbability Wahrscheinlichkeit des Zeichens,
gerundet auf 2 Stellen hinter dem
Komma.
private String szBitCode Huffmankodierung des Zeichens
private char cCodeLetter Zeichen an sich.
Konstruktor
- Zeichen()
Standardkonstruktor, muß explizit angelegt werden, da auch ein zweiter Konstruktor vorhanden
ist.
Methoden
Zu jedem Attribut gibt es die üblichen get- und set- Methoden.
- set
- toString
Gibt die Werte der Attribute als String zurück. Dient vor allem zum Debuggen.
Klasse NotEnoughLettersException
Inhalt
Die Klasse NotEnoughLettersException erbt von der Klasse Exception des JFC. Diese Exception wird
vom Controller geworfen, wenn der Eingabestring weniger als 2 Zeichen enthält, oder eine Folge
des gleichen Zeichens ist.
Konstruktor
- NotEnoughLettersException()
- NotEnoughLettersException(String s)
Klasse huffman
Inhalt
Die Klasse huffman ist von der Klasse Applet aus der Java API abgeleitet. Sie beinhaltet die
Initalisierung sämtlicher grafischer Objekte im Appletfenster. Die Klasse beinhaltet zusätzlich eine
„main“ Funktion die es ermöglicht, das Applet mit der Java-Virtual-Machine direkt zu starten.
Die Klasse verwendet den Layout Manager GridBagLayout (aus der Java API) sowie die
vorkompilierte Klasse GridBagConstraints2 welche die Parameter bezüglich der Anordnung der
einzelnen grafischen Objekte einstellt.
Button-Events wie z.b. drawTree oder drawNext werden von der Klasse abgefangen und bearbeitet
bzw. weitergereicht an die Controller Klasse.
Attribute
Modifier Typ Name Kurzbeschreibung
Public Controller con Beinhaltet den aktuellen Controller
der für das Errechnen der
Koordinaten zuständig ist.
Public TreePanel P1 Enthält das TreePanel-Objekt das
den Code Baum anzeigt.
Public Jpanel jp Ist die gecastete Version des
TreePanels P1. Der Designer des
JDeveloper erwartet ein Objekt
dieses Typs anstatt des Typs
TreePanel.
Public Label Label1 Alle Label Variablen wurden
automatisch vom Designer des
Jdevelopers erstellt und dienen nur
der Anzeige von konstantem Text
auf dem Applet.
Public boolean isStandAlone Wurde von Jdeveloper bei der
Erstellung der Applet Klasse
generiert und dient dazu das das
Program auch mit der Java VM per
main() Methode aufgerufen werden
kann.
Public ScrollBar ScrollbarV,Scrollbar Dienen der Darstellung der
H Scrollbar zum scrollen des Code
Baums
Public JtextField Plaintext Das grafische Objekt zum Eingeben
des Klartextes.
Public String Header Enthält den Tabellenkopf für die
Legende.
Konstruktor
- huffman()
Methoden
Init()
jbInit()
vom Designer des JDeveloper generierte Funktion, die die Anzeige und Positionierung der
grafischen Objekte des Applets vornimmt. Es werden ausserdem für die verschiedenen Buttons
ActionListener installiert, die auf Klicken der Buttons reagieren und diese Events dann an
entsprechende Funktionen weiterleiten.
componentResized(ComponentEvent e)
wird aufgerufen wenn sich die Größe des Applets ändert. Wenn das Applet sich in der Größe
verändert müssen die Scrollbars angepasst werden da sich auch die Größe des Feldes für die
Anzeige des Code Baumes ändert.
AdjustmentValuechanged(AdjustmentEvent e)
Wird aufgerufen wenn der Code Baum gescrollt wird. Passt die neuen Xund Y Koordinaten des
Code Baumes an.
Start()
Stop()
Destroy()
Funktionen die vom JDeveloper bei Erstellung der Applet Klasse eingefügt wurden.
DrawLegend
Zeichnet die Legende(Zeichen, Wahrscheinlichkeit und BitString) für alle Zeichen des Baumes
clear_actionPerformed(ActionEvent e)
tree_actionPerformed(ActionEvent e)
next_actionPerformed(ActionEvent e)
previous_actionPerformed(ActionEvent e)
Diese Event-Funktionen werden aufgerufen sobald der entsprechende Button gedrückt wurde.
Falls noch kein Controller Objekt existiert (z.b. ein neuer Text eingegeben wurde) wird dieses
von der Funktion zunächst erstellt. Das Controller Objekt bekommt dabei das TreePanel
Objekt „p1“ übergeben um deren Funktionen zum Zeichnen der Knoten aufrufen zu können.
Die Funktion ruft nun die dem Button zugeordenete Funktion des Controllers auf(drawNext,
drawPrevois...), und holt sich vom Controller noch die Informationen zur Legende und dem
Kompressionsgrad, die es dann anzeigt.
main(String[] args)
Wird nur aufgerufen das Program wenn nicht als Applet sondern durch „java huffman“
aufgerufen wurde. Initialisiert ein Fenster und erzeugt dann ein Objekt des Applets in diesem
Fenster.
Klasse UpperCaseField
Inhalt
Diese Klasse ist von JTextField abgeleitet und stellt das grafische Objekt für die Eingabe der
Zeichenfolge dar. Die Klasse begrenzt dieses Feld auf eine feste Länge.
Attribute
keine
Konstruktor
huffman()
createDefaultModel()
Klasse TreePanel
Inhalt
Diese Klasse ist von JPanel abgeleitet und beschreibt das Feld zum Anzeigen des Code Baumes.
Die Klasse stellt Funktionen zum Zeichnen der Knoten und Linien bereit. Die Eingabekoordinaten
für diese Funktionen sind normiert und liegen zwischen 0.0 und 1.0 und werden von der Klasse auf
die richtige Größe umgerechnet. Alle Knoten und Linien werden erst in einen Puffer gezeichnet und
nur der sichtbare Bereich des Baumes wird dann auf dem Bildschirm ausgegeben. Wenn der Baum
nicht in das Anzeigefeld passt kann gescrollt werden. Der normalisierte Radius (auch zwischen 0.0
und 1.0) bestimmt den Zoomfaktor für die Umrechnung der Koordinaten indem immer auf einen
konstanten Radius von 15 Pixeln gezoomt wird.
Attribute
Konstruktor
- TreePanel()
Methoden
paint(Graphics g)
setRadius(float r)
bestimmt den Zoomfaktor (den Faktor mit dem die normalisierten Koordinaten multipliziert
werden müssen um Pixel-Koordinaten zu bekommen). Erzeugt ein virtuelles Bild
(offScreenImage) mit der Größe der maximalen Pixelkoordinaten und löst das Event
COMPONENT_RESIZED aus, damit die ScrollBars sich dem neuen Zoom anpassen.
clearImage()
int getRealX(float x)
int getRealY(float y)